diff options
author | Nico Weber <nicolasweber@gmx.de> | 2016-10-27 16:32:06 +0000 |
---|---|---|
committer | Nico Weber <nicolasweber@gmx.de> | 2016-10-27 16:32:06 +0000 |
commit | 44f6f2ee423325e6157846593a74e5ed01ab3062 (patch) | |
tree | 7bb39737f18a1789a24d402a2e9e3f4f24109c1d /clang/lib/Sema | |
parent | 6c273763a366de3b1e22348b638795795fb7e005 (diff) | |
download | bcm5719-llvm-44f6f2ee423325e6157846593a74e5ed01ab3062.tar.gz bcm5719-llvm-44f6f2ee423325e6157846593a74e5ed01ab3062.zip |
Expand -Wlogical-not-parentheses to also fire on `!x & A`.
This is a misspelling of the intended !(x & A) negated bit test that happens in
practice every now and then.
I ran this on Chromium and all its dependencies, and it fired 0 times -- no
false or true positives, but it would've caught a bug in an in-progress change
that had to be caught by a Visual Studio warning instead.
https://reviews.llvm.org/D26035
llvm-svn: 285310
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 31 |
1 files changed, 20 insertions, 11 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 4735c6702f8..d6c8413d7aa 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -9095,10 +9095,10 @@ static void diagnoseObjCLiteralComparison(Sema &S, SourceLocation Loc, } } -static void diagnoseLogicalNotOnLHSofComparison(Sema &S, ExprResult &LHS, - ExprResult &RHS, - SourceLocation Loc, - BinaryOperatorKind Opc) { +/// Warns on !x < y, !x & y where !(x < y), !(x & y) was probably intended. +static void diagnoseLogicalNotOnLHSofCheck(Sema &S, ExprResult &LHS, + ExprResult &RHS, SourceLocation Loc, + BinaryOperatorKind Opc) { // Check that left hand side is !something. UnaryOperator *UO = dyn_cast<UnaryOperator>(LHS.get()->IgnoreImpCasts()); if (!UO || UO->getOpcode() != UO_LNot) return; @@ -9111,8 +9111,9 @@ static void diagnoseLogicalNotOnLHSofComparison(Sema &S, ExprResult &LHS, if (SubExpr->isKnownToHaveBooleanValue()) return; // Emit warning. - S.Diag(UO->getOperatorLoc(), diag::warn_logical_not_on_lhs_of_comparison) - << Loc; + bool IsBitwiseOp = Opc == BO_And || Opc == BO_Or || Opc == BO_Xor; + S.Diag(UO->getOperatorLoc(), diag::warn_logical_not_on_lhs_of_check) + << Loc << IsBitwiseOp; // First note suggest !(x < y) SourceLocation FirstOpen = SubExpr->getLocStart(); @@ -9121,6 +9122,7 @@ static void diagnoseLogicalNotOnLHSofComparison(Sema &S, ExprResult &LHS, if (FirstClose.isInvalid()) FirstOpen = SourceLocation(); S.Diag(UO->getOperatorLoc(), diag::note_logical_not_fix) + << IsBitwiseOp << FixItHint::CreateInsertion(FirstOpen, "(") << FixItHint::CreateInsertion(FirstClose, ")"); @@ -9169,7 +9171,7 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS, Expr *RHSStripped = RHS.get()->IgnoreParenImpCasts(); checkEnumComparison(*this, Loc, LHS.get(), RHS.get()); - diagnoseLogicalNotOnLHSofComparison(*this, LHS, RHS, Loc, Opc); + diagnoseLogicalNotOnLHSofCheck(*this, LHS, RHS, Loc, Opc); if (!LHSType->hasFloatingRepresentation() && !(LHSType->isBlockPointerType() && IsRelational) && @@ -9675,10 +9677,14 @@ QualType Sema::CheckVectorLogicalOperands(ExprResult &LHS, ExprResult &RHS, return GetSignedVectorType(LHS.get()->getType()); } -inline QualType Sema::CheckBitwiseOperands( - ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, bool IsCompAssign) { +inline QualType Sema::CheckBitwiseOperands(ExprResult &LHS, ExprResult &RHS, + SourceLocation Loc, + BinaryOperatorKind Opc) { checkArithmeticNull(*this, LHS, RHS, Loc, /*isCompare=*/false); + bool IsCompAssign = + Opc == BO_AndAssign || Opc == BO_OrAssign || Opc == BO_XorAssign; + if (LHS.get()->getType()->isVectorType() || RHS.get()->getType()->isVectorType()) { if (LHS.get()->getType()->hasIntegerRepresentation() && @@ -9689,6 +9695,9 @@ inline QualType Sema::CheckBitwiseOperands( return InvalidOperands(Loc, LHS, RHS); } + if (Opc == BO_And) + diagnoseLogicalNotOnLHSofCheck(*this, LHS, RHS, Loc, Opc); + ExprResult LHSResult = LHS, RHSResult = RHS; QualType compType = UsualArithmeticConversions(LHSResult, RHSResult, IsCompAssign); @@ -11057,7 +11066,7 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc, checkObjCPointerIntrospection(*this, LHS, RHS, OpLoc); case BO_Xor: case BO_Or: - ResultTy = CheckBitwiseOperands(LHS, RHS, OpLoc); + ResultTy = CheckBitwiseOperands(LHS, RHS, OpLoc, Opc); break; case BO_LAnd: case BO_LOr: @@ -11098,7 +11107,7 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc, case BO_OrAssign: // fallthrough DiagnoseSelfAssignment(*this, LHS.get(), RHS.get(), OpLoc); case BO_XorAssign: - CompResultTy = CheckBitwiseOperands(LHS, RHS, OpLoc, true); + CompResultTy = CheckBitwiseOperands(LHS, RHS, OpLoc, Opc); CompLHSTy = CompResultTy; if (!CompResultTy.isNull() && !LHS.isInvalid() && !RHS.isInvalid()) ResultTy = CheckAssignmentOperands(LHS.get(), RHS, OpLoc, CompResultTy); |