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; +} +