summaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaDeclCXX.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2011-02-16 08:02:54 +0000
committerJohn McCall <rjmccall@apple.com>2011-02-16 08:02:54 +0000
commit1bf5846abf2ce98c4c9c420d1757b01a1663d8cc (patch)
tree2dcbb6372072983963df0b5d6bf58a31bdf103d0 /clang/lib/Sema/SemaDeclCXX.cpp
parentc8fb2557b9e96fcde75d8cb4a5bf6de06e1ea470 (diff)
downloadllvm-1bf5846abf2ce98c4c9c420d1757b01a1663d8cc.tar.gz
Save a copy expression for non-trivial copy constructions of catch variables.
llvm-svn: 125661
Diffstat (limited to 'clang/lib/Sema/SemaDeclCXX.cpp')
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp38
1 files changed, 26 insertions, 12 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index f929aa039ed4..58f656c1454a 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -6593,7 +6593,7 @@ VarDecl *Sema::BuildExceptionDeclaration(Scope *S,
ExDecl->setExceptionVariable(true);
if (!Invalid) {
- if (const RecordType *RecordTy = ExDeclType->getAs<RecordType>()) {
+ if (const RecordType *recordType = ExDeclType->getAs<RecordType>()) {
// C++ [except.handle]p16:
// The object declared in an exception-declaration or, if the
// exception-declaration does not specify a name, a temporary (12.2) is
@@ -6603,18 +6603,32 @@ VarDecl *Sema::BuildExceptionDeclaration(Scope *S,
//
// We just pretend to initialize the object with itself, then make sure
// it can be destroyed later.
- InitializedEntity Entity = InitializedEntity::InitializeVariable(ExDecl);
- Expr *ExDeclRef = DeclRefExpr::Create(Context, 0, SourceRange(), ExDecl,
- Loc, ExDeclType, VK_LValue, 0);
- InitializationKind Kind = InitializationKind::CreateCopy(Loc,
- SourceLocation());
- InitializationSequence InitSeq(*this, Entity, Kind, &ExDeclRef, 1);
- ExprResult Result = InitSeq.Perform(*this, Entity, Kind,
- MultiExprArg(*this, &ExDeclRef, 1));
- if (Result.isInvalid())
+ QualType initType = ExDeclType;
+
+ InitializedEntity entity =
+ InitializedEntity::InitializeVariable(ExDecl);
+ InitializationKind initKind =
+ InitializationKind::CreateCopy(Loc, SourceLocation());
+
+ Expr *opaqueValue =
+ new (Context) OpaqueValueExpr(Loc, initType, VK_LValue, OK_Ordinary);
+ InitializationSequence sequence(*this, entity, initKind, &opaqueValue, 1);
+ ExprResult result = sequence.Perform(*this, entity, initKind,
+ MultiExprArg(&opaqueValue, 1));
+ if (result.isInvalid())
Invalid = true;
- else
- FinalizeVarWithDestructor(ExDecl, RecordTy);
+ else {
+ // If the constructor used was non-trivial, set this as the
+ // "initializer".
+ CXXConstructExpr *construct = cast<CXXConstructExpr>(result.take());
+ if (!construct->getConstructor()->isTrivial()) {
+ Expr *init = MaybeCreateExprWithCleanups(construct);
+ ExDecl->setInit(init);
+ }
+
+ // And make sure it's destructable.
+ FinalizeVarWithDestructor(ExDecl, recordType);
+ }
}
}