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
This commit is contained in:
zoecarver 2021-03-10 14:59:38 -08:00
parent c0891706bc
commit a89ac0dd18
3 changed files with 15 additions and 8 deletions

View File

@ -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

View File

@ -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

View File

@ -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;