diff --git a/clang/include/clang/Analysis/ProgramPoint.h b/clang/include/clang/Analysis/ProgramPoint.h index c40aa3d8ffb72..096ad48a42984 100644 --- a/clang/include/clang/Analysis/ProgramPoint.h +++ b/clang/include/clang/Analysis/ProgramPoint.h @@ -224,10 +224,14 @@ class ProgramPoint { class BlockEntrance : public ProgramPoint { public: - BlockEntrance(const CFGBlock *B, const LocationContext *L, - const ProgramPointTag *tag = nullptr) - : ProgramPoint(B, BlockEntranceKind, L, tag) { - assert(B && "BlockEntrance requires non-null block"); + BlockEntrance(const CFGBlock *PrevBlock, const CFGBlock *CurrBlock, + const LocationContext *L, const ProgramPointTag *Tag = nullptr) + : ProgramPoint(CurrBlock, PrevBlock, BlockEntranceKind, L, Tag) { + assert(CurrBlock && "BlockEntrance requires non-null block"); + } + + const CFGBlock *getPreviousBlock() const { + return reinterpret_cast(getData2()); } const CFGBlock *getBlock() const { @@ -760,13 +764,15 @@ template <> struct DenseMapInfo { static inline clang::ProgramPoint getEmptyKey() { uintptr_t x = reinterpret_cast(DenseMapInfo::getEmptyKey()) & ~0x7; - return clang::BlockEntrance(reinterpret_cast(x), nullptr); + return clang::BlockEntrance(nullptr, reinterpret_cast(x), + nullptr); } static inline clang::ProgramPoint getTombstoneKey() { uintptr_t x = reinterpret_cast(DenseMapInfo::getTombstoneKey()) & ~0x7; - return clang::BlockEntrance(reinterpret_cast(x), nullptr); + return clang::BlockEntrance(nullptr, reinterpret_cast(x), + nullptr); } static unsigned getHashValue(const clang::ProgramPoint &Loc) { diff --git a/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp b/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp index 8cc086a12ad70..bedb11f8b94a5 100644 --- a/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp @@ -315,7 +315,7 @@ void CoreEngine::HandleBlockEdge(const BlockEdge &L, ExplodedNode *Pred) { // Call into the ExprEngine to process entering the CFGBlock. ExplodedNodeSet dstNodes; - BlockEntrance BE(Blk, Pred->getLocationContext()); + BlockEntrance BE(L.getSrc(), L.getDst(), Pred->getLocationContext()); NodeBuilderWithSinks nodeBuilder(Pred, dstNodes, BuilderCtx, BE); ExprEng.processCFGBlockEntrance(L, nodeBuilder, Pred); diff --git a/clang/test/Analysis/exploration_order/noexprcrash.c b/clang/test/Analysis/exploration_order/noexprcrash.c index 75c2f0e6798a3..427c669783374 100644 --- a/clang/test/Analysis/exploration_order/noexprcrash.c +++ b/clang/test/Analysis/exploration_order/noexprcrash.c @@ -1,17 +1,18 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify -analyzer-config exploration_strategy=unexplored_first %s -// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify -analyzer-config exploration_strategy=dfs %s +// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify=common,ufirst -analyzer-config exploration_strategy=unexplored_first %s +// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify=common,dfs -analyzer-config exploration_strategy=dfs %s extern void clang_analyzer_eval(int); typedef struct { char a; } b; int c(b* input) { - int x = (input->a ?: input) ? 1 : 0; // expected-warning{{pointer/integer type mismatch}} + int x = (input->a ?: input) ? 1 : 0; // common-warning{{pointer/integer type mismatch}} if (input->a) { // FIXME: The value should actually be "TRUE", // but is incorrect due to a bug. - clang_analyzer_eval(x); // expected-warning{{FALSE}} + // dfs-warning@+1 {{FALSE}} ufirst-warning@+1 {{TRUE}} + clang_analyzer_eval(x); } else { - clang_analyzer_eval(x); // expected-warning{{TRUE}} + clang_analyzer_eval(x); // common-warning{{TRUE}} } return x; }