diff options
author | Anders Carlsson <andersca@mac.com> | 2009-09-14 01:30:44 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2009-09-14 01:30:44 +0000 |
commit | 283e4d59b8fe63e93f20b6ffb3a623a4f60a85ea (patch) | |
tree | 0a62837310f7b09b7f6dc58346f79129d8b08fef | |
parent | b9ea0b53d323cdca2b8284ff986a878e195cb97f (diff) |
If a function call returns a reference, don't bind it to a temporary.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@81743 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/CGCXXTemp.cpp | 8 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 9 | ||||
-rw-r--r-- | test/CodeGenCXX/temp-1.cpp | 14 |
3 files changed, 29 insertions, 2 deletions
diff --git a/lib/CodeGen/CGCXXTemp.cpp b/lib/CodeGen/CGCXXTemp.cpp index 177c6db3e8..4768556f6b 100644 --- a/lib/CodeGen/CGCXXTemp.cpp +++ b/lib/CodeGen/CGCXXTemp.cpp @@ -54,7 +54,13 @@ void CodeGenFunction::PopCXXTemporary() { assert(!CleanupInfo.EndBlock && "Should not have an end block for temporary cleanup!"); - EmitBlock(Info.DtorBlock); + llvm::BasicBlock *CurBB = Builder.GetInsertBlock(); + if (CurBB && !CurBB->getTerminator() && + Info.DtorBlock->getNumUses() == 0) { + CurBB->getInstList().splice(CurBB->end(), Info.DtorBlock->getInstList()); + delete Info.DtorBlock; + } else + EmitBlock(Info.DtorBlock); llvm::BasicBlock *CondEnd = 0; diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index a060e47067..a6bf82b590 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -1778,6 +1778,15 @@ Sema::OwningExprResult Sema::MaybeBindToTemporary(Expr *E) { if (RD->hasTrivialDestructor()) return Owned(E); + if (CallExpr *CE = dyn_cast<CallExpr>(E)) { + QualType Ty = CE->getCallee()->getType(); + if (const PointerType *PT = Ty->getAs<PointerType>()) + Ty = PT->getPointeeType(); + + const FunctionType *FTy = Ty->getAsFunctionType(); + if (FTy->getResultType()->isReferenceType()) + return Owned(E); + } CXXTemporary *Temp = CXXTemporary::Create(Context, RD->getDestructor(Context)); ExprTemporaries.push_back(Temp); diff --git a/test/CodeGenCXX/temp-1.cpp b/test/CodeGenCXX/temp-1.cpp index 19a6acecf2..9b97f0083c 100644 --- a/test/CodeGenCXX/temp-1.cpp +++ b/test/CodeGenCXX/temp-1.cpp @@ -63,9 +63,21 @@ struct E { }; // RUN: grep "call void @_ZN1EC1Ev" %t | count 3 && -// RUN: grep "call void @_ZN1ED1Ev" %t | count 5 +// RUN: grep "call void @_ZN1ED1Ev" %t | count 5 && void f5() { E() + E(); !E(); } +struct F { + F(); + ~F(); + F& f(); +}; + +// RUN: grep "call void @_ZN1FC1Ev" %t | count 1 && +// RUN: grep "call void @_ZN1FD1Ev" %t | count 1 +void f6() { + F().f(); +} + |