diff options
author | Vedant Kumar <vsk@apple.com> | 2016-10-19 20:21:16 +0000 |
---|---|---|
committer | Vedant Kumar <vsk@apple.com> | 2016-10-19 20:21:16 +0000 |
commit | b35098f3acfb5c873065cbd880aa559b43640ded (patch) | |
tree | 5956daf4031a80d23bd01974e70b4db5523346a1 /lib/CodeGen/CGExprCXX.cpp | |
parent | 8bd12ac7941aee16def56b2bf0d6d39d8c2aaa7b (diff) |
[ubsan] Use the object pointer's type info for devirtualized calls
ubsan reports a false positive 'invalid member call' diagnostic on the
following example (PR30478):
struct Base1 {
virtual int f1() { return 1; }
};
struct Base2 {
virtual int f1() { return 2; }
};
struct Derived2 final : Base1, Base2 {
int f1() override { return 3; }
};
int t1() {
Derived2 d;
return static_cast<Base2 *>(&d)->f1();
}
Adding the "final" attribute to a most-derived class allows clang to
devirtualize member calls into an instance of that class. We should pass
along the type info of the object pointer to avoid the FP. In this case,
that means passing along the type info for 'Derived2' instead of 'Base2'
when checking the dynamic type of static_cast<Base2 *>(&d2).
Differential Revision: https://reviews.llvm.org/D25448
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@284636 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGExprCXX.cpp')
-rw-r--r-- | lib/CodeGen/CGExprCXX.cpp | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp index ccab9f08d6..011000fc19 100644 --- a/lib/CodeGen/CGExprCXX.cpp +++ b/lib/CodeGen/CGExprCXX.cpp @@ -241,6 +241,9 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr( llvm::FunctionType *Ty = CGM.getTypes().GetFunctionType(*FInfo); + // FIXME: Uses of 'MD' past this point need to be audited. We may need to use + // 'CalleeDecl' instead. + // C++ [class.virtual]p12: // Explicit qualification with the scope operator (5.1) suppresses the // virtual call mechanism. @@ -268,9 +271,9 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr( cast<CXXDestructorDecl>(DevirtualizedMethod); Callee = CGM.GetAddrOfFunction(GlobalDecl(DDtor, Dtor_Complete), Ty); } - EmitCXXMemberOrOperatorCall(MD, Callee, ReturnValue, This.getPointer(), - /*ImplicitParam=*/nullptr, QualType(), CE, - nullptr); + EmitCXXMemberOrOperatorCall( + CalleeDecl, Callee, ReturnValue, This.getPointer(), + /*ImplicitParam=*/nullptr, QualType(), CE, nullptr); } return RValue::get(nullptr); } @@ -302,9 +305,9 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr( *this, CalleeDecl, This, UseVirtualCall); } - return EmitCXXMemberOrOperatorCall(MD, Callee, ReturnValue, This.getPointer(), - /*ImplicitParam=*/nullptr, QualType(), CE, - RtlArgs); + return EmitCXXMemberOrOperatorCall( + CalleeDecl, Callee, ReturnValue, This.getPointer(), + /*ImplicitParam=*/nullptr, QualType(), CE, RtlArgs); } RValue |