[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