mgrabovsky updated this revision to Diff 37720. mgrabovsky added a comment.
Change message wording http://reviews.llvm.org/D13643 Files: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaChecking.cpp test/Sema/bool-compare.c
Index: test/Sema/bool-compare.c =================================================================== --- test/Sema/bool-compare.c +++ test/Sema/bool-compare.c @@ -85,7 +85,9 @@ if ((a<y) != -1) {}// expected-warning {{comparison of constant -1 with boolean expression is always true}} if ((a<y) == z) {} // no warning - if (a>y<z) {} // no warning + if (a>y<z) {} // expected-warning {{comparisons such as 'a > b < c' do not have their mathematical meaning}} \ + // expected-note {{to achieve the expected behavior, turn this expression into a conjunction of two comparisons}} \ + // expected-note {{place parentheses around either of the comparisons to silence this warning}} if ((a<y) > z) {} // no warning if((a<y)>(z<y)) {} // no warning if((a<y)==(z<y)){} // no warning @@ -144,10 +146,18 @@ if (z !=(a<y)) {} // no warning if (-1 !=(a<y)) {} // expected-warning {{comparison of constant -1 with boolean expression is always true}} - if (z ==(a<y)) {} // no warning - if (z<a>y) {} // no warning - if (z > (a<y)) {} // no warning - if((z<y)>(a<y)) {} // no warning + if (a == b == z) {} // expected-warning {{comparisons such as 'a == b == c' do not have their mathematical meaning}} \ + // expected-note {{to achieve the expected behavior, turn this expression into a conjunction of two comparisons}} \ + // expected-note {{place parentheses around either of the comparisons to silence this warning}} + if ((a==y)==z) {} // no warning + if (a==(y==z)) {} // no warning + + if (z ==(a<y)) {} // no warning + if (z<a>y) {} // expected-warning {{comparisons such as 'a < b > c' do not have their mathematical meaning}} \ + // expected-note {{to achieve the expected behavior, turn this expression into a conjunction of two comparisons}} \ + // expected-note {{place parentheses around either of the comparisons to silence this warning}} + if (z > (a<y)) {} // no warning + if((z<y)>(a<y)) {} // no warning if((z<y)==(a<y)){} // no warning if((z<y)!=(a<y)){} // no warning if((y==z)<(z==x)){} // no warning Index: lib/Sema/SemaChecking.cpp =================================================================== --- lib/Sema/SemaChecking.cpp +++ lib/Sema/SemaChecking.cpp @@ -6693,6 +6693,24 @@ << E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange()); } +/// Diagnose attempts at ternary comparison, e.g., 1 < x < 2 +static void DiagnoseTernaryComparison(Sema &S, BinaryOperator *E) { + BinaryOperator *LHS = dyn_cast<BinaryOperator>(E->getLHS()); + if (!LHS || !LHS->isComparisonOp()) + return; + + SourceLocation Loc = E->getSourceRange().getBegin(); + + S.Diag(Loc, diag::warn_ternary_comparison) + << LHS->getOpcodeStr() + << E->getOpcodeStr() + << E->getSourceRange(); + S.Diag(Loc, diag::note_ternary_comparison_to_conjunction); + S.Diag(Loc, diag::note_ternary_comparison_silence) + << FixItHint::CreateInsertion(LHS->getSourceRange().getBegin(), "(") + << FixItHint::CreateInsertion(LHS->getSourceRange().getEnd(), ")"); +} + /// Analyze the operands of the given comparison. Implements the /// fallback case from AnalyzeComparison. static void AnalyzeImpConvsInComparison(Sema &S, BinaryOperator *E) { @@ -6716,11 +6734,13 @@ if (E->isValueDependent()) return AnalyzeImpConvsInComparison(S, E); + DiagnoseTernaryComparison(S, E); + Expr *LHS = E->getLHS()->IgnoreParenImpCasts(); Expr *RHS = E->getRHS()->IgnoreParenImpCasts(); - + bool IsComparisonConstant = false; - + // Check whether an integer constant comparison results in a value // of 'true' or 'false'. if (T->isIntegralType(S.Context)) { Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -5866,6 +5866,14 @@ def note_condition_assign_silence : Note< "place parentheses around the assignment to silence this warning">; +def warn_ternary_comparison : Warning<"comparisons such as 'a %0 b %1 c' do not " + "have their mathematical meaning">, + InGroup<Parentheses>; +def note_ternary_comparison_to_conjunction : Note<"to achieve the expected behavior, " + "turn this expression into a conjunction of two comparisons">; +def note_ternary_comparison_silence : Note<"place parentheses around either " + "of the comparisons to silence this warning">; + def warn_equality_with_extra_parens : Warning<"equality comparison with " "extraneous parentheses">, InGroup<ParenthesesOnEquality>; def note_equality_comparison_to_assign : Note<
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits