vabridgers updated this revision to Diff 282854.
vabridgers added a comment.

fix misc test formatting


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D85097/new/

https://reviews.llvm.org/D85097

Files:
  clang/docs/DiagnosticsReference.rst
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaExpr.cpp
  clang/test/Misc/warning-wall.c
  clang/test/Sema/warn-compare-op-parentheses.c

Index: clang/test/Sema/warn-compare-op-parentheses.c
===================================================================
--- /dev/null
+++ clang/test/Sema/warn-compare-op-parentheses.c
@@ -0,0 +1,176 @@
+// RUN: %clang_cc1 -fsyntax-only -Wcompare-op-parentheses -verify %s
+
+int tests(int p1, int p2, int p3, int p4, int p5, int p6) {
+  int b = 0;
+  b = p1 < p2 < p3;
+  // expected-warning@-1 {{comparisons like 'x<=y<=z' are interpreted as '(x<=y ? 1 : 0) <= z'}}
+  // expected-note@-2 {{place parentheses around the '<' expression to silence this warning}}
+  b = p1 < p2 <= p3;
+  // expected-warning@-1 {{comparisons like 'x<=y<=z' are interpreted as '(x<=y ? 1 : 0) <= z'}}
+  // expected-note@-2 {{place parentheses around the '<' expression to silence this warning}}
+  b = p1 <= p2 <= p3;
+  // expected-warning@-1 {{comparisons like 'x<=y<=z' are interpreted as '(x<=y ? 1 : 0) <= z'}}
+  // expected-note@-2 {{place parentheses around the '<=' expression to silence this warning}}
+  b = p1 <= p2 < p3;
+  // expected-warning@-1 {{comparisons like 'x<=y<=z' are interpreted as '(x<=y ? 1 : 0) <= z'}}
+  // expected-note@-2 {{place parentheses around the '<=' expression to silence this warning}}
+
+  b = p1 > p2 > p3;
+  // expected-warning@-1 {{comparisons like 'x<=y<=z' are interpreted as '(x<=y ? 1 : 0) <= z'}}
+  // expected-note@-2 {{place parentheses around the '>' expression to silence this warning}}
+  b = p1 > p2 >= p3;
+  // expected-warning@-1 {{comparisons like 'x<=y<=z' are interpreted as '(x<=y ? 1 : 0) <= z'}}
+  // expected-note@-2 {{place parentheses around the '>' expression to silence this warning}}
+  b = p1 >= p2 >= p3;
+  // expected-warning@-1 {{comparisons like 'x<=y<=z' are interpreted as '(x<=y ? 1 : 0) <= z'}}
+  // expected-note@-2 {{place parentheses around the '>=' expression to silence this warning}}
+  b = p1 >= p2 > p3;
+  // expected-warning@-1 {{comparisons like 'x<=y<=z' are interpreted as '(x<=y ? 1 : 0) <= z'}}
+  // expected-note@-2 {{place parentheses around the '>=' expression to silence this warning}}
+
+  b = p1 > p2 < p3;
+  // expected-warning@-1 {{comparisons like 'x<=y<=z' are interpreted as '(x<=y ? 1 : 0) <= z'}}
+  // expected-note@-2 {{place parentheses around the '>' expression to silence this warning}}
+  b = p1<p2> p3;
+  // expected-warning@-1 {{comparisons like 'x<=y<=z' are interpreted as '(x<=y ? 1 : 0) <= z'}}
+  // expected-note@-2 {{place parentheses around the '<' expression to silence this warning}}
+
+  b = p1 > p2 <= p3;
+  // expected-warning@-1 {{comparisons like 'x<=y<=z' are interpreted as '(x<=y ? 1 : 0) <= z'}}
+  // expected-note@-2 {{place parentheses around the '>' expression to silence this warning}}
+  b = p1 < p2 >= p3;
+  // expected-warning@-1 {{comparisons like 'x<=y<=z' are interpreted as '(x<=y ? 1 : 0) <= z'}}
+  // expected-note@-2 {{place parentheses around the '<' expression to silence this warning}}
+
+  b = p1 >= p2 < p3;
+  // expected-warning@-1 {{comparisons like 'x<=y<=z' are interpreted as '(x<=y ? 1 : 0) <= z'}}
+  // expected-note@-2 {{place parentheses around the '>=' expression to silence this warning}}
+  b = p1 <= p2 > p3;
+  // expected-warning@-1 {{comparisons like 'x<=y<=z' are interpreted as '(x<=y ? 1 : 0) <= z'}}
+  // expected-note@-2 {{place parentheses around the '<=' expression to silence this warning}}
+
+  b = p1 >= p2 <= p3;
+  // expected-warning@-1 {{comparisons like 'x<=y<=z' are interpreted as '(x<=y ? 1 : 0) <= z'}}
+  // expected-note@-2 {{place parentheses around the '>=' expression to silence this warning}}
+  b = p1 <= p2 >= p3;
+  // expected-warning@-1 {{comparisons like 'x<=y<=z' are interpreted as '(x<=y ? 1 : 0) <= z'}}
+  // expected-note@-2 {{place parentheses around the '<=' expression to silence this warning}}
+
+  b = p1 < p2 < p3 < p4;
+  // expected-warning@-1 {{comparisons like 'x<=y<=z' are interpreted as '(x<=y ? 1 : 0) <= z'}}
+  // expected-note@-2 {{place parentheses around the '<' expression to silence this warning}}
+  // expected-warning@-3 {{comparisons like 'x<=y<=z' are interpreted as '(x<=y ? 1 : 0) <= z'}}
+  // expected-note@-4 {{place parentheses around the '<' expression to silence this warning}}
+  b = (p1 < p2) < p3 < p4;
+  // expected-warning@-1 {{comparisons like 'x<=y<=z' are interpreted as '(x<=y ? 1 : 0) <= z'}}
+  // expected-note@-2 {{place parentheses around the '<' expression to silence this warning}}
+  b = p1 < (p2 < p3) < p4;
+  // expected-warning@-1 {{comparisons like 'x<=y<=z' are interpreted as '(x<=y ? 1 : 0) <= z'}}
+  // expected-note@-2 {{place parentheses around the '<' expression to silence this warning}}
+  b = p1 < p2 < (p3 < p4);
+  // expected-warning@-1 {{comparisons like 'x<=y<=z' are interpreted as '(x<=y ? 1 : 0) <= z'}}
+  // expected-note@-2 {{place parentheses around the '<' expression to silence this warning}}
+  b = (p1 < p2 < p3) < p4;
+  // expected-warning@-1 {{comparisons like 'x<=y<=z' are interpreted as '(x<=y ? 1 : 0) <= z'}}
+  // expected-note@-2 {{place parentheses around the '<' expression to silence this warning}}
+  b = p1 < (p2 < p3 < p4);
+  // expected-warning@-1 {{comparisons like 'x<=y<=z' are interpreted as '(x<=y ? 1 : 0) <= z'}}
+  // expected-note@-2 {{place parentheses around the '<' expression to silence this warning}}
+
+  b = p1 < p2 <= p3 < p4;
+  // expected-warning@-1 {{comparisons like 'x<=y<=z' are interpreted as '(x<=y ? 1 : 0) <= z'}}
+  // expected-note@-2 {{place parentheses around the '<' expression to silence this warning}}
+  // expected-warning@-3 {{comparisons like 'x<=y<=z' are interpreted as '(x<=y ? 1 : 0) <= z'}}
+  // expected-note@-4 {{place parentheses around the '<=' expression to silence this warning}}
+
+  b = (p1 < p2) < p3;   // no warning
+  b = p1 < (p2 < p3);   // no warning
+  b = (p1 < p2) <= p3;  // no warning
+  b = p1 < (p2 <= p3);  // no warning
+  b = (p1 <= p2) <= p3; // no warning
+  b = p1 <= (p2 <= p3); // no warning
+  b = (p1 <= p2) < p3;  // no warning
+  b = p1 <= (p2 < p3);  // no warning
+  b = (p1 > p2) > p3;   // no warning
+  b = p1 > (p2 > p3);   // no warning
+  b = (p1 > p2) >= p3;  // no warning
+  b = p1 > (p2 >= p3);  // no warning
+  b = (p1 >= p2) >= p3; // no warning
+  b = p1 >= (p2 >= p3); // no warning
+  b = (p1 >= p2) > p3;  // no warning
+  b = p1 >= (p2 > p3);  // no warning
+  b = (p1 > p2) < p3;   // no warning
+  b = p1 > (p2 < p3);   // no warning
+  b = (p1 < p2) > p3;   // no warning
+  b = p1 < (p2 > p3);   // no warning
+  b = (p1 > p2) <= p3;  // no warning
+  b = p1 > (p2 <= p3);  // no warning
+  b = (p1 < p2) >= p3;  // no warning
+  b = p1 < (p2 >= p3);  // no warning
+  b = (p1 >= p2) < p3;  // no warning
+  b = p1 >= (p2 < p3);  // no warning
+  b = (p1 <= p2) > p3;  // no warning
+  b = p1 <= (p2 > p3);  // no warning
+  b = (p1 >= p2) <= p3; // no warning
+  b = p1 >= (p2 <= p3); // no warning
+  b = (p1 <= p2) >= p3; // no warning
+  b = p1 <= (p2 >= p3); // no warning
+
+  b = (p1 < p2) < (p3 < p4); // no warning
+  b = p1 < ((p2 < p3) < p4); // no warning
+  b = ((p1 < p2) < p3) < p4; // no warning
+
+  b = (p1 < p2) <= (p3 < p4); // no warning
+
+  b = (p1 < p2 < p3);
+  // expected-warning@-1 {{comparisons like 'x<=y<=z' are interpreted as '(x<=y ? 1 : 0) <= z'}}
+  // expected-note@-2 {{place parentheses around the '<' expression to silence this warning}}
+  b = ((p1 < p2) && (p2 < p3)); // no warning
+  b = ((p1 < p2) && (p2));      // no warning
+  b = ((p1) && (p3 < p2));      // no warning
+  b = (p1 < p2) < p3 < p1;
+  // expected-warning@-1 {{comparisons like 'x<=y<=z' are interpreted as '(x<=y ? 1 : 0) <= z'}}
+  // expected-note@-2 {{place parentheses around the '<' expression to silence this warning}}
+  b = (p1 <= p2 < p3);
+  // expected-warning@-1 {{comparisons like 'x<=y<=z' are interpreted as '(x<=y ? 1 : 0) <= z'}}
+  // expected-note@-2 {{place parentheses around the '<=' expression to silence this warning}}
+  b = (p1 < p2 <= p3);
+  // expected-warning@-1 {{comparisons like 'x<=y<=z' are interpreted as '(x<=y ? 1 : 0) <= z'}}
+  // expected-note@-2 {{place parentheses around the '<' expression to silence this warning}}
+  b = (p1 <= p2 <= p3);
+  // expected-warning@-1 {{comparisons like 'x<=y<=z' are interpreted as '(x<=y ? 1 : 0) <= z'}}
+  // expected-note@-2 {{place parentheses around the '<=' expression to silence this warning}}
+
+  b = (p1 > p2 < p3);
+  // expected-warning@-1 {{comparisons like 'x<=y<=z' are interpreted as '(x<=y ? 1 : 0) <= z'}}
+  // expected-note@-2 {{place parentheses around the '>' expression to silence this warning}}
+
+  b = (p1 > p2 > p3);
+  // expected-warning@-1 {{comparisons like 'x<=y<=z' are interpreted as '(x<=y ? 1 : 0) <= z'}}
+  // expected-note@-2 {{place parentheses around the '>' expression to silence this warning}}
+
+  b = (p1 >= p2 > p3);
+  // expected-warning@-1 {{comparisons like 'x<=y<=z' are interpreted as '(x<=y ? 1 : 0) <= z'}}
+  // expected-note@-2 {{place parentheses around the '>=' expression to silence this warning}}
+
+  b = (p1 >= p2 >= p3);
+  // expected-warning@-1 {{comparisons like 'x<=y<=z' are interpreted as '(x<=y ? 1 : 0) <= z'}}
+  // expected-note@-2 {{place parentheses around the '>=' expression to silence this warning}}
+
+  b = (p1 >= p2 || p3); // no warning
+  b = (p1 && p3 < p2);  // no warning
+  b = ((p1 < p2) < p3); // no warning
+  b = (p1 < (p2 < p3)); // no warning
+
+  b = (0 <= (p1 < p2));
+  // expected-warning@-1 {{result of comparison of constant 0 with boolean expression is always true}}
+
+  // FIXME - These do not currently trigger any warnings
+  b = (p1 == p2 < p3);       // maybe intentional, but definitely deserving of a warning
+  b = (p1 == p2 == p3);      // definitely buggy and deserving of a warning
+  b = (p1 != p2 != p3);      // definitely buggy and deserving of a warning
+  b = (p1 < p2 == p3 < p4);  // maybe intentional, but definitely deserving of a warning
+  b = (p1 == p2 < p3 == p4); // definitely buggy and deserving of a warning
+
+  return b;
+}
Index: clang/test/Misc/warning-wall.c
===================================================================
--- clang/test/Misc/warning-wall.c
+++ clang/test/Misc/warning-wall.c
@@ -83,6 +83,7 @@
 CHECK-NEXT:    -Wextern-c-compat
 CHECK-NEXT:    -Wuser-defined-warnings
 CHECK-NEXT:  -Wparentheses
+CHECK-NEXT:    -Wcompare-op-parentheses
 CHECK-NEXT:    -Wlogical-op-parentheses
 CHECK-NEXT:    -Wlogical-not-parentheses
 CHECK-NEXT:    -Wbitwise-conditional-parentheses
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -14002,6 +14002,17 @@
     ParensRange);
 }
 
+static void EmitDiagnosticForAmbiguousComparison(Sema &Self,
+                                                 SourceLocation OpLoc,
+                                                 BinaryOperator *Bop) {
+  Self.Diag(Bop->getOperatorLoc(), diag::warn_comparison_parentheses)
+      << Bop->getSourceRange() << OpLoc;
+  SuggestParentheses(Self, Bop->getOperatorLoc(),
+                     Self.PDiag(diag::note_precedence_silence)
+                         << Bop->getOpcodeStr(),
+                     Bop->getSourceRange());
+}
+
 /// It accepts a '&&' expr that is inside a '||' one.
 /// Emit a diagnostic together with a fixit hint that wraps the '&&' expression
 /// in parentheses.
@@ -14033,6 +14044,15 @@
          E->EvaluateAsBooleanCondition(Res, S.getASTContext()) && !Res;
 }
 
+static void DiagnoseAmbiguousComparison(Sema &S, SourceLocation OpLoc,
+                                        Expr *LHSExpr, Expr *RHSExpr) {
+  if (BinaryOperator *Bop = dyn_cast<BinaryOperator>(LHSExpr)) {
+    if (Bop->isRelationalOp()) {
+      return EmitDiagnosticForAmbiguousComparison(S, OpLoc, Bop);
+    }
+  }
+}
+
 /// Look for '&&' in the left hand of a '||' expr.
 static void DiagnoseLogicalAndInLogicalOrLHS(Sema &S, SourceLocation OpLoc,
                                              Expr *LHSExpr, Expr *RHSExpr) {
@@ -14162,6 +14182,9 @@
   // cout << 5 == 4;
   if (BinaryOperator::isComparisonOp(Opc))
     DiagnoseShiftCompare(Self, OpLoc, LHSExpr, RHSExpr);
+
+  if (BinaryOperator::isRelationalOp(Opc))
+    DiagnoseAmbiguousComparison(Self, OpLoc, LHSExpr, RHSExpr);
 }
 
 // Binary Operators.  'Tok' is the token for the operator.
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -6130,6 +6130,10 @@
 def warn_bitwise_op_in_bitwise_op : Warning<
   "'%0' within '%1'">, InGroup<BitwiseOpParentheses>, DefaultIgnore;
 
