Index: clang/lib/StaticAnalyzer/Core/MemRegion.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/MemRegion.cpp +++ clang/lib/StaticAnalyzer/Core/MemRegion.cpp @@ -773,7 +773,7 @@ // A zero-length array at the end of a struct often stands for dynamically // allocated extra memory. if (Size.isZeroConstant()) { - if (isa(Ty)) + if (isa(Ty) || isa(Ty)) return UnknownVal(); } Index: clang/test/Analysis/out-of-bounds-new.cpp =================================================================== --- clang/test/Analysis/out-of-bounds-new.cpp +++ clang/test/Analysis/out-of-bounds-new.cpp @@ -1,4 +1,14 @@ -// RUN: %clang_analyze_cc1 -std=c++11 -Wno-array-bounds -analyzer-checker=unix,core,alpha.security.ArrayBoundV2 -verify %s +// RUN: %clang_analyze_cc1 -std=c++11 -Wno-array-bounds -verify %s \ +// RUN: -analyzer-checker=core,unix,alpha.security.ArrayBoundV2 \ +// RUN: -analyzer-checker=debug.ExprInspection + +using size_t = decltype(sizeof(int)); +size_t clang_analyzer_getExtent(void *); +void clang_analyzer_dump(size_t); + +void *alloca(size_t size); +void *malloc(size_t size); +void free(void *ptr); // Tests doing an out-of-bounds access after the end of an array using: // - constant integer index @@ -154,3 +164,29 @@ unsigned *U = nullptr; U = new unsigned[m + n + 1]; } + +void test_incomplete_array_fam() { + struct FAM { + char c; + int data[]; + }; + + FAM fam; + clang_analyzer_dump(clang_analyzer_getExtent(&fam)); + clang_analyzer_dump(clang_analyzer_getExtent(fam.data)); + // expected-warning@-2 {{4 S64b}} + // expected-warning@-2 {{Unknown}} + + FAM *p = (FAM *)alloca(sizeof(FAM)); + clang_analyzer_dump(clang_analyzer_getExtent(p)); + clang_analyzer_dump(clang_analyzer_getExtent(p->data)); + // expected-warning@-2 {{4 U64b}} + // expected-warning@-2 {{Unknown}} + + FAM *q = (FAM *)malloc(sizeof(FAM)); + clang_analyzer_dump(clang_analyzer_getExtent(q)); + clang_analyzer_dump(clang_analyzer_getExtent(q->data)); + // expected-warning@-2 {{4 U64b}} + // expected-warning@-2 {{Unknown}} + free(q); +}