summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGExprCXX.cpp
diff options
context:
space:
mode:
authorJames Y Knight <jyknight@google.com>2019-02-05 16:05:50 +0000
committerJames Y Knight <jyknight@google.com>2019-02-05 16:05:50 +0000
commitb92d290e48e908c083976ef3a807ed1fcc9bf209 (patch)
tree7e50929d62c9d59ad910c86a83d9e95220511427 /clang/lib/CodeGen/CGExprCXX.cpp
parentb3b896811730dc527a461a18c5e73c0db5de4aea (diff)
downloadbcm5719-llvm-b92d290e48e908c083976ef3a807ed1fcc9bf209.tar.gz
bcm5719-llvm-b92d290e48e908c083976ef3a807ed1fcc9bf209.zip
[opaque pointer types] Fix the CallInfo passed to EmitCall in some
edge cases. Currently, EmitCall emits a call instruction with a function type derived from the pointee-type of the callee. This *should* be the same as the type created from the CallInfo parameter, but in some cases an incorrect CallInfo was being passed. All of these fixes were discovered by the addition of the assert in EmitCall which verifies that the passed-in CallInfo matches the Callee's function type. As far as I know, these issues caused no bugs at the moment, as the correct types were ultimately being emitted. But, some would become problematic when pointee types are removed. List of fixes: * arrangeCXXConstructorCall was passing an incorrect value for the number of Required args, when calling an inheriting constructor where the inherited constructor is variadic. (The inheriting constructor doesn't actually get passed any of the user's args, but the code was calculating it as if it did). * arrangeFreeFunctionLikeCall was not including the count of the pass_object_size arguments in the count of required args. * OpenCL uses other address spaces for the "this" pointer. However, commonEmitCXXMemberOrOperatorCall was not annotating the address space on the "this" argument of the call. * Destructor calls were being created with EmitCXXMemberOrOperatorCall instead of EmitCXXDestructorCall in a few places. This was a problem because the calling convention sometimes has destructors returning "this" rather than void, and the latter function knows about that, and sets up the types properly (through calling arrangeCXXStructorDeclaration), while the former does not. * generateObjCGetterBody: the 'objc_getProperty' function returns type 'id', but was being called as if it returned the particular property's type. (That is of course the *dynamic* return type, and there's a downcast immediately after.) * OpenMP user-defined reduction functions (#pragma omp declare reduction) can be called with a subclass of the declared type. In such case, the call was being setup as if the function had been actually declared to take the subtype, rather than the base type. Differential Revision: https://reviews.llvm.org/D57664 llvm-svn: 353181
Diffstat (limited to 'clang/lib/CodeGen/CGExprCXX.cpp')
-rw-r--r--clang/lib/CodeGen/CGExprCXX.cpp30
1 files changed, 14 insertions, 16 deletions
diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp
index 86ec18dbe2a..13612d377c6 100644
--- a/clang/lib/CodeGen/CGExprCXX.cpp
+++ b/clang/lib/CodeGen/CGExprCXX.cpp
@@ -40,13 +40,11 @@ commonEmitCXXMemberOrOperatorCall(CodeGenFunction &CGF, const CXXMethodDecl *MD,
isa<CXXOperatorCallExpr>(CE));
assert(MD->isInstance() &&
"Trying to emit a member or operator call expr on a static method!");
- ASTContext &C = CGF.getContext();
// Push the this ptr.
const CXXRecordDecl *RD =
CGF.CGM.getCXXABI().getThisArgumentTypeForMethod(MD);
- Args.add(RValue::get(This),
- RD ? C.getPointerType(C.getTypeDeclType(RD)) : C.VoidPtrTy);
+ Args.add(RValue::get(This), CGF.getTypes().DeriveThisType(RD, MD));
// If there is an implicit parameter (e.g. VTT), emit it.
if (ImplicitParam) {
@@ -326,9 +324,6 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr(
CallLoc, This.getPointer(), C.getRecordType(CalleeDecl->getParent()),
/*Alignment=*/CharUnits::Zero(), SkippedChecks);
- // 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.
@@ -337,7 +332,7 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr(
// because then we know what the type is.
bool UseVirtualCall = CanUseVirtualCall && !DevirtualizedMethod;
- if (const CXXDestructorDecl *Dtor = dyn_cast<CXXDestructorDecl>(MD)) {
+ if (const CXXDestructorDecl *Dtor = dyn_cast<CXXDestructorDecl>(CalleeDecl)) {
assert(CE->arg_begin() == CE->arg_end() &&
"Destructor shouldn't have explicit parameters");
assert(ReturnValue.isNull() && "Destructor shouldn't have return value");
@@ -347,26 +342,29 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr(
cast<CXXMemberCallExpr>(CE));
} else {
CGCallee Callee;
- if (getLangOpts().AppleKext && MD->isVirtual() && HasQualifier)
- Callee = BuildAppleKextVirtualCall(MD, Qualifier, Ty);
+ if (getLangOpts().AppleKext && Dtor->isVirtual() && HasQualifier)
+ Callee = BuildAppleKextVirtualCall(Dtor, Qualifier, Ty);
else if (!DevirtualizedMethod)
Callee = CGCallee::forDirect(
CGM.getAddrOfCXXStructor(Dtor, StructorType::Complete, FInfo, Ty),
GlobalDecl(Dtor, Dtor_Complete));
else {
- const CXXDestructorDecl *DDtor =
- cast<CXXDestructorDecl>(DevirtualizedMethod);
Callee = CGCallee::forDirect(
- CGM.GetAddrOfFunction(GlobalDecl(DDtor, Dtor_Complete), Ty),
- GlobalDecl(DDtor, Dtor_Complete));
+ CGM.GetAddrOfFunction(GlobalDecl(Dtor, Dtor_Complete), Ty),
+ GlobalDecl(Dtor, Dtor_Complete));
}
- EmitCXXMemberOrOperatorCall(
- CalleeDecl, Callee, ReturnValue, This.getPointer(),
- /*ImplicitParam=*/nullptr, QualType(), CE, nullptr);
+
+ EmitCXXDestructorCall(Dtor, Callee, This.getPointer(),
+ /*ImplicitParam=*/nullptr,
+ /*ImplicitParamTy=*/QualType(), nullptr,
+ getFromDtorType(Dtor_Complete));
}
return RValue::get(nullptr);
}
+ // FIXME: Uses of 'MD' past this point need to be audited. We may need to use
+ // 'CalleeDecl' instead.
+
CGCallee Callee;
if (const CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(MD)) {
Callee = CGCallee::forDirect(
OpenPOWER on IntegriCloud