diff --git a/clang/include/clang/Analysis/ProgramPoint.h b/clang/include/clang/Analysis/ProgramPoint.h --- a/clang/include/clang/Analysis/ProgramPoint.h +++ b/clang/include/clang/Analysis/ProgramPoint.h @@ -21,6 +21,7 @@ #include "llvm/ADT/Optional.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/AlignOf.h" #include "llvm/Support/Casting.h" #include "llvm/Support/DataTypes.h" #include @@ -85,9 +86,31 @@ MaxImplicitCallKind = PostImplicitCallKind, LoopExitKind, EpsilonKind}; - private: - const void *Data1; + union PtrOrSLoc { + PtrOrSLoc() {} + PtrOrSLoc(const void *P) { + memset(Raw.buffer, 0, sizeof(Raw.buffer)); + Ptr = P; + } + PtrOrSLoc(SourceLocation L) { + memset(Raw.buffer, 0, sizeof(Raw.buffer)); + new (&SLoc) SourceLocation(L); + } + bool operator==(const PtrOrSLoc &RHS) const { + return memcmp(this, &RHS, sizeof(PtrOrSLoc)) == 0; + } + bool operator!=(const PtrOrSLoc &RHS) const { return !(*this == RHS); } + StringRef AsBuffer() const { + const char *c = (const char *)this; + return StringRef(c, sizeof(PtrOrSLoc)); + } + const void *Ptr; + SourceLocation SLoc; + llvm::AlignedCharArrayUnion Raw; + }; + + PtrOrSLoc Data1; llvm::PointerIntPair Data2; // The LocationContext could be NULL to allow ProgramPoint to be used in @@ -108,30 +131,38 @@ Tag(tag, (((unsigned) k) >> 4) & 0x3) { assert(getKind() == k); assert(getLocationContext() == l); - assert(getData1() == P); + assert(getData1Ptr() == 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) {} - -protected: - const void *getData1() const { return Data1; } - const void *getData2() const { return Data2.getPointer(); } - void setData2(const void *d) { Data2.setPointer(d); } - -public: - /// Create a new ProgramPoint object that is the same as the original - /// except for using the specified tag value. - ProgramPoint withTag(const ProgramPointTag *tag) const { - return ProgramPoint(getData1(), getData2(), getKind(), - getLocationContext(), tag); + ProgramPoint(PtrOrSLoc D1, const void *P2, Kind k, + const LocationContext *l, + const ProgramPointTag *tag = nullptr) + : Data1(D1), Data2(P2, (((unsigned)k) >> 0) & 0x3), + L(l, (((unsigned)k) >> 2) & 0x3), + Tag(tag, (((unsigned)k) >> 4) & 0x3) {} + + ProgramPoint(const void *P1, const void *P2, Kind k, + const LocationContext *l, + const ProgramPointTag *tag = nullptr) + : ProgramPoint(PtrOrSLoc(P1), P2, k, l, tag) {} + + ProgramPoint(SourceLocation Loc, const void *P2, Kind k, + const LocationContext *l, + const ProgramPointTag *tag = nullptr) + : ProgramPoint(PtrOrSLoc(Loc), P2, k, l, tag) {} + + protected: + const PtrOrSLoc &getData1() const { return Data1; } + const void *getData1Ptr() const { return Data1.Ptr; } + const void *getData2() const { return Data2.getPointer(); } + void setData2(const void *d) { Data2.setPointer(d); } + + public: + /// Create a new ProgramPoint object that is the same as the original + /// except for using the specified tag value. + ProgramPoint withTag(const ProgramPointTag *tag) const { + return ProgramPoint(getData1(), getData2(), getKind(), + getLocationContext(), tag); } /// Convert to the specified ProgramPoint type, asserting that this @@ -207,7 +238,7 @@ void Profile(llvm::FoldingSetNodeID& ID) const { ID.AddInteger((unsigned) getKind()); - ID.AddPointer(getData1()); + ID.AddString(getData1().AsBuffer()); ID.AddPointer(getData2()); ID.AddPointer(getLocationContext()); ID.AddPointer(getTag()); @@ -231,7 +262,7 @@ } const CFGBlock *getBlock() const { - return reinterpret_cast(getData1()); + return reinterpret_cast(getData1Ptr()); } Optional getFirstElement() const { @@ -253,7 +284,7 @@ : ProgramPoint(B, BlockExitKind, L) {} const CFGBlock *getBlock() const { - return reinterpret_cast(getData1()); + return reinterpret_cast(getData1Ptr()); } const Stmt *getTerminator() const { @@ -276,7 +307,7 @@ assert(S); } - const Stmt *getStmt() const { return (const Stmt*) getData1(); } + const Stmt *getStmt() const { return (const Stmt *)getData1Ptr(); } template const T* getStmtAs() const { return dyn_cast(getStmt()); } @@ -344,7 +375,7 @@ } const ReturnStmt *getStmt() const { - return reinterpret_cast(getData1()); + return reinterpret_cast(getData1Ptr()); } private: @@ -509,7 +540,7 @@ } const CFGBlock *getSrc() const { - return static_cast(getData1()); + return static_cast(getData1Ptr()); } const CFGBlock *getDst() const { @@ -537,7 +568,7 @@ : ProgramPoint(I, Loc, PostInitializerKind, L) {} const CXXCtorInitializer *getInitializer() const { - return static_cast(getData1()); + return static_cast(getData1Ptr()); } /// Returns the location of the field. @@ -560,12 +591,10 @@ public: ImplicitCallPoint(const Decl *D, SourceLocation Loc, Kind K, const LocationContext *L, const ProgramPointTag *Tag) - : ProgramPoint(Loc.getPtrEncoding(), D, K, L, Tag) {} + : ProgramPoint(Loc, D, K, L, Tag) {} const Decl *getDecl() const { return static_cast(getData2()); } - SourceLocation getLocation() const { - return SourceLocation::getFromPtrEncoding(getData1()); - } + SourceLocation getLocation() const { return getData1().SLoc; } protected: ImplicitCallPoint() = default; @@ -634,7 +663,7 @@ : ProgramPoint(stmt, calleeCtx, CallEnterKind, callerCtx, nullptr) {} const Stmt *getCallExpr() const { - return static_cast(getData1()); + return static_cast(getData1Ptr()); } const StackFrameContext *getCalleeContext() const { @@ -672,7 +701,7 @@ : ProgramPoint(RS, CallExitBeginKind, L, nullptr) { } const ReturnStmt *getReturnStmt() const { - return static_cast(getData1()); + return static_cast(getData1Ptr()); } private: @@ -693,7 +722,7 @@ : ProgramPoint(CalleeCtx, CallExitEndKind, CallerCtx, nullptr) {} const StackFrameContext *getCalleeContext() const { - return static_cast(getData1()); + return static_cast(getData1Ptr()); } private: @@ -716,7 +745,7 @@ : ProgramPoint(LoopStmt, nullptr, LoopExitKind, LC) {} const Stmt *getLoopStmt() const { - return static_cast(getData1()); + return static_cast(getData1Ptr()); } private: @@ -736,7 +765,7 @@ const ProgramPointTag *tag = nullptr) : ProgramPoint(Data1, Data2, EpsilonKind, L, tag) {} - const void *getData() const { return getData1(); } + const void *getData() const { return getData1Ptr(); } private: friend class ProgramPoint;