kmarshall created this revision.

The extent calculation function had a bug which caused it to ignore if the size 
value was defined prior to casting it. As a result, size expressions with free 
variables would trigger assertion failures during the cast operation.

This patch adds that missing check, and replaces the redundant call to 
castAs<>() with the SVar that is returned by the checked cast.

Added a regression test "Malloc+NewDynamicArray" that exercises the fix.


https://reviews.llvm.org/D30312

Files:
  lib/StaticAnalyzer/Checkers/MallocChecker.cpp
  test/Analysis/Malloc+NewDynamicArray.cpp


Index: test/Analysis/Malloc+NewDynamicArray.cpp
===================================================================
--- test/Analysis/Malloc+NewDynamicArray.cpp
+++ test/Analysis/Malloc+NewDynamicArray.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=unix.Malloc -verify %s
+
+//-----------------------------------------------------------------------
+// Check that arrays sized using expressions with free variables
+// do not cause the unix.Malloc checker to crash.
+//
+// The function should not actually be called from anywhere, otherwise
+// the compiler will optimize the length expression and replace it with
+// with precomputed literals.
+//-----------------------------------------------------------------------
+
+void AllocateExpr(int lhs, int rhs) {
+  new int[lhs + rhs];
+}
+
+// expected-no-diagnostics
+
Index: lib/StaticAnalyzer/Checkers/MallocChecker.cpp
===================================================================
--- lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -1026,12 +1026,11 @@
   ASTContext &AstContext = C.getASTContext();
   CharUnits TypeSize = AstContext.getTypeSizeInChars(ElementType);
 
-  if (Optional<DefinedOrUnknownSVal> DefinedSize =
-          ElementCount.getAs<DefinedOrUnknownSVal>()) {
+  if (Optional<NonLoc> DefinedSize = ElementCount.getAs<NonLoc>()) {
     DefinedOrUnknownSVal Extent = Region->getExtent(svalBuilder);
     // size in Bytes = ElementCount*TypeSize
     SVal SizeInBytes = svalBuilder.evalBinOpNN(
-        State, BO_Mul, ElementCount.castAs<NonLoc>(),
+        State, BO_Mul, *DefinedSize,
         svalBuilder.makeArrayIndex(TypeSize.getQuantity()),
         svalBuilder.getArrayIndexType());
     DefinedOrUnknownSVal extentMatchesSize = svalBuilder.evalEQ(


Index: test/Analysis/Malloc+NewDynamicArray.cpp
===================================================================
--- test/Analysis/Malloc+NewDynamicArray.cpp
+++ test/Analysis/Malloc+NewDynamicArray.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=unix.Malloc -verify %s
+
+//-----------------------------------------------------------------------
+// Check that arrays sized using expressions with free variables
+// do not cause the unix.Malloc checker to crash.
+//
+// The function should not actually be called from anywhere, otherwise
+// the compiler will optimize the length expression and replace it with
+// with precomputed literals.
+//-----------------------------------------------------------------------
+
+void AllocateExpr(int lhs, int rhs) {
+  new int[lhs + rhs];
+}
+
+// expected-no-diagnostics
+
Index: lib/StaticAnalyzer/Checkers/MallocChecker.cpp
===================================================================
--- lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -1026,12 +1026,11 @@
   ASTContext &AstContext = C.getASTContext();
   CharUnits TypeSize = AstContext.getTypeSizeInChars(ElementType);
 
-  if (Optional<DefinedOrUnknownSVal> DefinedSize =
-          ElementCount.getAs<DefinedOrUnknownSVal>()) {
+  if (Optional<NonLoc> DefinedSize = ElementCount.getAs<NonLoc>()) {
     DefinedOrUnknownSVal Extent = Region->getExtent(svalBuilder);
     // size in Bytes = ElementCount*TypeSize
     SVal SizeInBytes = svalBuilder.evalBinOpNN(
-        State, BO_Mul, ElementCount.castAs<NonLoc>(),
+        State, BO_Mul, *DefinedSize,
         svalBuilder.makeArrayIndex(TypeSize.getQuantity()),
         svalBuilder.getArrayIndexType());
     DefinedOrUnknownSVal extentMatchesSize = svalBuilder.evalEQ(
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to