summaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGExprCXX.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-12-28 21:23:03 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-12-28 21:23:03 +0000
commit55e6d896ad333f07bb3b1ba487df214fc268a4ab (patch)
tree9ac2087dfbe8507c56dd39d17cad42836448829f /lib/CodeGen/CGExprCXX.cpp
parent1de93ee5610e8a97e753c881c574f8d994e71373 (diff)
Notes
Diffstat (limited to 'lib/CodeGen/CGExprCXX.cpp')
-rw-r--r--lib/CodeGen/CGExprCXX.cpp26
1 files changed, 21 insertions, 5 deletions
diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp
index 0749b0ac46a7..c32f1e5415da 100644
--- a/lib/CodeGen/CGExprCXX.cpp
+++ b/lib/CodeGen/CGExprCXX.cpp
@@ -2056,6 +2056,15 @@ static llvm::Value *EmitTypeidFromVTable(CodeGenFunction &CGF, const Expr *E,
// Get the vtable pointer.
Address ThisPtr = CGF.EmitLValue(E).getAddress();
+ QualType SrcRecordTy = E->getType();
+
+ // C++ [class.cdtor]p4:
+ // If the operand of typeid refers to the object under construction or
+ // destruction and the static type of the operand is neither the constructor
+ // or destructor’s class nor one of its bases, the behavior is undefined.
+ CGF.EmitTypeCheck(CodeGenFunction::TCK_DynamicOperation, E->getExprLoc(),
+ ThisPtr.getPointer(), SrcRecordTy);
+
// C++ [expr.typeid]p2:
// If the glvalue expression is obtained by applying the unary * operator to
// a pointer and the pointer is a null pointer value, the typeid expression
@@ -2064,7 +2073,6 @@ static llvm::Value *EmitTypeidFromVTable(CodeGenFunction &CGF, const Expr *E,
// However, this paragraph's intent is not clear. We choose a very generous
// interpretation which implores us to consider comma operators, conditional
// operators, parentheses and other such constructs.
- QualType SrcRecordTy = E->getType();
if (CGF.CGM.getCXXABI().shouldTypeidBeNullChecked(
isGLValueFromPointerDeref(E), SrcRecordTy)) {
llvm::BasicBlock *BadTypeidBlock =
@@ -2127,10 +2135,6 @@ llvm::Value *CodeGenFunction::EmitDynamicCast(Address ThisAddr,
CGM.EmitExplicitCastExprType(DCE, this);
QualType DestTy = DCE->getTypeAsWritten();
- if (DCE->isAlwaysNull())
- if (llvm::Value *T = EmitDynamicCastToNull(*this, DestTy))
- return T;
-
QualType SrcTy = DCE->getSubExpr()->getType();
// C++ [expr.dynamic.cast]p7:
@@ -2151,6 +2155,18 @@ llvm::Value *CodeGenFunction::EmitDynamicCast(Address ThisAddr,
DestRecordTy = DestTy->castAs<ReferenceType>()->getPointeeType();
}
+ // C++ [class.cdtor]p5:
+ // If the operand of the dynamic_cast refers to the object under
+ // construction or destruction and the static type of the operand is not a
+ // pointer to or object of the constructor or destructor’s own class or one
+ // of its bases, the dynamic_cast results in undefined behavior.
+ EmitTypeCheck(TCK_DynamicOperation, DCE->getExprLoc(), ThisAddr.getPointer(),
+ SrcRecordTy);
+
+ if (DCE->isAlwaysNull())
+ if (llvm::Value *T = EmitDynamicCastToNull(*this, DestTy))
+ return T;
+
assert(SrcRecordTy->isRecordType() && "source type must be a record type!");
// C++ [expr.dynamic.cast]p4: