[llvm-branch-commits] [cfe-branch] r71864 - /cfe/branches/Apple/Dib/lib/Analysis/GRExprEngineInternalChecks.cpp
Mike Stump
mrs at apple.com
Fri May 15 09:18:07 PDT 2009
Author: mrs
Date: Fri May 15 11:18:01 2009
New Revision: 71864
URL: http://llvm.org/viewvc/llvm-project?rev=71864&view=rev
Log:
Merge in 71838:
Cleanup internal checks bug reporting, allowing intermediate diagnostics to be generated for bad argument warnings, bad branches, etc.
Modified:
cfe/branches/Apple/Dib/lib/Analysis/GRExprEngineInternalChecks.cpp
Modified: cfe/branches/Apple/Dib/lib/Analysis/GRExprEngineInternalChecks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/Dib/lib/Analysis/GRExprEngineInternalChecks.cpp?rev=71864&r1=71863&r2=71864&view=diff
==============================================================================
--- cfe/branches/Apple/Dib/lib/Analysis/GRExprEngineInternalChecks.cpp (original)
+++ cfe/branches/Apple/Dib/lib/Analysis/GRExprEngineInternalChecks.cpp Fri May 15 11:18:01 2009
@@ -39,8 +39,15 @@
// Forward declarations for bug reporter visitors.
//===----------------------------------------------------------------------===//
+static const Stmt *GetDerefExpr(const ExplodedNode<GRState> *N);
+static const Stmt *GetReceiverExpr(const ExplodedNode<GRState> *N);
+static const Stmt *GetDenomExpr(const ExplodedNode<GRState> *N);
+static const Stmt *GetCalleeExpr(const ExplodedNode<GRState> *N);
+static const Stmt *GetRetValExpr(const ExplodedNode<GRState> *N);
+
static void registerTrackNullOrUndefValue(BugReporterContext& BRC,
- const ExplodedNode<GRState>* N);
+ const Stmt *ValExpr,
+ const ExplodedNode<GRState>* N);
//===----------------------------------------------------------------------===//
// Bug Descriptions.
@@ -54,6 +61,10 @@
ExplodedNode<GRState> *n)
: RangedBugReport(bt, desc, n) {}
+ BuiltinBugReport(BugType& bt, const char *shortDesc, const char *desc,
+ ExplodedNode<GRState> *n)
+ : RangedBugReport(bt, shortDesc, desc, n) {}
+
void registerInitialVisitors(BugReporterContext& BRC,
const ExplodedNode<GRState>* N);
};
@@ -104,7 +115,7 @@
void registerInitialVisitors(BugReporterContext& BRC,
const ExplodedNode<GRState>* N,
BuiltinBugReport *R) {
- registerTrackNullOrUndefValue(BRC, N);
+ registerTrackNullOrUndefValue(BRC, GetDerefExpr(N), N);
}
};
@@ -136,7 +147,7 @@
void registerInitialVisitors(BugReporterContext& BRC,
const ExplodedNode<GRState>* N,
BuiltinBugReport *R) {
- registerTrackNullOrUndefValue(BRC, N);
+ registerTrackNullOrUndefValue(BRC, GetReceiverExpr(N), N);
}
};
@@ -170,7 +181,7 @@
void registerInitialVisitors(BugReporterContext& BRC,
const ExplodedNode<GRState>* N,
BuiltinBugReport *R) {
- registerTrackNullOrUndefValue(BRC, N);
+ registerTrackNullOrUndefValue(BRC, GetReceiverExpr(N), N);
}
};
@@ -186,7 +197,7 @@
void registerInitialVisitors(BugReporterContext& BRC,
const ExplodedNode<GRState>* N,
BuiltinBugReport *R) {
- registerTrackNullOrUndefValue(BRC, N);
+ registerTrackNullOrUndefValue(BRC, GetDerefExpr(N), N);
}
};
@@ -199,6 +210,12 @@
void FlushReportsImpl(BugReporter& BR, GRExprEngine& Eng) {
Emit(BR, Eng.explicit_bad_divides_begin(), Eng.explicit_bad_divides_end());
}
+
+ void registerInitialVisitors(BugReporterContext& BRC,
+ const ExplodedNode<GRState>* N,
+ BuiltinBugReport *R) {
+ registerTrackNullOrUndefValue(BRC, GetDenomExpr(N), N);
+ }
};
class VISIBILITY_HIDDEN UndefResult : public BuiltinBug {
@@ -220,10 +237,31 @@
void FlushReportsImpl(BugReporter& BR, GRExprEngine& Eng) {
Emit(BR, Eng.bad_calls_begin(), Eng.bad_calls_end());
}
+
+ void registerInitialVisitors(BugReporterContext& BRC,
+ const ExplodedNode<GRState>* N,
+ BuiltinBugReport *R) {
+ registerTrackNullOrUndefValue(BRC, GetCalleeExpr(N), N);
+ }
};
-class VISIBILITY_HIDDEN BadArg : public BuiltinBug {
+
+class VISIBILITY_HIDDEN ArgReport : public BuiltinBugReport {
+ const Stmt *Arg;
public:
+ ArgReport(BugType& bt, const char* desc, ExplodedNode<GRState> *n,
+ const Stmt *arg)
+ : BuiltinBugReport(bt, desc, n), Arg(arg) {}
+
+ ArgReport(BugType& bt, const char *shortDesc, const char *desc,
+ ExplodedNode<GRState> *n, const Stmt *arg)
+ : BuiltinBugReport(bt, shortDesc, desc, n), Arg(arg) {}
+
+ const Stmt *getArg() const { return Arg; }
+};
+
+class VISIBILITY_HIDDEN BadArg : public BuiltinBug {
+public:
BadArg(GRExprEngine* eng) : BuiltinBug(eng,"Uninitialized argument",
"Pass-by-value argument in function call is undefined.") {}
@@ -234,12 +272,19 @@
for (GRExprEngine::UndefArgsTy::iterator I = Eng.undef_arg_begin(),
E = Eng.undef_arg_end(); I!=E; ++I) {
// Generate a report for this bug.
- RangedBugReport *report = new RangedBugReport(*this, desc.c_str(),
- I->first);
+ ArgReport *report = new ArgReport(*this, desc.c_str(), I->first,
+ I->second);
report->addRange(I->second->getSourceRange());
BR.EmitReport(report);
}
}
+
+ void registerInitialVisitors(BugReporterContext& BRC,
+ const ExplodedNode<GRState>* N,
+ BuiltinBugReport *R) {
+ registerTrackNullOrUndefValue(BRC, static_cast<ArgReport*>(R)->getArg(),
+ N);
+ }
};
class VISIBILITY_HIDDEN BadMsgExprArg : public BadArg {
@@ -251,12 +296,12 @@
for (GRExprEngine::UndefArgsTy::iterator I=Eng.msg_expr_undef_arg_begin(),
E = Eng.msg_expr_undef_arg_end(); I!=E; ++I) {
// Generate a report for this bug.
- BuiltinBugReport *report = new BuiltinBugReport(*this, desc.c_str(),
- I->first);
+ ArgReport *report = new ArgReport(*this, desc.c_str(), I->first,
+ I->second);
report->addRange(I->second->getSourceRange());
BR.EmitReport(report);
}
- }
+ }
};
class VISIBILITY_HIDDEN BadReceiver : public BuiltinBug {
@@ -279,12 +324,12 @@
BR.EmitReport(report);
}
}
-
+
void registerInitialVisitors(BugReporterContext& BRC,
const ExplodedNode<GRState>* N,
BuiltinBugReport *R) {
- registerTrackNullOrUndefValue(BRC, N);
- }
+ registerTrackNullOrUndefValue(BRC, GetReceiverExpr(N), N);
+ }
};
class VISIBILITY_HIDDEN RetStack : public BuiltinBug {
@@ -358,8 +403,8 @@
void registerInitialVisitors(BugReporterContext& BRC,
const ExplodedNode<GRState>* N,
BuiltinBugReport *R) {
- registerTrackNullOrUndefValue(BRC, N);
- }
+ registerTrackNullOrUndefValue(BRC, GetRetValExpr(N), N);
+ }
};
class VISIBILITY_HIDDEN UndefBranch : public BuiltinBug {
@@ -423,11 +468,18 @@
FindUndefExpr FindIt(Eng.getStateManager(), St);
Ex = FindIt.FindExpr(Ex);
- RangedBugReport *R = new RangedBugReport(*this, desc.c_str(), *I);
+ ArgReport *R = new ArgReport(*this, desc.c_str(), *I, Ex);
R->addRange(Ex->getSourceRange());
BR.EmitReport(R);
}
}
+
+ void registerInitialVisitors(BugReporterContext& BRC,
+ const ExplodedNode<GRState>* N,
+ BuiltinBugReport *R) {
+ registerTrackNullOrUndefValue(BRC, static_cast<ArgReport*>(R)->getArg(),
+ N);
+ }
};
class VISIBILITY_HIDDEN OutOfBoundMemoryAccess : public BuiltinBug {
@@ -481,13 +533,20 @@
<< (isUndefined ? "garbage value for array size"
: "has zero elements (undefined behavior)");
- RangedBugReport *report = new RangedBugReport(*this,
- os_short.str().c_str(),
- os.str().c_str(), N);
+ ArgReport *report = new ArgReport(*this, os_short.str().c_str(),
+ os.str().c_str(), N, SizeExpr);
+
report->addRange(SizeExpr->getSourceRange());
BR.EmitReport(report);
}
}
+
+ void registerInitialVisitors(BugReporterContext& BRC,
+ const ExplodedNode<GRState>* N,
+ BuiltinBugReport *R) {
+ registerTrackNullOrUndefValue(BRC, static_cast<ArgReport*>(R)->getArg(),
+ N);
+ }
};
//===----------------------------------------------------------------------===//
@@ -549,6 +608,47 @@
// Definitions for bug reporter visitors.
//===----------------------------------------------------------------------===//
+static const Stmt *GetDerefExpr(const ExplodedNode<GRState> *N) {
+ // Pattern match for a few useful cases (do something smarter later):
+ // a[0], p->f, *p
+ const Stmt *S = N->getLocationAs<PostStmt>()->getStmt();
+
+ if (const UnaryOperator *U = dyn_cast<UnaryOperator>(S)) {
+ if (U->getOpcode() == UnaryOperator::Deref)
+ return U->getSubExpr()->IgnoreParenCasts();
+ }
+ else if (const MemberExpr *ME = dyn_cast<MemberExpr>(S)) {
+ return ME->getBase()->IgnoreParenCasts();
+ }
+ else if (const ArraySubscriptExpr *AE = dyn_cast<ArraySubscriptExpr>(S)) {
+ // Retrieve the base for arrays since BasicStoreManager doesn't know how
+ // to reason about them.
+ return AE->getBase();
+ }
+
+ return NULL;
+}
+
+static const Stmt *GetReceiverExpr(const ExplodedNode<GRState> *N) {
+ const Stmt *S = N->getLocationAs<PostStmt>()->getStmt();
+ return cast<ObjCMessageExpr>(S)->getReceiver();
+}
+
+static const Stmt *GetDenomExpr(const ExplodedNode<GRState> *N) {
+ const Stmt *S = N->getLocationAs<PostStmt>()->getStmt();
+ return cast<BinaryOperator>(S)->getRHS();
+}
+
+static const Stmt *GetCalleeExpr(const ExplodedNode<GRState> *N) {
+ const Stmt *S = N->getLocationAs<PostStmt>()->getStmt();
+ return cast<CallExpr>(S)->getCallee();
+}
+
+static const Stmt *GetRetValExpr(const ExplodedNode<GRState> *N) {
+ const Stmt *S = N->getLocationAs<PostStmt>()->getStmt();
+ return cast<ReturnStmt>(S)->getRetValue();
+}
+
namespace {
class VISIBILITY_HIDDEN FindLastStoreBRVisitor : public BugReporterVisitor {
const MemRegion *R;
@@ -624,6 +724,9 @@
if (!b)
os << "initialized to a null pointer value";
}
+ else if (isa<nonloc::ConcreteInt>(V)) {
+ os << "initialized to " << cast<nonloc::ConcreteInt>(V).getValue();
+ }
else if (V.isUndef()) {
if (isa<VarRegion>(R)) {
const VarDecl *VD = cast<VarDecl>(DS->getSingleDecl());
@@ -635,7 +738,7 @@
}
}
}
-
+
if (os.str().empty()) {
if (isa<loc::ConcreteInt>(V)) {
bool b = false;
@@ -734,7 +837,7 @@
if (isa<Loc>(Constraint)) {
os << "Assuming pointer value is ";
- os << (Assumption ? "non-NULL" : "NULL");
+ os << (Assumption ? "non-null" : "null");
}
if (os.str().empty())
@@ -771,65 +874,29 @@
}
static void registerTrackNullOrUndefValue(BugReporterContext& BRC,
- const ExplodedNode<GRState>* N) {
+ const Stmt *S,
+ const ExplodedNode<GRState>* N) {
- ProgramPoint P = N->getLocation();
- PostStmt *PS = dyn_cast<PostStmt>(&P);
-
- if (!PS)
+ if (!S)
return;
-
- Stmt *S = PS->getStmt();
+
GRStateManager &StateMgr = BRC.getStateManager();
- const GRState *state = N->getState();
+ const GRState *state = N->getState();
- // Pattern match for a few useful cases (do something smarter later):
- // a[0], p->f, *p
- const DeclRefExpr *DR = 0;
-
- if (const UnaryOperator *U = dyn_cast<UnaryOperator>(S)) {
- if (U->getOpcode() == UnaryOperator::Deref)
- DR = dyn_cast<DeclRefExpr>(U->getSubExpr()->IgnoreParenCasts());
- }
- else if (const MemberExpr *ME = dyn_cast<MemberExpr>(S)) {
- DR = dyn_cast<DeclRefExpr>(ME->getBase()->IgnoreParenCasts());
- }
- else if (const ObjCMessageExpr *MSE = dyn_cast<ObjCMessageExpr>(S)) {
- // FIXME: We should probably distinguish between cases where we had
- // a nil receiver and null dereferences.
- const Expr *Receiver = MSE->getReceiver();
- if (Receiver) {
- DR = dyn_cast<DeclRefExpr>(Receiver->IgnoreParenCasts());
- }
- }
- else if (const ReturnStmt *RS = dyn_cast<ReturnStmt>(S)) {
- if (const Expr *Ret = RS->getRetValue())
- DR = dyn_cast<DeclRefExpr>(Ret->IgnoreParenCasts());
- }
- else if (const Expr *Ex = dyn_cast<Expr>(S)) {
- // Keep this case last.
- DR = dyn_cast<DeclRefExpr>(Ex->IgnoreParenCasts());
- }
-
- if (DR) {
+ if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(S)) {
if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
const VarRegion *R =
StateMgr.getRegionManager().getVarRegion(VD);
// What did we load?
- SVal V = StateMgr.GetSVal(state, R);
+ SVal V = StateMgr.GetSVal(state, S);
- if (isa<loc::ConcreteInt>(V) || V.isUndef()) {
+ if (isa<loc::ConcreteInt>(V) || isa<nonloc::ConcreteInt>(V)
+ || V.isUndef()) {
registerFindLastStore(BRC, R, V);
}
}
}
-
- // Retrieve the base for arrays since BasicStoreManager doesn't know how
- // to reason about them.
- if (ArraySubscriptExpr *AE = dyn_cast<ArraySubscriptExpr>(S)) {
- S = AE->getBase();
- }
SVal V = StateMgr.GetSValAsScalarOrLoc(state, S);
@@ -849,10 +916,6 @@
registerTrackConstraint(BRC, loc::MemRegionVal(R), false);
}
}
-
- // Was it a hard integer?
-// if (isa<nonloc::ConcreteInt>(V))
-// registerTrackValue(BRC, S, V, N);
}
//===----------------------------------------------------------------------===//
More information about the llvm-branch-commits
mailing list