summaryrefslogtreecommitdiffstats
path: root/clang/lib/Analysis/ConstructionContext.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Analysis/ConstructionContext.cpp')
-rw-r--r--clang/lib/Analysis/ConstructionContext.cpp22
1 files changed, 16 insertions, 6 deletions
diff --git a/clang/lib/Analysis/ConstructionContext.cpp b/clang/lib/Analysis/ConstructionContext.cpp
index 31657df259c..ad0dbd2bb11 100644
--- a/clang/lib/Analysis/ConstructionContext.cpp
+++ b/clang/lib/Analysis/ConstructionContext.cpp
@@ -62,21 +62,31 @@ const ConstructionContext *ConstructionContext::createFromLayers(
// lifetime extension on the parent layer.
if (const ConstructionContextLayer *ParentLayer = TopLayer->getParent()) {
assert(ParentLayer->isLast());
+ // C++17 *requires* elision of the constructor at the return site
+ // and at variable/member initialization site, while previous standards
+ // were allowing an optional elidable constructor.
+ // This is the C++17 copy-elided construction into a ctor initializer.
+ if (const CXXCtorInitializer *I = ParentLayer->getTriggerInit()) {
+ return create<
+ CXX17ElidedCopyConstructorInitializerConstructionContext>(C,
+ I, BTE);
+ }
+ assert(ParentLayer->getTriggerStmt() &&
+ "Non-statement-based layers have been handled above!");
+ // This is the normal, non-C++17 case: a temporary object which has
+ // both destruction and materialization info attached to it in the AST.
if ((MTE = dyn_cast<MaterializeTemporaryExpr>(
ParentLayer->getTriggerStmt()))) {
- // A temporary object which has both destruction and
- // materialization info.
return create<TemporaryObjectConstructionContext>(C, BTE, MTE);
}
- // C++17 *requires* elision of the constructor at the return site
- // and at variable initialization site, while previous standards
- // were allowing an optional elidable constructor.
+ // This is C++17 copy-elided construction into return statement.
if (auto *RS = dyn_cast<ReturnStmt>(ParentLayer->getTriggerStmt())) {
assert(!RS->getRetValue()->getType().getCanonicalType()
->getAsCXXRecordDecl()->hasTrivialDestructor());
return create<CXX17ElidedCopyReturnedValueConstructionContext>(C,
RS, BTE);
}
+ // This is C++17 copy-elided construction into a simple variable.
if (auto *DS = dyn_cast<DeclStmt>(ParentLayer->getTriggerStmt())) {
assert(!cast<VarDecl>(DS->getSingleDecl())->getType()
.getCanonicalType()->getAsCXXRecordDecl()
@@ -104,7 +114,7 @@ const ConstructionContext *ConstructionContext::createFromLayers(
llvm_unreachable("Unexpected construction context with statement!");
} else if (const CXXCtorInitializer *I = TopLayer->getTriggerInit()) {
assert(TopLayer->isLast());
- return create<ConstructorInitializerConstructionContext>(C, I);
+ return create<SimpleConstructorInitializerConstructionContext>(C, I);
}
llvm_unreachable("Unexpected construction context!");
}
OpenPOWER on IntegriCloud