r178685 - [analyzer] make peelOffOuterExpr in BugReporterVisitors recursively peel off select Exprs
Anna Zaks
ganna at apple.com
Wed Apr 3 12:28:16 PDT 2013
Author: zaks
Date: Wed Apr 3 14:28:15 2013
New Revision: 178685
URL: http://llvm.org/viewvc/llvm-project?rev=178685&view=rev
Log:
[analyzer] make peelOffOuterExpr in BugReporterVisitors recursively peel off select Exprs
Modified:
cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
cfe/trunk/test/Analysis/inlining/false-positive-suppression.c
Modified: cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp?rev=178685&r1=178684&r2=178685&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp Wed Apr 3 14:28:15 2013
@@ -789,36 +789,33 @@ static const MemRegion *getLocationRegio
return 0;
}
-static const Expr *peelOffOuterExpr(const Stmt *S,
+static const Expr *peelOffOuterExpr(const Expr *Ex,
const ExplodedNode *N) {
- if (const Expr *Ex = dyn_cast<Expr>(S)) {
- Ex = Ex->IgnoreParenCasts();
- if (const ExprWithCleanups *EWC = dyn_cast<ExprWithCleanups>(Ex))
- return EWC->getSubExpr();
- if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(Ex))
- return OVE->getSourceExpr();
-
- // Peel off the ternary operator.
- if (const ConditionalOperator *CO = dyn_cast<ConditionalOperator>(Ex)) {
- const Expr *CondEx = CO->getCond();
-
- // Find a node where the value of the condition is known.
- do {
- ProgramStateRef State = N->getState();
- SVal CondVal = State->getSVal(CondEx, N->getLocationContext());
- ConditionTruthVal CondEvaluated = State->isNull(CondVal);
- if (CondEvaluated.isConstrained()) {
- if (CondEvaluated.isConstrainedTrue())
- return CO->getFalseExpr();
- else
- return CO->getTrueExpr();
- }
- N = N->getFirstPred();
- } while (N);
-
- }
+ Ex = Ex->IgnoreParenCasts();
+ if (const ExprWithCleanups *EWC = dyn_cast<ExprWithCleanups>(Ex))
+ return peelOffOuterExpr(EWC->getSubExpr(), N);
+ if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(Ex))
+ return peelOffOuterExpr(OVE->getSourceExpr(), N);
+
+ // Peel off the ternary operator.
+ if (const ConditionalOperator *CO = dyn_cast<ConditionalOperator>(Ex)) {
+ const Expr *CondEx = CO->getCond();
+
+ // Find a node where the value of the condition is known.
+ do {
+ ProgramStateRef State = N->getState();
+ SVal CondVal = State->getSVal(CondEx, N->getLocationContext());
+ ConditionTruthVal CondEvaluated = State->isNull(CondVal);
+ if (CondEvaluated.isConstrained()) {
+ if (CondEvaluated.isConstrainedTrue())
+ return peelOffOuterExpr(CO->getFalseExpr(), N);
+ else
+ return peelOffOuterExpr(CO->getTrueExpr(), N);
+ }
+ N = N->getFirstPred();
+ } while (N);
}
- return 0;
+ return Ex;
}
bool bugreporter::trackNullOrUndefValue(const ExplodedNode *N,
@@ -828,8 +825,12 @@ bool bugreporter::trackNullOrUndefValue(
if (!S || !N)
return false;
- if (const Expr *Ex = peelOffOuterExpr(S, N))
- S = Ex;
+ if (const Expr *Ex = dyn_cast<Expr>(S)) {
+ Ex = Ex->IgnoreParenCasts();
+ const Expr *PeeledEx = peelOffOuterExpr(Ex, N);
+ if (Ex != PeeledEx)
+ S = PeeledEx;
+ }
const Expr *Inner = 0;
if (const Expr *Ex = dyn_cast<Expr>(S)) {
Modified: cfe/trunk/test/Analysis/inlining/false-positive-suppression.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/inlining/false-positive-suppression.c?rev=178685&r1=178684&r2=178685&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/inlining/false-positive-suppression.c (original)
+++ cfe/trunk/test/Analysis/inlining/false-positive-suppression.c Wed Apr 3 14:28:15 2013
@@ -240,4 +240,29 @@ int ternaryRetNull(char cond) {
#endif
}
+// Test suppression of nested conditional operators.
+int testConditionalOperatorSuppress(int x) {
+ return *(x ? getNull() : getPtr());
+#ifndef SUPPRESSED
+ // expected-warning at -2 {{Dereference of null pointer}}
+#endif
+}
+int testNestedConditionalOperatorSuppress(int x) {
+ return *(x ? (x ? getNull() : getPtr()) : getPtr());
+#ifndef SUPPRESSED
+ // expected-warning at -2 {{Dereference of null pointer}}
+#endif
+}
+int testConditionalOperator(int x) {
+ return *(x ? 0 : getPtr()); // expected-warning {{Dereference of null pointer}}
+}
+int testNestedConditionalOperator(int x) {
+ return *(x ? (x ? 0 : getPtr()) : getPtr()); // expected-warning {{Dereference of null pointer}}
+}
+
+// False Positve - we are unable to suppress this case because the condition is
+// float.
+int testConditionalOperatorSuppressFloatCond(float x) {
+ return *(x ? getNull() : getPtr()); // expected-warning {{Dereference of null pointer}}
+}
More information about the cfe-commits
mailing list