[cfe-commits] r163407 - in /cfe/trunk: lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp test/Analysis/malloc-sizeof.c

Anna Zaks ganna at apple.com
Fri Sep 7 12:20:13 PDT 2012


Author: zaks
Date: Fri Sep  7 14:20:13 2012
New Revision: 163407

URL: http://llvm.org/viewvc/llvm-project?rev=163407&view=rev
Log:
[analyzer] Fix a false positive in sizeof malloc checker.

Don't warn when the sizeof argument is an array with the same element
type as the pointee of the return type.

Modified:
    cfe/trunk/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp
    cfe/trunk/test/Analysis/malloc-sizeof.c

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp?rev=163407&r1=163406&r2=163407&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp Fri Sep  7 14:20:13 2012
@@ -184,42 +184,58 @@
           continue;
 
         QualType SizeofType = SFinder.Sizeofs[0]->getTypeOfArgument();
-        if (!typesCompatible(BR.getContext(), PointeeType, SizeofType)) {
-          const TypeSourceInfo *TSI = 0;
-          if (i->CastedExprParent.is<const VarDecl *>()) {
-            TSI =
+
+        if (typesCompatible(BR.getContext(), PointeeType, SizeofType))
+          continue;
+
+        // If the argument to sizeof is an array, the result could be a
+        // pointer to the array element.
+        if (const ArrayType *AT = dyn_cast<ArrayType>(SizeofType)) {
+          QualType ElemType = AT->getElementType();
+          if (typesCompatible(BR.getContext(), PointeeType,
+                                               AT->getElementType()))
+            continue;
+            
+          // For now, let's only reason about arrays of built in types.
+          if (!ElemType->isBuiltinType())
+            continue;
+        }
+
+
+        const TypeSourceInfo *TSI = 0;
+        if (i->CastedExprParent.is<const VarDecl *>()) {
+          TSI =
               i->CastedExprParent.get<const VarDecl *>()->getTypeSourceInfo();
-          } else {
-            TSI = i->ExplicitCastType;
-          }
-
-          SmallString<64> buf;
-          llvm::raw_svector_ostream OS(buf);
-
-          OS << "Result of ";
-          const FunctionDecl *Callee = i->AllocCall->getDirectCallee();
-          if (Callee && Callee->getIdentifier())
-            OS << '\'' << Callee->getIdentifier()->getName() << '\'';
-          else
-            OS << "call";
-          OS << " is converted to a pointer of type '"
-             << PointeeType.getAsString() << "', which is incompatible with "
-             << "sizeof operand type '" << SizeofType.getAsString() << "'";
-          llvm::SmallVector<SourceRange, 4> Ranges;
-          Ranges.push_back(i->AllocCall->getCallee()->getSourceRange());
-          Ranges.push_back(SFinder.Sizeofs[0]->getSourceRange());
-          if (TSI)
-            Ranges.push_back(TSI->getTypeLoc().getSourceRange());
+        } else {
+          TSI = i->ExplicitCastType;
+        }
+
+        SmallString<64> buf;
+        llvm::raw_svector_ostream OS(buf);
 
-          PathDiagnosticLocation L =
+        OS << "Result of ";
+        const FunctionDecl *Callee = i->AllocCall->getDirectCallee();
+        if (Callee && Callee->getIdentifier())
+          OS << '\'' << Callee->getIdentifier()->getName() << '\'';
+        else
+          OS << "call";
+        OS << " is converted to a pointer of type '"
+            << PointeeType.getAsString() << "', which is incompatible with "
+            << "sizeof operand type '" << SizeofType.getAsString() << "'";
+        llvm::SmallVector<SourceRange, 4> Ranges;
+        Ranges.push_back(i->AllocCall->getCallee()->getSourceRange());
+        Ranges.push_back(SFinder.Sizeofs[0]->getSourceRange());
+        if (TSI)
+          Ranges.push_back(TSI->getTypeLoc().getSourceRange());
+
+        PathDiagnosticLocation L =
             PathDiagnosticLocation::createBegin(i->AllocCall->getCallee(),
-                                                BR.getSourceManager(), ADC);
+                BR.getSourceManager(), ADC);
 
-          BR.EmitBasicReport(D, "Allocator sizeof operand mismatch",
-                             categories::UnixAPI,
-                             OS.str(),
-                             L, Ranges.data(), Ranges.size());
-        }
+        BR.EmitBasicReport(D, "Allocator sizeof operand mismatch",
+            categories::UnixAPI,
+            OS.str(),
+            L, Ranges.data(), Ranges.size());
       }
     }
   }

Modified: cfe/trunk/test/Analysis/malloc-sizeof.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/malloc-sizeof.c?rev=163407&r1=163406&r2=163407&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/malloc-sizeof.c (original)
+++ cfe/trunk/test/Analysis/malloc-sizeof.c Fri Sep  7 14:20:13 2012
@@ -34,3 +34,17 @@
   const char ***y = (const char ***)malloc(1 * sizeof(char *)); // expected-warning {{Result of 'malloc' is converted to a pointer of type 'const char **', which is incompatible with sizeof operand type 'char *'}}
   free(x);
 }
+
+int *mallocArraySize() {
+  static const int sTable[10];
+  static const int nestedTable[10][10];
+  int *table = malloc(sizeof sTable);
+  int *table1 = malloc(sizeof nestedTable);
+  return table;
+}
+
+int *mallocWrongArraySize() {
+  static const double sTable[10];
+  int *table = malloc(sizeof sTable); // expected-warning {{Result of 'malloc' is converted to a pointer of type 'int', which is incompatible with sizeof operand type 'const double [10]'}}
+  return table;
+}





More information about the cfe-commits mailing list