diff options
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/Analysis/CFG.cpp | 14 | ||||
| -rw-r--r-- | clang/lib/Analysis/ConstructionContext.cpp | 22 | ||||
| -rw-r--r-- | clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp | 3 |
3 files changed, 29 insertions, 10 deletions
diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp index 77eb1d37a40..77770c56f31 100644 --- a/clang/lib/Analysis/CFG.cpp +++ b/clang/lib/Analysis/CFG.cpp @@ -4911,10 +4911,18 @@ static void print_construction_context(raw_ostream &OS, const ConstructionContext *CC) { const Stmt *S1 = nullptr, *S2 = nullptr; switch (CC->getKind()) { - case ConstructionContext::ConstructorInitializerKind: { + case ConstructionContext::SimpleConstructorInitializerKind: { OS << ", "; - const auto *ICC = cast<ConstructorInitializerConstructionContext>(CC); - print_initializer(OS, Helper, ICC->getCXXCtorInitializer()); + const auto *SICC = cast<SimpleConstructorInitializerConstructionContext>(CC); + print_initializer(OS, Helper, SICC->getCXXCtorInitializer()); + break; + } + case ConstructionContext::CXX17ElidedCopyConstructorInitializerKind: { + OS << ", "; + const auto *CICC = + cast<CXX17ElidedCopyConstructorInitializerConstructionContext>(CC); + print_initializer(OS, Helper, CICC->getCXXCtorInitializer()); + S2 = CICC->getCXXBindTemporaryExpr(); break; } case ConstructionContext::SimpleVariableKind: { 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!"); } diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp index ea1d1d30c39..3bea9465706 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp @@ -134,7 +134,7 @@ ExprEngine::getRegionForConstructedObject(const CXXConstructExpr *CE, makeZeroElementRegion(State, LValue, Ty, CallOpts.IsArrayCtorOrDtor); return LValue.getAsRegion(); } - case ConstructionContext::ConstructorInitializerKind: { + case ConstructionContext::SimpleConstructorInitializerKind: { const auto *ICC = cast<ConstructorInitializerConstructionContext>(CC); const auto *Init = ICC->getCXXCtorInitializer(); assert(Init->isAnyMemberInitializer()); @@ -217,6 +217,7 @@ ExprEngine::getRegionForConstructedObject(const CXXConstructExpr *CE, } case ConstructionContext::CXX17ElidedCopyVariableKind: case ConstructionContext::CXX17ElidedCopyReturnedValueKind: + case ConstructionContext::CXX17ElidedCopyConstructorInitializerKind: // Not implemented yet. break; } |

