When checking whether to bind an expression to a temporary, don't bind Obj-C message send expressions who call methods that return references.
llvm-svn: 108559
This commit is contained in:
parent
e1c6749665
commit
bb4cfdff7e
|
@ -2579,29 +2579,17 @@ Sema::OwningExprResult Sema::MaybeBindToTemporary(Expr *E) {
|
|||
if (!RT)
|
||||
return Owned(E);
|
||||
|
||||
// If this is the result of a call expression, our source might
|
||||
// actually be a reference, in which case we shouldn't bind.
|
||||
// If this is the result of a call or an Objective-C message send expression,
|
||||
// our source might actually be a reference, in which case we shouldn't bind.
|
||||
if (CallExpr *CE = dyn_cast<CallExpr>(E)) {
|
||||
QualType Ty = CE->getCallee()->getType();
|
||||
if (const PointerType *PT = Ty->getAs<PointerType>())
|
||||
Ty = PT->getPointeeType();
|
||||
else if (const BlockPointerType *BPT = Ty->getAs<BlockPointerType>())
|
||||
Ty = BPT->getPointeeType();
|
||||
|
||||
const FunctionType *FTy = Ty->getAs<FunctionType>();
|
||||
if (FTy->getResultType()->isReferenceType())
|
||||
if (CE->getCallReturnType()->isReferenceType())
|
||||
return Owned(E);
|
||||
} else if (ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(E)) {
|
||||
if (const ObjCMethodDecl *MD = ME->getMethodDecl()) {
|
||||
if (MD->getResultType()->isReferenceType())
|
||||
return Owned(E);
|
||||
}
|
||||
}
|
||||
else if (ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(E)) {
|
||||
QualType Ty = ME->getType();
|
||||
if (const PointerType *PT = Ty->getAs<PointerType>())
|
||||
Ty = PT->getPointeeType();
|
||||
else if (const BlockPointerType *BPT = Ty->getAs<BlockPointerType>())
|
||||
Ty = BPT->getPointeeType();
|
||||
if (Ty->isReferenceType())
|
||||
return Owned(E);
|
||||
}
|
||||
|
||||
|
||||
// That should be enough to guarantee that this type is complete.
|
||||
// If it has a trivial destructor, we can avoid the extra copy.
|
||||
|
|
|
@ -19,6 +19,7 @@ struct A { ~A(); };
|
|||
|
||||
// CHECK: define void @_Z1fP1B
|
||||
// CHECK: objc_msgSend to
|
||||
// CHECK-NOT: call void @_ZN1AD1Ev
|
||||
// CHECK: ret void
|
||||
void f(B* b) {
|
||||
(void)[b getA];
|
||||
|
|
Loading…
Reference in New Issue