Author: zoecarver Date: Mon Sep 23 08:41:20 2019 New Revision: 372621 URL: http://llvm.org/viewvc/llvm-project?rev=372621&view=rev Log: Fix __is_signed builtin
Summary: This patch fixes the __is_signed builtin type trait to work with floating point types and enums. Now, the builtin will return true if it is passed a floating point type and false for an enum type. Reviewers: EricWF, rsmith, erichkeane, craig.topper, efriedma Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D67897 Modified: cfe/trunk/docs/LanguageExtensions.rst cfe/trunk/lib/Sema/SemaExprCXX.cpp cfe/trunk/test/SemaCXX/type-traits.cpp Modified: cfe/trunk/docs/LanguageExtensions.rst URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LanguageExtensions.rst?rev=372621&r1=372620&r2=372621&view=diff ============================================================================== --- cfe/trunk/docs/LanguageExtensions.rst (original) +++ cfe/trunk/docs/LanguageExtensions.rst Mon Sep 23 08:41:20 2019 @@ -1161,10 +1161,7 @@ The following type trait primitives are * ``__is_sealed`` (Microsoft): Synonym for ``__is_final``. * ``__is_signed`` (C++, Embarcadero): - Note that this currently returns true for enumeration types if the underlying - type is signed, and returns false for floating-point types, in violation of - the requirements for ``std::is_signed``. This behavior is likely to change in - a future version of Clang. + 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) Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=372621&r1=372620&r2=372621&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original) +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Mon Sep 23 08:41:20 2019 @@ -4605,7 +4605,9 @@ static bool EvaluateUnaryTypeTrait(Sema return RD->hasAttr<FinalAttr>(); return false; case UTT_IsSigned: - return T->isSignedIntegerType(); + // Enum types should always return false. + // Floating points should always return true. + return !T->isEnumeralType() && (T->isFloatingType() || T->isSignedIntegerType()); case UTT_IsUnsigned: return T->isUnsignedIntegerType(); Modified: cfe/trunk/test/SemaCXX/type-traits.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/type-traits.cpp?rev=372621&r1=372620&r2=372621&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/type-traits.cpp (original) +++ cfe/trunk/test/SemaCXX/type-traits.cpp Mon Sep 23 08:41:20 2019 @@ -12,6 +12,7 @@ typedef NonPOD NonPODArMB[10][2]; // PODs enum Enum { EV }; +enum SignedEnum : signed int { }; struct POD { Enum e; int i; float f; NonPOD* p; }; struct Empty {}; struct IncompleteStruct; @@ -56,14 +57,14 @@ struct HasInheritedCons : HasDefaultCons struct HasNoInheritedCons : HasCons {}; struct HasCopyAssign { HasCopyAssign operator =(const HasCopyAssign&); }; struct HasMoveAssign { HasMoveAssign operator =(const HasMoveAssign&&); }; -struct HasNoThrowMoveAssign { +struct HasNoThrowMoveAssign { HasNoThrowMoveAssign& operator=( const HasNoThrowMoveAssign&&) throw(); }; -struct HasNoExceptNoThrowMoveAssign { +struct HasNoExceptNoThrowMoveAssign { HasNoExceptNoThrowMoveAssign& operator=( - const HasNoExceptNoThrowMoveAssign&&) noexcept; + const HasNoExceptNoThrowMoveAssign&&) noexcept; }; -struct HasThrowMoveAssign { +struct HasThrowMoveAssign { HasThrowMoveAssign& operator=(const HasThrowMoveAssign&&) #if __cplusplus <= 201402L throw(POD); @@ -73,7 +74,7 @@ struct HasThrowMoveAssign { }; -struct HasNoExceptFalseMoveAssign { +struct HasNoExceptFalseMoveAssign { HasNoExceptFalseMoveAssign& operator=( const HasNoExceptFalseMoveAssign&&) noexcept(false); }; struct HasMoveCtor { HasMoveCtor(const HasMoveCtor&&); }; @@ -82,17 +83,17 @@ struct HasMemberMoveAssign { HasMoveAssi struct HasStaticMemberMoveCtor { static HasMoveCtor member; }; struct HasStaticMemberMoveAssign { static HasMoveAssign member; }; struct HasMemberThrowMoveAssign { HasThrowMoveAssign member; }; -struct HasMemberNoExceptFalseMoveAssign { +struct HasMemberNoExceptFalseMoveAssign { HasNoExceptFalseMoveAssign member; }; struct HasMemberNoThrowMoveAssign { HasNoThrowMoveAssign member; }; -struct HasMemberNoExceptNoThrowMoveAssign { +struct HasMemberNoExceptNoThrowMoveAssign { HasNoExceptNoThrowMoveAssign member; }; -struct HasDefaultTrivialCopyAssign { +struct HasDefaultTrivialCopyAssign { HasDefaultTrivialCopyAssign &operator=( - const HasDefaultTrivialCopyAssign&) = default; + const HasDefaultTrivialCopyAssign&) = default; }; -struct TrivialMoveButNotCopy { +struct TrivialMoveButNotCopy { TrivialMoveButNotCopy &operator=(TrivialMoveButNotCopy&&) = default; TrivialMoveButNotCopy &operator=(const TrivialMoveButNotCopy&); }; @@ -361,7 +362,7 @@ void is_enum() struct FinalClass final { }; -template<typename T> +template<typename T> struct PotentiallyFinal { }; template<typename T> @@ -1419,12 +1420,12 @@ void is_signed() int t04[T(__is_signed(short))]; int t05[T(__is_signed(signed char))]; int t06[T(__is_signed(wchar_t))]; + int t07[T(__is_signed(float))]; + int t08[T(__is_signed(double))]; + int t09[T(__is_signed(long double))]; - int t10[F(__is_signed(bool))]; - int t11[F(__is_signed(cvoid))]; - int t12[F(__is_signed(float))]; - int t13[F(__is_signed(double))]; - int t14[F(__is_signed(long double))]; + int t13[F(__is_signed(bool))]; + int t14[F(__is_signed(cvoid))]; int t15[F(__is_signed(unsigned char))]; int t16[F(__is_signed(unsigned int))]; int t17[F(__is_signed(unsigned long long))]; @@ -1434,9 +1435,10 @@ void is_signed() int t21[F(__is_signed(ClassType))]; int t22[F(__is_signed(Derives))]; int t23[F(__is_signed(Enum))]; - int t24[F(__is_signed(IntArNB))]; - int t25[F(__is_signed(Union))]; - int t26[F(__is_signed(UnionAr))]; + int t24[F(__is_signed(SignedEnum))]; + int t25[F(__is_signed(IntArNB))]; + int t26[F(__is_signed(Union))]; + int t27[F(__is_signed(UnionAr))]; } void is_unsigned() @@ -2005,7 +2007,7 @@ class PrivateCopy { }; template<typename T> -struct X0 { +struct X0 { template<typename U> X0(const X0<U>&); }; @@ -2766,7 +2768,7 @@ struct CanBeUniqueIfNoPadding : NotUniqu char b[7]; }; -static_assert(!has_unique_object_representations<NotUniqueBecauseTailPadding>::value, +static_assert(!has_unique_object_representations<NotUniqueBecauseTailPadding>::value, "non trivial"); // Can be unique on Itanium, since the is child class' data is 'folded' into the // parent's tail padding. _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits