[clang-tidy] avoid 64-bit truncation in redundant bitwise checks#201363
Open
unterumarmung wants to merge 2 commits into
Open
[clang-tidy] avoid 64-bit truncation in redundant bitwise checks#201363unterumarmung wants to merge 2 commits into
unterumarmung wants to merge 2 commits into
Conversation
|
@llvm/pr-subscribers-clang-tidy Author: Daniil Dudkin (unterumarmung) ChangesFixes #201115 Full diff: https://github.com/llvm/llvm-project/pull/201363.diff 2 Files Affected:
diff --git a/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp b/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp
index 9db297990b274..de489da96de3b 100644
--- a/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp
@@ -1178,8 +1178,10 @@ void RedundantExpressionCheck::checkBitwiseExpr(
!retrieveIntegerConstantExpr(Result, "rhs", RhsValue))
return;
- const uint64_t LhsConstant = LhsValue.getZExtValue();
- const uint64_t RhsConstant = RhsValue.getZExtValue();
+ const unsigned ConstantWidth =
+ std::max(LhsValue.getBitWidth(), RhsValue.getBitWidth());
+ const llvm::APInt LhsConstant = LhsValue.extOrTrunc(ConstantWidth);
+ const llvm::APInt RhsConstant = RhsValue.extOrTrunc(ConstantWidth);
const SourceLocation Loc = ComparisonOperator->getOperatorLoc();
// Check expression: x & k1 == k2 (i.e. x & 0xFF == 0xF00)
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/redundant-expression.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/redundant-expression.cpp
index 4ff0ba867ebb9..4bd2d2df343dc 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/redundant-expression.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/redundant-expression.cpp
@@ -572,6 +572,51 @@ int TestBitwise(int X, int Y) {
return 0;
}
+bool TestBitwiseUInt128(unsigned __int128 Value) {
+ constexpr unsigned __int128 BigBit =
+ static_cast<unsigned __int128>(1) << 100;
+
+ if ((Value & BigBit) == BigBit) return true;
+
+ constexpr unsigned __int128 LowMask = static_cast<unsigned __int128>(0xFF);
+
+ if ((Value & LowMask) == BigBit) return true;
+ // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: logical expression is always false
+ if ((Value & LowMask) != BigBit) return true;
+ // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: logical expression is always true
+ if ((Value | BigBit) == LowMask) return true;
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: logical expression is always false
+ if ((Value | BigBit) != LowMask) return true;
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: logical expression is always true
+
+ return false;
+}
+
+#define UINT128_BIG_BIT (static_cast<unsigned __int128>(1) << 100)
+
+bool TestBitwiseUInt128Macro(unsigned __int128 Value) {
+ return (Value & UINT128_BIG_BIT) == UINT128_BIG_BIT;
+}
+
+template <int N>
+bool TestBitwiseUInt128Template(unsigned __int128 Value) {
+ constexpr unsigned __int128 Mask = static_cast<unsigned __int128>(1) << N;
+ return (Value & Mask) == Mask;
+}
+
+bool UseBitwiseUInt128Template(unsigned __int128 Value) {
+ return TestBitwiseUInt128Template<100>(Value);
+}
+
+using RedundantExpressionU128 = unsigned __int128;
+typedef unsigned __int128 RedundantExpressionTypedefU128;
+
+bool TestBitwiseUInt128AliasCvRef(const RedundantExpressionU128 &Value) {
+ constexpr RedundantExpressionTypedefU128 Mask =
+ static_cast<RedundantExpressionU128>(1) << 100;
+ return (Value & Mask) == Mask;
+}
+
// Overloaded operators that compare an instance of a struct and an integer
// constant.
struct S {
|
|
@llvm/pr-subscribers-clang-tools-extra Author: Daniil Dudkin (unterumarmung) ChangesFixes #201115 Full diff: https://github.com/llvm/llvm-project/pull/201363.diff 2 Files Affected:
diff --git a/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp b/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp
index 9db297990b274..de489da96de3b 100644
--- a/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp
@@ -1178,8 +1178,10 @@ void RedundantExpressionCheck::checkBitwiseExpr(
!retrieveIntegerConstantExpr(Result, "rhs", RhsValue))
return;
- const uint64_t LhsConstant = LhsValue.getZExtValue();
- const uint64_t RhsConstant = RhsValue.getZExtValue();
+ const unsigned ConstantWidth =
+ std::max(LhsValue.getBitWidth(), RhsValue.getBitWidth());
+ const llvm::APInt LhsConstant = LhsValue.extOrTrunc(ConstantWidth);
+ const llvm::APInt RhsConstant = RhsValue.extOrTrunc(ConstantWidth);
const SourceLocation Loc = ComparisonOperator->getOperatorLoc();
// Check expression: x & k1 == k2 (i.e. x & 0xFF == 0xF00)
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/redundant-expression.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/redundant-expression.cpp
index 4ff0ba867ebb9..4bd2d2df343dc 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/redundant-expression.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/redundant-expression.cpp
@@ -572,6 +572,51 @@ int TestBitwise(int X, int Y) {
return 0;
}
+bool TestBitwiseUInt128(unsigned __int128 Value) {
+ constexpr unsigned __int128 BigBit =
+ static_cast<unsigned __int128>(1) << 100;
+
+ if ((Value & BigBit) == BigBit) return true;
+
+ constexpr unsigned __int128 LowMask = static_cast<unsigned __int128>(0xFF);
+
+ if ((Value & LowMask) == BigBit) return true;
+ // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: logical expression is always false
+ if ((Value & LowMask) != BigBit) return true;
+ // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: logical expression is always true
+ if ((Value | BigBit) == LowMask) return true;
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: logical expression is always false
+ if ((Value | BigBit) != LowMask) return true;
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: logical expression is always true
+
+ return false;
+}
+
+#define UINT128_BIG_BIT (static_cast<unsigned __int128>(1) << 100)
+
+bool TestBitwiseUInt128Macro(unsigned __int128 Value) {
+ return (Value & UINT128_BIG_BIT) == UINT128_BIG_BIT;
+}
+
+template <int N>
+bool TestBitwiseUInt128Template(unsigned __int128 Value) {
+ constexpr unsigned __int128 Mask = static_cast<unsigned __int128>(1) << N;
+ return (Value & Mask) == Mask;
+}
+
+bool UseBitwiseUInt128Template(unsigned __int128 Value) {
+ return TestBitwiseUInt128Template<100>(Value);
+}
+
+using RedundantExpressionU128 = unsigned __int128;
+typedef unsigned __int128 RedundantExpressionTypedefU128;
+
+bool TestBitwiseUInt128AliasCvRef(const RedundantExpressionU128 &Value) {
+ constexpr RedundantExpressionTypedefU128 Mask =
+ static_cast<RedundantExpressionU128>(1) << 100;
+ return (Value & Mask) == Mask;
+}
+
// Overloaded operators that compare an instance of a struct and an integer
// constant.
struct S {
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #201115