diff --git a/clang/lib/StaticAnalyzer/Core/Store.cpp b/clang/lib/StaticAnalyzer/Core/Store.cpp --- a/clang/lib/StaticAnalyzer/Core/Store.cpp +++ b/clang/lib/StaticAnalyzer/Core/Store.cpp @@ -442,6 +442,15 @@ SVal StoreManager::getLValueElement(QualType elementType, NonLoc Offset, SVal Base) { + + // Special case, if index is 0, return the same type as if + // this was not an array dereference. + if (Offset.isZeroConstant()) { + QualType BT = Base.getType(this->Ctx); + if (!BT.isNull() && BT->getPointeeType() == elementType) + return Base; + } + // If the base is an unknown or undefined value, just return it back. // FIXME: For absolute pointer addresses, we just return that value back as // well, although in reality we should return the offset added to that diff --git a/clang/test/Analysis/ptr-arith.c b/clang/test/Analysis/ptr-arith.c --- a/clang/test/Analysis/ptr-arith.c +++ b/clang/test/Analysis/ptr-arith.c @@ -330,3 +330,17 @@ simd_float2 x = {0, 1}; return x[1]; // no-warning } + +struct s { + int v; + char y; +}; + +// These three expressions should produce the same sym vals. +// TBD: add test verification here. +void foo(struct s *ps) { + struct s ss = *ps; + clang_analyzer_dump((*ps).v); // reg_$1}.v> + clang_analyzer_dump(ps[0].v); // reg_$1}.v> + clang_analyzer_dump(ps->v); // reg_$1}.v> +}