[cfe-commits] r159563 - in /cfe/trunk: lib/StaticAnalyzer/Checkers/AttrNonNullChecker.cpp lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp test/Analysis/misc-ps-region-store.m test/Analysis/nonnull.m
Anna Zaks
ganna at apple.com
Mon Jul 16 13:28:13 PDT 2012
On Jul 2, 2012, at 12:28 PM, Jordan Rose wrote:
> Author: jrose
> Date: Mon Jul 2 14:28:21 2012
> New Revision: 159563
>
> URL: http://llvm.org/viewvc/llvm-project?rev=159563&view=rev
> Log:
> [analyzer] Convert existing checkers to use check::preCall and check::postCall.
>
> Added:
> cfe/trunk/test/Analysis/nonnull.m
> Modified:
> cfe/trunk/lib/StaticAnalyzer/Checkers/AttrNonNullChecker.cpp
> cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
> cfe/trunk/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp
> cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
> cfe/trunk/test/Analysis/misc-ps-region-store.m
>
> Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/AttrNonNullChecker.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/AttrNonNullChecker.cpp?rev=159563&r1=159562&r2=159563&view=diff
> ==============================================================================
> --- cfe/trunk/lib/StaticAnalyzer/Checkers/AttrNonNullChecker.cpp (original)
> +++ cfe/trunk/lib/StaticAnalyzer/Checkers/AttrNonNullChecker.cpp Mon Jul 2 14:28:21 2012
> @@ -15,6 +15,7 @@
> #include "ClangSACheckers.h"
> #include "clang/StaticAnalyzer/Core/Checker.h"
> #include "clang/StaticAnalyzer/Core/CheckerManager.h"
> +#include "clang/StaticAnalyzer/Core/PathSensitive/Calls.h"
> #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
> #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
>
> @@ -23,40 +24,32 @@
>
> namespace {
> class AttrNonNullChecker
> - : public Checker< check::PreStmt<CallExpr> > {
> + : public Checker< check::PreCall > {
> mutable OwningPtr<BugType> BT;
> public:
>
> - void checkPreStmt(const CallExpr *CE, CheckerContext &C) const;
> + void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
> };
> } // end anonymous namespace
>
> -void AttrNonNullChecker::checkPreStmt(const CallExpr *CE,
> +void AttrNonNullChecker::checkPreCall(const CallEvent &Call,
> CheckerContext &C) const {
> - ProgramStateRef state = C.getState();
> - const LocationContext *LCtx = C.getLocationContext();
> -
> - // Check if the callee has a 'nonnull' attribute.
> - SVal X = state->getSVal(CE->getCallee(), LCtx);
> -
> - const FunctionDecl *FD = X.getAsFunctionDecl();
> + const Decl *FD = Call.getDecl();
> if (!FD)
> return;
>
> - const NonNullAttr* Att = FD->getAttr<NonNullAttr>();
> + const NonNullAttr *Att = FD->getAttr<NonNullAttr>();
> if (!Att)
> return;
>
> - // Iterate through the arguments of CE and check them for null.
> - unsigned idx = 0;
> -
> - for (CallExpr::const_arg_iterator I=CE->arg_begin(), E=CE->arg_end(); I!=E;
> - ++I, ++idx) {
> + ProgramStateRef state = C.getState();
>
> + // Iterate through the arguments of CE and check them for null.
> + for (unsigned idx = 0, count = Call.getNumArgs(); idx != count; ++idx) {
> if (!Att->isNonNull(idx))
> continue;
>
> - SVal V = state->getSVal(*I, LCtx);
> + SVal V = Call.getArgSVal(idx);
> DefinedSVal *DV = dyn_cast<DefinedSVal>(&V);
>
> // If the value is unknown or undefined, we can't perform this check.
> @@ -65,11 +58,16 @@
>
> if (!isa<Loc>(*DV)) {
> // If the argument is a union type, we want to handle a potential
> - // transparent_unoin GCC extension.
> - QualType T = (*I)->getType();
> + // transparent_union GCC extension.
> + const Expr *ArgE = Call.getArgExpr(idx);
> + if (!ArgE)
> + continue;
> +
> + QualType T = ArgE->getType();
> const RecordType *UT = T->getAsUnionType();
> if (!UT || !UT->getDecl()->hasAttr<TransparentUnionAttr>())
> continue;
> +
> if (nonloc::CompoundVal *CSV = dyn_cast<nonloc::CompoundVal>(DV)) {
> nonloc::CompoundVal::iterator CSV_I = CSV->begin();
> assert(CSV_I != CSV->end());
> @@ -78,8 +76,7 @@
> assert(++CSV_I == CSV->end());
> if (!DV)
> continue;
> - }
> - else {
> + } else {
> // FIXME: Handle LazyCompoundVals?
> continue;
> }
> @@ -106,10 +103,10 @@
> "'nonnull' parameter", errorNode);
>
> // Highlight the range of the argument that was null.
> - const Expr *arg = *I;
> - R->addRange(arg->getSourceRange());
> - R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(errorNode,
> - arg, R));
> + R->addRange(Call.getArgSourceRange(idx));
> + if (const Expr *ArgE = Call.getArgExpr(idx))
> + R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(errorNode,
> + ArgE, R));
> // Emit the bug report.
> C.EmitReport(R);
> }
>
> Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp?rev=159563&r1=159562&r2=159563&view=diff
> ==============================================================================
> --- cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp (original)
> +++ cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp Mon Jul 2 14:28:21 2012
> @@ -27,7 +27,8 @@
>
> namespace {
> class CallAndMessageChecker
> - : public Checker< check::PreStmt<CallExpr>, check::PreObjCMessage > {
> + : public Checker< check::PreStmt<CallExpr>, check::PreObjCMessage,
> + check::PreCall > {
> mutable OwningPtr<BugType> BT_call_null;
> mutable OwningPtr<BugType> BT_call_undef;
> mutable OwningPtr<BugType> BT_call_arg;
> @@ -39,15 +40,13 @@
>
> void checkPreStmt(const CallExpr *CE, CheckerContext &C) const;
> void checkPreObjCMessage(const ObjCMethodCall &msg, CheckerContext &C) const;
> + void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
>
> private:
> - static void PreVisitProcessArgs(CheckerContext &C, const CallEvent &Call,
> - const char *BT_desc, OwningPtr<BugType> &BT);
> - static bool PreVisitProcessArg(CheckerContext &C, SVal V,SourceRange argRange,
> - const Expr *argEx,
> + static bool PreVisitProcessArg(CheckerContext &C, SVal V,
> + SourceRange argRange, const Expr *argEx,
> const bool checkUninitFields,
> - const char *BT_desc,
> - OwningPtr<BugType> &BT);
> + const char *BT_desc, OwningPtr<BugType> &BT);
>
> static void EmitBadCall(BugType *BT, CheckerContext &C, const CallExpr *CE);
> void emitNilReceiverBug(CheckerContext &C, const ObjCMethodCall &msg,
> @@ -76,26 +75,6 @@
> C.EmitReport(R);
> }
>
> -void CallAndMessageChecker::PreVisitProcessArgs(CheckerContext &C,
> - const CallEvent &Call,
> - const char *BT_desc,
> - OwningPtr<BugType> &BT) {
> - // Don't check for uninitialized field values in arguments if the
> - // caller has a body that is available and we have the chance to inline it.
> - // This is a hack, but is a reasonable compromise betweens sometimes warning
> - // and sometimes not depending on if we decide to inline a function.
> - const Decl *D = Call.getDecl();
> - const bool checkUninitFields =
> - !(C.getAnalysisManager().shouldInlineCall() &&
> - (D && D->getBody()));
> -
> - for (unsigned i = 0, e = Call.getNumArgs(); i != e; ++i)
> - if (PreVisitProcessArg(C, Call.getArgSVal(i),
> - Call.getArgSourceRange(i), Call.getArgExpr(i),
> - checkUninitFields, BT_desc, BT))
> - return;
> -}
> -
> bool CallAndMessageChecker::PreVisitProcessArg(CheckerContext &C,
> SVal V, SourceRange argRange,
> const Expr *argEx,
> @@ -104,10 +83,10 @@
> OwningPtr<BugType> &BT) {
> if (V.isUndef()) {
> if (ExplodedNode *N = C.generateSink()) {
> - LazyInit_BT(BT_desc, BT);
> + LazyInit_BT("Uninitialized argument value", BT);
>
> // Generate a report for this bug.
> - BugReport *R = new BugReport(*BT, BT->getName(), N);
> + BugReport *R = new BugReport(*BT, BT_desc, N);
> R->addRange(argRange);
> if (argEx)
> R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, argEx,
> @@ -227,24 +206,47 @@
> new BuiltinBug("Called function pointer is null (null dereference)"));
> EmitBadCall(BT_call_null.get(), C, CE);
> }
> +}
>
> - // FIXME: This tree of switching can go away if/when we add a check::postCall.
> - if (dyn_cast_or_null<BlockDataRegion>(L.getAsRegion())) {
> - BlockCall Call(CE, State, LCtx);
> - PreVisitProcessArgs(C, Call,
> - "Block call argument is an uninitialized value",
> - BT_call_arg);
> - } else if (const CXXMemberCallExpr *me = dyn_cast<CXXMemberCallExpr>(CE)) {
> - CXXMemberCall Call(me, State, LCtx);
> - PreVisitProcessArgs(C, Call,
> - "Function call argument is an uninitialized value",
> - BT_call_arg);
> - } else {
> - FunctionCall Call(CE, State, LCtx);
> - PreVisitProcessArgs(C, Call,
> - "Function call argument is an uninitialized value",
> - BT_call_arg);
> +void CallAndMessageChecker::checkPreCall(const CallEvent &Call,
> + CheckerContext &C) const {
> + // Don't check for uninitialized field values in arguments if the
> + // caller has a body that is available and we have the chance to inline it.
> + // This is a hack, but is a reasonable compromise betweens sometimes warning
> + // and sometimes not depending on if we decide to inline a function.
> + const Decl *D = Call.getDecl();
> + const bool checkUninitFields =
> + !(C.getAnalysisManager().shouldInlineCall() &&
> + (D && D->getBody()));
> +
> + OwningPtr<BugType> *BT;
> + const char *Desc;
> +
> + switch (Call.getKind()) {
> + case CE_ObjCPropertyAccess:
> + BT = &BT_msg_arg;
> + // Getters do not have arguments, so we don't need to worry about this.
> + Desc = "Argument for property setter is an uninitialized value";
> + break;
> + case CE_ObjCMessage:
> + BT = &BT_msg_arg;
> + Desc = "Argument in message expression is an uninitialized value";
> + break;
> + case CE_Block:
> + BT = &BT_call_arg;
> + Desc = "Block call argument is an uninitialized value";
> + break;
> + default:
> + BT = &BT_call_arg;
> + Desc = "Function call argument is an uninitialized value";
> + break;
> }
Can we only switch/perform bug description assignment if we know there is an error?
> +
> + for (unsigned i = 0, e = Call.getNumArgs(); i != e; ++i)
> + if (PreVisitProcessArg(C, Call.getArgSVal(i),
> + Call.getArgSourceRange(i), Call.getArgExpr(i),
> + checkUninitFields, Desc, *BT))
> + return;
> }
>
> void CallAndMessageChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
> @@ -289,15 +291,6 @@
> return;
> }
> }
> -
> - const char *bugDesc = "Argument in message expression is an "
> - "uninitialized value";
> - if (const ObjCPropertyAccess *Prop = dyn_cast<ObjCPropertyAccess>(&msg))
> - if (Prop->isSetter())
> - bugDesc = "Argument for property setter is an uninitialized value";
> -
> - // Check for any arguments that are uninitialized/undefined.
> - PreVisitProcessArgs(C, msg, bugDesc, BT_msg_arg);
> }
>
> void CallAndMessageChecker::emitNilReceiverBug(CheckerContext &C,
>
> Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp?rev=159563&r1=159562&r2=159563&view=diff
> ==============================================================================
> --- cfe/trunk/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp (original)
> +++ cfe/trunk/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp Mon Jul 2 14:28:21 2012
> @@ -54,27 +54,23 @@
> static bool isSelfVar(SVal location, CheckerContext &C);
>
> namespace {
> -class ObjCSelfInitChecker : public Checker< check::PreObjCMessage,
> - check::PostObjCMessage,
> +class ObjCSelfInitChecker : public Checker< check::PostObjCMessage,
> check::PostStmt<ObjCIvarRefExpr>,
> check::PreStmt<ReturnStmt>,
> - check::PreStmt<CallExpr>,
> - check::PostStmt<CallExpr>,
> + check::PreCall,
> + check::PostCall,
> check::Location,
> check::Bind > {
> public:
> - void checkPreObjCMessage(const ObjCMethodCall &Msg, CheckerContext &C) const;
> void checkPostObjCMessage(const ObjCMethodCall &Msg, CheckerContext &C) const;
> void checkPostStmt(const ObjCIvarRefExpr *E, CheckerContext &C) const;
> void checkPreStmt(const ReturnStmt *S, CheckerContext &C) const;
> - void checkPreStmt(const CallExpr *CE, CheckerContext &C) const;
> - void checkPostStmt(const CallExpr *CE, CheckerContext &C) const;
> void checkLocation(SVal location, bool isLoad, const Stmt *S,
> CheckerContext &C) const;
> void checkBind(SVal loc, SVal val, const Stmt *S, CheckerContext &C) const;
>
> - void checkPreStmt(const CallEvent &CE, CheckerContext &C) const;
> - void checkPostStmt(const CallEvent &CE, CheckerContext &C) const;
> + void checkPreCall(const CallEvent &CE, CheckerContext &C) const;
> + void checkPostCall(const CallEvent &CE, CheckerContext &C) const;
>
> };
> } // end anonymous namespace
> @@ -208,8 +204,6 @@
> return;
> }
>
> - checkPostStmt(Msg, C);
> -
> // We don't check for an invalid 'self' in an obj-c message expression to cut
> // down false positives where logging functions get information from self
> // (like its class) or doing "invalidation" on self when the initialization
> @@ -240,8 +234,8 @@
> "'[(super or self) init...]'");
> }
>
> -// When a call receives a reference to 'self', [Pre/Post]VisitGenericCall pass
> -// the SelfFlags from the object 'self' point to before the call, to the new
> +// When a call receives a reference to 'self', [Pre/Post]Call pass
> +// the SelfFlags from the object 'self' points to before the call to the new
> // object after the call. This is to avoid invalidation of 'self' by logging
> // functions.
> // Another common pattern in classes with multiple initializers is to put the
> @@ -256,53 +250,13 @@
> // Until we can use inter-procedural analysis, in such a call, transfer the
> // SelfFlags to the result of the call.
>
> -void ObjCSelfInitChecker::checkPreStmt(const CallExpr *CE,
> +void ObjCSelfInitChecker::checkPreCall(const CallEvent &CE,
> CheckerContext &C) const {
> - // FIXME: This tree of switching can go away if/when we add a check::postCall.
> - const Expr *Callee = CE->getCallee()->IgnoreParens();
> - ProgramStateRef State = C.getState();
> - const LocationContext *LCtx = C.getLocationContext();
> - SVal L = State->getSVal(Callee, LCtx);
> -
> - if (dyn_cast_or_null<BlockDataRegion>(L.getAsRegion())) {
> - BlockCall Call(CE, State, LCtx);
> - checkPreStmt(Call, C);
> - } else if (const CXXMemberCallExpr *me = dyn_cast<CXXMemberCallExpr>(CE)) {
> - CXXMemberCall Call(me, State, LCtx);
> - checkPreStmt(Call, C);
> - } else {
> - FunctionCall Call(CE, State, LCtx);
> - checkPreStmt(Call, C);
> - }
> -}
> -
> -void ObjCSelfInitChecker::checkPostStmt(const CallExpr *CE,
> - CheckerContext &C) const {
> - // FIXME: This tree of switching can go away if/when we add a check::postCall.
> - const Expr *Callee = CE->getCallee()->IgnoreParens();
> - ProgramStateRef State = C.getState();
> - const LocationContext *LCtx = C.getLocationContext();
> - SVal L = State->getSVal(Callee, LCtx);
> -
> - if (dyn_cast_or_null<BlockDataRegion>(L.getAsRegion())) {
> - BlockCall Call(CE, State, LCtx);
> - checkPostStmt(Call, C);
> - } else if (const CXXMemberCallExpr *me = dyn_cast<CXXMemberCallExpr>(CE)) {
> - CXXMemberCall Call(me, State, LCtx);
> - checkPostStmt(Call, C);
> - } else {
> - FunctionCall Call(CE, State, LCtx);
> - checkPostStmt(Call, C);
> - }
> -}
> -
> -void ObjCSelfInitChecker::checkPreObjCMessage(const ObjCMethodCall &Msg,
> - CheckerContext &C) const {
> - checkPreStmt(Msg, C);
> -}
> + // FIXME: A callback should disable checkers at the start of functions.
> + if (!shouldRunOnFunctionOrMethod(dyn_cast<NamedDecl>(
> + C.getCurrentAnalysisDeclContext()->getDecl())))
> + return;
>
> -void ObjCSelfInitChecker::checkPreStmt(const CallEvent &CE,
> - CheckerContext &C) const {
> ProgramStateRef state = C.getState();
> unsigned NumArgs = CE.getNumArgs();
> // If we passed 'self' as and argument to the call, record it in the state
> @@ -324,9 +278,19 @@
> }
> }
>
> -void ObjCSelfInitChecker::checkPostStmt(const CallEvent &CE,
> +void ObjCSelfInitChecker::checkPostCall(const CallEvent &CE,
> CheckerContext &C) const {
> + // FIXME: A callback should disable checkers at the start of functions.
> + if (!shouldRunOnFunctionOrMethod(dyn_cast<NamedDecl>(
> + C.getCurrentAnalysisDeclContext()->getDecl())))
> + return;
> +
> ProgramStateRef state = C.getState();
> + SelfFlagEnum prevFlags = (SelfFlagEnum)state->get<PreCallSelfFlags>();
> + if (!prevFlags)
> + return;
> + state = state->remove<PreCallSelfFlags>();
> +
> unsigned NumArgs = CE.getNumArgs();
> for (unsigned i = 0; i < NumArgs; ++i) {
> SVal argV = CE.getArgSVal(i);
> @@ -334,8 +298,6 @@
> // If the address of 'self' is being passed to the call, assume that the
> // 'self' after the call will have the same flags.
> // EX: log(&self)
> - SelfFlagEnum prevFlags = (SelfFlagEnum)state->get<PreCallSelfFlags>();
> - state = state->remove<PreCallSelfFlags>();
> addSelfFlag(state, state->getSVal(cast<Loc>(argV)), prevFlags, C);
> return;
> } else if (hasSelfFlag(argV, SelfFlag_Self, C)) {
> @@ -343,8 +305,6 @@
> // returns 'self'. So assign the flags, which were set on 'self' to the
> // return value.
> // EX: self = performMoreInitialization(self)
> - SelfFlagEnum prevFlags = (SelfFlagEnum)state->get<PreCallSelfFlags>();
> - state = state->remove<PreCallSelfFlags>();
> const Expr *CallExpr = CE.getOriginExpr();
> if (CallExpr)
> addSelfFlag(state, state->getSVal(CallExpr, C.getLocationContext()),
>
> Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp?rev=159563&r1=159562&r2=159563&view=diff
> ==============================================================================
> --- cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp (original)
> +++ cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp Mon Jul 2 14:28:21 2012
> @@ -2379,12 +2379,10 @@
> check::EndPath,
> check::PostStmt<BlockExpr>,
> check::PostStmt<CastExpr>,
> - check::PostStmt<CallExpr>,
> - check::PostStmt<CXXConstructExpr>,
> check::PostStmt<ObjCArrayLiteral>,
> check::PostStmt<ObjCDictionaryLiteral>,
> check::PostStmt<ObjCBoxedExpr>,
> - check::PostObjCMessage,
> + check::PostCall,
> check::PreStmt<ReturnStmt>,
> check::RegionChanges,
> eval::Assume,
> @@ -2523,13 +2521,11 @@
> void checkPostStmt(const BlockExpr *BE, CheckerContext &C) const;
> void checkPostStmt(const CastExpr *CE, CheckerContext &C) const;
>
> - void checkPostStmt(const CallExpr *CE, CheckerContext &C) const;
> - void checkPostStmt(const CXXConstructExpr *CE, CheckerContext &C) const;
> void checkPostStmt(const ObjCArrayLiteral *AL, CheckerContext &C) const;
> void checkPostStmt(const ObjCDictionaryLiteral *DL, CheckerContext &C) const;
> void checkPostStmt(const ObjCBoxedExpr *BE, CheckerContext &C) const;
>
> - void checkPostObjCMessage(const ObjCMethodCall &Msg, CheckerContext &C) const;
> + void checkPostCall(const CallEvent &Call, CheckerContext &C) const;
>
> void checkSummary(const RetainSummary &Summ, const CallEvent &Call,
> CheckerContext &C) const;
> @@ -2685,54 +2681,6 @@
> C.addTransition(state);
> }
>
> -void RetainCountChecker::checkPostStmt(const CallExpr *CE,
> - CheckerContext &C) const {
> - if (C.wasInlined)
> - return;
> -
> - // Get the callee.
> - ProgramStateRef state = C.getState();
> - const Expr *Callee = CE->getCallee();
> - SVal L = state->getSVal(Callee, C.getLocationContext());
> -
> - RetainSummaryManager &Summaries = getSummaryManager(C);
> -
> - // FIXME: This tree of switching can go away if/when we add a check::postCall.
> - if (dyn_cast_or_null<BlockDataRegion>(L.getAsRegion())) {
> - // FIXME: Better support for blocks. For now we stop tracking anything
> - // that is passed to blocks.
> - // FIXME: Need to handle variables that are "captured" by the block.
> - BlockCall Call(CE, state, C.getLocationContext());
> - const RetainSummary *Summ = Summaries.getSummary(Call, state);
> - checkSummary(*Summ, Call, C);
> -
> - } else if (const CXXMemberCallExpr *me = dyn_cast<CXXMemberCallExpr>(CE)) {
> - CXXMemberCall Call(me, state, C.getLocationContext());
> - const RetainSummary *Summ = Summaries.getSummary(Call, state);
> - checkSummary(*Summ, Call, C);
> -
> - } else {
> - FunctionCall Call(CE, state, C.getLocationContext());
> - const RetainSummary *Summ = Summaries.getSummary(Call, state);
> - checkSummary(*Summ, Call, C);
> - }
> -}
> -
> -void RetainCountChecker::checkPostStmt(const CXXConstructExpr *CE,
> - CheckerContext &C) const {
> - const CXXConstructorDecl *Ctor = CE->getConstructor();
> - if (!Ctor)
> - return;
> -
> - RetainSummaryManager &Summaries = getSummaryManager(C);
> - ProgramStateRef state = C.getState();
> - CXXConstructorCall Call(CE, state, C.getLocationContext());
> -
> - const RetainSummary *Summ = Summaries.getSummary(Call, state);
> -
> - checkSummary(*Summ, Call, C);
> -}
> -
> void RetainCountChecker::processObjCLiterals(CheckerContext &C,
> const Expr *Ex) const {
> ProgramStateRef state = C.getState();
> @@ -2791,12 +2739,14 @@
> C.addTransition(State);
> }
>
> -void RetainCountChecker::checkPostObjCMessage(const ObjCMethodCall &Msg,
> - CheckerContext &C) const {
> - RetainSummaryManager &Summaries = getSummaryManager(C);
> - const RetainSummary *Summ = Summaries.getSummary(Msg, C.getState());
> +void RetainCountChecker::checkPostCall(const CallEvent &Call,
> + CheckerContext &C) const {
> + if (C.wasInlined)
> + return;
>
> - checkSummary(*Summ, Msg, C);
> + RetainSummaryManager &Summaries = getSummaryManager(C);
> + const RetainSummary *Summ = Summaries.getSummary(Call, C.getState());
> + checkSummary(*Summ, Call, C);
> }
>
> /// GetReturnType - Used to get the return type of a message expression or
>
> Modified: cfe/trunk/test/Analysis/misc-ps-region-store.m
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/misc-ps-region-store.m?rev=159563&r1=159562&r2=159563&view=diff
> ==============================================================================
> --- cfe/trunk/test/Analysis/misc-ps-region-store.m (original)
> +++ cfe/trunk/test/Analysis/misc-ps-region-store.m Mon Jul 2 14:28:21 2012
> @@ -673,7 +673,7 @@
> builder = ^(id object) {
> id x;
> if (object) {
> - builder(x); // expected-warning{{Function call argument is an uninitialized value}}
> + builder(x); // expected-warning{{Block call argument is an uninitialized value}}
> }
> };
> builder(target);
>
> Added: cfe/trunk/test/Analysis/nonnull.m
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/nonnull.m?rev=159563&view=auto
> ==============================================================================
> --- cfe/trunk/test/Analysis/nonnull.m (added)
> +++ cfe/trunk/test/Analysis/nonnull.m Mon Jul 2 14:28:21 2012
> @@ -0,0 +1,23 @@
> +// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify %s
> +
> + at interface MyObject
> +- (void)takePointer:(void *)ptr __attribute__((nonnull(1)));
> + at end
> +
> +void testNonNullMethod(int *p, MyObject *obj) {
> + if (p)
> + return;
> + [obj takePointer:p]; // expected-warning{{nonnull}}
> +}
> +
> +
> + at interface Subclass : MyObject
> +// [[nonnull]] is an inherited attribute.
> +- (void)takePointer:(void *)ptr;
> + at end
> +
> +void testSubclass(int *p, Subclass *obj) {
> + if (p)
> + return;
> + [obj takePointer:p]; // expected-warning{{nonnull}}
> +}
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list