summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorDavid Bolvansky <david.bolvansky@gmail.com>2019-09-05 20:50:48 +0000
committerDavid Bolvansky <david.bolvansky@gmail.com>2019-09-05 20:50:48 +0000
commit872108bea55fa4e5c5888bd93e43f2612cd5e78f (patch)
tree286b78f744d6b32548660e73070994ccaace143c /clang/lib
parentdc97ca9f25aca6d14981a889748fd0810e2dd0e8 (diff)
downloadbcm5719-llvm-872108bea55fa4e5c5888bd93e43f2612cd5e78f.tar.gz
bcm5719-llvm-872108bea55fa4e5c5888bd93e43f2612cd5e78f.zip
[Diagnostics] Minor improvements for -Wxor-used-as-pow
Extracted from D66397; implemented suggestion for 2^64; tests revisited. llvm-svn: 371122
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Sema/SemaExpr.cpp57
1 files changed, 35 insertions, 22 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 5f5f4c8d044..b5ad208e998 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -11081,33 +11081,42 @@ QualType Sema::CheckVectorCompareOperands(ExprResult &LHS, ExprResult &RHS,
return GetSignedVectorType(vType);
}
-static void diagnoseXorMisusedAsPow(Sema &S, ExprResult &LHS, ExprResult &RHS,
- SourceLocation Loc) {
+static void diagnoseXorMisusedAsPow(Sema &S, const ExprResult &XorLHS,
+ const ExprResult &XorRHS,
+ const SourceLocation Loc) {
// Do not diagnose macros.
if (Loc.isMacroID())
return;
bool Negative = false;
- const auto *LHSInt = dyn_cast<IntegerLiteral>(LHS.get());
- const auto *RHSInt = dyn_cast<IntegerLiteral>(RHS.get());
+ bool ExplicitPlus = false;
+ const auto *LHSInt = dyn_cast<IntegerLiteral>(XorLHS.get());
+ const auto *RHSInt = dyn_cast<IntegerLiteral>(XorRHS.get());
if (!LHSInt)
return;
if (!RHSInt) {
// Check negative literals.
- if (const auto *UO = dyn_cast<UnaryOperator>(RHS.get())) {
- if (UO->getOpcode() != UO_Minus)
+ if (const auto *UO = dyn_cast<UnaryOperator>(XorRHS.get())) {
+ UnaryOperatorKind Opc = UO->getOpcode();
+ if (Opc != UO_Minus && Opc != UO_Plus)
return;
RHSInt = dyn_cast<IntegerLiteral>(UO->getSubExpr());
if (!RHSInt)
return;
- Negative = true;
+ Negative = (Opc == UO_Minus);
+ ExplicitPlus = !Negative;
} else {
return;
}
}
- if (LHSInt->getValue().getBitWidth() != RHSInt->getValue().getBitWidth())
+ const llvm::APInt &LeftSideValue = LHSInt->getValue();
+ llvm::APInt RightSideValue = RHSInt->getValue();
+ if (LeftSideValue != 2 && LeftSideValue != 10)
+ return;
+
+ if (LeftSideValue.getBitWidth() != RightSideValue.getBitWidth())
return;
CharSourceRange ExprRange = CharSourceRange::getCharRange(
@@ -11123,10 +11132,6 @@ static void diagnoseXorMisusedAsPow(Sema &S, ExprResult &LHS, ExprResult &RHS,
if (XorStr == "xor")
return;
- const llvm::APInt &LeftSideValue = LHSInt->getValue();
- const llvm::APInt &RightSideValue = RHSInt->getValue();
- const llvm::APInt XorValue = LeftSideValue ^ RightSideValue;
-
std::string LHSStr = Lexer::getSourceText(
CharSourceRange::getTokenRange(LHSInt->getSourceRange()),
S.getSourceManager(), S.getLangOpts());
@@ -11134,23 +11139,30 @@ static void diagnoseXorMisusedAsPow(Sema &S, ExprResult &LHS, ExprResult &RHS,
CharSourceRange::getTokenRange(RHSInt->getSourceRange()),
S.getSourceManager(), S.getLangOpts());
- int64_t RightSideIntValue = RightSideValue.getSExtValue();
if (Negative) {
- RightSideIntValue = -RightSideIntValue;
+ RightSideValue = -RightSideValue;
RHSStr = "-" + RHSStr;
+ } else if (ExplicitPlus) {
+ RHSStr = "+" + RHSStr;
}
StringRef LHSStrRef = LHSStr;
StringRef RHSStrRef = RHSStr;
- // Do not diagnose binary, hexadecimal, octal literals.
+ // Do not diagnose literals with digit separators, binary, hexadecimal, octal
+ // literals.
if (LHSStrRef.startswith("0b") || LHSStrRef.startswith("0B") ||
RHSStrRef.startswith("0b") || RHSStrRef.startswith("0B") ||
LHSStrRef.startswith("0x") || LHSStrRef.startswith("0X") ||
RHSStrRef.startswith("0x") || RHSStrRef.startswith("0X") ||
(LHSStrRef.size() > 1 && LHSStrRef.startswith("0")) ||
- (RHSStrRef.size() > 1 && RHSStrRef.startswith("0")))
+ (RHSStrRef.size() > 1 && RHSStrRef.startswith("0")) ||
+ LHSStrRef.find('\'') != StringRef::npos ||
+ RHSStrRef.find('\'') != StringRef::npos)
return;
+ bool SuggestXor = S.getLangOpts().CPlusPlus || S.getPreprocessor().isMacroDefined("xor");
+ const llvm::APInt XorValue = LeftSideValue ^ RightSideValue;
+ int64_t RightSideIntValue = RightSideValue.getSExtValue();
if (LeftSideValue == 2 && RightSideIntValue >= 0) {
std::string SuggestedExpr = "1 << " + RHSStr;
bool Overflow = false;
@@ -11161,8 +11173,9 @@ static void diagnoseXorMisusedAsPow(Sema &S, ExprResult &LHS, ExprResult &RHS,
S.Diag(Loc, diag::warn_xor_used_as_pow_base)
<< ExprStr << XorValue.toString(10, true) << ("1LL << " + RHSStr)
<< FixItHint::CreateReplacement(ExprRange, "1LL << " + RHSStr);
+ else if (RightSideIntValue == 64)
+ S.Diag(Loc, diag::warn_xor_used_as_pow) << ExprStr << XorValue.toString(10, true);
else
- // TODO: 2 ^ 64 - 1
return;
} else {
S.Diag(Loc, diag::warn_xor_used_as_pow_base_extra)
@@ -11172,13 +11185,13 @@ static void diagnoseXorMisusedAsPow(Sema &S, ExprResult &LHS, ExprResult &RHS,
ExprRange, (RightSideIntValue == 0) ? "1" : SuggestedExpr);
}
- S.Diag(Loc, diag::note_xor_used_as_pow_silence) << ("0x2 ^ " + RHSStr);
+ S.Diag(Loc, diag::note_xor_used_as_pow_silence) << ("0x2 ^ " + RHSStr) << SuggestXor;
} else if (LeftSideValue == 10) {
std::string SuggestedValue = "1e" + std::to_string(RightSideIntValue);
S.Diag(Loc, diag::warn_xor_used_as_pow_base)
<< ExprStr << XorValue.toString(10, true) << SuggestedValue
<< FixItHint::CreateReplacement(ExprRange, SuggestedValue);
- S.Diag(Loc, diag::note_xor_used_as_pow_silence) << ("0xA ^ " + RHSStr);
+ S.Diag(Loc, diag::note_xor_used_as_pow_silence) << ("0xA ^ " + RHSStr) << SuggestXor;
}
}
@@ -11225,9 +11238,6 @@ inline QualType Sema::CheckBitwiseOperands(ExprResult &LHS, ExprResult &RHS,
if (Opc == BO_And)
diagnoseLogicalNotOnLHSofCheck(*this, LHS, RHS, Loc, Opc);
- if (Opc == BO_Xor)
- diagnoseXorMisusedAsPow(*this, LHS, RHS, Loc);
-
ExprResult LHSResult = LHS, RHSResult = RHS;
QualType compType = UsualArithmeticConversions(LHSResult, RHSResult,
IsCompAssign);
@@ -11236,6 +11246,9 @@ inline QualType Sema::CheckBitwiseOperands(ExprResult &LHS, ExprResult &RHS,
LHS = LHSResult.get();
RHS = RHSResult.get();
+ if (Opc == BO_Xor)
+ diagnoseXorMisusedAsPow(*this, LHS, RHS, Loc);
+
if (!compType.isNull() && compType->isIntegralOrUnscopedEnumerationType())
return compType;
return InvalidOperands(Loc, LHS, RHS);
OpenPOWER on IntegriCloud