r254962 - [analyzer] Fix crash when lambda captures a variable-length array.

Devin Coughlin via cfe-commits cfe-commits at lists.llvm.org
Mon Dec 7 15:01:54 PST 2015


Author: dcoughlin
Date: Mon Dec  7 17:01:53 2015
New Revision: 254962

URL: http://llvm.org/viewvc/llvm-project?rev=254962&view=rev
Log:
[analyzer] Fix crash when lambda captures a variable-length array.

When a C++ lambda captures a variable-length array, it creates a capture
field to store the size of the array. The initialization expression for this
capture is null, which led the analyzer to crash when initializing the field.
To avoid this, use the size expression from the VLA type to determine the
initialization value.

rdar://problem/23748072

Modified:
    cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
    cfe/trunk/test/Analysis/lambdas.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp?rev=254962&r1=254961&r2=254962&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp Mon Dec  7 17:01:53 2015
@@ -531,9 +531,23 @@ void ExprEngine::VisitLambdaExpr(const L
   for (LambdaExpr::const_capture_init_iterator i = LE->capture_init_begin(),
                                                e = LE->capture_init_end();
        i != e; ++i, ++CurField) {
-    SVal Field = State->getLValue(*CurField, V);
-    SVal InitExpr = State->getSVal(*i, LocCtxt);
-    State = State->bindLoc(Field, InitExpr);
+    FieldDecl *FieldForCapture = *CurField;
+    SVal FieldLoc = State->getLValue(FieldForCapture, V);
+
+    SVal InitVal;
+    if (!FieldForCapture->hasCapturedVLAType()) {
+      Expr *InitExpr = *i;
+      assert(InitExpr && "Capture missing initialization expression");
+      InitVal = State->getSVal(InitExpr, LocCtxt);
+    } else {
+      // The field stores the length of a captured variable-length array.
+      // These captures don't have initialization expressions; instead we
+      // get the length from the VLAType size expression.
+      Expr *SizeExpr = FieldForCapture->getCapturedVLAType()->getSizeExpr();
+      InitVal = State->getSVal(SizeExpr, LocCtxt);
+    }
+
+    State = State->bindLoc(FieldLoc, InitVal);
   }
 
   // Decay the Loc into an RValue, because there might be a

Modified: cfe/trunk/test/Analysis/lambdas.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/lambdas.cpp?rev=254962&r1=254961&r2=254962&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/lambdas.cpp (original)
+++ cfe/trunk/test/Analysis/lambdas.cpp Mon Dec  7 17:01:53 2015
@@ -173,6 +173,19 @@ void testFunctionPointerCapture() {
   clang_analyzer_eval(i == 6); // expected-warning{{TRUE}}
 }
 
+// Captured variable-length array.
+
+void testVariableLengthArrayCaptured() {
+  int n = 2;
+  int array[n];
+  array[0] = 7;
+
+  int i = [&]{
+    return array[0];
+  }();
+
+  clang_analyzer_eval(i == 7); // expected-warning{{TRUE}}
+}
 
 // Test inline defensive checks
 int getNum();




More information about the cfe-commits mailing list