[clang-tools-extra] [clang-tidy] avoid 64-bit truncation in redundant bitwise checks (PR #201363)
@@ -572,6 +572,51 @@ int TestBitwise(int X, int Y) {
return 0;
}
+bool TestBitwiseUInt128(unsigned __int128 Value) {
+ constexpr unsigned __int128 BigBit =
unterumarmung wrote:
Is it better to specify the target in the RUN directive or put this test under
ifdef?
https://github.com/llvm/llvm-project/pull/201363
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] avoid 64-bit truncation in redundant bitwise checks (PR #201363)
@@ -572,6 +572,51 @@ int TestBitwise(int X, int Y) {
return 0;
}
+bool TestBitwiseUInt128(unsigned __int128 Value) {
+ constexpr unsigned __int128 BigBit =
vbvictor wrote:
yes, this can probably break on 32bit buildbots
https://github.com/llvm/llvm-project/pull/201363
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] avoid 64-bit truncation in redundant bitwise checks (PR #201363)
@@ -572,6 +572,51 @@ int TestBitwise(int X, int Y) {
return 0;
}
+bool TestBitwiseUInt128(unsigned __int128 Value) {
+ constexpr unsigned __int128 BigBit =
zeyi2 wrote:
AFAIK `unsigned __int128` is not available on every target in buildbot, maybe
we could add an explicit target to RUN lines.
https://github.com/llvm/llvm-project/pull/201363
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] avoid 64-bit truncation in redundant bitwise checks (PR #201363)
https://github.com/zeyi2 edited https://github.com/llvm/llvm-project/pull/201363 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] avoid 64-bit truncation in redundant bitwise checks (PR #201363)
https://github.com/zeyi2 approved this pull request. LGTM with one comment for tests. Thank you :) https://github.com/llvm/llvm-project/pull/201363 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] avoid 64-bit truncation in redundant bitwise checks (PR #201363)
https://github.com/unterumarmung updated
https://github.com/llvm/llvm-project/pull/201363
>From c201e710c4b75832e35f921347c1985f4e834c8f Mon Sep 17 00:00:00 2001
From: Daniil Dudkin
Date: Wed, 3 Jun 2026 16:52:07 +0300
Subject: [PATCH 1/2] [clang-tidy] avoid 64-bit truncation in redundant bitwise
checks
Fixes #201115
---
.../misc/RedundantExpressionCheck.cpp | 6 ++-
.../checkers/misc/redundant-expression.cpp| 45 +++
2 files changed, 49 insertions(+), 2 deletions(-)
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(1) << 100;
+
+ if ((Value & BigBit) == BigBit) return true;
+
+ constexpr unsigned __int128 LowMask = static_cast(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(1) << 100)
+
+bool TestBitwiseUInt128Macro(unsigned __int128 Value) {
+ return (Value & UINT128_BIG_BIT) == UINT128_BIG_BIT;
+}
+
+template
+bool TestBitwiseUInt128Template(unsigned __int128 Value) {
+ constexpr unsigned __int128 Mask = static_cast(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(1) << 100;
+ return (Value & Mask) == Mask;
+}
+
// Overloaded operators that compare an instance of a struct and an integer
// constant.
struct S {
>From ebdf0cdf31eb6909f82ee1ae0e90145ce2bec12c Mon Sep 17 00:00:00 2001
From: Daniil Dudkin
Date: Wed, 3 Jun 2026 16:56:48 +0300
Subject: [PATCH 2/2] add release note
---
clang-tools-extra/docs/ReleaseNotes.rst | 4
1 file changed, 4 insertions(+)
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst
b/clang-tools-extra/docs/ReleaseNotes.rst
index e6897ebb4cf9f..0617121cb0623 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -539,6 +539,10 @@ Changes in existing checks
` by avoiding false positives
when
virtual inheritance causes concrete bases to be counted more than once.
+- Improved :doc:`misc-redundant-expression
+ ` check by fixing a crash when
+ evaluating bitwise comparisons against integer constants wider than 64 bits.
+
- Improved :doc:`misc-throw-by-value-catch-by-reference
` check:
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] avoid 64-bit truncation in redundant bitwise checks (PR #201363)
llvmorg-github-actions[bot] wrote:
@llvm/pr-subscribers-clang-tools-extra
Author: Daniil Dudkin (unterumarmung)
Changes
Fixes #201115
---
Full diff: https://github.com/llvm/llvm-project/pull/201363.diff
2 Files Affected:
- (modified) clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp
(+4-2)
- (modified)
clang-tools-extra/test/clang-tidy/checkers/misc/redundant-expression.cpp (+45)
``diff
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(1) << 100;
+
+ if ((Value & BigBit) == BigBit) return true;
+
+ constexpr unsigned __int128 LowMask = static_cast(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(1) << 100)
+
+bool TestBitwiseUInt128Macro(unsigned __int128 Value) {
+ return (Value & UINT128_BIG_BIT) == UINT128_BIG_BIT;
+}
+
+template
+bool TestBitwiseUInt128Template(unsigned __int128 Value) {
+ constexpr unsigned __int128 Mask = static_cast(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(1) << 100;
+ return (Value & Mask) == Mask;
+}
+
// Overloaded operators that compare an instance of a struct and an integer
// constant.
struct S {
``
https://github.com/llvm/llvm-project/pull/201363
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] avoid 64-bit truncation in redundant bitwise checks (PR #201363)
llvmorg-github-actions[bot] wrote:
@llvm/pr-subscribers-clang-tidy
Author: Daniil Dudkin (unterumarmung)
Changes
Fixes #201115
---
Full diff: https://github.com/llvm/llvm-project/pull/201363.diff
2 Files Affected:
- (modified) clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp
(+4-2)
- (modified)
clang-tools-extra/test/clang-tidy/checkers/misc/redundant-expression.cpp (+45)
``diff
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(1) << 100;
+
+ if ((Value & BigBit) == BigBit) return true;
+
+ constexpr unsigned __int128 LowMask = static_cast(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(1) << 100)
+
+bool TestBitwiseUInt128Macro(unsigned __int128 Value) {
+ return (Value & UINT128_BIG_BIT) == UINT128_BIG_BIT;
+}
+
+template
+bool TestBitwiseUInt128Template(unsigned __int128 Value) {
+ constexpr unsigned __int128 Mask = static_cast(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(1) << 100;
+ return (Value & Mask) == Mask;
+}
+
// Overloaded operators that compare an instance of a struct and an integer
// constant.
struct S {
``
https://github.com/llvm/llvm-project/pull/201363
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] avoid 64-bit truncation in redundant bitwise checks (PR #201363)
https://github.com/unterumarmung created
https://github.com/llvm/llvm-project/pull/201363
Fixes #201115
>From c201e710c4b75832e35f921347c1985f4e834c8f Mon Sep 17 00:00:00 2001
From: Daniil Dudkin
Date: Wed, 3 Jun 2026 16:52:07 +0300
Subject: [PATCH] [clang-tidy] avoid 64-bit truncation in redundant bitwise
checks
Fixes #201115
---
.../misc/RedundantExpressionCheck.cpp | 6 ++-
.../checkers/misc/redundant-expression.cpp| 45 +++
2 files changed, 49 insertions(+), 2 deletions(-)
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(1) << 100;
+
+ if ((Value & BigBit) == BigBit) return true;
+
+ constexpr unsigned __int128 LowMask = static_cast(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(1) << 100)
+
+bool TestBitwiseUInt128Macro(unsigned __int128 Value) {
+ return (Value & UINT128_BIG_BIT) == UINT128_BIG_BIT;
+}
+
+template
+bool TestBitwiseUInt128Template(unsigned __int128 Value) {
+ constexpr unsigned __int128 Mask = static_cast(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(1) << 100;
+ return (Value & Mask) == Mask;
+}
+
// Overloaded operators that compare an instance of a struct and an integer
// constant.
struct S {
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
