diff options
author | Jordan Rose <jordan_rose@apple.com> | 2012-07-10 22:07:42 +0000 |
---|---|---|
committer | Jordan Rose <jordan_rose@apple.com> | 2012-07-10 22:07:42 +0000 |
commit | 28038f33aa2db4833881fea757a1f0daf85ac02b (patch) | |
tree | c2814066ca3c1d5e9a807ee488a5f9d27ce0e9a8 /include/clang/Analysis/ProgramPoint.h | |
parent | 13106117060c90d6f84bd2ed7a5c03e0502ff419 (diff) |
[analyzer] Add new PreImplicitCall and PostImplicitCall ProgramPoints.
These are currently unused, but are intended to be used in lieu of PreStmt
and PostStmt when the call is implicit (e.g. an automatic object destructor).
This also modifies the Data1 field of ProgramPoints to allow storing any
pointer-sized value, as opposed to only aligned pointers. This is necessary
to store SourceLocations.
There is currently no BugReporter support for these; they should be skipped
over in any diagnostic output.
This commit also tags checkers that currently rely on function calls only
occurring at StmtPoints.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@160019 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang/Analysis/ProgramPoint.h')
-rw-r--r-- | include/clang/Analysis/ProgramPoint.h | 84 |
1 files changed, 68 insertions, 16 deletions
diff --git a/include/clang/Analysis/ProgramPoint.h b/include/clang/Analysis/ProgramPoint.h index 57e5fc1028..4dcf92e7f2 100644 --- a/include/clang/Analysis/ProgramPoint.h +++ b/include/clang/Analysis/ProgramPoint.h @@ -55,17 +55,21 @@ public: CallExitEndKind, MinPostStmtKind = PostStmtKind, MaxPostStmtKind = CallExitEndKind, + PreImplicitCallKind, + PostImplicitCallKind, + MinImplicitCallKind = PreImplicitCallKind, + MaxImplicitCallKind = PostImplicitCallKind, EpsilonKind}; private: - llvm::PointerIntPair<const void *, 2, unsigned> Data1; + const void *Data1; llvm::PointerIntPair<const void *, 2, unsigned> Data2; // The LocationContext could be NULL to allow ProgramPoint to be used in // context insensitive analysis. llvm::PointerIntPair<const LocationContext *, 2, unsigned> L; - const ProgramPointTag *Tag; + llvm::PointerIntPair<const ProgramPointTag *, 2, unsigned> Tag; ProgramPoint(); @@ -74,10 +78,10 @@ protected: Kind k, const LocationContext *l, const ProgramPointTag *tag = 0) - : Data1(P, ((unsigned) k) & 0x3), - Data2(0, (((unsigned) k) >> 2) & 0x3), - L(l, (((unsigned) k) >> 4) & 0x3), - Tag(tag) { + : Data1(P), + Data2(0, (((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); @@ -88,13 +92,13 @@ protected: Kind k, const LocationContext *l, const ProgramPointTag *tag = 0) - : Data1(P1, ((unsigned) k) & 0x3), - Data2(P2, (((unsigned) k) >> 2) & 0x3), - L(l, (((unsigned) k) >> 4) & 0x3), - Tag(tag) {} + : 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.getPointer(); } + const void *getData1() const { return Data1; } const void *getData2() const { return Data2.getPointer(); } void setData2(const void *d) { Data2.setPointer(d); } @@ -107,11 +111,11 @@ public: } Kind getKind() const { - unsigned x = L.getInt(); + unsigned x = Tag.getInt(); x <<= 2; - x |= Data2.getInt(); + x |= L.getInt(); x <<= 2; - x |= Data1.getInt(); + x |= Data2.getInt(); return (Kind) x; } @@ -123,7 +127,7 @@ public: K == PreStmtPurgeDeadSymbolsKind); } - const ProgramPointTag *getTag() const { return Tag; } + const ProgramPointTag *getTag() const { return Tag.getPointer(); } const LocationContext *getLocationContext() const { return L.getPointer(); @@ -157,7 +161,7 @@ public: ID.AddPointer(getData1()); ID.AddPointer(getData2()); ID.AddPointer(getLocationContext()); - ID.AddPointer(Tag); + ID.AddPointer(getTag()); } static ProgramPoint getProgramPoint(const Stmt *S, ProgramPoint::Kind K, @@ -408,6 +412,54 @@ public: } }; +/// Represents an implicit call event. +/// +/// The nearest statement is provided for diagnostic purposes. +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 Decl *getDecl() const { return static_cast<const Decl *>(getData2()); } + SourceLocation getLocation() const { + return SourceLocation::getFromPtrEncoding(getData1()); + } + + static bool classof(const ProgramPoint *Location) { + return Location->getKind() >= MinImplicitCallKind && + Location->getKind() <= MaxImplicitCallKind; + } +}; + +/// Represents a program point just before an implicit call event. +/// +/// Explicit calls will appear as PreStmt program points. +class PreImplicitCall : public ImplicitCallPoint { +public: + PreImplicitCall(const Decl *D, SourceLocation Loc, + const LocationContext *L, const ProgramPointTag *Tag = 0) + : ImplicitCallPoint(D, Loc, PreImplicitCallKind, L, Tag) {} + + static bool classof(const ProgramPoint *Location) { + return Location->getKind() == PreImplicitCallKind; + } +}; + +/// Represents a program point just after an implicit call event. +/// +/// Explicit calls will appear as PostStmt program points. +class PostImplicitCall : public ImplicitCallPoint { +public: + PostImplicitCall(const Decl *D, SourceLocation Loc, + const LocationContext *L, const ProgramPointTag *Tag = 0) + : ImplicitCallPoint(D, Loc, PostImplicitCallKind, L, Tag) {} + + static bool classof(const ProgramPoint *Location) { + return Location->getKind() == PostImplicitCallKind; + } +}; + /// Represents a point when we begin processing an inlined call. class CallEnter : public StmtPoint { public: |