summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGExprCXX.cpp
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2017-12-28 12:45:41 +0000
committerStephan Bergmann <sbergman@redhat.com>2017-12-28 12:45:41 +0000
commitd71ad177eb186eee445c3843699c53ad4619240e (patch)
treef93b3981b3f51fe2394acf18d615f59434023219 /clang/lib/CodeGen/CGExprCXX.cpp
parent703478ae6e529de9ec346f79961d980c604c299e (diff)
downloadbcm5719-llvm-d71ad177eb186eee445c3843699c53ad4619240e.tar.gz
bcm5719-llvm-d71ad177eb186eee445c3843699c53ad4619240e.zip
-fsanitize=vptr warnings on bad static types in dynamic_cast and typeid
...when such an operation is done on an object during con-/destruction. This is the cfe part of a patch covering both cfe and compiler-rt. Differential Revision: https://reviews.llvm.org/D40295 llvm-svn: 321519
Diffstat (limited to 'clang/lib/CodeGen/CGExprCXX.cpp')
-rw-r--r--clang/lib/CodeGen/CGExprCXX.cpp26
1 files changed, 21 insertions, 5 deletions
diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp
index 0749b0ac46a..c32f1e5415d 100644
--- a/clang/lib/CodeGen/CGExprCXX.cpp
+++ b/clang/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:
OpenPOWER on IntegriCloud