+def warn_comparison_parentheses : Warning<
+  "chained comparisons like 'x<=y<=z' are interpreted as '(x<=y ? 1 : 0) <= z'">,
+  InGroup<CompareOpParentheses>, DefaultIgnore;
+
 def warn_logical_and_in_logical_or : Warning<
   "'&&' within '||'">, InGroup<LogicalOpParentheses>, DefaultIgnore;
 
Index: clang/include/clang/Basic/DiagnosticGroups.td
===================================================================
--- clang/include/clang/Basic/DiagnosticGroups.td
+++ clang/include/clang/Basic/DiagnosticGroups.td
@@ -341,6 +341,7 @@
 def GlobalConstructors : DiagGroup<"global-constructors">;
 def BitwiseConditionalParentheses: DiagGroup<"bitwise-conditional-parentheses">;
 def BitwiseOpParentheses: DiagGroup<"bitwise-op-parentheses">;
+def CompareOpParentheses: DiagGroup<"compare-op-parentheses">;
 def LogicalOpParentheses: DiagGroup<"logical-op-parentheses">;
 def LogicalNotParentheses: DiagGroup<"logical-not-parentheses">;
 def ShiftOpParentheses: DiagGroup<"shift-op-parentheses">;
@@ -785,7 +786,8 @@
 // do not want these warnings.
 def ParenthesesOnEquality : DiagGroup<"parentheses-equality">;
 def Parentheses : DiagGroup<"parentheses",
-                            [LogicalOpParentheses,
+                            [CompareOpParentheses,
+                             LogicalOpParentheses,
                              LogicalNotParentheses,
                              BitwiseConditionalParentheses,
                              BitwiseOpParentheses,
Index: clang/docs/DiagnosticsReference.rst
===================================================================
--- clang/docs/DiagnosticsReference.rst
+++ clang/docs/DiagnosticsReference.rst
@@ -2850,6 +2850,15 @@
 +---------------------------------------------------------------------------+
 
 
+-Wcompare-op-parentheses
+--------------------------------
+**Diagnostic text:**
+
++----------------------------------------------------------------------------------------------------------+
+|:warning:`warning:` |nbsp| :diagtext:`comparisons like 'x<=y<=z' are interpreted as '(x<=y ? 1 : 0) <= z'`|
++----------------------------------------------------------------------------------------------------------+
+
+
 -Wcomplex-component-init
 ------------------------
 **Diagnostic text:**
@@ -9873,7 +9882,7 @@
 -------------
 Some of the diagnostics controlled by this flag are enabled by default.
 
-Also controls `-Wbitwise-conditional-parentheses`_, `-Wbitwise-op-parentheses`_, `-Wdangling-else`_, `-Wlogical-not-parentheses`_, `-Wlogical-op-parentheses`_, `-Woverloaded-shift-op-parentheses`_, `-Wparentheses-equality`_, `-Wshift-op-parentheses`_.
+Also controls `-Wbitwise-conditional-parentheses`_, `-Wbitwise-op-parentheses`_, `-Wcompare-op-parentheses`_, `-Wdangling-else`_, `-Wlogical-not-parentheses`_, `-Wlogical-op-parentheses`_, `-Woverloaded-shift-op-parentheses`_, `-Wparentheses-equality`_, `-Wshift-op-parentheses`_.
 
 **Diagnostic text:**
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to