baloghadamsoftware created this revision. baloghadamsoftware added reviewers: NoQ, dcoughlin. baloghadamsoftware added a project: clang. Herald added subscribers: gamesh411, donat.nagy, mikhail.ramalho, a.sidorin, szepet.
This patch is a fix for bug 40625 <https://bugs.llvm.org/show_bug.cgi?id=40625>. `FindLastStoreBRVisitor` tries to find the first node in the exploded graph where the current value was assigned to a region. This node is called the "store site". It is identified by a pair of `Pred` and `Succ` nodes where `Succ` already has the binding for the value while `Pred` does not have it. However the visitor mistakenly identifies a node pair as the store site where the value is a `LazyCompoundVal` and `Pred` does not have a store yet but `Succ` has it. In this case the `LazyCompoundVal` is different in the `Pred` node because it also contains the store which is different in the two nodes. This error may lead to crashes (a declaration is cast to a parameter declaration without check) or misleading bug path notes. In this patch we fix this problem by checking for unequal `LazyCompoundVals`: if their region is equal, and their store is the same as the store of their nodes we consider them as equal when looking for the store site. Repository: rC Clang https://reviews.llvm.org/D58067 Files: lib/StaticAnalyzer/Core/BugReporterVisitors.cpp test/Analysis/PR40625.cpp test/Analysis/const_array.cpp test/Analysis/uninit-vals.m
Index: test/Analysis/uninit-vals.m =================================================================== --- test/Analysis/uninit-vals.m +++ test/Analysis/uninit-vals.m @@ -394,11 +394,11 @@ struct { int : 4; int y : 4; - } a, b, c; + } a, b, c; // expected-note{{'c' initialized here}} a.y = 2; - b = a; // expected-note{{Value assigned to 'c'}} + b = a; clang_analyzer_eval(b.y == 2); // expected-warning{{TRUE}} // expected-note@-1{{TRUE}} @@ -411,11 +411,11 @@ struct { int x : 4; int : 4; - } a, b, c; + } a, b, c; // expected-note{{'c' initialized here}} a.x = 1; - b = a; // expected-note{{Value assigned to 'c'}} + b = a; clang_analyzer_eval(b.x == 1); // expected-warning{{TRUE}} // expected-note@-1{{TRUE}} Index: test/Analysis/const_array.cpp =================================================================== --- test/Analysis/const_array.cpp +++ /dev/null @@ -1,22 +0,0 @@ -// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,alpha.core.CallAndMessageUnInitRefArg %s -verify - -// expect-no-diagnostics - -const int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; - -void f(const int *begin, const int *end) { - int sum = 0; - for (const int *p = begin; p != end; ++p) { - sum += *p; - } -} - -typedef const int intarray[10]; - -void g(const intarray &arrr) { - f(arrr, arrr+sizeof(arrr)); -} - -void h() { - g(arr); -} Index: test/Analysis/PR40625.cpp =================================================================== --- /dev/null +++ test/Analysis/PR40625.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,alpha.core.CallAndMessageUnInitRefArg %s -verify + +void f(const int *end); + +void g(const int (&arrr)[10]) { + f(arrr+sizeof(arrr)); // expected-warning{{1st function call argument is a pointer to uninitialized value}} + // FIXME: This is a false positive that should be fixed. Until then this + // tests the crash fix in FindLastStoreBRVisitor (beside + // uninit-vals.m). +} + +void h() { + int arr[10]; + + g(arr); +} Index: lib/StaticAnalyzer/Core/BugReporterVisitors.cpp =================================================================== --- lib/StaticAnalyzer/Core/BugReporterVisitors.cpp +++ lib/StaticAnalyzer/Core/BugReporterVisitors.cpp @@ -153,6 +153,27 @@ return E; } +/// Two values match if either they are equal, or for LazyCompoundVals their +/// regions are equal and their stores are equal to the stores of their +/// exploded nodes. +bool matchesValue(const ExplodedNode *LeftNode, SVal LeftVal, + const ExplodedNode *RightNode, SVal RightVal) { + if (LeftVal == RightVal) + return true; + + const auto LLCV = LeftVal.getAs<nonloc::LazyCompoundVal>(); + if (!LLCV) + return false; + + const auto RLCV = RightVal.getAs<nonloc::LazyCompoundVal>(); + if (!RLCV) + return false; + + return LLCV->getRegion() == RLCV->getRegion() && + LLCV->getStore() == LeftNode->getState()->getStore() && + RLCV->getStore() == RightNode->getState()->getStore(); +} + //===----------------------------------------------------------------------===// // Definitions for bug reporter visitors. //===----------------------------------------------------------------------===// @@ -1177,7 +1198,7 @@ if (Succ->getState()->getSVal(R) != V) return nullptr; - if (Pred->getState()->getSVal(R) == V) { + if (matchesValue(Pred, Pred->getState()->getSVal(R), Succ, V)) { Optional<PostStore> PS = Succ->getLocationAs<PostStore>(); if (!PS || PS->getLocationValue() != R) return nullptr; @@ -1198,6 +1219,7 @@ // UndefinedVal.) if (Optional<CallEnter> CE = Succ->getLocationAs<CallEnter>()) { if (const auto *VR = dyn_cast<VarRegion>(R)) { + const auto *Param = cast<ParmVarDecl>(VR->getDecl()); ProgramStateManager &StateMgr = BRC.getStateManager();
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits