]> granicus.if.org Git - clang/commitdiff
[analyzer] Address John's code review for r163407.
authorAnna Zaks <ganna@apple.com>
Sat, 8 Sep 2012 00:09:02 +0000 (00:09 +0000)
committerAnna Zaks <ganna@apple.com>
Sat, 8 Sep 2012 00:09:02 +0000 (00:09 +0000)
Teach malloc sizeof checker to find type inconsistencies in multi-
dimensional arrays.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@163438 91177308-0d34-0410-b5e6-96231b3b80d8

lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp
test/Analysis/malloc-sizeof.c

index 404ea1089f0a7c463ea1c8b4cc78d87192c613e8..fb40f222b8464a7c15b471621fc0c3842599d647 100644 (file)
@@ -157,6 +157,18 @@ static bool typesCompatible(ASTContext &C, QualType A, QualType B) {
   return false;
 }
 
+static bool compatibleWithArrayType(ASTContext &C, QualType PT, QualType T) {
+  // Ex: 'int a[10][2]' is compatible with 'int', 'int[2]', 'int[10][2]'.
+  while (const ArrayType *AT = T->getAsArrayTypeUnsafe()) {
+    QualType ElemType = AT->getElementType();
+    if (typesCompatible(C, PT, AT->getElementType()))
+      return true;
+    T = ElemType;
+  }
+
+  return false;
+}
+
 class MallocSizeofChecker : public Checker<check::ASTCodeBody> {
 public:
   void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
@@ -189,18 +201,9 @@ public:
           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;
-        }
-
+        // pointer to any array element.
+        if (compatibleWithArrayType(BR.getContext(), PointeeType, SizeofType))
+          continue;
 
         const TypeSourceInfo *TSI = 0;
         if (i->CastedExprParent.is<const VarDecl *>()) {
index 943c4ce17c826c5becc5cfb4d7f4c7a6b66bcbd5..7a8585fa84422830d2eaaf617625e81cec240159 100644 (file)
@@ -37,9 +37,11 @@ void ignore_const() {
 
 int *mallocArraySize() {
   static const int sTable[10];
-  static const int nestedTable[10][10];
+  static const int nestedTable[10][2];
   int *table = malloc(sizeof sTable);
   int *table1 = malloc(sizeof nestedTable);
+  int (*table2)[2] = malloc(sizeof nestedTable);
+  int (*table3)[10][2] = malloc(sizeof nestedTable);
   return table;
 }