diff --git a/clang/lib/StaticAnalyzer/Core/MemRegion.cpp b/clang/lib/StaticAnalyzer/Core/MemRegion.cpp --- a/clang/lib/StaticAnalyzer/Core/MemRegion.cpp +++ b/clang/lib/StaticAnalyzer/Core/MemRegion.cpp @@ -1077,13 +1077,16 @@ } } - return getSubRegion(D, sReg); + return getNonParamVarRegion(D, sReg); } const NonParamVarRegion * MemRegionManager::getNonParamVarRegion(const VarDecl *D, const MemRegion *superR) { + // Prefer the definition over the canonical decl as the canonical form. D = D->getCanonicalDecl(); + if (const VarDecl *Def = D->getDefinition()) + D = Def; return getSubRegion(D, superR); } diff --git a/clang/test/Analysis/globals.c b/clang/test/Analysis/globals.c new file mode 100644 --- /dev/null +++ b/clang/test/Analysis/globals.c @@ -0,0 +1,18 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify %s + +typedef typeof(sizeof(int)) size_t; +size_t clang_analyzer_getExtent(const void *p); +void clang_analyzer_dump(size_t n); + +extern const unsigned char extern_redecl[]; +const unsigned char extern_redecl[] = { 1,2,3,4 }; +const unsigned char tentative_redecl[]; +const unsigned char tentative_redecl[] = { 1,2,3,4 }; + +const unsigned char direct_decl[] = { 1,2,3,4 }; + +void test_redeclaration_extent(void) { + clang_analyzer_dump(clang_analyzer_getExtent(direct_decl)); // expected-warning {{4 S64b}} + clang_analyzer_dump(clang_analyzer_getExtent(extern_redecl)); // expected-warning {{4 S64b}} + clang_analyzer_dump(clang_analyzer_getExtent(tentative_redecl)); // expected-warning {{4 S64b}} +}