[clang] [clang] Skip tautological comparison if the comparison involves the 'size_t' type (PR #74427)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Dec 4 23:42:41 PST 2023
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Shivam Gupta (xgupta)
<details>
<summary>Changes</summary>
The issue with size_t comes when we are trying to add -Wtype-limits to -Wextra for GCC compatibility in review https://reviews.llvm.org/D142826.
Example of issue (false positive) -
$ cat clang/test/Sema/type-limit-compare.cpp
// RUN: %clang_cc1 %s -fsyntax-only -Wtautological-type-limit-compare -verify
namespace std {
using size_t = decltype(sizeof(0));
} // namespace std
bool func(uint64_t Size) {
if (sizeof(std::size_t) < sizeof(uint64_t) &&
Size > (uint64_t)(__SIZE_MAX__))
return false;
return true;
}
$ clang -c -Wtautological-type-limit-compare clang/test/Sema/type-limit-compare.cpp
clang/test/Sema/type-limit-compare.cpp:16:11: warning: result of comparison 'uint64_t' (aka 'unsigned long') > 18446744073709551615 is always false [-Wtautological-type-limit-compare]
16 | Size > (uint64_t)(__SIZE_MAX__))
| ~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
---
Full diff: https://github.com/llvm/llvm-project/pull/74427.diff
2 Files Affected:
- (modified) clang/lib/Sema/SemaChecking.cpp (+19)
- (added) clang/test/Sema/type-limit-compare.cpp (+20)
``````````diff
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 07ced5ffc3407..51a26f41f3d69 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -14577,6 +14577,25 @@ static bool CheckTautologicalComparison(Sema &S, BinaryOperator *E,
if (InRange && IsEnumConstOrFromMacro(S, Constant))
return false;
+ // Don't warn if the comparison involves integral or floating-point types with
+ // the same canonical types.
+ QualType LHSCanonical = Constant->getType().getCanonicalType();
+ QualType RHSCanonical = Other->getType().getCanonicalType();
+ if (TautologicalTypeCompare &&
+ (LHSCanonical->isIntegralOrEnumerationType() ||
+ LHSCanonical->isFloatingType()) &&
+ S.Context.hasSameType(LHSCanonical, RHSCanonical) &&
+ !S.Context.hasSameType(Constant->getType(), Other->getType())) {
+ return false;
+ }
+
+ // Don't warn if the comparison involves the 'size_t' type.
+ QualType SizeT = S.Context.getSizeType();
+ if (S.Context.hasSameType(Constant->getType().getCanonicalType(), SizeT) &&
+ S.Context.hasSameType(Other->getType().getCanonicalType(), SizeT)) {
+ return false;
+ }
+
// A comparison of an unsigned bit-field against 0 is really a type problem,
// even though at the type level the bit-field might promote to 'signed int'.
if (Other->refersToBitField() && InRange && Value == 0 &&
diff --git a/clang/test/Sema/type-limit-compare.cpp b/clang/test/Sema/type-limit-compare.cpp
new file mode 100644
index 0000000000000..f585356541668
--- /dev/null
+++ b/clang/test/Sema/type-limit-compare.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 %s -fsyntax-only -Wtautological-type-limit-compare -verify
+
+// expected-no-diagnostics
+#if defined(_WIN32)
+typedef unsigned long long uint64_t;
+#else
+typedef unsigned long uint64_t;
+#endif
+
+namespace std {
+using size_t = decltype(sizeof(0));
+} // namespace std
+
+bool func(uint64_t Size) {
+ if (sizeof(std::size_t) < sizeof(uint64_t) &&
+ Size > (uint64_t)(__SIZE_MAX__))
+ return false;
+ return true;
+}
+
``````````
</details>
https://github.com/llvm/llvm-project/pull/74427
More information about the cfe-commits
mailing list