forked from OSchip/llvm-project
[CFG] [analyzer] Add construction contexts for loop condition variables.
Loop condition variables, eg. while (shared_ptr<int> P = getIntPtr()) { ... }) weren't handled in r324794 because they don't go through the common CFGBuilder::VisitDeclStmt method. Which means that they regressed after r324800. Fix the regression by duplicating the necessary construction context scan in the loop visiting code. Differential Revision: https://reviews.llvm.org/D45706 llvm-svn: 330382
This commit is contained in:
parent
468bc0d8b9
commit
ab9b78b200
|
@ -3169,7 +3169,13 @@ CFGBlock *CFGBuilder::VisitForStmt(ForStmt *F) {
|
|||
if (VarDecl *VD = F->getConditionVariable()) {
|
||||
if (Expr *Init = VD->getInit()) {
|
||||
autoCreateBlock();
|
||||
appendStmt(Block, F->getConditionVariableDeclStmt());
|
||||
const DeclStmt *DS = F->getConditionVariableDeclStmt();
|
||||
assert(DS->isSingleDecl());
|
||||
findConstructionContexts(
|
||||
ConstructionContextLayer::create(cfg->getBumpVectorContext(),
|
||||
const_cast<DeclStmt *>(DS)),
|
||||
Init);
|
||||
appendStmt(Block, DS);
|
||||
EntryConditionBlock = addStmt(Init);
|
||||
assert(Block == EntryConditionBlock);
|
||||
maybeAddScopeBeginForVarDecl(EntryConditionBlock, VD, C);
|
||||
|
@ -3494,7 +3500,13 @@ CFGBlock *CFGBuilder::VisitWhileStmt(WhileStmt *W) {
|
|||
if (VarDecl *VD = W->getConditionVariable()) {
|
||||
if (Expr *Init = VD->getInit()) {
|
||||
autoCreateBlock();
|
||||
appendStmt(Block, W->getConditionVariableDeclStmt());
|
||||
const DeclStmt *DS = W->getConditionVariableDeclStmt();
|
||||
assert(DS->isSingleDecl());
|
||||
findConstructionContexts(
|
||||
ConstructionContextLayer::create(cfg->getBumpVectorContext(),
|
||||
const_cast<DeclStmt *>(DS)),
|
||||
Init);
|
||||
appendStmt(Block, DS);
|
||||
EntryConditionBlock = addStmt(Init);
|
||||
assert(Block == EntryConditionBlock);
|
||||
maybeAddScopeBeginForVarDecl(EntryConditionBlock, VD, C);
|
||||
|
|
|
@ -388,7 +388,8 @@ void test_if_jumps() {
|
|||
// CHECK: [B4]
|
||||
// CHECK-NEXT: 1: a
|
||||
// CHECK-NEXT: 2: [B4.1] (ImplicitCastExpr, NoOp, const class A)
|
||||
// CHECK-NEXT: 3: [B4.2] (CXXConstructExpr, class A)
|
||||
// WARNINGS-NEXT: 3: [B4.2] (CXXConstructExpr, class A)
|
||||
// ANALYZER-NEXT: 3: [B4.2] (CXXConstructExpr, [B4.4], class A)
|
||||
// CHECK-NEXT: 4: A b = a;
|
||||
// CHECK-NEXT: 5: b
|
||||
// CHECK-NEXT: 6: [B4.5] (ImplicitCastExpr, NoOp, const class A)
|
||||
|
@ -478,7 +479,8 @@ void test_while_implicit_scope() {
|
|||
// CHECK: [B10]
|
||||
// CHECK-NEXT: 1: a
|
||||
// CHECK-NEXT: 2: [B10.1] (ImplicitCastExpr, NoOp, const class A)
|
||||
// CHECK-NEXT: 3: [B10.2] (CXXConstructExpr, class A)
|
||||
// WARNINGS-NEXT: 3: [B10.2] (CXXConstructExpr, class A)
|
||||
// ANALYZER-NEXT: 3: [B10.2] (CXXConstructExpr, [B10.4], class A)
|
||||
// CHECK-NEXT: 4: A b = a;
|
||||
// CHECK-NEXT: 5: b
|
||||
// CHECK-NEXT: 6: [B10.5] (ImplicitCastExpr, NoOp, const class A)
|
||||
|
@ -761,7 +763,8 @@ void test_switch_jumps() {
|
|||
// CHECK: [B4]
|
||||
// CHECK-NEXT: 1: a
|
||||
// CHECK-NEXT: 2: [B4.1] (ImplicitCastExpr, NoOp, const class A)
|
||||
// CHECK-NEXT: 3: [B4.2] (CXXConstructExpr, class A)
|
||||
// WARNINGS-NEXT: 3: [B4.2] (CXXConstructExpr, class A)
|
||||
// ANALYZER-NEXT: 3: [B4.2] (CXXConstructExpr, [B4.4], class A)
|
||||
// CHECK-NEXT: 4: A b = a;
|
||||
// CHECK-NEXT: 5: b
|
||||
// CHECK-NEXT: 6: [B4.5] (ImplicitCastExpr, NoOp, const class A)
|
||||
|
@ -851,7 +854,8 @@ void test_for_implicit_scope() {
|
|||
// CHECK: [B10]
|
||||
// CHECK-NEXT: 1: b
|
||||
// CHECK-NEXT: 2: [B10.1] (ImplicitCastExpr, NoOp, const class A)
|
||||
// CHECK-NEXT: 3: [B10.2] (CXXConstructExpr, class A)
|
||||
// WARNINGS-NEXT: 3: [B10.2] (CXXConstructExpr, class A)
|
||||
// ANALYZER-NEXT: 3: [B10.2] (CXXConstructExpr, [B10.4], class A)
|
||||
// CHECK-NEXT: 4: A c = b;
|
||||
// CHECK-NEXT: 5: c
|
||||
// CHECK-NEXT: 6: [B10.5] (ImplicitCastExpr, NoOp, const class A)
|
||||
|
|
|
@ -450,6 +450,85 @@ void temporaryInCondition() {
|
|||
if (C());
|
||||
}
|
||||
|
||||
// CHECK: void temporaryInConditionVariable()
|
||||
// CHECK: 1: C() (CXXConstructExpr, [B2.2], class C)
|
||||
// CXX11-NEXT: 2: [B2.1]
|
||||
// CXX11-NEXT: 3: [B2.2] (CXXConstructExpr, [B2.4], class C)
|
||||
// CXX11-NEXT: 4: C c = C();
|
||||
// CXX11-NEXT: 5: c
|
||||
// CXX11-NEXT: 6: [B2.5] (ImplicitCastExpr, NoOp, const class C)
|
||||
// CXX11-NEXT: 7: [B2.6].operator bool
|
||||
// CXX11-NEXT: 8: [B2.6]
|
||||
// CXX11-NEXT: 9: [B2.8] (ImplicitCastExpr, UserDefinedConversion, _Bool)
|
||||
// CXX11-NEXT: T: if [B2.9]
|
||||
// CXX17-NEXT: 2: C c = C();
|
||||
// CXX17-NEXT: 3: c
|
||||
// CXX17-NEXT: 4: [B2.3] (ImplicitCastExpr, NoOp, const class C)
|
||||
// CXX17-NEXT: 5: [B2.4].operator bool
|
||||
// CXX17-NEXT: 6: [B2.4]
|
||||
// CXX17-NEXT: 7: [B2.6] (ImplicitCastExpr, UserDefinedConversion, _Bool)
|
||||
// CXX17-NEXT: T: if [B2.7]
|
||||
void temporaryInConditionVariable() {
|
||||
if (C c = C());
|
||||
}
|
||||
|
||||
|
||||
// CHECK: void temporaryInForLoopConditionVariable()
|
||||
// CHECK: [B2]
|
||||
// CXX11-NEXT: 1: C() (CXXConstructExpr, [B2.2], class C)
|
||||
// CXX11-NEXT: 2: [B2.1]
|
||||
// CXX11-NEXT: 3: [B2.2] (CXXConstructExpr, [B2.4], class C)
|
||||
// CXX11-NEXT: 4: C c2 = C();
|
||||
// CXX11-NEXT: 5: c2
|
||||
// CXX11-NEXT: 6: [B2.5] (ImplicitCastExpr, NoOp, const class C)
|
||||
// CXX11-NEXT: 7: [B2.6].operator bool
|
||||
// CXX11-NEXT: 8: [B2.6]
|
||||
// CXX11-NEXT: 9: [B2.8] (ImplicitCastExpr, UserDefinedConversion, _Bool)
|
||||
// CXX11-NEXT: T: for (...; [B2.9]; )
|
||||
// CXX17-NEXT: 1: C() (CXXConstructExpr, [B2.2], class C)
|
||||
// CXX17-NEXT: 2: C c2 = C();
|
||||
// CXX17-NEXT: 3: c2
|
||||
// CXX17-NEXT: 4: [B2.3] (ImplicitCastExpr, NoOp, const class C)
|
||||
// CXX17-NEXT: 5: [B2.4].operator bool
|
||||
// CXX17-NEXT: 6: [B2.4]
|
||||
// CXX17-NEXT: 7: [B2.6] (ImplicitCastExpr, UserDefinedConversion, _Bool)
|
||||
// CXX17-NEXT: T: for (...; [B2.7]; )
|
||||
// CHECK: [B3]
|
||||
// CXX11-NEXT: 1: C() (CXXConstructExpr, [B3.2], class C)
|
||||
// CXX11-NEXT: 2: [B3.1]
|
||||
// CXX11-NEXT: 3: [B3.2] (CXXConstructExpr, [B3.4], class C)
|
||||
// CXX11-NEXT: 4: C c1 = C();
|
||||
// CXX17-NEXT: 1: C() (CXXConstructExpr, [B3.2], class C)
|
||||
// CXX17-NEXT: 2: C c1 = C();
|
||||
void temporaryInForLoopConditionVariable() {
|
||||
for (C c1 = C(); C c2 = C(); );
|
||||
}
|
||||
|
||||
|
||||
// FIXME: Find construction context for the loop condition variable.
|
||||
// CHECK: void temporaryInWhileLoopConditionVariable()
|
||||
// CXX11: 1: C() (CXXConstructExpr, [B2.2], class C)
|
||||
// CXX11-NEXT: 2: [B2.1]
|
||||
// CXX11-NEXT: 3: [B2.2] (CXXConstructExpr, [B2.4], class C)
|
||||
// CXX11-NEXT: 4: C c = C();
|
||||
// CXX11-NEXT: 5: c
|
||||
// CXX11-NEXT: 6: [B2.5] (ImplicitCastExpr, NoOp, const class C)
|
||||
// CXX11-NEXT: 7: [B2.6].operator bool
|
||||
// CXX11-NEXT: 8: [B2.6]
|
||||
// CXX11-NEXT: 9: [B2.8] (ImplicitCastExpr, UserDefinedConversion, _Bool)
|
||||
// CXX11-NEXT: T: while [B2.9]
|
||||
// CXX17: 1: C() (CXXConstructExpr, [B2.2], class C)
|
||||
// CXX17-NEXT: 2: C c = C();
|
||||
// CXX17-NEXT: 3: c
|
||||
// CXX17-NEXT: 4: [B2.3] (ImplicitCastExpr, NoOp, const class C)
|
||||
// CXX17-NEXT: 5: [B2.4].operator bool
|
||||
// CXX17-NEXT: 6: [B2.4]
|
||||
// CXX17-NEXT: 7: [B2.6] (ImplicitCastExpr, UserDefinedConversion, _Bool)
|
||||
// CXX17-NEXT: T: while [B2.7]
|
||||
void temporaryInWhileLoopConditionVariable() {
|
||||
while (C c = C());
|
||||
}
|
||||
|
||||
} // end namespace temporary_object_expr_without_dtors
|
||||
|
||||
namespace temporary_object_expr_with_dtors {
|
||||
|
|
|
@ -296,7 +296,7 @@ void test_if_jumps() {
|
|||
// CHECK-NEXT: 1: CFGScopeBegin(b)
|
||||
// CHECK-NEXT: 2: a
|
||||
// CHECK-NEXT: 3: [B4.2] (ImplicitCastExpr, NoOp, const class A)
|
||||
// CHECK-NEXT: 4: [B4.3] (CXXConstructExpr, class A)
|
||||
// CHECK-NEXT: 4: [B4.3] (CXXConstructExpr, [B4.5], class A)
|
||||
// CHECK-NEXT: 5: A b = a;
|
||||
// CHECK-NEXT: 6: b
|
||||
// CHECK-NEXT: 7: [B4.6] (ImplicitCastExpr, NoOp, const class A)
|
||||
|
@ -395,7 +395,7 @@ void test_while_implicit_scope() {
|
|||
// CHECK-NEXT: 1: CFGScopeBegin(b)
|
||||
// CHECK-NEXT: 2: a
|
||||
// CHECK-NEXT: 3: [B10.2] (ImplicitCastExpr, NoOp, const class A)
|
||||
// CHECK-NEXT: 4: [B10.3] (CXXConstructExpr, class A)
|
||||
// CHECK-NEXT: 4: [B10.3] (CXXConstructExpr, [B10.5], class A)
|
||||
// CHECK-NEXT: 5: A b = a;
|
||||
// CHECK-NEXT: 6: b
|
||||
// CHECK-NEXT: 7: [B10.6] (ImplicitCastExpr, NoOp, const class A)
|
||||
|
@ -540,7 +540,7 @@ void test_do_jumps() {
|
|||
// CHECK-NEXT: 1: CFGScopeBegin(b)
|
||||
// CHECK-NEXT: 2: a
|
||||
// CHECK-NEXT: 3: [B4.2] (ImplicitCastExpr, NoOp, const class A)
|
||||
// CHECK-NEXT: 4: [B4.3] (CXXConstructExpr, class A)
|
||||
// CHECK-NEXT: 4: [B4.3] (CXXConstructExpr, [B4.5], class A)
|
||||
// CHECK-NEXT: 5: A b = a;
|
||||
// CHECK-NEXT: 6: b
|
||||
// CHECK-NEXT: 7: [B4.6] (ImplicitCastExpr, NoOp, const class A)
|
||||
|
@ -640,7 +640,7 @@ void test_for_implicit_scope() {
|
|||
// CHECK-NEXT: 1: CFGScopeBegin(c)
|
||||
// CHECK-NEXT: 2: b
|
||||
// CHECK-NEXT: 3: [B10.2] (ImplicitCastExpr, NoOp, const class A)
|
||||
// CHECK-NEXT: 4: [B10.3] (CXXConstructExpr, class A)
|
||||
// CHECK-NEXT: 4: [B10.3] (CXXConstructExpr, [B10.5], class A)
|
||||
// CHECK-NEXT: 5: A c = b;
|
||||
// CHECK-NEXT: 6: c
|
||||
// CHECK-NEXT: 7: [B10.6] (ImplicitCastExpr, NoOp, const class A)
|
||||
|
|
Loading…
Reference in New Issue