diff options
| -rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 7 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 26 | ||||
| -rw-r--r-- | clang/test/Sema/parentheses.c | 3 | 
3 files changed, 32 insertions, 4 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 55109d089be..4c8325621fb 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -2156,7 +2156,12 @@ def note_precedence_bitwise_silence : Note<  def warn_logical_instead_of_bitwise : Warning<    "use of logical %0 with constant operand; switch to bitwise %1 or "    "remove constant">, InGroup<DiagGroup<"constant-logical-operand">>; -   + +def warn_logical_and_in_logical_or : Warning< +  "'&&' within '||'">, InGroup<Parentheses>; +def note_logical_and_in_logical_or_silence : Note< +  "place parentheses around the '&&' expression to silence this warning">; +  def err_sizeof_nonfragile_interface : Error<    "invalid application of '%select{alignof|sizeof}1' to interface %0 in "    "non-fragile ABI">; diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 7555af375f7..80ee2963a72 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -7329,13 +7329,33 @@ static void DiagnoseBitwisePrecedence(Sema &Self, BinaryOperatorKind Opc,                         rhs->getSourceRange());  } +static void DiagnoseLogicalAndInLogicalOr(Sema &Self, SourceLocation OpLoc, +                                          Expr *E) { +  if (BinaryOperator *Bop = dyn_cast<BinaryOperator>(E)) { +    if (Bop->getOpcode() == BO_LAnd) { +      SuggestParentheses(Self, OpLoc, +        Self.PDiag(diag::warn_logical_and_in_logical_or) +            << E->getSourceRange(), +        Self.PDiag(diag::note_logical_and_in_logical_or_silence), +        E->getSourceRange(), +        Self.PDiag(0), SourceRange()); +    } +  } +} +  /// DiagnoseBinOpPrecedence - Emit warnings for expressions with tricky -/// precedence. This currently diagnoses only "arg1 'bitwise' arg2 'eq' arg3". -/// But it could also warn about arg1 && arg2 || arg3, as GCC 4.3+ does. +/// precedence.  static void DiagnoseBinOpPrecedence(Sema &Self, BinaryOperatorKind Opc,                                      SourceLocation OpLoc, Expr *lhs, Expr *rhs){ +  // Diagnose "arg1 'bitwise' arg2 'eq' arg3".    if (BinaryOperator::isBitwiseOp(Opc)) -    DiagnoseBitwisePrecedence(Self, Opc, OpLoc, lhs, rhs); +    return DiagnoseBitwisePrecedence(Self, Opc, OpLoc, lhs, rhs); + +  /// Warn about arg1 && arg2 || arg3, as GCC 4.3+ does. +  if (Opc == BO_LOr) { +    DiagnoseLogicalAndInLogicalOr(Self, OpLoc, lhs); +    DiagnoseLogicalAndInLogicalOr(Self, OpLoc, rhs); +  }  }  // Binary Operators.  'Tok' is the token for the operator. diff --git a/clang/test/Sema/parentheses.c b/clang/test/Sema/parentheses.c index e53f0eb99bc..a219c9b342d 100644 --- a/clang/test/Sema/parentheses.c +++ b/clang/test/Sema/parentheses.c @@ -25,4 +25,7 @@ void bitwise_rel(unsigned i) {    // Eager logical op    (void)(i == 1 | i == 2 | i == 3);    (void)(i != 1 & i != 2 & i != 3); + +  (void)(i || i && i); // expected-warning {{'&&' within '||'}} \ +                       // expected-note {{place parentheses around the '&&' expression to silence this warning}}  }  | 

