vabridgers created this revision. vabridgers added reviewers: steakhal, martong. Herald added subscribers: manas, ASDenysPetrov, dkrupp, donat.nagy, Szelethus, mikhail.ramalho, a.sidorin, rnkovacs, szepet, baloghadamsoftware, xazax.hun, whisperity. vabridgers requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
This simple change addresses a special case of structure/pointer aliasing that produced different symbvals, leading to false positives during analysis. The reproducer is as simple as this. struct s { int v; char y; }; void foo(struct s *ps) { struct s ss = *ps; clang_analyzer_dump(ss.v); // reg_$1<int Element{SymRegion{reg_$0<struct s *ps>},0 S64b,struct s}.v> clang_analyzer_dump(ps->v); //reg_$3<int SymRegion{reg_$0<struct s *ps>}.v> clang_analyzer_eval(ss.v == ps->v); // UNKNOWN } Acks: Many thanks to @steakhal and @martong for the group debug session. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D110625 Files: clang/lib/StaticAnalyzer/Core/Store.cpp clang/test/Analysis/ptr-arith.c Index: clang/test/Analysis/ptr-arith.c =================================================================== --- clang/test/Analysis/ptr-arith.c +++ 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<int SymRegion{reg_$0<struct s * ps>}.v> + clang_analyzer_dump(ps[0].v); // reg_$1<int SymRegion{reg_$0<struct s * ps>}.v> + clang_analyzer_dump(ps->v); // reg_$1<int SymRegion{reg_$0<struct s * ps>}.v> +} Index: clang/lib/StaticAnalyzer/Core/Store.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/Store.cpp +++ 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
Index: clang/test/Analysis/ptr-arith.c =================================================================== --- clang/test/Analysis/ptr-arith.c +++ 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<int SymRegion{reg_$0<struct s * ps>}.v> + clang_analyzer_dump(ps[0].v); // reg_$1<int SymRegion{reg_$0<struct s * ps>}.v> + clang_analyzer_dump(ps->v); // reg_$1<int SymRegion{reg_$0<struct s * ps>}.v> +} Index: clang/lib/StaticAnalyzer/Core/Store.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/Store.cpp +++ 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
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits