From 852afed5e0200b70047c28ccf4424a17089d17b0 Mon Sep 17 00:00:00 2001 From: Dmitri Gribenko Date: Thu, 3 Feb 2022 22:19:35 +0100 Subject: [PATCH] Revert "[clang] Mark `trivial_abi` types as "trivially relocatable"." This reverts commit 19aa2db023c0128913da223d4fb02c474541ee22. It breaks a PS4 buildbot. --- clang/docs/LanguageExtensions.rst | 5 --- clang/include/clang/AST/Type.h | 2 - clang/include/clang/Basic/AttrDocs.td | 3 -- clang/include/clang/Basic/TokenKinds.def | 1 - clang/lib/AST/Type.cpp | 19 -------- clang/lib/Sema/SemaExprCXX.cpp | 9 +--- clang/test/SemaCXX/attr-trivial-abi.cpp | 40 ----------------- clang/test/SemaCXX/type-traits.cpp | 61 -------------------------- clang/test/SemaObjCXX/arc-type-traits.mm | 10 +---- clang/test/SemaObjCXX/objc-weak-type-traits.mm | 11 +---- 10 files changed, 4 insertions(+), 157 deletions(-) diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst index e74539d..f848fb0 100644 --- a/clang/docs/LanguageExtensions.rst +++ b/clang/docs/LanguageExtensions.rst @@ -1365,11 +1365,6 @@ The following type trait primitives are supported by Clang. Those traits marked * ``__is_trivially_constructible`` (C++, GNU, Microsoft) * ``__is_trivially_copyable`` (C++, GNU, Microsoft) * ``__is_trivially_destructible`` (C++, MSVC 2013) -* ``__is_trivially_relocatable`` (Clang): Returns true if moving an object - of the given type, and then destroying the source object, is known to be - functionally equivalent to copying the underlying bytes and then dropping the - source object on the floor. This is true of trivial types and types which - were made trivially relocatable via the ``clang::trivial_abi`` attribute. * ``__is_union`` (C++, GNU, Microsoft, Embarcadero) * ``__is_unsigned`` (C++, Embarcadero): Returns false for enumeration types. Note, before Clang 13, returned true for diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 3c71cbb..a69c0ae 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -829,8 +829,6 @@ public: /// Return true if this is a trivially copyable type (C++0x [basic.types]p9) bool isTriviallyCopyableType(const ASTContext &Context) const; - /// Return true if this is a trivially relocatable type. - bool isTriviallyRelocatableType(const ASTContext &Context) const; /// Returns true if it is a class and it might be dynamic. bool mayBeDynamicClass() const; diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index e12a0b2..efd2af1 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -3295,9 +3295,6 @@ If a type is trivial for the purposes of calls, has a non-trivial destructor, and is passed as an argument by value, the convention is that the callee will destroy the object before returning. -If a type is trivial for the purpose of calls, it is assumed to be trivially -relocatable for the purpose of ``__is_trivially_relocatable``. - Attribute ``trivial_abi`` has no effect in the following cases: - The class directly declares a virtual base or virtual methods. diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def index b9d5cd7..e55244e 100644 --- a/clang/include/clang/Basic/TokenKinds.def +++ b/clang/include/clang/Basic/TokenKinds.def @@ -510,7 +510,6 @@ TYPE_TRAIT_1(__has_unique_object_representations, KEYWORD(__underlying_type , KEYCXX) // Clang-only C++ Type Traits -TYPE_TRAIT_1(__is_trivially_relocatable, IsTriviallyRelocatable, KEYCXX) TYPE_TRAIT_2(__reference_binds_to_temporary, ReferenceBindsToTemporary, KEYCXX) // Embarcadero Expression Traits diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 1c7499c..774b3e9 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -2495,25 +2495,6 @@ bool QualType::isTriviallyCopyableType(const ASTContext &Context) const { return false; } -bool QualType::isTriviallyRelocatableType(const ASTContext &Context) const { - QualType BaseElementType = Context.getBaseElementType(*this); - - if (BaseElementType->isIncompleteType()) { - return false; - } else if (const auto *RD = BaseElementType->getAsRecordDecl()) { - return RD->canPassInRegisters(); - } else { - switch (isNonTrivialToPrimitiveDestructiveMove()) { - case PCK_Trivial: - return !isDestructedType(); - case PCK_ARCStrong: - return true; - default: - return false; - } - } -} - bool QualType::isNonWeakInMRRWithObjCWeak(const ASTContext &Context) const { return !Context.getLangOpts().ObjCAutoRefCount && Context.getLangOpts().ObjCWeak && diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 0a8612a..7ce125f 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -11,6 +11,8 @@ /// //===----------------------------------------------------------------------===// +#include "clang/Sema/Template.h" +#include "clang/Sema/SemaInternal.h" #include "TreeTransform.h" #include "TypeLocBuilder.h" #include "clang/AST/ASTContext.h" @@ -25,7 +27,6 @@ #include "clang/Basic/AlignedAllocation.h" #include "clang/Basic/PartialDiagnostic.h" #include "clang/Basic/TargetInfo.h" -#include "clang/Basic/TypeTraits.h" #include "clang/Lex/Preprocessor.h" #include "clang/Sema/DeclSpec.h" #include "clang/Sema/Initialization.h" @@ -33,9 +34,7 @@ #include "clang/Sema/ParsedTemplate.h" #include "clang/Sema/Scope.h" #include "clang/Sema/ScopeInfo.h" -#include "clang/Sema/SemaInternal.h" #include "clang/Sema/SemaLambda.h" -#include "clang/Sema/Template.h" #include "clang/Sema/TemplateDeduction.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/STLExtras.h" @@ -4747,8 +4746,6 @@ static bool CheckUnaryTypeTraitTypeCompleteness(Sema &S, TypeTrait UTT, case UTT_IsStandardLayout: case UTT_IsPOD: case UTT_IsLiteral: - // By analogy, is_trivially_relocatable imposes the same constraints. - case UTT_IsTriviallyRelocatable: // Per the GCC type traits documentation, T shall be a complete type, cv void, // or an array of unknown bound. But GCC actually imposes the same constraints // as above. @@ -5213,8 +5210,6 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT, return !T->isIncompleteType(); case UTT_HasUniqueObjectRepresentations: return C.hasUniqueObjectRepresentations(T); - case UTT_IsTriviallyRelocatable: - return T.isTriviallyRelocatableType(C); } } diff --git a/clang/test/SemaCXX/attr-trivial-abi.cpp b/clang/test/SemaCXX/attr-trivial-abi.cpp index ffff5db..334b471 100644 --- a/clang/test/SemaCXX/attr-trivial-abi.cpp +++ b/clang/test/SemaCXX/attr-trivial-abi.cpp @@ -5,41 +5,27 @@ void __attribute__((trivial_abi)) foo(); // expected-warning {{'trivial_abi' att // Should not crash. template class __attribute__((trivial_abi)) a { a(a &&); }; -#ifdef _WIN32 -// On Windows, to be trivial-for-calls, an object must be trivially copyable. -// (And it is only trivially relocatable, currently, if it is trivial for calls.) -// In this case, it is suppressed by an explicitly defined move constructor. -// Similar concerns apply to later tests that have #ifdef _WIN32. -static_assert(!__is_trivially_relocatable(a), ""); -#else -static_assert(__is_trivially_relocatable(a), ""); -#endif struct [[clang::trivial_abi]] S0 { int a; }; -static_assert(__is_trivially_relocatable(S0), ""); struct __attribute__((trivial_abi)) S1 { int a; }; -static_assert(__is_trivially_relocatable(S1), ""); struct __attribute__((trivial_abi)) S3 { // expected-warning {{'trivial_abi' cannot be applied to 'S3'}} expected-note {{is polymorphic}} virtual void m(); }; -static_assert(!__is_trivially_relocatable(S3), ""); struct S3_2 { virtual void m(); } __attribute__((trivial_abi)); // expected-warning {{'trivial_abi' cannot be applied to 'S3_2'}} expected-note {{is polymorphic}} -static_assert(!__is_trivially_relocatable(S3_2), ""); struct __attribute__((trivial_abi)) S3_3 { // expected-warning {{'trivial_abi' cannot be applied to 'S3_3'}} expected-note {{has a field of a non-trivial class type}} S3_3(S3_3 &&); S3_2 s32; }; -static_assert(!__is_trivially_relocatable(S3_3), ""); // Diagnose invalid trivial_abi even when the type is templated because it has a non-trivial field. template @@ -47,20 +33,16 @@ struct __attribute__((trivial_abi)) S3_4 { // expected-warning {{'trivial_abi' c S3_4(S3_4 &&); S3_2 s32; }; -static_assert(!__is_trivially_relocatable(S3_4), ""); struct S4 { int a; }; -static_assert(__is_trivially_relocatable(S4), ""); struct __attribute__((trivial_abi)) S5 : public virtual S4 { // expected-warning {{'trivial_abi' cannot be applied to 'S5'}} expected-note {{has a virtual base}} }; -static_assert(!__is_trivially_relocatable(S5), ""); struct __attribute__((trivial_abi)) S9 : public S4 { }; -static_assert(__is_trivially_relocatable(S9), ""); struct __attribute__((trivial_abi(1))) S8 { // expected-error {{'trivial_abi' attribute takes no arguments}} int a; @@ -73,8 +55,6 @@ struct __attribute__((trivial_abi)) S10 { }; S10 p1; -static_assert(__is_trivially_relocatable(S10), ""); -static_assert(!__is_trivially_relocatable(S10), ""); template struct S14 { @@ -86,15 +66,11 @@ struct __attribute__((trivial_abi)) S15 : S14 { }; S15 s15; -static_assert(__is_trivially_relocatable(S15), ""); -static_assert(!__is_trivially_relocatable(S15), ""); template struct __attribute__((trivial_abi)) S16 { S14 a; }; -static_assert(__is_trivially_relocatable(S16), ""); -static_assert(!__is_trivially_relocatable(S16), ""); S16 s16; @@ -103,50 +79,34 @@ struct __attribute__((trivial_abi)) S17 { }; S17 s17; -static_assert(__is_trivially_relocatable(S17), ""); -static_assert(__is_trivially_relocatable(S17), ""); namespace deletedCopyMoveConstructor { struct __attribute__((trivial_abi)) CopyMoveDeleted { // expected-warning {{'trivial_abi' cannot be applied to 'CopyMoveDeleted'}} expected-note {{copy constructors and move constructors are all deleted}} CopyMoveDeleted(const CopyMoveDeleted &) = delete; CopyMoveDeleted(CopyMoveDeleted &&) = delete; }; -static_assert(!__is_trivially_relocatable(CopyMoveDeleted), ""); struct __attribute__((trivial_abi)) S18 { // expected-warning {{'trivial_abi' cannot be applied to 'S18'}} expected-note {{copy constructors and move constructors are all deleted}} CopyMoveDeleted a; }; -static_assert(!__is_trivially_relocatable(S18), ""); struct __attribute__((trivial_abi)) CopyDeleted { CopyDeleted(const CopyDeleted &) = delete; CopyDeleted(CopyDeleted &&) = default; }; -#ifdef _WIN32 -static_assert(!__is_trivially_relocatable(CopyDeleted), ""); -#else -static_assert(__is_trivially_relocatable(CopyDeleted), ""); -#endif struct __attribute__((trivial_abi)) MoveDeleted { MoveDeleted(const MoveDeleted &) = default; MoveDeleted(MoveDeleted &&) = delete; }; -static_assert(__is_trivially_relocatable(MoveDeleted), ""); struct __attribute__((trivial_abi)) S19 { // expected-warning {{'trivial_abi' cannot be applied to 'S19'}} expected-note {{copy constructors and move constructors are all deleted}} CopyDeleted a; MoveDeleted b; }; -static_assert(!__is_trivially_relocatable(S19), ""); // This is fine since the move constructor isn't deleted. struct __attribute__((trivial_abi)) S20 { int &&a; // a member of rvalue reference type deletes the copy constructor. }; -#ifdef _WIN32 -static_assert(!__is_trivially_relocatable(S20), ""); -#else -static_assert(__is_trivially_relocatable(S20), ""); -#endif } // namespace deletedCopyMoveConstructor diff --git a/clang/test/SemaCXX/type-traits.cpp b/clang/test/SemaCXX/type-traits.cpp index e46908e..d576e438 100644 --- a/clang/test/SemaCXX/type-traits.cpp +++ b/clang/test/SemaCXX/type-traits.cpp @@ -2854,64 +2854,3 @@ void test() { (void) __is_constructible(int, T32768(int)); } #undef T16384 #undef T32768 } // namespace type_trait_expr_numargs_overflow - -namespace is_trivially_relocatable { - -static_assert(!__is_trivially_relocatable(void), ""); -static_assert(__is_trivially_relocatable(int), ""); -static_assert(__is_trivially_relocatable(int[]), ""); - -enum Enum {}; -static_assert(__is_trivially_relocatable(Enum), ""); -static_assert(__is_trivially_relocatable(Enum[]), ""); - -union Union {int x;}; -static_assert(__is_trivially_relocatable(Union), ""); -static_assert(__is_trivially_relocatable(Union[]), ""); - -struct Trivial {}; -static_assert(__is_trivially_relocatable(Trivial), ""); -static_assert(__is_trivially_relocatable(Trivial[]), ""); - -struct Incomplete; // expected-note {{forward declaration of 'is_trivially_relocatable::Incomplete'}} -bool unused = __is_trivially_relocatable(Incomplete); // expected-error {{incomplete type}} - -struct NontrivialDtor { - ~NontrivialDtor() {} -}; -static_assert(!__is_trivially_relocatable(NontrivialDtor), ""); -static_assert(!__is_trivially_relocatable(NontrivialDtor[]), ""); - -struct NontrivialCopyCtor { - NontrivialCopyCtor(const NontrivialCopyCtor&) {} -}; -static_assert(!__is_trivially_relocatable(NontrivialCopyCtor), ""); -static_assert(!__is_trivially_relocatable(NontrivialCopyCtor[]), ""); - -struct NontrivialMoveCtor { - NontrivialMoveCtor(NontrivialMoveCtor&&) {} -}; -static_assert(!__is_trivially_relocatable(NontrivialMoveCtor), ""); -static_assert(!__is_trivially_relocatable(NontrivialMoveCtor[]), ""); - -struct [[clang::trivial_abi]] TrivialAbiNontrivialDtor { - ~TrivialAbiNontrivialDtor() {} -}; -static_assert(__is_trivially_relocatable(TrivialAbiNontrivialDtor), ""); -static_assert(__is_trivially_relocatable(TrivialAbiNontrivialDtor[]), ""); - -struct [[clang::trivial_abi]] TrivialAbiNontrivialCopyCtor { - TrivialAbiNontrivialCopyCtor(const TrivialAbiNontrivialCopyCtor&) {} -}; -static_assert(__is_trivially_relocatable(TrivialAbiNontrivialCopyCtor), ""); -static_assert(__is_trivially_relocatable(TrivialAbiNontrivialCopyCtor[]), ""); - -// A more complete set of tests for the behavior of trivial_abi can be found in -// clang/test/SemaCXX/attr-trivial-abi.cpp -struct [[clang::trivial_abi]] TrivialAbiNontrivialMoveCtor { - TrivialAbiNontrivialMoveCtor(TrivialAbiNontrivialMoveCtor&&) {} -}; -static_assert(__is_trivially_relocatable(TrivialAbiNontrivialMoveCtor), ""); -static_assert(__is_trivially_relocatable(TrivialAbiNontrivialMoveCtor[]), ""); - -} // namespace is_trivially_relocatable diff --git a/clang/test/SemaObjCXX/arc-type-traits.mm b/clang/test/SemaObjCXX/arc-type-traits.mm index 8694fe7..12993a9 100644 --- a/clang/test/SemaObjCXX/arc-type-traits.mm +++ b/clang/test/SemaObjCXX/arc-type-traits.mm @@ -12,7 +12,7 @@ #define TRAIT_IS_FALSE(Trait, Type) char JOIN2(Trait,__LINE__)[Trait(Type)? -1 : 1] #define TRAIT_IS_TRUE_2(Trait, Type1, Type2) char JOIN2(Trait,__LINE__)[Trait(Type1, Type2)? 1 : -1] #define TRAIT_IS_FALSE_2(Trait, Type1, Type2) char JOIN2(Trait,__LINE__)[Trait(Type1, Type2)? -1 : 1] - + struct HasStrong { id obj; }; struct HasWeak { __weak id obj; }; struct HasUnsafeUnretained { __unsafe_unretained id obj; }; @@ -213,11 +213,3 @@ TRAIT_IS_FALSE_2(__is_trivially_constructible, HasWeak, HasWeak&&); TRAIT_IS_TRUE_2(__is_trivially_constructible, HasUnsafeUnretained, HasUnsafeUnretained); TRAIT_IS_TRUE_2(__is_trivially_constructible, HasUnsafeUnretained, HasUnsafeUnretained&&); -// __is_trivially_relocatable -TRAIT_IS_TRUE(__is_trivially_relocatable, __strong id); -TRAIT_IS_FALSE(__is_trivially_relocatable, __weak id); -TRAIT_IS_TRUE(__is_trivially_relocatable, __autoreleasing id); -TRAIT_IS_TRUE(__is_trivially_relocatable, __unsafe_unretained id); -TRAIT_IS_TRUE(__is_trivially_relocatable, HasStrong); -TRAIT_IS_FALSE(__is_trivially_relocatable, HasWeak); -TRAIT_IS_TRUE(__is_trivially_relocatable, HasUnsafeUnretained); diff --git a/clang/test/SemaObjCXX/objc-weak-type-traits.mm b/clang/test/SemaObjCXX/objc-weak-type-traits.mm index 423f228..f425f47 100644 --- a/clang/test/SemaObjCXX/objc-weak-type-traits.mm +++ b/clang/test/SemaObjCXX/objc-weak-type-traits.mm @@ -8,7 +8,7 @@ #define TRAIT_IS_FALSE(Trait, Type) static_assert(!Trait(Type), "") #define TRAIT_IS_TRUE_2(Trait, Type1, Type2) static_assert(Trait(Type1, Type2), "") #define TRAIT_IS_FALSE_2(Trait, Type1, Type2) static_assert(!Trait(Type1, Type2), "") - + struct HasStrong { id obj; }; struct HasWeak { __weak id obj; }; struct HasUnsafeUnretained { __unsafe_unretained id obj; }; @@ -208,12 +208,3 @@ TRAIT_IS_FALSE_2(__is_trivially_constructible, HasWeak, HasWeak); TRAIT_IS_FALSE_2(__is_trivially_constructible, HasWeak, HasWeak&&); TRAIT_IS_TRUE_2(__is_trivially_constructible, HasUnsafeUnretained, HasUnsafeUnretained); TRAIT_IS_TRUE_2(__is_trivially_constructible, HasUnsafeUnretained, HasUnsafeUnretained&&); - -// __is_trivially_relocatable -TRAIT_IS_TRUE(__is_trivially_relocatable, __strong id); -TRAIT_IS_FALSE(__is_trivially_relocatable, __weak id); -TRAIT_IS_TRUE(__is_trivially_relocatable, __autoreleasing id); -TRAIT_IS_TRUE(__is_trivially_relocatable, __unsafe_unretained id); -TRAIT_IS_TRUE(__is_trivially_relocatable, HasStrong); -TRAIT_IS_FALSE(__is_trivially_relocatable, HasWeak); -TRAIT_IS_TRUE(__is_trivially_relocatable, HasUnsafeUnretained); -- 2.7.4