Author: zoecarver Date: 2021-03-10T15:00:26-08:00 New Revision: a89ac0dd185d72607d4ee1356467fffc48711c9a
URL: https://github.com/llvm/llvm-project/commit/a89ac0dd185d72607d4ee1356467fffc48711c9a DIFF: https://github.com/llvm/llvm-project/commit/a89ac0dd185d72607d4ee1356467fffc48711c9a.diff LOG: Update __is_unsigned builtin to match the Standard. Updates __is_unsigned to have the same behavior as the standard specifies. This is in line with 511dbd8, which applied the same change to __is_signed. Refs D67897. Differential Revision: https://reviews.llvm.org/D98104 Added: Modified: clang/docs/LanguageExtensions.rst clang/lib/Sema/SemaExprCXX.cpp clang/test/SemaCXX/type-traits.cpp Removed: ################################################################################ diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst index 6c4cca0fe5e8..a906dc79e03b 100644 --- a/clang/docs/LanguageExtensions.rst +++ b/clang/docs/LanguageExtensions.rst @@ -1194,7 +1194,9 @@ The following type trait primitives are supported by Clang. Those traits marked * ``__is_sealed`` (Microsoft): Synonym for ``__is_final``. * ``__is_signed`` (C++, Embarcadero): - Returns false for enumeration types, and returns true for floating-point types. Note, before Clang 10, returned true for enumeration types if the underlying type was signed, and returned false for floating-point types. + Returns false for enumeration types, and returns true for floating-point + types. Note, before Clang 10, returned true for enumeration types if the + underlying type was signed, and returned false for floating-point types. * ``__is_standard_layout`` (C++, GNU, Microsoft, Embarcadero) * ``__is_trivial`` (C++, GNU, Microsoft, Embarcadero) * ``__is_trivially_assignable`` (C++, GNU, Microsoft) @@ -1202,10 +1204,9 @@ The following type trait primitives are supported by Clang. Those traits marked * ``__is_trivially_copyable`` (C++, GNU, Microsoft) * ``__is_trivially_destructible`` (C++, MSVC 2013) * ``__is_union`` (C++, GNU, Microsoft, Embarcadero) -* ``__is_unsigned`` (C++, Embarcadero) - Note that this currently returns true for enumeration types if the underlying - type is unsigned, in violation of the requirements for ``std::is_unsigned``. - This behavior is likely to change in a future version of Clang. +* ``__is_unsigned`` (C++, Embarcadero): + Returns false for enumeration types. Note, before Clang 13, returned true for + enumeration types if the underlying type was unsigned. * ``__is_void`` (C++, Embarcadero) * ``__is_volatile`` (C++, Embarcadero) * ``__reference_binds_to_temporary(T, U)`` (Clang): Determines whether a diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 6a79d621f5de..9dbe347e1c90 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -4856,9 +4856,11 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT, case UTT_IsSigned: // Enum types should always return false. // Floating points should always return true. - return !T->isEnumeralType() && (T->isFloatingType() || T->isSignedIntegerType()); + return T->isFloatingType() || + (T->isSignedIntegerType() && !T->isEnumeralType()); case UTT_IsUnsigned: - return T->isUnsignedIntegerType(); + // Enum types should always return false. + return T->isUnsignedIntegerType() && !T->isEnumeralType(); // Type trait expressions which query classes regarding their construction, // destruction, and copying. Rather than being based directly on the diff --git a/clang/test/SemaCXX/type-traits.cpp b/clang/test/SemaCXX/type-traits.cpp index 5adb1f99c27f..d576e4388d6f 100644 --- a/clang/test/SemaCXX/type-traits.cpp +++ b/clang/test/SemaCXX/type-traits.cpp @@ -13,6 +13,7 @@ typedef NonPOD NonPODArMB[10][2]; // PODs enum Enum { EV }; enum SignedEnum : signed int { }; +enum UnsignedEnum : unsigned int { }; struct POD { Enum e; int i; float f; NonPOD* p; }; struct Empty {}; struct IncompleteStruct; @@ -1440,6 +1441,7 @@ void is_signed() int t25[F(__is_signed(IntArNB))]; int t26[F(__is_signed(Union))]; int t27[F(__is_signed(UnionAr))]; + int t28[F(__is_signed(UnsignedEnum))]; } void is_unsigned() @@ -1450,7 +1452,6 @@ void is_unsigned() int t04[T(__is_unsigned(unsigned int))]; int t05[T(__is_unsigned(unsigned long))]; int t06[T(__is_unsigned(unsigned long long))]; - int t07[T(__is_unsigned(Enum))]; int t10[F(__is_unsigned(void))]; int t11[F(__is_unsigned(cvoid))]; @@ -1468,6 +1469,9 @@ void is_unsigned() int t24[F(__is_unsigned(Derives))]; int t25[F(__is_unsigned(ClassType))]; int t26[F(__is_unsigned(IntArNB))]; + int t27[F(__is_unsigned(Enum))]; + int t28[F(__is_unsigned(UnsignedEnum))]; + int t29[F(__is_unsigned(SignedEnum))]; } typedef Int& IntRef; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits