[cfe-commits] r160817 - in /cfe/trunk: include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h lib/StaticAnalyzer/Core/CallEvent.cpp
Manman Ren
mren at apple.com
Thu Jul 26 16:27:04 PDT 2012
Seeing this failure , looks like yours :)
http://lab.llvm.org:8011/builders/clang-x86_64-darwin10-nt-O3/builds/1581/steps/compile/logs/stdio
/Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/clang-x86_64-darwin10-nt-O3/llvm.src/tools/clang/lib/StaticAnalyzer/Core/../../../include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h: In copy constructor 'clang::ento::ObjCMethodCall::ObjCMethodCall(const clang::ento::ObjCMethodCall&)':
/Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/clang-x86_64-darwin10-nt-O3/llvm.src/tools/clang/lib/StaticAnalyzer/Core/../../../include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h:63: error: 'clang::ento::CallEvent::CallEvent(const clang::ento::CallEvent&)' is private
/Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/clang-x86_64-darwin10-nt-O3/llvm.src/tools/clang/lib/StaticAnalyzer/Core/../../../include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h:584: error: within this context
/Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/clang-x86_64-darwin10-nt-O3/llvm.src/tools/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp: In member function 'void clang::ento::ExprEngine::Visit(const clang::Stmt*, clang::ento::ExplodedNode*, clang::ento::ExplodedNodeSet&)':
/Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/clang-x86_64-darwin10-nt-O3/llvm.src/tools/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp:883: note: synthesized method 'clang::ento::ObjCMethodCall::ObjCMethodCall(const clang::ento::ObjCMethodCall&)' first required here
make[5]: *** [/Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/clang-x86_64-darwin10-nt-O3/llvm.obj/tools/clang/lib/StaticAnalyzer/Core/Release+Asserts/ExprEngine.o] Error 1
make[4]: *** [Core/.makeall] Error 2
make[4]: *** Waiting for unfinished jobs....
http://lab.llvm.org:8011/builders/clang-x86_64-darwin11-self-mingw32/builds/5499/steps/compile/logs/stdio
llvm[5]: Compiling ObjCSelfInitChecker.cpp for Debug+Asserts build
/Volumes/Macintosh_HD2/buildbots/clang-x86_64-darwin11-self-mingw32/llvm.src/include/llvm/ADT/DenseMap.h: In copy constructor 'llvm::DenseMap<KeyT, ValueT, KeyInfoT>::DenseMap(const llvm::DenseMap<KeyT, ValueT, KeyInfoT>&) [with KeyT = clang::Expr*, ValueT = char, KeyInfoT = llvm::DenseMapInfo<clang::Expr*>]':
/Volumes/Macintosh_HD2/buildbots/clang-x86_64-darwin11-self-mingw32/llvm.src/include/llvm/ADT/DenseSet.h:30: instantiated from 'llvm::DenseSet<ValueT, ValueInfoT>::DenseSet(const llvm::DenseSet<ValueT, ValueInfoT>&) [with ValueT = clang::Expr*, ValueInfoT = llvm::DenseMapInfo<clang::Expr*>]'
/Volumes/Macintosh_HD2/buildbots/clang-x86_64-darwin11-self-mingw32/llvm.src/tools/clang/lib/ARCMigrate/TransAutoreleasePool.cpp:419: instantiated from '_Tp& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const _Key&) [with _Key = clang::VarDecl*, _Tp = <unnamed>::AutoreleasePoolRewriter::PoolVarInfo, _Compare = std::less<clang::VarDecl*>, _Alloc = std::allocator<std::pair<clang::VarDecl* const, <unnamed>::AutoreleasePoolRewriter::PoolVarInfo> >]'
/Volumes/Macintosh_HD2/buildbots/clang-x86_64-darwin11-self-mingw32/llvm.src/tools/clang/lib/ARCMigrate/TransAutoreleasePool.cpp:111: instantiated from here
/Volumes/Macintosh_HD2/buildbots/clang-x86_64-darwin11-self-mingw32/llvm.src/include/llvm/ADT/DenseMap.h:533: warning: base class 'class llvm::DenseMapBase<llvm::DenseMap<clang::Expr*, char, llvm::DenseMapInfo<clang::Expr*> >, clang::Expr*, char, llvm::DenseMapInfo<clang::Expr*> >' should be explicitly initialized in the copy constructor
llvm[5]: Compiling ObjCUnusedIVarsChecker.cpp for Debug+Asserts build
Thanks,
Manman
On Jul 26, 2012, at 2:41 PM, Jordan Rose wrote:
> Author: jrose
> Date: Thu Jul 26 16:41:15 2012
> New Revision: 160817
>
> URL: http://llvm.org/viewvc/llvm-project?rev=160817&view=rev
> Log:
> [analyzer] CallEvent is no longer a value object.
>
> After discussion, the type-based dispatch was decided to be bad for
> maintenance and made it very easy for subtle bugs to creep in. Instead,
> we'll just be very careful when we do have to allocate these on the heap.
>
> Modified:
> cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
> cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp
>
> Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h?rev=160817&r1=160816&r2=160817&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h (original)
> +++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h Thu Jul 26 16:41:15 2012
> @@ -55,45 +55,31 @@
> typedef CallEventKind Kind;
>
> private:
> - // PointerIntPair doesn't respect IntrusiveRefCntPtr, so we have to manually
> - // retain and release the state.
> - llvm::PointerIntPair<const ProgramState *, 2> State;
> - llvm::PointerIntPair<const LocationContext *, 2> LCtx;
> + ProgramStateRef State;
> + const LocationContext *LCtx;
> llvm::PointerUnion<const Expr *, const Decl *> Origin;
>
> + // DO NOT IMPLEMENT! CallEvents should not be copied.
> + CallEvent(const CallEvent &);
> + CallEvent &operator=(const CallEvent &);
> +
> protected:
> // This is user data for subclasses.
> const void *Data;
> SourceLocation Location;
>
> - CallEvent(const Expr *E, ProgramStateRef state, const LocationContext *lctx,
> - Kind k)
> - : State(state.getPtr(), (k & 0x3)),
> - LCtx(lctx, ((k >> 2) & 0x3)),
> - Origin(E) {
> - IntrusiveRefCntPtrInfo<const ProgramState>::retain(getState());
> - assert(k == getKind() && "More kinds than bits in the PointerIntPairs.");
> - }
> -
> - CallEvent(const Decl *D, ProgramStateRef state, const LocationContext *lctx,
> - Kind k)
> - : State(state.getPtr(), (k & 0x3)),
> - LCtx(lctx, ((k >> 2) & 0x3)),
> - Origin(D) {
> - IntrusiveRefCntPtrInfo<const ProgramState>::retain(getState());
> - assert(k == getKind() && "More kinds than bits in the PointerIntPairs.");
> - }
> + CallEvent(const Expr *E, ProgramStateRef state, const LocationContext *lctx)
> + : State(state), LCtx(lctx), Origin(E) {}
>
> - const ProgramState *getState() const {
> - return State.getPointer();
> - }
> + CallEvent(const Decl *D, ProgramStateRef state, const LocationContext *lctx)
> + : State(state), LCtx(lctx), Origin(D) {}
>
> - const LocationContext *getLocationContext() const {
> - return LCtx.getPointer();
> + ProgramStateRef getState() const {
> + return State;
> }
>
> - ~CallEvent() {
> - IntrusiveRefCntPtrInfo<const ProgramState>::release(getState());
> + const LocationContext *getLocationContext() const {
> + return LCtx;
> }
>
>
> @@ -106,24 +92,26 @@
>
> /// \brief Used to specify non-argument regions that will be invalidated as a
> /// result of this call.
> - void getExtraInvalidatedRegions(RegionList &Regions) const;
> + virtual void getExtraInvalidatedRegions(RegionList &Regions) const {}
>
> - QualType getDeclaredResultType() const;
> + virtual QualType getDeclaredResultType() const = 0;
>
> public:
> + virtual ~CallEvent() {}
> +
> /// \brief Returns the kind of call this is.
> - Kind getKind() const {
> - return static_cast<Kind>((State.getInt()) | (LCtx.getInt() << 2));
> - }
> + virtual Kind getKind() const = 0;
>
> /// \brief Returns the declaration of the function or method that will be
> /// called. May be null.
> - const Decl *getDecl() const;
> + virtual const Decl *getDecl() const {
> + return Origin.dyn_cast<const Decl *>();
> + }
>
> /// \brief Returns the definition of the function or method that will be
> /// called. Returns NULL if the definition cannot be found; ex: due to
> /// dynamic dispatch in ObjC methods.
> - const Decl *getRuntimeDefinition() const;
> + virtual const Decl *getRuntimeDefinition() const = 0;
>
> /// \brief Returns the expression whose value will be the result of this call.
> /// May be null.
> @@ -136,7 +124,7 @@
> /// Note that this may be greater than the number of parameters in the
> /// callee's declaration, and that it may include arguments not written in
> /// the source.
> - unsigned getNumArgs() const;
> + virtual unsigned getNumArgs() const = 0;
>
> /// \brief Returns true if the callee is known to be from a system header.
> bool isInSystemHeader() const {
> @@ -161,27 +149,30 @@
>
> /// \brief Returns a source range for the entire call, suitable for
> /// outputting in diagnostics.
> - SourceRange getSourceRange() const;
> + virtual SourceRange getSourceRange() const {
> + return getOriginExpr()->getSourceRange();
> + }
>
> /// \brief Returns the value of a given argument at the time of the call.
> - SVal getArgSVal(unsigned Index) const;
> + virtual SVal getArgSVal(unsigned Index) const;
>
> /// \brief Returns the expression associated with a given argument.
> /// May be null if this expression does not appear in the source.
> - const Expr *getArgExpr(unsigned Index) const;
> + virtual const Expr *getArgExpr(unsigned Index) const { return 0; }
>
> /// \brief Returns the source range for errors associated with this argument.
> + ///
> /// May be invalid if the argument is not written in the source.
> - // FIXME: Is it better to return an invalid range or the range of the origin
> - // expression?
> - SourceRange getArgSourceRange(unsigned Index) const;
> + virtual SourceRange getArgSourceRange(unsigned Index) const;
>
> /// \brief Returns the result type, adjusted for references.
> QualType getResultType() const;
>
> /// \brief Returns the value of the implicit 'this' object, or UndefinedVal if
> /// this is not a C++ member function call.
> - SVal getCXXThisVal() const;
> + virtual SVal getCXXThisVal() const {
> + return UndefinedVal();
> + }
>
> /// \brief Returns true if any of the arguments appear to represent callbacks.
> bool hasNonZeroCallbackArg() const;
> @@ -191,7 +182,9 @@
> // NOTE: The exact semantics of this are still being defined!
> // We don't really want a list of hardcoded exceptions in the long run,
> // but we don't want duplicated lists of known APIs in the short term either.
> - bool argumentsMayEscape() const;
> + virtual bool argumentsMayEscape() const {
> + return hasNonZeroCallbackArg();
> + }
>
> /// \brief Returns an appropriate ProgramPoint for this call.
> ProgramPoint getProgramPoint(bool IsPreVisit = false,
> @@ -206,6 +199,9 @@
>
> /// \brief Returns true if this is a statement that can be considered for
> /// inlining.
> + ///
> + /// FIXME: This should go away once CallEvents are cheap and easy to
> + /// construct from ExplodedNodes.
> static bool mayBeInlined(const Stmt *S);
>
> // Iterator access to formal parameters and their types.
> @@ -229,9 +225,9 @@
> /// If the call has no accessible declaration (or definition, if
> /// \p UseDefinitionParams is set), \c param_begin() will be equal to
> /// \c param_end().
> - param_iterator param_begin(bool UseDefinitionParams = false) const;
> + virtual param_iterator param_begin(bool UseDefinitionParams = false) const =0;
> /// \sa param_begin()
> - param_iterator param_end(bool UseDefinitionParams = false) const;
> + virtual param_iterator param_end(bool UseDefinitionParams = false) const = 0;
>
> typedef llvm::mapped_iterator<param_iterator, get_type_fun>
> param_type_iterator;
> @@ -261,29 +257,24 @@
> /// \brief Represents a call to any sort of function that might have a
> /// FunctionDecl.
> class AnyFunctionCall : public CallEvent {
> - friend class CallEvent;
> -
> protected:
> AnyFunctionCall(const Expr *E, ProgramStateRef St,
> - const LocationContext *LCtx, Kind K)
> - : CallEvent(E, St, LCtx, K) {}
> + const LocationContext *LCtx)
> + : CallEvent(E, St, LCtx) {}
> AnyFunctionCall(const Decl *D, ProgramStateRef St,
> - const LocationContext *LCtx, Kind K)
> - : CallEvent(D, St, LCtx, K) {}
> -
> - // Most function calls have no extra invalidated regions.
> - void getExtraInvalidatedRegions(RegionList &Regions) const {}
> + const LocationContext *LCtx)
> + : CallEvent(D, St, LCtx) {}
>
> - QualType getDeclaredResultType() const;
> + virtual QualType getDeclaredResultType() const;
>
> public:
> // This function is overridden by subclasses, but they must return
> // a FunctionDecl.
> - const FunctionDecl *getDecl() const {
> - return cast_or_null<FunctionDecl>(CallEvent::getDecl());
> + virtual const FunctionDecl *getDecl() const {
> + return cast<FunctionDecl>(CallEvent::getDecl());
> }
>
> - const Decl *getRuntimeDefinition() const {
> + virtual const Decl *getRuntimeDefinition() const {
> const FunctionDecl *FD = getDecl();
> // Note that hasBody() will fill FD with the definition FunctionDecl.
> if (FD && FD->hasBody(FD))
> @@ -291,13 +282,10 @@
> return 0;
> }
>
> - bool argumentsMayEscape() const;
> -
> - SVal getArgSVal(unsigned Index) const;
> - SourceRange getArgSourceRange(unsigned Index) const;
> + virtual bool argumentsMayEscape() const;
>
> - param_iterator param_begin(bool UseDefinitionParams = false) const;
> - param_iterator param_end(bool UseDefinitionParams = false) const;
> + virtual param_iterator param_begin(bool UseDefinitionParams = false) const;
> + virtual param_iterator param_end(bool UseDefinitionParams = false) const;
>
> static bool classof(const CallEvent *CA) {
> return CA->getKind() >= CE_BEG_FUNCTION_CALLS &&
> @@ -309,23 +297,20 @@
> class SimpleCall : public AnyFunctionCall {
> protected:
> SimpleCall(const CallExpr *CE, ProgramStateRef St,
> - const LocationContext *LCtx, Kind K)
> - : AnyFunctionCall(CE, St, LCtx, K) {
> + const LocationContext *LCtx)
> + : AnyFunctionCall(CE, St, LCtx) {
> }
>
> public:
> - const CallExpr *getOriginExpr() const {
> + virtual const CallExpr *getOriginExpr() const {
> return cast<CallExpr>(AnyFunctionCall::getOriginExpr());
> }
>
> - const FunctionDecl *getDecl() const;
> + virtual const FunctionDecl *getDecl() const;
>
> - unsigned getNumArgs() const { return getOriginExpr()->getNumArgs(); }
> - SourceRange getSourceRange() const {
> - return getOriginExpr()->getSourceRange();
> - }
> -
> - const Expr *getArgExpr(unsigned Index) const {
> + virtual unsigned getNumArgs() const { return getOriginExpr()->getNumArgs(); }
> +
> + virtual const Expr *getArgExpr(unsigned Index) const {
> return getOriginExpr()->getArg(Index);
> }
>
> @@ -342,9 +327,9 @@
> public:
> FunctionCall(const CallExpr *CE, ProgramStateRef St,
> const LocationContext *LCtx)
> - : SimpleCall(CE, St, LCtx, CE_Function) {}
> + : SimpleCall(CE, St, LCtx) {}
>
> - SVal getCXXThisVal() const { return UndefinedVal(); }
> + virtual Kind getKind() const { return CE_Function; }
>
> static bool classof(const CallEvent *CA) {
> return CA->getKind() == CE_Function;
> @@ -354,17 +339,15 @@
> /// \brief Represents a non-static C++ member function call, no matter how
> /// it is written.
> class CXXInstanceCall : public SimpleCall {
> - friend class CallEvent;
> -
> protected:
> - void getExtraInvalidatedRegions(RegionList &Regions) const;
> + virtual void getExtraInvalidatedRegions(RegionList &Regions) const;
>
> CXXInstanceCall(const CallExpr *CE, ProgramStateRef St,
> - const LocationContext *LCtx, Kind K)
> - : SimpleCall(CE, St, LCtx, K) {}
> + const LocationContext *LCtx)
> + : SimpleCall(CE, St, LCtx) {}
>
> public:
> - const Decl *getRuntimeDefinition() const;
> + virtual const Decl *getRuntimeDefinition() const;
>
> static bool classof(const CallEvent *CA) {
> return CA->getKind() >= CE_BEG_CXX_INSTANCE_CALLS &&
> @@ -379,13 +362,15 @@
> public:
> CXXMemberCall(const CXXMemberCallExpr *CE, ProgramStateRef St,
> const LocationContext *LCtx)
> - : CXXInstanceCall(CE, St, LCtx, CE_CXXMember) {}
> + : CXXInstanceCall(CE, St, LCtx) {}
>
> - const CXXMemberCallExpr *getOriginExpr() const {
> + virtual const CXXMemberCallExpr *getOriginExpr() const {
> return cast<CXXMemberCallExpr>(SimpleCall::getOriginExpr());
> }
>
> - SVal getCXXThisVal() const;
> + virtual SVal getCXXThisVal() const;
> +
> + virtual Kind getKind() const { return CE_CXXMember; }
>
> static bool classof(const CallEvent *CA) {
> return CA->getKind() == CE_CXXMember;
> @@ -400,18 +385,22 @@
> public:
> CXXMemberOperatorCall(const CXXOperatorCallExpr *CE, ProgramStateRef St,
> const LocationContext *LCtx)
> - : CXXInstanceCall(CE, St, LCtx, CE_CXXMemberOperator) {}
> + : CXXInstanceCall(CE, St, LCtx) {}
>
> - const CXXOperatorCallExpr *getOriginExpr() const {
> + virtual const CXXOperatorCallExpr *getOriginExpr() const {
> return cast<CXXOperatorCallExpr>(SimpleCall::getOriginExpr());
> }
>
> - unsigned getNumArgs() const { return getOriginExpr()->getNumArgs() - 1; }
> - const Expr *getArgExpr(unsigned Index) const {
> + virtual unsigned getNumArgs() const {
> + return getOriginExpr()->getNumArgs() - 1;
> + }
> + virtual const Expr *getArgExpr(unsigned Index) const {
> return getOriginExpr()->getArg(Index + 1);
> }
>
> - SVal getCXXThisVal() const;
> + virtual SVal getCXXThisVal() const;
> +
> + virtual Kind getKind() const { return CE_CXXMemberOperator; }
>
> static bool classof(const CallEvent *CA) {
> return CA->getKind() == CE_CXXMemberOperator;
> @@ -422,17 +411,15 @@
> ///
> /// Example: <tt>^{ /* ... */ }()</tt>
> class BlockCall : public SimpleCall {
> - friend class CallEvent;
> -
> protected:
> - void getExtraInvalidatedRegions(RegionList &Regions) const;
> + virtual void getExtraInvalidatedRegions(RegionList &Regions) const;
>
> - QualType getDeclaredResultType() const;
> + virtual QualType getDeclaredResultType() const;
>
> public:
> BlockCall(const CallExpr *CE, ProgramStateRef St,
> const LocationContext *LCtx)
> - : SimpleCall(CE, St, LCtx, CE_Block) {}
> + : SimpleCall(CE, St, LCtx) {}
>
> /// \brief Returns the region associated with this instance of the block.
> ///
> @@ -450,14 +437,14 @@
> return BR->getDecl();
> }
>
> - const Decl *getRuntimeDefinition() const {
> + virtual const Decl *getRuntimeDefinition() const {
> return getBlockDecl();
> }
>
> - param_iterator param_begin(bool UseDefinitionParams = false) const;
> - param_iterator param_end(bool UseDefinitionParams = false) const;
> + virtual param_iterator param_begin(bool UseDefinitionParams = false) const;
> + virtual param_iterator param_end(bool UseDefinitionParams = false) const;
>
> - SVal getCXXThisVal() const { return UndefinedVal(); }
> + virtual Kind getKind() const { return CE_Block; }
>
> static bool classof(const CallEvent *CA) {
> return CA->getKind() == CE_Block;
> @@ -468,45 +455,41 @@
> ///
> /// Example: \c T(1)
> class CXXConstructorCall : public AnyFunctionCall {
> - friend class CallEvent;
> -
> protected:
> - void getExtraInvalidatedRegions(RegionList &Regions) const;
> + virtual void getExtraInvalidatedRegions(RegionList &Regions) const;
>
> public:
> /// Represents a constructor call to a new or unknown region.
> CXXConstructorCall(const CXXConstructExpr *CE, ProgramStateRef St,
> const LocationContext *LCtx)
> - : AnyFunctionCall(CE, St, LCtx, CE_CXXConstructor) {
> + : AnyFunctionCall(CE, St, LCtx) {
> Data = 0;
> }
>
> /// Represents a constructor call on an existing object region.
> CXXConstructorCall(const CXXConstructExpr *CE, const MemRegion *target,
> ProgramStateRef St, const LocationContext *LCtx)
> - : AnyFunctionCall(CE, St, LCtx, CE_CXXConstructor) {
> + : AnyFunctionCall(CE, St, LCtx) {
> Data = target;
> }
>
> - const CXXConstructExpr *getOriginExpr() const {
> + virtual const CXXConstructExpr *getOriginExpr() const {
> return cast<CXXConstructExpr>(AnyFunctionCall::getOriginExpr());
> }
>
> - SourceRange getSourceRange() const {
> - return getOriginExpr()->getSourceRange();
> - }
> -
> - const CXXConstructorDecl *getDecl() const {
> + virtual const CXXConstructorDecl *getDecl() const {
> return getOriginExpr()->getConstructor();
> }
>
> - unsigned getNumArgs() const { return getOriginExpr()->getNumArgs(); }
> + virtual unsigned getNumArgs() const { return getOriginExpr()->getNumArgs(); }
>
> - const Expr *getArgExpr(unsigned Index) const {
> + virtual const Expr *getArgExpr(unsigned Index) const {
> return getOriginExpr()->getArg(Index);
> }
>
> - SVal getCXXThisVal() const;
> + virtual SVal getCXXThisVal() const;
> +
> + virtual Kind getKind() const { return CE_CXXConstructor; }
>
> static bool classof(const CallEvent *CA) {
> return CA->getKind() == CE_CXXConstructor;
> @@ -518,10 +501,8 @@
> /// This can occur at the end of a scope (for automatic objects), at the end
> /// of a full-expression (for temporaries), or as part of a delete.
> class CXXDestructorCall : public AnyFunctionCall {
> - friend class CallEvent;
> -
> protected:
> - void getExtraInvalidatedRegions(RegionList &Regions) const;
> + virtual void getExtraInvalidatedRegions(RegionList &Regions) const;
>
> public:
> /// Creates an implicit destructor.
> @@ -534,16 +515,18 @@
> CXXDestructorCall(const CXXDestructorDecl *DD, const Stmt *Trigger,
> const MemRegion *Target, ProgramStateRef St,
> const LocationContext *LCtx)
> - : AnyFunctionCall(DD, St, LCtx, CE_CXXDestructor) {
> + : AnyFunctionCall(DD, St, LCtx) {
> Data = Target;
> Location = Trigger->getLocEnd();
> }
>
> - SourceRange getSourceRange() const { return Location; }
> - unsigned getNumArgs() const { return 0; }
> + virtual SourceRange getSourceRange() const { return Location; }
> + virtual unsigned getNumArgs() const { return 0; }
> +
> + virtual SVal getCXXThisVal() const;
> + virtual const Decl *getRuntimeDefinition() const;
>
> - SVal getCXXThisVal() const;
> - const Decl *getRuntimeDefinition() const;
> + virtual Kind getKind() const { return CE_CXXDestructor; }
>
> static bool classof(const CallEvent *CA) {
> return CA->getKind() == CE_CXXDestructor;
> @@ -557,33 +540,28 @@
> public:
> CXXAllocatorCall(const CXXNewExpr *E, ProgramStateRef St,
> const LocationContext *LCtx)
> - : AnyFunctionCall(E, St, LCtx, CE_CXXAllocator) {}
> + : AnyFunctionCall(E, St, LCtx) {}
>
> - const CXXNewExpr *getOriginExpr() const {
> + virtual const CXXNewExpr *getOriginExpr() const {
> return cast<CXXNewExpr>(AnyFunctionCall::getOriginExpr());
> }
>
> - // FIXME: This isn't exactly the range of the allocator...
> - SourceRange getSourceRange() const {
> - return getOriginExpr()->getSourceRange();
> - }
> -
> - const FunctionDecl *getDecl() const {
> + virtual const FunctionDecl *getDecl() const {
> return getOriginExpr()->getOperatorNew();
> }
>
> - unsigned getNumArgs() const {
> + virtual unsigned getNumArgs() const {
> return getOriginExpr()->getNumPlacementArgs() + 1;
> }
>
> - const Expr *getArgExpr(unsigned Index) const {
> + virtual const Expr *getArgExpr(unsigned Index) const {
> // The first argument of an allocator call is the size of the allocation.
> if (Index == 0)
> return 0;
> return getOriginExpr()->getPlacementArg(Index - 1);
> }
>
> - SVal getCXXThisVal() const { return UndefinedVal(); }
> + virtual Kind getKind() const { return CE_CXXAllocator; }
>
> static bool classof(const CallEvent *CE) {
> return CE->getKind() == CE_CXXAllocator;
> @@ -604,34 +582,32 @@
> ///
> /// This includes all of the kinds listed in ObjCMessageKind.
> class ObjCMethodCall : public CallEvent {
> - friend class CallEvent;
> -
> const PseudoObjectExpr *getContainingPseudoObjectExpr() const;
>
> protected:
> - void getExtraInvalidatedRegions(RegionList &Regions) const;
> + virtual void getExtraInvalidatedRegions(RegionList &Regions) const;
>
> - QualType getDeclaredResultType() const;
> + virtual QualType getDeclaredResultType() const;
> ObjCMethodDecl *LookupClassMethodDefinition(Selector Sel,
> ObjCInterfaceDecl *ClassDecl) const;
>
> public:
> ObjCMethodCall(const ObjCMessageExpr *Msg, ProgramStateRef St,
> const LocationContext *LCtx)
> - : CallEvent(Msg, St, LCtx, CE_ObjCMessage) {
> + : CallEvent(Msg, St, LCtx) {
> Data = 0;
> }
>
> - const ObjCMessageExpr *getOriginExpr() const {
> + virtual const ObjCMessageExpr *getOriginExpr() const {
> return cast<ObjCMessageExpr>(CallEvent::getOriginExpr());
> }
> - const ObjCMethodDecl *getDecl() const {
> + virtual const ObjCMethodDecl *getDecl() const {
> return getOriginExpr()->getMethodDecl();
> }
> - unsigned getNumArgs() const {
> + virtual unsigned getNumArgs() const {
> return getOriginExpr()->getNumArgs();
> }
> - const Expr *getArgExpr(unsigned Index) const {
> + virtual const Expr *getArgExpr(unsigned Index) const {
> return getOriginExpr()->getArg(Index);
> }
>
> @@ -645,7 +621,7 @@
> return getOriginExpr()->getSelector();
> }
>
> - SourceRange getSourceRange() const;
> + virtual SourceRange getSourceRange() const;
>
> /// \brief Returns the value of the receiver at the time of this call.
> SVal getReceiverSVal() const;
> @@ -675,7 +651,7 @@
> // TODO: We might want to only compute this once (or change the API for
> // getting the parameters). Currently, this gets called 3 times during
> // inlining.
> - const Decl *getRuntimeDefinition() const {
> + virtual const Decl *getRuntimeDefinition() const {
>
> const ObjCMessageExpr *E = getOriginExpr();
> if (E->isInstanceMessage()) {
> @@ -692,129 +668,16 @@
> return 0;
> }
>
> - SVal getCXXThisVal() const { return UndefinedVal(); }
> + virtual param_iterator param_begin(bool UseDefinitionParams = false) const;
> + virtual param_iterator param_end(bool UseDefinitionParams = false) const;
>
> - bool argumentsMayEscape() const {
> - return hasNonZeroCallbackArg();
> - }
> -
> - SVal getArgSVal(unsigned Index) const { return getSVal(getArgExpr(Index)); }
> - SourceRange getArgSourceRange(unsigned Index) const {
> - return getArgExpr(Index)->getSourceRange();
> - }
> -
> - param_iterator param_begin(bool UseDefinitionParams = false) const;
> - param_iterator param_end(bool UseDefinitionParams = false) const;
> + virtual Kind getKind() const { return CE_ObjCMessage; }
>
> static bool classof(const CallEvent *CA) {
> return CA->getKind() == CE_ObjCMessage;
> }
> };
>
> -
> -// FIXME: Use a .def or .td file for this.
> -#define DISPATCH(fn) \
> - switch (getKind()) { \
> - case CE_Function: \
> - return cast<FunctionCall>(this)->fn(); \
> - case CE_CXXMember: \
> - return cast<CXXMemberCall>(this)->fn(); \
> - case CE_CXXMemberOperator: \
> - return cast<CXXMemberOperatorCall>(this)->fn(); \
> - case CE_Block: \
> - return cast<BlockCall>(this)->fn(); \
> - case CE_CXXConstructor: \
> - return cast<CXXConstructorCall>(this)->fn(); \
> - case CE_CXXDestructor: \
> - return cast<CXXDestructorCall>(this)->fn(); \
> - case CE_CXXAllocator: \
> - return cast<CXXAllocatorCall>(this)->fn(); \
> - case CE_ObjCMessage: \
> - return cast<ObjCMethodCall>(this)->fn(); \
> - } \
> - llvm_unreachable("unknown CallEvent kind");
> -
> -#define DISPATCH_ARG(fn, arg) \
> - switch (getKind()) { \
> - case CE_Function: \
> - return cast<FunctionCall>(this)->fn(arg); \
> - case CE_CXXMember: \
> - return cast<CXXMemberCall>(this)->fn(arg); \
> - case CE_CXXMemberOperator: \
> - return cast<CXXMemberOperatorCall>(this)->fn(arg); \
> - case CE_Block: \
> - return cast<BlockCall>(this)->fn(arg); \
> - case CE_CXXConstructor: \
> - return cast<CXXConstructorCall>(this)->fn(arg); \
> - case CE_CXXDestructor: \
> - return cast<CXXDestructorCall>(this)->fn(arg); \
> - case CE_CXXAllocator: \
> - return cast<CXXAllocatorCall>(this)->fn(arg); \
> - case CE_ObjCMessage: \
> - return cast<ObjCMethodCall>(this)->fn(arg); \
> - } \
> - llvm_unreachable("unknown CallEvent kind");
> -
> -inline void CallEvent::getExtraInvalidatedRegions(RegionList &Regions) const {
> - DISPATCH_ARG(getExtraInvalidatedRegions, Regions);
> -}
> -
> -inline QualType CallEvent::getDeclaredResultType() const {
> - DISPATCH(getDeclaredResultType);
> -}
> -
> -inline const Decl *CallEvent::getDecl() const {
> - if (const Decl *D = Origin.dyn_cast<const Decl *>())
> - return D;
> - DISPATCH(getDecl);
> -}
> -
> -inline const Decl *CallEvent::getRuntimeDefinition() const {
> - DISPATCH(getRuntimeDefinition);
> -}
> -
> -inline unsigned CallEvent::getNumArgs() const {
> - DISPATCH(getNumArgs);
> -}
> -
> -inline SourceRange CallEvent::getSourceRange() const {
> - DISPATCH(getSourceRange);
> -}
> -
> -inline SVal CallEvent::getArgSVal(unsigned Index) const {
> - DISPATCH_ARG(getArgSVal, Index);
> -}
> -
> -inline const Expr *CallEvent::getArgExpr(unsigned Index) const {
> - DISPATCH_ARG(getArgExpr, Index);
> -}
> -
> -inline SourceRange CallEvent::getArgSourceRange(unsigned Index) const {
> - DISPATCH_ARG(getArgSourceRange, Index);
> -}
> -
> -inline SVal CallEvent::getCXXThisVal() const {
> - DISPATCH(getCXXThisVal);
> -}
> -
> -
> -inline bool CallEvent::argumentsMayEscape() const {
> - DISPATCH(argumentsMayEscape);
> -}
> -
> -inline CallEvent::param_iterator
> -CallEvent::param_begin(bool UseDefinitionParams) const {
> - DISPATCH_ARG(param_begin, UseDefinitionParams);
> -}
> -
> -inline CallEvent::param_iterator
> -CallEvent::param_end(bool UseDefinitionParams) const {
> - DISPATCH_ARG(param_end, UseDefinitionParams);
> -}
> -
> -#undef DISPATCH
> -#undef DISPATCH_ARG
> -
> } // end namespace ento
> } // end namespace clang
>
>
> Modified: cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp?rev=160817&r1=160816&r2=160817&view=diff
> ==============================================================================
> --- cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp (original)
> +++ cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp Thu Jul 26 16:41:15 2012
> @@ -193,9 +193,43 @@
> return PostImplicitCall(D, Loc, getLocationContext(), Tag);
> }
>
> +SVal CallEvent::getArgSVal(unsigned Index) const {
> + const Expr *ArgE = getArgExpr(Index);
> + if (!ArgE)
> + return UnknownVal();
> + return getSVal(ArgE);
> +}
> +
> +SourceRange CallEvent::getArgSourceRange(unsigned Index) const {
> + const Expr *ArgE = getArgExpr(Index);
> + if (!ArgE)
> + return SourceRange();
> + return ArgE->getSourceRange();
> +}
> +
> +void CallEvent::dump(raw_ostream &Out) const {
> + ASTContext &Ctx = getState()->getStateManager().getContext();
> + if (const Expr *E = getOriginExpr()) {
> + E->printPretty(Out, Ctx, 0, Ctx.getPrintingPolicy());
> + Out << "\n";
> + return;
> + }
> +
> + if (const Decl *D = getDecl()) {
> + Out << "Call to ";
> + D->print(Out, Ctx.getPrintingPolicy());
> + return;
> + }
> +
> + // FIXME: a string representation of the kind would be nice.
> + Out << "Unknown call (type " << getKind() << ")";
> +}
> +
>
> bool CallEvent::mayBeInlined(const Stmt *S) {
> - return isa<CallExpr>(S);
> + // FIXME: Kill this.
> + return isa<CallExpr>(S) || isa<ObjCMessageExpr>(S)
> + || isa<CXXConstructExpr>(S);
> }
>
>
> @@ -283,20 +317,6 @@
> return false;
> }
>
> -SVal AnyFunctionCall::getArgSVal(unsigned Index) const {
> - const Expr *ArgE = getArgExpr(Index);
> - if (!ArgE)
> - return UnknownVal();
> - return getSVal(ArgE);
> -}
> -
> -SourceRange AnyFunctionCall::getArgSourceRange(unsigned Index) const {
> - const Expr *ArgE = getArgExpr(Index);
> - if (!ArgE)
> - return SourceRange();
> - return ArgE->getSourceRange();
> -}
> -
>
> const FunctionDecl *SimpleCall::getDecl() const {
> const FunctionDecl *D = getOriginExpr()->getDirectCallee();
> @@ -306,24 +326,6 @@
> return getSVal(getOriginExpr()->getCallee()).getAsFunctionDecl();
> }
>
> -void CallEvent::dump(raw_ostream &Out) const {
> - ASTContext &Ctx = getState()->getStateManager().getContext();
> - if (const Expr *E = getOriginExpr()) {
> - E->printPretty(Out, Ctx, 0, Ctx.getLangOpts());
> - Out << "\n";
> - return;
> - }
> -
> - if (const Decl *D = getDecl()) {
> - Out << "Call to ";
> - D->print(Out, Ctx.getLangOpts());
> - return;
> - }
> -
> - // FIXME: a string representation of the kind would be nice.
> - Out << "Unknown call (type " << getKind() << ")";
> -}
> -
>
> void CXXInstanceCall::getExtraInvalidatedRegions(RegionList &Regions) const {
> if (const MemRegion *R = getCXXThisVal().getAsRegion())
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20120726/e4a94ca2/attachment.html>
More information about the cfe-commits
mailing list