From 9ed6d8068f767819951bc4eebf6f4912087c442a Mon Sep 17 00:00:00 2001 From: Anna Zaks Date: Thu, 25 Apr 2013 21:52:35 +0000 Subject: [PATCH] [analyzer] Teach DeadStoreChecker to look though BO_Comma and disregard the LHS. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@180579 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Checkers/DeadStoresChecker.cpp | 14 ++++++++---- test/Analysis/dead-stores.c | 22 +++++++++++++++++++ 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp b/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp index f2e3e6d781..f336a6e680 100644 --- a/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp @@ -101,7 +101,8 @@ void ReachableCode::computeReachableBlocks() { } } -static const Expr *LookThroughTransitiveAssignments(const Expr *Ex) { +static const Expr * +LookThroughTransitiveAssignmentsAndCommaOperators(const Expr *Ex) { while (Ex) { const BinaryOperator *BO = dyn_cast(Ex->IgnoreParenCasts()); @@ -111,6 +112,10 @@ static const Expr *LookThroughTransitiveAssignments(const Expr *Ex) { Ex = BO->getRHS(); continue; } + if (BO->getOpcode() == BO_Comma) { + Ex = BO->getRHS(); + continue; + } break; } return Ex; @@ -266,7 +271,9 @@ public: if (VarDecl *VD = dyn_cast(DR->getDecl())) { // Special case: check for assigning null to a pointer. // This is a common form of defensive programming. - const Expr *RHS = LookThroughTransitiveAssignments(B->getRHS()); + const Expr *RHS = + LookThroughTransitiveAssignmentsAndCommaOperators(B->getRHS()); + RHS = RHS->IgnoreParenCasts(); QualType T = VD->getType(); if (T->isPointerType() || T->isObjCObjectPointerType()) { @@ -274,7 +281,6 @@ public: return; } - RHS = RHS->IgnoreParenCasts(); // Special case: self-assignments. These are often used to shut up // "unused variable" compiler warnings. if (const DeclRefExpr *RhsDR = dyn_cast(RHS)) @@ -326,7 +332,7 @@ public: // Look through transitive assignments, e.g.: // int x = y = 0; - E = LookThroughTransitiveAssignments(E); + E = LookThroughTransitiveAssignmentsAndCommaOperators(E); // Don't warn on C++ objects (yet) until we can show that their // constructors/destructors don't have side effects. diff --git a/test/Analysis/dead-stores.c b/test/Analysis/dead-stores.c index 165a12b59b..067a0504f1 100644 --- a/test/Analysis/dead-stores.c +++ b/test/Analysis/dead-stores.c @@ -547,3 +547,25 @@ int *radar11185138_baz() { return y; } +int getInt(); +int *getPtr(); +void testBOComma() { + int x0 = (getInt(), 0); // expected-warning{{unused variable 'x0'}} + int x1 = (getInt(), getInt()); // expected-warning {{Value stored to 'x1' during its initialization is never read}} // expected-warning{{unused variable 'x1'}} + int x2 = (getInt(), getInt(), getInt()); //expected-warning{{Value stored to 'x2' during its initialization is never read}} // expected-warning{{unused variable 'x2'}} + int x3; + x3 = (getInt(), getInt(), 0); // expected-warning{{Value stored to 'x3' is never read}} + int x4 = (getInt(), (getInt(), 0)); // expected-warning{{unused variable 'x4'}} + int y; + int x5 = (getInt(), (y = 0)); // expected-warning{{unused variable 'x5'}} + int x6 = (getInt(), (y = getInt())); //expected-warning {{Value stored to 'x6' during its initialization is never read}} // expected-warning{{unused variable 'x6'}} + int x7 = 0, x8 = getInt(); //expected-warning {{Value stored to 'x8' during its initialization is never read}} // expected-warning{{unused variable 'x8'}} // expected-warning{{unused variable 'x7'}} + int x9 = getInt(), x10 = 0; //expected-warning {{Value stored to 'x9' during its initialization is never read}} // expected-warning{{unused variable 'x9'}} // expected-warning{{unused variable 'x10'}} + int m = getInt(), mm, mmm; //expected-warning {{Value stored to 'm' during its initialization is never read}} // expected-warning{{unused variable 'm'}} // expected-warning{{unused variable 'mm'}} // expected-warning{{unused variable 'mmm'}} + int n, nn = getInt(); //expected-warning {{Value stored to 'nn' during its initialization is never read}} // expected-warning{{unused variable 'n'}} // expected-warning{{unused variable 'nn'}} + + int *p; + p = (getPtr(), (int *)0); // no warning + +} + -- 2.40.0