summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorArtem Dergachev <artem.dergachev@gmail.com>2018-03-22 22:02:38 +0000
committerArtem Dergachev <artem.dergachev@gmail.com>2018-03-22 22:02:38 +0000
commit922455fe62b55dd20d6e10f1c226c96944c1adbf (patch)
tree14224a81b0cafa2d3d16e6ff6af1da1b5adbe04f /clang/lib
parent40d3b32e1275458c1b5b0afaec8e42b80412587a (diff)
downloadbcm5719-llvm-922455fe62b55dd20d6e10f1c226c96944c1adbf.tar.gz
bcm5719-llvm-922455fe62b55dd20d6e10f1c226c96944c1adbf.zip
[CFG] [analyzer] Add C++17-specific ctor-initializer construction contexts.
CXXCtorInitializer-based constructors are also affected by the C++17 mandatory copy elision, like variable constructors and return value constructors. Extend r328248 to support those. Differential Revision: https://reviews.llvm.org/D44763 llvm-svn: 328255
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Analysis/CFG.cpp14
-rw-r--r--clang/lib/Analysis/ConstructionContext.cpp22
-rw-r--r--clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp3
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;
}
OpenPOWER on IntegriCloud