From: Richard Smith Date: Thu, 17 Jan 2013 22:06:26 +0000 (+0000) Subject: -Wunsequenced: if the LHS of an &&, || or ?: is not constant, check for X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=995e4a7530d705147c875b63608532c483c011a8;p=clang -Wunsequenced: if the LHS of an &&, || or ?: is not constant, check for unsequenced operations in the RHS. We don't compare the RHS with the rest of the expression yet; such checks will need care to avoid diagnosing unsequenced operations which are both in conditionally-evaluated subexpressions which actually can't occur together, such as in '(b && ++x) + (!b && ++x)'. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@172760 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index 69500ae87c..1b9239c6e9 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -5507,9 +5507,18 @@ public: bool Result; if (!BO->getLHS()->isValueDependent() && - BO->getLHS()->EvaluateAsBooleanCondition(Result, SemaRef.Context) && - !Result) - Visit(BO->getRHS()); + BO->getLHS()->EvaluateAsBooleanCondition(Result, SemaRef.Context)) { + if (!Result) + Visit(BO->getRHS()); + } else { + // Check for unsequenced operations in the RHS, treating it as an + // entirely separate evaluation. + // + // FIXME: If there are operations in the RHS which are unsequenced + // with respect to operations outside the RHS, and those operations + // are unconditionally evaluated, diagnose them. + SequenceChecker(SemaRef, BO->getRHS()); + } } void VisitBinLAnd(BinaryOperator *BO) { { @@ -5519,9 +5528,12 @@ public: bool Result; if (!BO->getLHS()->isValueDependent() && - BO->getLHS()->EvaluateAsBooleanCondition(Result, SemaRef.Context) && - Result) - Visit(BO->getRHS()); + BO->getLHS()->EvaluateAsBooleanCondition(Result, SemaRef.Context)) { + if (Result) + Visit(BO->getRHS()); + } else { + SequenceChecker(SemaRef, BO->getRHS()); + } } // Only visit the condition, unless we can be sure which subexpression will @@ -5534,6 +5546,10 @@ public: if (!CO->getCond()->isValueDependent() && CO->getCond()->EvaluateAsBooleanCondition(Result, SemaRef.Context)) Visit(Result ? CO->getTrueExpr() : CO->getFalseExpr()); + else { + SequenceChecker(SemaRef, CO->getTrueExpr()); + SequenceChecker(SemaRef, CO->getFalseExpr()); + } } void VisitCXXConstructExpr(CXXConstructExpr *CCE) { diff --git a/test/SemaCXX/warn-unsequenced.cpp b/test/SemaCXX/warn-unsequenced.cpp index dcac097586..15ca1dba7a 100644 --- a/test/SemaCXX/warn-unsequenced.cpp +++ b/test/SemaCXX/warn-unsequenced.cpp @@ -88,4 +88,11 @@ void test() { xs[0] = (a = 1, a); // ok (a -= 128) &= 128; // ok ++a += 1; // ok + + xs[8] ? ++a + a++ : 0; // expected-warning {{multiple unsequenced modifications}} + xs[8] ? 0 : ++a + a++; // expected-warning {{multiple unsequenced modifications}} + xs[8] ? ++a : a++; // ok + + xs[8] && (++a + a++); // expected-warning {{multiple unsequenced modifications}} + xs[8] || (++a + a++); // expected-warning {{multiple unsequenced modifications}} }