diff options
-rw-r--r-- | lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp | 27 | ||||
-rw-r--r-- | test/Analysis/malloc-sizeof.c | 4 |
2 files changed, 18 insertions, 13 deletions
diff --git a/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp b/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp index 404ea1089f..fb40f222b8 100644 --- a/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp @@ -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 *>()) { diff --git a/test/Analysis/malloc-sizeof.c b/test/Analysis/malloc-sizeof.c index 943c4ce17c..7a8585fa84 100644 --- a/test/Analysis/malloc-sizeof.c +++ b/test/Analysis/malloc-sizeof.c @@ -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; } |