[clang] 8f670d5 - CFG: Create scope for non-compound range-for body.

James Y Knight via cfe-commits cfe-commits at lists.llvm.org
Sun Jan 31 15:43:32 PST 2021


Author: James Y Knight
Date: 2021-01-31T18:43:00-05:00
New Revision: 8f670d5b6d8f39bf9bf1d142dacef3afaed6d70b

URL: https://github.com/llvm/llvm-project/commit/8f670d5b6d8f39bf9bf1d142dacef3afaed6d70b
DIFF: https://github.com/llvm/llvm-project/commit/8f670d5b6d8f39bf9bf1d142dacef3afaed6d70b.diff

LOG: CFG: Create scope for non-compound range-for body.

Previously, it was omitting the destructor call from the CFG, which
could result in incorrect diagnostics.

Added: 
    

Modified: 
    clang/lib/Analysis/CFG.cpp
    clang/test/Analysis/auto-obj-dtors-cfg-output.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp
index edc86c41c3b9..56445881873f 100644
--- a/clang/lib/Analysis/CFG.cpp
+++ b/clang/lib/Analysis/CFG.cpp
@@ -4475,8 +4475,14 @@ CFGBlock *CFGBuilder::VisitCXXForRangeStmt(CXXForRangeStmt *S) {
     // Add implicit scope and dtors for loop variable.
     addLocalScopeAndDtors(S->getLoopVarStmt());
 
+    // If body is not a compound statement create implicit scope
+    // and add destructors.
+    if (!isa<CompoundStmt>(S->getBody()))
+      addLocalScopeAndDtors(S->getBody());
+
     // Populate a new block to contain the loop body and loop variable.
     addStmt(S->getBody());
+
     if (badCFG)
       return nullptr;
     CFGBlock *LoopVarStmtBlock = addStmt(S->getLoopVarStmt());

diff  --git a/clang/test/Analysis/auto-obj-dtors-cfg-output.cpp b/clang/test/Analysis/auto-obj-dtors-cfg-output.cpp
index 5b98dea4c6b1..8e396bddf09d 100644
--- a/clang/test/Analysis/auto-obj-dtors-cfg-output.cpp
+++ b/clang/test/Analysis/auto-obj-dtors-cfg-output.cpp
@@ -1075,6 +1075,59 @@ void test_for_implicit_scope() {
     A c;
 }
 
+// CHECK-LABEL: void test_for_range_implicit_scope()
+// CHECK:      [B5 (ENTRY)]
+// CHECK-NEXT:   Succs (1): B4
+// CHECK:      [B1]
+// CHECK-NEXT:   1: __begin1
+// CHECK-NEXT:   2: [B1.1] (ImplicitCastExpr, LValueToRValue, int *)
+// CHECK-NEXT:   3: __end1
+// CHECK-NEXT:   4: [B1.3] (ImplicitCastExpr, LValueToRValue, int *)
+// CHECK-NEXT:   5: [B1.2] != [B1.4]
+// CHECK-NEXT:   T: for (int n : [B4.2])
+// CHECK-NEXT:[B3.7]
+// CHECK-NEXT:   Preds (2): B2 B4
+// CHECK-NEXT:   Succs (2): B3 B0
+// CHECK:      [B2]
+// CHECK-NEXT:   1: __begin1
+// CHECK-NEXT:   2: ++[B2.1]
+// CHECK-NEXT:   Preds (1): B3
+// CHECK-NEXT:   Succs (1): B1
+// CHECK:      [B3]
+// CHECK-NEXT:   1: __begin1
+// CHECK-NEXT:   2: [B3.1] (ImplicitCastExpr, LValueToRValue, int *)
+// CHECK-NEXT:   3: *[B3.2]
+// CHECK-NEXT:   4: [B3.3] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:   5: int n = *__begin1;
+// WARNINGS-NEXT:   6:  (CXXConstructExpr, class A)
+// ANALYZER-NEXT:   6:  (CXXConstructExpr, [B3.7], class A)
+// CHECK-NEXT:   7: A c;
+// CHECK-NEXT:   8: [B3.7].~A() (Implicit destructor)
+// CHECK-NEXT:   Preds (1): B1
+// CHECK-NEXT:   Succs (1): B2
+// CHECK:      [B4]
+// CHECK-NEXT:   1: int nums[4];
+// CHECK-NEXT:   2: nums
+// CHECK-NEXT:   3: auto &&__range1 = nums;
+// CHECK-NEXT:   4: __range1
+// CHECK-NEXT:   5: [B4.4] (ImplicitCastExpr, ArrayToPointerDecay, int *)
+// CHECK-NEXT:   6: 4L
+// CHECK-NEXT:   7: [B4.5] + [B4.6]
+// CHECK-NEXT:   8: auto __end1 = __range1 + 4L;
+// CHECK-NEXT:   9: __range1
+// CHECK-NEXT:  10: [B4.9] (ImplicitCastExpr, ArrayToPointerDecay, int *)
+// CHECK-NEXT:  11: auto __begin1 = __range1;
+// CHECK-NEXT:   Preds (1): B5
+// CHECK-NEXT:   Succs (1): B1
+// CHECK:      [B0 (EXIT)]
+// CHECK-NEXT:   Preds (1): B1
+void test_for_range_implicit_scope() {
+  int nums[4];
+  for (int n : nums)
+    A c;
+}
+
+
 // CHECK:      [B12 (ENTRY)]
 // CHECK-NEXT:   Succs (1): B11
 // CHECK:      [B1]


        


More information about the cfe-commits mailing list