Skip to content

Commit

Permalink
[analyzer] Remove the loop from the exploded graph caused by missing …
Browse files Browse the repository at this point in the history
…information in program points

This patch adds CFGElementRef to ProgramPoints
and helps the analyzer to differentiate between
two otherwise identically looking ProgramPoints.

Fixes #60412

Differential Revision: https://reviews.llvm.org/D143328
  • Loading branch information
isuckatcs committed Mar 4, 2023
1 parent b056c1c commit d65379c
Show file tree
Hide file tree
Showing 13 changed files with 259 additions and 144 deletions.
68 changes: 34 additions & 34 deletions clang/include/clang/Analysis/ProgramPoint.h
Expand Up @@ -95,35 +95,33 @@ class ProgramPoint {

llvm::PointerIntPair<const ProgramPointTag *, 2, unsigned> Tag;

CFGBlock::ConstCFGElementRef ElemRef = {nullptr, 0};

protected:
ProgramPoint() = default;
ProgramPoint(const void *P,
Kind k,
const LocationContext *l,
const ProgramPointTag *tag = nullptr)
: Data1(P),
Data2(nullptr, (((unsigned) k) >> 0) & 0x3),
L(l, (((unsigned) k) >> 2) & 0x3),
Tag(tag, (((unsigned) k) >> 4) & 0x3) {
assert(getKind() == k);
assert(getLocationContext() == l);
assert(getData1() == P);
}

ProgramPoint(const void *P1,
const void *P2,
Kind k,
const LocationContext *l,
const ProgramPointTag *tag = nullptr)
: Data1(P1),
Data2(P2, (((unsigned) k) >> 0) & 0x3),
L(l, (((unsigned) k) >> 2) & 0x3),
Tag(tag, (((unsigned) k) >> 4) & 0x3) {}
ProgramPoint(const void *P, Kind k, const LocationContext *l,
const ProgramPointTag *tag = nullptr,
CFGBlock::ConstCFGElementRef ElemRef = {nullptr, 0})
: Data1(P), Data2(nullptr, (((unsigned)k) >> 0) & 0x3),
L(l, (((unsigned)k) >> 2) & 0x3), Tag(tag, (((unsigned)k) >> 4) & 0x3),
ElemRef(ElemRef) {
assert(getKind() == k);
assert(getLocationContext() == l);
assert(getData1() == P);
}

ProgramPoint(const void *P1, const void *P2, Kind k, const LocationContext *l,
const ProgramPointTag *tag = nullptr,
CFGBlock::ConstCFGElementRef ElemRef = {nullptr, 0})
: Data1(P1), Data2(P2, (((unsigned)k) >> 0) & 0x3),
L(l, (((unsigned)k) >> 2) & 0x3), Tag(tag, (((unsigned)k) >> 4) & 0x3),
ElemRef(ElemRef) {}

protected:
const void *getData1() const { return Data1; }
const void *getData2() const { return Data2.getPointer(); }
void setData2(const void *d) { Data2.setPointer(d); }
CFGBlock::ConstCFGElementRef getElementRef() const { return ElemRef; }

public:
/// Create a new ProgramPoint object that is the same as the original
Expand Down Expand Up @@ -190,17 +188,13 @@ class ProgramPoint {
}

bool operator==(const ProgramPoint & RHS) const {
return Data1 == RHS.Data1 &&
Data2 == RHS.Data2 &&
L == RHS.L &&
Tag == RHS.Tag;
return Data1 == RHS.Data1 && Data2 == RHS.Data2 && L == RHS.L &&
Tag == RHS.Tag && ElemRef == RHS.ElemRef;
}

bool operator!=(const ProgramPoint &RHS) const {
return Data1 != RHS.Data1 ||
Data2 != RHS.Data2 ||
L != RHS.L ||
Tag != RHS.Tag;
return Data1 != RHS.Data1 || Data2 != RHS.Data2 || L != RHS.L ||
Tag != RHS.Tag || ElemRef != RHS.ElemRef;
}

void Profile(llvm::FoldingSetNodeID& ID) const {
Expand All @@ -209,6 +203,8 @@ class ProgramPoint {
ID.AddPointer(getData2());
ID.AddPointer(getLocationContext());
ID.AddPointer(getTag());
ID.AddPointer(ElemRef.getParent());
ID.AddInteger(ElemRef.getIndexInBlock());
}

void printJson(llvm::raw_ostream &Out, const char *NL = "\n") const;
Expand Down Expand Up @@ -266,6 +262,7 @@ class BlockExit : public ProgramPoint {
}
};

// FIXME: Eventually we want to take a CFGElementRef as parameter here too.
class StmtPoint : public ProgramPoint {
public:
StmtPoint(const Stmt *S, const void *p2, Kind k, const LocationContext *L,
Expand Down Expand Up @@ -557,8 +554,9 @@ class PostInitializer : public ProgramPoint {
class ImplicitCallPoint : public ProgramPoint {
public:
ImplicitCallPoint(const Decl *D, SourceLocation Loc, Kind K,
const LocationContext *L, const ProgramPointTag *Tag)
: ProgramPoint(Loc.getPtrEncoding(), D, K, L, Tag) {}
const LocationContext *L, const ProgramPointTag *Tag,
CFGBlock::ConstCFGElementRef ElemRef)
: ProgramPoint(Loc.getPtrEncoding(), D, K, L, Tag, ElemRef) {}

const Decl *getDecl() const { return static_cast<const Decl *>(getData2()); }
SourceLocation getLocation() const {
Expand All @@ -581,8 +579,9 @@ class ImplicitCallPoint : public ProgramPoint {
class PreImplicitCall : public ImplicitCallPoint {
public:
PreImplicitCall(const Decl *D, SourceLocation Loc, const LocationContext *L,
CFGBlock::ConstCFGElementRef ElemRef,
const ProgramPointTag *Tag = nullptr)
: ImplicitCallPoint(D, Loc, PreImplicitCallKind, L, Tag) {}
: ImplicitCallPoint(D, Loc, PreImplicitCallKind, L, Tag, ElemRef) {}

private:
friend class ProgramPoint;
Expand All @@ -598,8 +597,9 @@ class PreImplicitCall : public ImplicitCallPoint {
class PostImplicitCall : public ImplicitCallPoint {
public:
PostImplicitCall(const Decl *D, SourceLocation Loc, const LocationContext *L,
CFGBlock::ConstCFGElementRef ElemRef,
const ProgramPointTag *Tag = nullptr)
: ImplicitCallPoint(D, Loc, PostImplicitCallKind, L, Tag) {}
: ImplicitCallPoint(D, Loc, PostImplicitCallKind, L, Tag, ElemRef) {}

private:
friend class ProgramPoint;
Expand Down

0 comments on commit d65379c

Please sign in to comment.