2009/11/25 Ted Kremenek <[email protected]>:
> Hi Zhongxing,
>
> Thanks for doing this. Removing GRExprEngineInternalChecks.cpp was indeed
> the goal!
>
> The only concern I have is that the NilReceiverStructRet and
> NilReceiverLargerThanVoidPtrRet weren't really precondition checks; they
> actually handled the evaluation of the message expression itself. Currently
> PreVisitObjCMessageExpr is only designed to handle preconditions. That's the
> reason I held off from doing this refactoring until I thought about this more.
>
> A problem I see is in code such as the following:
>
> + SVal V = C.getValueManager().makeZeroVal(ME->getType());
> + C.GenerateNode(StNull->BindExpr(ME, V));
> + return;
> + }
> + }
> Here we will bind a value to the ObjCMessageExpr (representing the evaluation
> of the method) but then in GRExprEngine we will then call
> getTF().EvalObjCMessagExpr(). This is incorrect. The plug-in transfer
> function logic shouldn't even be called in this case, since the semantics of
> the message expression have been completely evaluated.
>
> As a partial solution, GRExprEngine::VisitObjCMessageExprDispatchHelper()
> should check if the receiver is NULL before calling
> getTF().EvalObjCMessagExpr(). That will at least address the current
> problem, but it isn't the general solution.
I noticed this in the process of migrating the checker. So I added
this code into CFRefCount.cpp:
// FIXME: Since we moved the nil check into a checker, we could get nil
// receiver here. Need a better way to check such case.
if (Expr* Receiver = ME->getReceiver()) {
const GRState *state = Pred->getState();
DefinedOrUnknownSVal L=cast<DefinedOrUnknownSVal>(state->getSVal(Receiver));
if (!state->Assume(L, true)) {
Dst.Add(Pred);
return;
}
}
>
> A more general problem that we should discuss is how to we want to handle
> model transfer functions (via the Checker interface) that don't just handle
> pre- and post- conditions, but also the entire effects of the called
> function/method. Currently the GRTransferFuncs object has this
> responsibility, but as we've discussed off the mailing list we'd like to move
> in a direction where GRTransferfuncs is no longer needed and we have a way of
> nicely composing transfer function logic for the evaluation of function
> calls. This also needs to interact nicely with our plans for (optional)
> interprocedural analysis via inlining. Once we figure out that solution, we
> can also remove all the OSAtomics logic out of GRExprEngine as well.
>
I remember we didn't say to remove GRTransferfuncs. I proposed to use
it to decide some big evaluation scheme, like intra- vs inter-
procedural analysis. We implement different EvalCall() in transfer
functions.
> On Nov 23, 2009, at 11:06 PM, Zhongxing Xu wrote:
>
>> Author: zhongxingxu
>> Date: Tue Nov 24 01:06:39 2009
>> New Revision: 89745
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=89745&view=rev
>> Log:
>> Refactor NilReceiverStructRet and NilReceiverLargerThanVoidPtrRet into
>> CallAndMessageChecker.
>>
>> Modified:
>> cfe/trunk/include/clang/Analysis/PathSensitive/Checker.h
>> cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h
>> cfe/trunk/lib/Analysis/CFRefCount.cpp
>> cfe/trunk/lib/Analysis/CallAndMessageChecker.cpp
>> cfe/trunk/lib/Analysis/GRExprEngine.cpp
>> cfe/trunk/lib/Analysis/GRExprEngineInternalChecks.cpp
>>
>> Modified: cfe/trunk/include/clang/Analysis/PathSensitive/Checker.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/Checker.h?rev=89745&r1=89744&r2=89745&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/include/clang/Analysis/PathSensitive/Checker.h (original)
>> +++ cfe/trunk/include/clang/Analysis/PathSensitive/Checker.h Tue Nov 24
>> 01:06:39 2009
>> @@ -81,6 +81,10 @@
>> return getBugReporter().getSourceManager();
>> }
>>
>> + ValueManager &getValueManager() {
>> + return Eng.getValueManager();
>> + }
>> +
>> ExplodedNode *GenerateNode(bool autoTransition = true) {
>> assert(statement && "Only transitions with statements currently
>> supported");
>> ExplodedNode *N = GenerateNodeImpl(statement, getState(), false);
>>
>> Modified: cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h?rev=89745&r1=89744&r2=89745&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h (original)
>> +++ cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h Tue Nov 24
>> 01:06:39 2009
>> @@ -90,38 +90,6 @@
>> public:
>> typedef llvm::SmallPtrSet<ExplodedNode*,2> ErrorNodes;
>>
>> - /// NilReceiverStructRetExplicit - Nodes in the ExplodedGraph that
>> resulted
>> - /// from [x ...] with 'x' definitely being nil and the result was a
>> 'struct'
>> - // (an undefined value).
>> - ErrorNodes NilReceiverStructRetExplicit;
>> -
>> - /// NilReceiverStructRetImplicit - Nodes in the ExplodedGraph that
>> resulted
>> - /// from [x ...] with 'x' possibly being nil and the result was a
>> 'struct'
>> - // (an undefined value).
>> - ErrorNodes NilReceiverStructRetImplicit;
>> -
>> - /// NilReceiverLargerThanVoidPtrRetExplicit - Nodes in the ExplodedGraph
>> that
>> - /// resulted from [x ...] with 'x' definitely being nil and the result's
>> size
>> - // was larger than sizeof(void *) (an undefined value).
>> - ErrorNodes NilReceiverLargerThanVoidPtrRetExplicit;
>> -
>> - /// NilReceiverLargerThanVoidPtrRetImplicit - Nodes in the ExplodedGraph
>> that
>> - /// resulted from [x ...] with 'x' possibly being nil and the result's
>> size
>> - // was larger than sizeof(void *) (an undefined value).
>> - ErrorNodes NilReceiverLargerThanVoidPtrRetImplicit;
>> -
>> - /// UndefBranches - Nodes in the ExplodedGraph that result from
>> - /// taking a branch based on an undefined value.
>> - ErrorNodes UndefBranches;
>> -
>> - /// UndefStores - Sinks in the ExplodedGraph that result from
>> - /// making a store to an undefined lvalue.
>> - ErrorNodes UndefStores;
>> -
>> - /// NoReturnCalls - Sinks in the ExplodedGraph that result from
>> - // calling a function with the attribute "noreturn".
>> - ErrorNodes NoReturnCalls;
>> -
>> /// UndefResults - Nodes in the ExplodedGraph where the operands are
>> defined
>> /// by the result is not. Excludes divide-by-zero errors.
>> ErrorNodes UndefResults;
>> @@ -185,36 +153,6 @@
>> return static_cast<CHECKER*>(lookupChecker(CHECKER::getTag()));
>> }
>>
>> - bool isNoReturnCall(const ExplodedNode* N) const {
>> - return N->isSink() && NoReturnCalls.count(const_cast<ExplodedNode*>(N))
>> != 0;
>> - }
>> -
>> - typedef ErrorNodes::iterator undef_branch_iterator;
>> - undef_branch_iterator undef_branches_begin() { return
>> UndefBranches.begin(); }
>> - undef_branch_iterator undef_branches_end() { return UndefBranches.end(); }
>> -
>> - typedef ErrorNodes::iterator nil_receiver_struct_ret_iterator;
>> -
>> - nil_receiver_struct_ret_iterator nil_receiver_struct_ret_begin() {
>> - return NilReceiverStructRetExplicit.begin();
>> - }
>> -
>> - nil_receiver_struct_ret_iterator nil_receiver_struct_ret_end() {
>> - return NilReceiverStructRetExplicit.end();
>> - }
>> -
>> - typedef ErrorNodes::iterator
>> nil_receiver_larger_than_voidptr_ret_iterator;
>> -
>> - nil_receiver_larger_than_voidptr_ret_iterator
>> - nil_receiver_larger_than_voidptr_ret_begin() {
>> - return NilReceiverLargerThanVoidPtrRetExplicit.begin();
>> - }
>> -
>> - nil_receiver_larger_than_voidptr_ret_iterator
>> - nil_receiver_larger_than_voidptr_ret_end() {
>> - return NilReceiverLargerThanVoidPtrRetExplicit.end();
>> - }
>> -
>> typedef ErrorNodes::iterator undef_result_iterator;
>> undef_result_iterator undef_results_begin() { return UndefResults.begin();
>> }
>> undef_result_iterator undef_results_end() { return UndefResults.end(); }
>>
>> Modified: cfe/trunk/lib/Analysis/CFRefCount.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFRefCount.cpp?rev=89745&r1=89744&r2=89745&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/Analysis/CFRefCount.cpp (original)
>> +++ cfe/trunk/lib/Analysis/CFRefCount.cpp Tue Nov 24 01:06:39 2009
>> @@ -3066,6 +3066,16 @@
>> GRStmtNodeBuilder& Builder,
>> ObjCMessageExpr* ME,
>> ExplodedNode* Pred) {
>> + // FIXME: Since we moved the nil check into a checker, we could get nil
>> + // receiver here. Need a better way to check such case.
>> + if (Expr* Receiver = ME->getReceiver()) {
>> + const GRState *state = Pred->getState();
>> + DefinedOrUnknownSVal
>> L=cast<DefinedOrUnknownSVal>(state->getSVal(Receiver));
>> + if (!state->Assume(L, true)) {
>> + Dst.Add(Pred);
>> + return;
>> + }
>> + }
>>
>> RetainSummary *Summ =
>> ME->getReceiver()
>>
>> Modified: cfe/trunk/lib/Analysis/CallAndMessageChecker.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CallAndMessageChecker.cpp?rev=89745&r1=89744&r2=89745&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/Analysis/CallAndMessageChecker.cpp (original)
>> +++ cfe/trunk/lib/Analysis/CallAndMessageChecker.cpp Tue Nov 24 01:06:39 2009
>> @@ -14,6 +14,7 @@
>>
>> #include "clang/Analysis/PathSensitive/CheckerVisitor.h"
>> #include "clang/Analysis/PathSensitive/BugReporter.h"
>> +#include "clang/AST/ParentMap.h"
>> #include "GRExprEngineInternalChecks.h"
>>
>> using namespace clang;
>> @@ -26,10 +27,13 @@
>> BugType *BT_call_arg;
>> BugType *BT_msg_undef;
>> BugType *BT_msg_arg;
>> + BugType *BT_struct_ret;
>> + BugType *BT_void_ptr;
>> public:
>> CallAndMessageChecker() :
>> BT_call_null(0), BT_call_undef(0), BT_call_arg(0),
>> - BT_msg_undef(0), BT_msg_arg(0) {}
>> + BT_msg_undef(0), BT_msg_arg(0), BT_struct_ret(0), BT_void_ptr(0) {}
>> +
>> static void *getTag() {
>> static int x = 0;
>> return &x;
>> @@ -119,8 +123,8 @@
>> }
>>
>> // Check for any arguments that are uninitialized/undefined.
>> - for (ObjCMessageExpr::const_arg_iterator I = ME->arg_begin(), E =
>> ME->arg_end();
>> - I != E; ++I) {
>> + for (ObjCMessageExpr::const_arg_iterator I = ME->arg_begin(),
>> + E = ME->arg_end(); I != E; ++I) {
>> if (state->getSVal(*I).isUndef()) {
>> if (ExplodedNode *N = C.GenerateSink()) {
>> if (!BT_msg_arg)
>> @@ -137,4 +141,112 @@
>> }
>> }
>> }
>> +
>> + // Check if the receiver was nil and then return value a struct.
>> + if (const Expr *Receiver = ME->getReceiver()) {
>> + SVal L_untested = state->getSVal(Receiver);
>> + // Assume that the receiver is not NULL.
>> + DefinedOrUnknownSVal L = cast<DefinedOrUnknownSVal>(L_untested);
>> + const GRState *StNotNull = state->Assume(L, true);
>> +
>> + // Assume that the receiver is NULL.
>> + const GRState *StNull = state->Assume(L, false);
>> +
>> + if (StNull) {
>> + QualType RetTy = ME->getType();
>> + if (RetTy->isRecordType()) {
>> + if (C.getPredecessor()->getParentMap().isConsumedExpr(ME)) {
>> + // The [0 ...] expressions will return garbage. Flag either an
>> + // explicit or implicit error. Because of the structure of this
>> + // function we currently do not bifurfacte the state graph at
>> + // this point.
>> + // FIXME: We should bifurcate and fill the returned struct with
>> + // garbage.
>> + if (ExplodedNode* N = C.GenerateSink(StNull)) {
>> + if (!StNotNull) {
>> + if (!BT_struct_ret) {
>> + std::string sbuf;
>> + llvm::raw_string_ostream os(sbuf);
>> + os << "The receiver in the message expression is 'nil' and "
>> + "results in the returned value (of type '"
>> + << ME->getType().getAsString()
>> + << "') to be garbage or otherwise undefined";
>> + BT_struct_ret = new BuiltinBug(os.str().c_str());
>> + }
>> +
>> + EnhancedBugReport *R = new EnhancedBugReport(*BT_struct_ret,
>> +
>> BT_struct_ret->getName(), N);
>> + R->addRange(Receiver->getSourceRange());
>> +
>> R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue,
>> + Receiver);
>> + C.EmitReport(R);
>> + return;
>> + }
>> + else
>> + // Do not report implicit bug.
>> + return;
>> + }
>> + }
>> + } else {
>> + ASTContext &Ctx = C.getASTContext();
>> + if (RetTy != Ctx.VoidTy) {
>> + if (C.getPredecessor()->getParentMap().isConsumedExpr(ME)) {
>> + // sizeof(void *)
>> + const uint64_t voidPtrSize = Ctx.getTypeSize(Ctx.VoidPtrTy);
>> + // sizeof(return type)
>> + const uint64_t returnTypeSize = Ctx.getTypeSize(ME->getType());
>> +
>> + if (voidPtrSize < returnTypeSize) {
>> + if (ExplodedNode* N = C.GenerateSink(StNull)) {
>> + if (!StNotNull) {
>> + if (!BT_struct_ret) {
>> + std::string sbuf;
>> + llvm::raw_string_ostream os(sbuf);
>> + os << "The receiver in the message expression is 'nil'
>> and "
>> + "results in the returned value (of type '"
>> + << ME->getType().getAsString()
>> + << "' and of size "
>> + << returnTypeSize / 8
>> + << " bytes) to be garbage or otherwise undefined";
>> + BT_void_ptr = new BuiltinBug(os.str().c_str());
>> + }
>> +
>> + EnhancedBugReport *R = new EnhancedBugReport(*BT_void_ptr,
>> +
>> BT_void_ptr->getName(), N);
>> + R->addRange(Receiver->getSourceRange());
>> + R->addVisitorCreator(
>> + bugreporter::registerTrackNullOrUndefValue,
>> Receiver);
>> + C.EmitReport(R);
>> + return;
>> + } else
>> + // Do not report implicit bug.
>> + return;
>> + }
>> + }
>> + else if (!StNotNull) {
>> + // Handle the safe cases where the return value is 0 if the
>> + // receiver is nil.
>> + //
>> + // FIXME: For now take the conservative approach that we only
>> + // return null values if we *know* that the receiver is nil.
>> + // This is because we can have surprises like:
>> + //
>> + // ... = [[NSScreens screens] objectAtIndex:0];
>> + //
>> + // What can happen is that [... screens] could return nil, but
>> + // it most likely isn't nil. We should assume the semantics
>> + // of this case unless we have *a lot* more knowledge.
>> + //
>> + SVal V = C.getValueManager().makeZeroVal(ME->getType());
>> + C.GenerateNode(StNull->BindExpr(ME, V));
>> + return;
>> + }
>> + }
>> + }
>> + }
>> + }
>> + // Do not propagate null state.
>> + if (StNotNull)
>> + C.GenerateNode(StNotNull);
>> + }
>> }
>>
>> Modified: cfe/trunk/lib/Analysis/GRExprEngine.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRExprEngine.cpp?rev=89745&r1=89744&r2=89745&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/Analysis/GRExprEngine.cpp (original)
>> +++ cfe/trunk/lib/Analysis/GRExprEngine.cpp Tue Nov 24 01:06:39 2009
>> @@ -860,8 +860,9 @@
>>
>> if (isa<loc::ConcreteInt>(V) || isa<UndefinedVal>(V)) {
>> // Dispatch to the first target and mark it as a sink.
>> - ExplodedNode* N = builder.generateNode(builder.begin(), state, true);
>> - UndefBranches.insert(N);
>> + //ExplodedNode* N = builder.generateNode(builder.begin(), state, true);
>> + // FIXME: add checker visit.
>> + // UndefBranches.insert(N);
>> return;
>> }
>>
>> @@ -912,8 +913,10 @@
>> SVal CondV_untested = state->getSVal(CondE);
>>
>> if (CondV_untested.isUndef()) {
>> - ExplodedNode* N = builder.generateDefaultCaseNode(state, true);
>> - UndefBranches.insert(N);
>> + //ExplodedNode* N = builder.generateDefaultCaseNode(state, true);
>> + // FIXME: add checker
>> + //UndefBranches.insert(N);
>> +
>> return;
>> }
>> DefinedOrUnknownSVal CondV = cast<DefinedOrUnknownSVal>(CondV_untested);
>> @@ -1858,88 +1861,9 @@
>> for (ExplodedNodeSet::iterator DI = DstTmp.begin(), DE = DstTmp.end();
>> DI!=DE; ++DI) {
>> Pred = *DI;
>> - // FIXME: More logic for the processing the method call.
>> - const GRState* state = GetState(Pred);
>> bool RaisesException = false;
>>
>> - if (Expr* Receiver = ME->getReceiver()) {
>> - SVal L_untested = state->getSVal(Receiver);
>> -
>> - // "Assume" that the receiver is not NULL.
>> - DefinedOrUnknownSVal L = cast<DefinedOrUnknownSVal>(L_untested);
>> - const GRState *StNotNull = state->Assume(L, true);
>> -
>> - // "Assume" that the receiver is NULL.
>> - const GRState *StNull = state->Assume(L, false);
>> -
>> - if (StNull) {
>> - QualType RetTy = ME->getType();
>> -
>> - // Check if the receiver was nil and the return value a struct.
>> - if (RetTy->isRecordType()) {
>> - if (Pred->getParentMap().isConsumedExpr(ME)) {
>> - // The [0 ...] expressions will return garbage. Flag either an
>> - // explicit or implicit error. Because of the structure of this
>> - // function we currently do not bifurfacte the state graph at
>> - // this point.
>> - // FIXME: We should bifurcate and fill the returned struct with
>> - // garbage.
>> - if (ExplodedNode* N = Builder->generateNode(ME, StNull, Pred)) {
>> - N->markAsSink();
>> - if (StNotNull)
>> - NilReceiverStructRetImplicit.insert(N);
>> - else
>> - NilReceiverStructRetExplicit.insert(N);
>> - }
>> - }
>> - }
>> - else {
>> - ASTContext& Ctx = getContext();
>> - if (RetTy != Ctx.VoidTy) {
>> - if (Pred->getParentMap().isConsumedExpr(ME)) {
>> - // sizeof(void *)
>> - const uint64_t voidPtrSize = Ctx.getTypeSize(Ctx.VoidPtrTy);
>> - // sizeof(return type)
>> - const uint64_t returnTypeSize =
>> Ctx.getTypeSize(ME->getType());
>> -
>> - if (voidPtrSize < returnTypeSize) {
>> - if (ExplodedNode* N = Builder->generateNode(ME, StNull,
>> Pred)) {
>> - N->markAsSink();
>> - if (StNotNull)
>> - NilReceiverLargerThanVoidPtrRetImplicit.insert(N);
>> - else
>> - NilReceiverLargerThanVoidPtrRetExplicit.insert(N);
>> - }
>> - }
>> - else if (!StNotNull) {
>> - // Handle the safe cases where the return value is 0 if the
>> - // receiver is nil.
>> - //
>> - // FIXME: For now take the conservative approach that we
>> only
>> - // return null values if we *know* that the receiver is nil.
>> - // This is because we can have surprises like:
>> - //
>> - // ... = [[NSScreens screens] objectAtIndex:0];
>> - //
>> - // What can happen is that [... screens] could return nil,
>> but
>> - // it most likely isn't nil. We should assume the semantics
>> - // of this case unless we have *a lot* more knowledge.
>> - //
>> - SVal V = ValMgr.makeZeroVal(ME->getType());
>> - MakeNode(Dst, ME, Pred, StNull->BindExpr(ME, V));
>> - return;
>> - }
>> - }
>> - }
>> - }
>> - // We have handled the cases where the receiver is nil. The
>> remainder
>> - // of this method should assume that the receiver is not nil.
>> - if (!StNotNull)
>> - return;
>> -
>> - state = StNotNull;
>> - }
>> -
>> + if (ME->getReceiver()) {
>> // Check if the "raise" message was sent.
>> if (ME->getSelector() == RaiseSel)
>> RaisesException = true;
>> @@ -2840,11 +2764,10 @@
>> GraphPrintCheckerState->isBadCall(N) ||
>> GraphPrintCheckerState->isUndefArg(N))
>> return "color=\"red\",style=\"filled\"";
>> -#endif
>>
>> if (GraphPrintCheckerState->isNoReturnCall(N))
>> return "color=\"blue\",style=\"filled\"";
>> -
>> +#endif
>> return "";
>> }
>>
>>
>> Modified: cfe/trunk/lib/Analysis/GRExprEngineInternalChecks.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRExprEngineInternalChecks.cpp?rev=89745&r1=89744&r2=89745&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/Analysis/GRExprEngineInternalChecks.cpp (original)
>> +++ cfe/trunk/lib/Analysis/GRExprEngineInternalChecks.cpp Tue Nov 24
>> 01:06:39 2009
>> @@ -62,72 +62,6 @@
>> GetNode(I)));
>> }
>>
>> -class VISIBILITY_HIDDEN NilReceiverStructRet : public BuiltinBug {
>> -public:
>> - NilReceiverStructRet(GRExprEngine* eng) :
>> - BuiltinBug(eng, "'nil' receiver with struct return type") {}
>> -
>> - void FlushReportsImpl(BugReporter& BR, GRExprEngine& Eng) {
>> - for (GRExprEngine::nil_receiver_struct_ret_iterator
>> - I=Eng.nil_receiver_struct_ret_begin(),
>> - E=Eng.nil_receiver_struct_ret_end(); I!=E; ++I) {
>> -
>> - std::string sbuf;
>> - llvm::raw_string_ostream os(sbuf);
>> - PostStmt P = cast<PostStmt>((*I)->getLocation());
>> - const ObjCMessageExpr *ME = cast<ObjCMessageExpr>(P.getStmt());
>> - os << "The receiver in the message expression is 'nil' and results in
>> the"
>> - " returned value (of type '"
>> - << ME->getType().getAsString()
>> - << "') to be garbage or otherwise undefined";
>> -
>> - BuiltinBugReport *R = new BuiltinBugReport(*this, os.str().c_str(),
>> *I);
>> - R->addRange(ME->getReceiver()->getSourceRange());
>> - BR.EmitReport(R);
>> - }
>> - }
>> -
>> - void registerInitialVisitors(BugReporterContext& BRC,
>> - const ExplodedNode* N,
>> - BuiltinBugReport *R) {
>> - registerTrackNullOrUndefValue(BRC, GetReceiverExpr(N), N);
>> - }
>> -};
>> -
>> -class VISIBILITY_HIDDEN NilReceiverLargerThanVoidPtrRet : public BuiltinBug
>> {
>> -public:
>> - NilReceiverLargerThanVoidPtrRet(GRExprEngine* eng) :
>> - BuiltinBug(eng,
>> - "'nil' receiver with return type larger than sizeof(void
>> *)") {}
>> -
>> - void FlushReportsImpl(BugReporter& BR, GRExprEngine& Eng) {
>> - for (GRExprEngine::nil_receiver_larger_than_voidptr_ret_iterator
>> - I=Eng.nil_receiver_larger_than_voidptr_ret_begin(),
>> - E=Eng.nil_receiver_larger_than_voidptr_ret_end(); I!=E; ++I) {
>> -
>> - std::string sbuf;
>> - llvm::raw_string_ostream os(sbuf);
>> - PostStmt P = cast<PostStmt>((*I)->getLocation());
>> - const ObjCMessageExpr *ME = cast<ObjCMessageExpr>(P.getStmt());
>> - os << "The receiver in the message expression is 'nil' and results in
>> the"
>> - " returned value (of type '"
>> - << ME->getType().getAsString()
>> - << "' and of size "
>> - << Eng.getContext().getTypeSize(ME->getType()) / 8
>> - << " bytes) to be garbage or otherwise undefined";
>> -
>> - BuiltinBugReport *R = new BuiltinBugReport(*this, os.str().c_str(),
>> *I);
>> - R->addRange(ME->getReceiver()->getSourceRange());
>> - BR.EmitReport(R);
>> - }
>> - }
>> - void registerInitialVisitors(BugReporterContext& BRC,
>> - const ExplodedNode* N,
>> - BuiltinBugReport *R) {
>> - registerTrackNullOrUndefValue(BRC, GetReceiverExpr(N), N);
>> - }
>> -};
>> -
>> class VISIBILITY_HIDDEN UndefResult : public BuiltinBug {
>> public:
>> UndefResult(GRExprEngine* eng)
>> @@ -217,8 +151,6 @@
>> // analyzing a function. Generation of BugReport objects is done via a
>> call
>> // to 'FlushReports' from BugReporter.
>> BR.Register(new UndefResult(this));
>> - BR.Register(new NilReceiverStructRet(this));
>> - BR.Register(new NilReceiverLargerThanVoidPtrRet(this));
>>
>> // The following checks do not need to have their associated BugTypes
>> // explicitly registered with the BugReporter. If they issue any
>> BugReports,
>>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> [email protected]
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
>
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits