forked from OSchip/llvm-project
				
			Warn for un-parenthesized '&' inside '|' (a & b | c), rdar://9553326.
Patch by Henry Mason with tweaks by me. llvm-svn: 133453
This commit is contained in:
		
							parent
							
								
									c7df192279
								
							
						
					
					
						commit
						01bf777597
					
				| 
						 | 
				
			
			@ -62,6 +62,7 @@ def ExitTimeDestructors : DiagGroup<"exit-time-destructors">;
 | 
			
		|||
def FourByteMultiChar : DiagGroup<"four-char-constants">;
 | 
			
		||||
def GlobalConstructors : DiagGroup<"global-constructors">;
 | 
			
		||||
def : DiagGroup<"idiomatic-parentheses">;
 | 
			
		||||
def BitwiseOpParentheses: DiagGroup<"bitwise-op-parentheses">;
 | 
			
		||||
def LogicalOpParentheses: DiagGroup<"logical-op-parentheses">;
 | 
			
		||||
def IgnoredQualifiers : DiagGroup<"ignored-qualifiers">;
 | 
			
		||||
def : DiagGroup<"import">;
 | 
			
		||||
| 
						 | 
				
			
			@ -195,7 +196,8 @@ def DuplicateArgDecl : DiagGroup<"duplicate-method-arg">;
 | 
			
		|||
// in -Wparentheses because most users who use -Wparentheses explicitly
 | 
			
		||||
// do not want these warnings.
 | 
			
		||||
def Parentheses : DiagGroup<"parentheses",
 | 
			
		||||
                            [LogicalOpParentheses]>;
 | 
			
		||||
                            [LogicalOpParentheses,
 | 
			
		||||
                             BitwiseOpParentheses]>;
 | 
			
		||||
 | 
			
		||||
// -Wconversion has its own warnings, but we split a few out for
 | 
			
		||||
// legacy reasons:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2777,6 +2777,11 @@ 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_bitwise_and_in_bitwise_or : Warning<
 | 
			
		||||
  "'&' within '|'">, InGroup<BitwiseOpParentheses>;
 | 
			
		||||
def note_bitwise_and_in_bitwise_or_silence : Note<
 | 
			
		||||
  "place parentheses around the '&' expression to silence this warning">;
 | 
			
		||||
 | 
			
		||||
def warn_logical_and_in_logical_or : Warning<
 | 
			
		||||
  "'&&' within '||'">, InGroup<LogicalOpParentheses>;
 | 
			
		||||
def note_logical_and_in_logical_or_silence : Note<
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9147,6 +9147,20 @@ static void DiagnoseBitwisePrecedence(Sema &Self, BinaryOperatorKind Opc,
 | 
			
		|||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// \brief It accepts a '&' expr that is inside a '|' one.
 | 
			
		||||
/// Emit a diagnostic together with a fixit hint that wraps the '&' expression
 | 
			
		||||
/// in parentheses.
 | 
			
		||||
static void
 | 
			
		||||
EmitDiagnosticForBitwiseAndInBitwiseOr(Sema &Self, SourceLocation OpLoc,
 | 
			
		||||
                                       BinaryOperator *Bop) {
 | 
			
		||||
  assert(Bop->getOpcode() == BO_And);
 | 
			
		||||
  Self.Diag(Bop->getOperatorLoc(), diag::warn_bitwise_and_in_bitwise_or)
 | 
			
		||||
      << Bop->getSourceRange() << OpLoc;
 | 
			
		||||
  SuggestParentheses(Self, Bop->getOperatorLoc(),
 | 
			
		||||
    Self.PDiag(diag::note_bitwise_and_in_bitwise_or_silence),
 | 
			
		||||
    Bop->getSourceRange());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// \brief It accepts a '&&' expr that is inside a '||' one.
 | 
			
		||||
/// Emit a diagnostic together with a fixit hint that wraps the '&&' expression
 | 
			
		||||
/// in parentheses.
 | 
			
		||||
| 
						 | 
				
			
			@ -9212,13 +9226,28 @@ static void DiagnoseLogicalAndInLogicalOrRHS(Sema &S, SourceLocation OpLoc,
 | 
			
		|||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// \brief Look for '&' in the left or right hand of a '|' expr.
 | 
			
		||||
static void DiagnoseBitwiseAndInBitwiseOr(Sema &S, SourceLocation OpLoc,
 | 
			
		||||
                                             Expr *OrArg) {
 | 
			
		||||
  if (BinaryOperator *Bop = dyn_cast<BinaryOperator>(OrArg)) {
 | 
			
		||||
    if (Bop->getOpcode() == BO_And)
 | 
			
		||||
      return EmitDiagnosticForBitwiseAndInBitwiseOr(S, OpLoc, Bop);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// DiagnoseBinOpPrecedence - Emit warnings for expressions with tricky
 | 
			
		||||
/// precedence.
 | 
			
		||||
static void DiagnoseBinOpPrecedence(Sema &Self, BinaryOperatorKind Opc,
 | 
			
		||||
                                    SourceLocation OpLoc, Expr *lhs, Expr *rhs){
 | 
			
		||||
  // Diagnose "arg1 'bitwise' arg2 'eq' arg3".
 | 
			
		||||
  if (BinaryOperator::isBitwiseOp(Opc))
 | 
			
		||||
    return DiagnoseBitwisePrecedence(Self, Opc, OpLoc, lhs, rhs);
 | 
			
		||||
    DiagnoseBitwisePrecedence(Self, Opc, OpLoc, lhs, rhs);
 | 
			
		||||
 | 
			
		||||
  // Diagnose "arg1 & arg2 | arg3"
 | 
			
		||||
  if (Opc == BO_Or && !OpLoc.isMacroID()/* Don't warn in macros. */) {
 | 
			
		||||
    DiagnoseBitwiseAndInBitwiseOr(Self, OpLoc, lhs);
 | 
			
		||||
    DiagnoseBitwiseAndInBitwiseOr(Self, OpLoc, rhs);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Warn about arg1 || arg2 && arg3, as GCC 4.3+ does.
 | 
			
		||||
  // We don't warn for 'assert(a || b && "bad")' since this is safe.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,6 +26,12 @@ void bitwise_rel(unsigned i) {
 | 
			
		|||
  (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}}
 | 
			
		||||
 | 
			
		||||
  (void)(i | i & i); // expected-warning {{'&' within '|'}} \
 | 
			
		||||
                     // expected-note {{place parentheses around the '&' expression to silence this warning}}
 | 
			
		||||
 | 
			
		||||
  (void)(i ||
 | 
			
		||||
             i && i); // expected-warning {{'&&' within '||'}} \
 | 
			
		||||
                       // expected-note {{place parentheses around the '&&' expression to silence this warning}}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue