NoQ created this revision.
NoQ added reviewers: dcoughlin, xazax.hun, a.sidorin, george.karpenkov, szepet.
Herald added subscribers: cfe-commits, rnkovacs.

Loop condition variables (eg. `while (shared_ptr<int> P = getIntPtr()) { ... 
}`) weren't handled in https://reviews.llvm.org/D42699 because they don't go 
through `CFGBuilder::VisitDeclStmt`. Which means that they regressed in 
https://reviews.llvm.org/D42721.

Fix them by providing the construction context.


Repository:
  rC Clang

https://reviews.llvm.org/D45706

Files:
  lib/Analysis/CFG.cpp
  test/Analysis/auto-obj-dtors-cfg-output.cpp
  test/Analysis/cfg-rich-constructors.cpp
  test/Analysis/scopes-cfg-output.cpp

Index: test/Analysis/scopes-cfg-output.cpp
===================================================================
--- test/Analysis/scopes-cfg-output.cpp
+++ test/Analysis/scopes-cfg-output.cpp
@@ -296,7 +296,7 @@
 // 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 @@
 // 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 @@
 // 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 @@
 // 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)
Index: test/Analysis/cfg-rich-constructors.cpp
===================================================================
--- test/Analysis/cfg-rich-constructors.cpp
+++ test/Analysis/cfg-rich-constructors.cpp
@@ -450,6 +450,85 @@
   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 {
Index: test/Analysis/auto-obj-dtors-cfg-output.cpp
===================================================================
--- test/Analysis/auto-obj-dtors-cfg-output.cpp
+++ test/Analysis/auto-obj-dtors-cfg-output.cpp
@@ -388,7 +388,8 @@
 // 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 @@
 // 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 @@
 // 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 @@
 // 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)
Index: lib/Analysis/CFG.cpp
===================================================================
--- lib/Analysis/CFG.cpp
+++ lib/Analysis/CFG.cpp
@@ -3169,7 +3169,13 @@
       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 @@
     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);
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D45706: [CFG] [ana... Artem Dergachev via Phabricator via cfe-commits

Reply via email to