https://github.com/Endilll updated https://github.com/llvm/llvm-project/pull/96097
>From b77b2d9b10ad90ee67893904732003bf11eec21d Mon Sep 17 00:00:00 2001 From: Corentin Jabot <corentinja...@gmail.com> Date: Wed, 19 Jun 2024 19:47:43 +0200 Subject: [PATCH 1/3] [Clang] Move the builtin workaround logic to the lexer --- .../include/clang/Basic/DiagnosticLexKinds.td | 4 + clang/include/clang/Basic/IdentifierTable.h | 19 +++- clang/include/clang/Parse/Parser.h | 4 - clang/lib/Basic/IdentifierTable.cpp | 75 +++++++++++++++ clang/lib/Lex/Preprocessor.cpp | 5 + clang/lib/Parse/ParseDecl.cpp | 19 +--- clang/lib/Parse/ParseDeclCXX.cpp | 71 --------------- clang/lib/Parse/ParseExpr.cpp | 91 ------------------- clang/test/SemaCXX/libstdcxx_is_pod_hack.cpp | 14 +-- 9 files changed, 109 insertions(+), 193 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.td b/clang/include/clang/Basic/DiagnosticLexKinds.td index 25fbfe83fa2bc..372d549dc59ba 100644 --- a/clang/include/clang/Basic/DiagnosticLexKinds.td +++ b/clang/include/clang/Basic/DiagnosticLexKinds.td @@ -85,6 +85,10 @@ def warn_c99_keyword : Warning<"'%0' is a keyword in C99">, def warn_c23_keyword : Warning<"'%0' is a keyword in C23">, InGroup<C23Compat>, DefaultIgnore; +def warn_deprecated_builtin_replacement : Warning< + "using the name of the builtin '%0' outside of " + "a builtin invocation is deprecated">, InGroup<KeywordCompat>; + def ext_unterminated_char_or_string : ExtWarn< "missing terminating %select{'|'\"'}0 character">, InGroup<InvalidPPToken>; def ext_empty_character : ExtWarn<"empty character constant">, diff --git a/clang/include/clang/Basic/IdentifierTable.h b/clang/include/clang/Basic/IdentifierTable.h index ae9ebd9f59154..00d1f9b7c9949 100644 --- a/clang/include/clang/Basic/IdentifierTable.h +++ b/clang/include/clang/Basic/IdentifierTable.h @@ -196,6 +196,9 @@ class alignas(IdentifierInfoAlignment) IdentifierInfo { LLVM_PREFERRED_TYPE(bool) unsigned IsFinal : 1; + LLVM_PREFERRED_TYPE(bool) + unsigned IsReusableBuiltinName : 1; + // 22 bits left in a 64-bit word. // Managed by the language front-end. @@ -213,7 +216,8 @@ class alignas(IdentifierInfoAlignment) IdentifierInfo { IsFromAST(false), ChangedAfterLoad(false), FEChangedAfterLoad(false), RevertedTokenID(false), OutOfDate(false), IsModulesImport(false), IsMangledOpenMPVariantName(false), IsDeprecatedMacro(false), - IsRestrictExpansion(false), IsFinal(false) {} + IsRestrictExpansion(false), IsFinal(false), + IsReusableBuiltinName(false) {} public: IdentifierInfo(const IdentifierInfo &) = delete; @@ -332,6 +336,16 @@ class alignas(IdentifierInfoAlignment) IdentifierInfo { RevertedTokenID = false; } + bool isReusableBuiltinName() const { return IsReusableBuiltinName; }; + + void setIsReusableBuiltinName(bool Val) { + IsReusableBuiltinName = Val; + if (Val) + NeedsHandleIdentifier = true; + else + RecomputeNeedsHandleIdentifier(); + }; + /// Return the preprocessor keyword ID for this identifier. /// /// For example, "define" will return tok::pp_define. @@ -569,7 +583,8 @@ class alignas(IdentifierInfoAlignment) IdentifierInfo { void RecomputeNeedsHandleIdentifier() { NeedsHandleIdentifier = isPoisoned() || hasMacroDefinition() || isExtensionToken() || isFutureCompatKeyword() || - isOutOfDate() || isModulesImport(); + isReusableBuiltinName() || isOutOfDate() || + isModulesImport(); } }; diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index d054b8cf0d240..ed5d32bf5e076 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -169,10 +169,6 @@ class Parser : public CodeCompletionHandler { mutable IdentifierInfo *Ident_import; mutable IdentifierInfo *Ident_module; - // C++ type trait keywords that can be reverted to identifiers and still be - // used as type traits. - llvm::SmallDenseMap<IdentifierInfo *, tok::TokenKind> RevertibleTypeTraits; - std::unique_ptr<PragmaHandler> AlignHandler; std::unique_ptr<PragmaHandler> GCCVisibilityHandler; std::unique_ptr<PragmaHandler> OptionsHandler; diff --git a/clang/lib/Basic/IdentifierTable.cpp b/clang/lib/Basic/IdentifierTable.cpp index feea84544d62f..f2f2fb822a378 100644 --- a/clang/lib/Basic/IdentifierTable.cpp +++ b/clang/lib/Basic/IdentifierTable.cpp @@ -246,6 +246,79 @@ static KeywordStatus getKeywordStatus(const LangOptions &LangOpts, return CurStatus; } +static bool isReusableBuiltinName(tok::TokenKind TokenCode) { +#define RTT_JOIN(X, Y) X##Y +#define REVERTIBLE_TYPE_TRAIT(Name) \ + case RTT_JOIN(tok::kw_, Name): \ + return true; + + switch (TokenCode) { + default: + return false; + REVERTIBLE_TYPE_TRAIT(__is_abstract); + REVERTIBLE_TYPE_TRAIT(__is_aggregate); + REVERTIBLE_TYPE_TRAIT(__is_arithmetic); + REVERTIBLE_TYPE_TRAIT(__is_array); + REVERTIBLE_TYPE_TRAIT(__is_assignable); + REVERTIBLE_TYPE_TRAIT(__is_base_of); + REVERTIBLE_TYPE_TRAIT(__is_bounded_array); + REVERTIBLE_TYPE_TRAIT(__is_class); + REVERTIBLE_TYPE_TRAIT(__is_complete_type); + REVERTIBLE_TYPE_TRAIT(__is_compound); + REVERTIBLE_TYPE_TRAIT(__is_const); + REVERTIBLE_TYPE_TRAIT(__is_constructible); + REVERTIBLE_TYPE_TRAIT(__is_convertible); + REVERTIBLE_TYPE_TRAIT(__is_convertible_to); + REVERTIBLE_TYPE_TRAIT(__is_destructible); + REVERTIBLE_TYPE_TRAIT(__is_empty); + REVERTIBLE_TYPE_TRAIT(__is_enum); + REVERTIBLE_TYPE_TRAIT(__is_floating_point); + REVERTIBLE_TYPE_TRAIT(__is_final); + REVERTIBLE_TYPE_TRAIT(__is_function); + REVERTIBLE_TYPE_TRAIT(__is_fundamental); + REVERTIBLE_TYPE_TRAIT(__is_integral); + REVERTIBLE_TYPE_TRAIT(__is_interface_class); + REVERTIBLE_TYPE_TRAIT(__is_layout_compatible); + REVERTIBLE_TYPE_TRAIT(__is_literal); + REVERTIBLE_TYPE_TRAIT(__is_lvalue_expr); + REVERTIBLE_TYPE_TRAIT(__is_lvalue_reference); + REVERTIBLE_TYPE_TRAIT(__is_member_function_pointer); + REVERTIBLE_TYPE_TRAIT(__is_member_object_pointer); + REVERTIBLE_TYPE_TRAIT(__is_member_pointer); + REVERTIBLE_TYPE_TRAIT(__is_nothrow_assignable); + REVERTIBLE_TYPE_TRAIT(__is_nothrow_constructible); + REVERTIBLE_TYPE_TRAIT(__is_nothrow_destructible); + REVERTIBLE_TYPE_TRAIT(__is_nothrow_convertible); + REVERTIBLE_TYPE_TRAIT(__is_nullptr); + REVERTIBLE_TYPE_TRAIT(__is_object); + REVERTIBLE_TYPE_TRAIT(__is_pod); + REVERTIBLE_TYPE_TRAIT(__is_pointer); + REVERTIBLE_TYPE_TRAIT(__is_polymorphic); + REVERTIBLE_TYPE_TRAIT(__is_reference); + REVERTIBLE_TYPE_TRAIT(__is_referenceable); + REVERTIBLE_TYPE_TRAIT(__is_rvalue_expr); + REVERTIBLE_TYPE_TRAIT(__is_rvalue_reference); + REVERTIBLE_TYPE_TRAIT(__is_same); + REVERTIBLE_TYPE_TRAIT(__is_scalar); + REVERTIBLE_TYPE_TRAIT(__is_scoped_enum); + REVERTIBLE_TYPE_TRAIT(__is_sealed); + REVERTIBLE_TYPE_TRAIT(__is_signed); + REVERTIBLE_TYPE_TRAIT(__is_standard_layout); + REVERTIBLE_TYPE_TRAIT(__is_trivial); + REVERTIBLE_TYPE_TRAIT(__is_trivially_assignable); + REVERTIBLE_TYPE_TRAIT(__is_trivially_constructible); + REVERTIBLE_TYPE_TRAIT(__is_trivially_copyable); + REVERTIBLE_TYPE_TRAIT(__is_trivially_equality_comparable); + REVERTIBLE_TYPE_TRAIT(__is_unbounded_array); + REVERTIBLE_TYPE_TRAIT(__is_union); + REVERTIBLE_TYPE_TRAIT(__is_unsigned); + REVERTIBLE_TYPE_TRAIT(__is_void); + REVERTIBLE_TYPE_TRAIT(__is_volatile); + REVERTIBLE_TYPE_TRAIT(__reference_binds_to_temporary); + } + return false; +} + /// AddKeyword - This method is used to associate a token ID with specific /// identifiers because they are language keywords. This causes the lexer to /// automatically map matching identifiers to specialized token codes. @@ -261,6 +334,8 @@ static void AddKeyword(StringRef Keyword, Table.get(Keyword, AddResult == KS_Future ? tok::identifier : TokenCode); Info.setIsExtensionToken(AddResult == KS_Extension); Info.setIsFutureCompatKeyword(AddResult == KS_Future); + Info.setIsReusableBuiltinName(LangOpts.CPlusPlus && + isReusableBuiltinName(TokenCode)); } /// AddCXXOperatorKeyword - Register a C++ operator keyword alternative diff --git a/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp index 44b69a58f3411..7fb1e4db3b87e 100644 --- a/clang/lib/Lex/Preprocessor.cpp +++ b/clang/lib/Lex/Preprocessor.cpp @@ -837,6 +837,11 @@ bool Preprocessor::HandleIdentifier(Token &Identifier) { II.setIsFutureCompatKeyword(false); } + if (II.isReusableBuiltinName() && !isNextPPTokenLParen()) { + Identifier.setKind(tok::identifier); + Diag(Identifier, diag::warn_deprecated_builtin_replacement) << II.getName(); + } + // If this is an extension token, diagnose its use. // We avoid diagnosing tokens that originate from macro definitions. // FIXME: This warning is disabled in cases where it shouldn't be, diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index c528917437332..c1dea20e298f0 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -3906,24 +3906,7 @@ void Parser::ParseDeclarationSpecifiers( continue; } - - case tok::kw___is_signed: - // GNU libstdc++ 4.4 uses __is_signed as an identifier, but Clang - // typically treats it as a trait. If we see __is_signed as it appears - // in libstdc++, e.g., - // - // static const bool __is_signed; - // - // then treat __is_signed as an identifier rather than as a keyword. - if (DS.getTypeSpecType() == TST_bool && - DS.getTypeQualifiers() == DeclSpec::TQ_const && - DS.getStorageClassSpec() == DeclSpec::SCS_static) - TryKeywordIdentFallback(true); - - // We're done with the declaration-specifiers. - goto DoneWithDeclSpec; - - // typedef-name + // typedef-name case tok::kw___super: case tok::kw_decltype: case tok::identifier: diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index d02548f6441f9..e863f24770b10 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -1718,77 +1718,6 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, // C++11 attributes SourceLocation AttrFixitLoc = Tok.getLocation(); - if (TagType == DeclSpec::TST_struct && Tok.isNot(tok::identifier) && - !Tok.isAnnotation() && Tok.getIdentifierInfo() && - Tok.isOneOf( -#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) tok::kw___##Trait, -#include "clang/Basic/TransformTypeTraits.def" - tok::kw___is_abstract, - tok::kw___is_aggregate, - tok::kw___is_arithmetic, - tok::kw___is_array, - tok::kw___is_assignable, - tok::kw___is_base_of, - tok::kw___is_bounded_array, - tok::kw___is_class, - tok::kw___is_complete_type, - tok::kw___is_compound, - tok::kw___is_const, - tok::kw___is_constructible, - tok::kw___is_convertible, - tok::kw___is_convertible_to, - tok::kw___is_destructible, - tok::kw___is_empty, - tok::kw___is_enum, - tok::kw___is_floating_point, - tok::kw___is_final, - tok::kw___is_function, - tok::kw___is_fundamental, - tok::kw___is_integral, - tok::kw___is_interface_class, - tok::kw___is_literal, - tok::kw___is_lvalue_expr, - tok::kw___is_lvalue_reference, - tok::kw___is_member_function_pointer, - tok::kw___is_member_object_pointer, - tok::kw___is_member_pointer, - tok::kw___is_nothrow_assignable, - tok::kw___is_nothrow_constructible, - tok::kw___is_nothrow_convertible, - tok::kw___is_nothrow_destructible, - tok::kw___is_nullptr, - tok::kw___is_object, - tok::kw___is_pod, - tok::kw___is_pointer, - tok::kw___is_polymorphic, - tok::kw___is_reference, - tok::kw___is_referenceable, - tok::kw___is_rvalue_expr, - tok::kw___is_rvalue_reference, - tok::kw___is_same, - tok::kw___is_scalar, - tok::kw___is_scoped_enum, - tok::kw___is_sealed, - tok::kw___is_signed, - tok::kw___is_standard_layout, - tok::kw___is_trivial, - tok::kw___is_trivially_equality_comparable, - tok::kw___is_trivially_assignable, - tok::kw___is_trivially_constructible, - tok::kw___is_trivially_copyable, - tok::kw___is_unbounded_array, - tok::kw___is_union, - tok::kw___is_unsigned, - tok::kw___is_void, - tok::kw___is_volatile - )) - // GNU libstdc++ 4.2 and libc++ use certain intrinsic names as the - // name of struct templates, but some are keywords in GCC >= 4.3 - // and Clang. Therefore, when we see the token sequence "struct - // X", make X into a normal identifier rather than a keyword, to - // allow libstdc++ 4.2 and libc++ to work properly. - TryKeywordIdentFallback(true); - struct PreserveAtomicIdentifierInfoRAII { PreserveAtomicIdentifierInfoRAII(Token &Tok, bool Enabled) : AtomicII(nullptr) { diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index eb7447fa038e4..baea7df1d88d1 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -1097,97 +1097,6 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind, isVectorLiteral, NotPrimaryExpression); } - // If this identifier was reverted from a token ID, and the next token - // is a parenthesis, this is likely to be a use of a type trait. Check - // those tokens. - else if (Next.is(tok::l_paren) && Tok.is(tok::identifier) && - Tok.getIdentifierInfo()->hasRevertedTokenIDToIdentifier()) { - IdentifierInfo *II = Tok.getIdentifierInfo(); - // Build up the mapping of revertible type traits, for future use. - if (RevertibleTypeTraits.empty()) { -#define RTT_JOIN(X,Y) X##Y -#define REVERTIBLE_TYPE_TRAIT(Name) \ - RevertibleTypeTraits[PP.getIdentifierInfo(#Name)] \ - = RTT_JOIN(tok::kw_,Name) - - REVERTIBLE_TYPE_TRAIT(__is_abstract); - REVERTIBLE_TYPE_TRAIT(__is_aggregate); - REVERTIBLE_TYPE_TRAIT(__is_arithmetic); - REVERTIBLE_TYPE_TRAIT(__is_array); - REVERTIBLE_TYPE_TRAIT(__is_assignable); - REVERTIBLE_TYPE_TRAIT(__is_base_of); - REVERTIBLE_TYPE_TRAIT(__is_bounded_array); - REVERTIBLE_TYPE_TRAIT(__is_class); - REVERTIBLE_TYPE_TRAIT(__is_complete_type); - REVERTIBLE_TYPE_TRAIT(__is_compound); - REVERTIBLE_TYPE_TRAIT(__is_const); - REVERTIBLE_TYPE_TRAIT(__is_constructible); - REVERTIBLE_TYPE_TRAIT(__is_convertible); - REVERTIBLE_TYPE_TRAIT(__is_convertible_to); - REVERTIBLE_TYPE_TRAIT(__is_destructible); - REVERTIBLE_TYPE_TRAIT(__is_empty); - REVERTIBLE_TYPE_TRAIT(__is_enum); - REVERTIBLE_TYPE_TRAIT(__is_floating_point); - REVERTIBLE_TYPE_TRAIT(__is_final); - REVERTIBLE_TYPE_TRAIT(__is_function); - REVERTIBLE_TYPE_TRAIT(__is_fundamental); - REVERTIBLE_TYPE_TRAIT(__is_integral); - REVERTIBLE_TYPE_TRAIT(__is_interface_class); - REVERTIBLE_TYPE_TRAIT(__is_layout_compatible); - REVERTIBLE_TYPE_TRAIT(__is_literal); - REVERTIBLE_TYPE_TRAIT(__is_lvalue_expr); - REVERTIBLE_TYPE_TRAIT(__is_lvalue_reference); - REVERTIBLE_TYPE_TRAIT(__is_member_function_pointer); - REVERTIBLE_TYPE_TRAIT(__is_member_object_pointer); - REVERTIBLE_TYPE_TRAIT(__is_member_pointer); - REVERTIBLE_TYPE_TRAIT(__is_nothrow_assignable); - REVERTIBLE_TYPE_TRAIT(__is_nothrow_constructible); - REVERTIBLE_TYPE_TRAIT(__is_nothrow_destructible); - REVERTIBLE_TYPE_TRAIT(__is_nullptr); - REVERTIBLE_TYPE_TRAIT(__is_object); - REVERTIBLE_TYPE_TRAIT(__is_pod); - REVERTIBLE_TYPE_TRAIT(__is_pointer); - REVERTIBLE_TYPE_TRAIT(__is_polymorphic); - REVERTIBLE_TYPE_TRAIT(__is_reference); - REVERTIBLE_TYPE_TRAIT(__is_referenceable); - REVERTIBLE_TYPE_TRAIT(__is_rvalue_expr); - REVERTIBLE_TYPE_TRAIT(__is_rvalue_reference); - REVERTIBLE_TYPE_TRAIT(__is_same); - REVERTIBLE_TYPE_TRAIT(__is_scalar); - REVERTIBLE_TYPE_TRAIT(__is_scoped_enum); - REVERTIBLE_TYPE_TRAIT(__is_sealed); - REVERTIBLE_TYPE_TRAIT(__is_signed); - REVERTIBLE_TYPE_TRAIT(__is_standard_layout); - REVERTIBLE_TYPE_TRAIT(__is_trivial); - REVERTIBLE_TYPE_TRAIT(__is_trivially_assignable); - REVERTIBLE_TYPE_TRAIT(__is_trivially_constructible); - REVERTIBLE_TYPE_TRAIT(__is_trivially_copyable); - REVERTIBLE_TYPE_TRAIT(__is_unbounded_array); - REVERTIBLE_TYPE_TRAIT(__is_union); - REVERTIBLE_TYPE_TRAIT(__is_unsigned); - REVERTIBLE_TYPE_TRAIT(__is_void); - REVERTIBLE_TYPE_TRAIT(__is_volatile); - REVERTIBLE_TYPE_TRAIT(__reference_binds_to_temporary); -#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) \ - REVERTIBLE_TYPE_TRAIT(RTT_JOIN(__, Trait)); -#include "clang/Basic/TransformTypeTraits.def" -#undef REVERTIBLE_TYPE_TRAIT -#undef RTT_JOIN - } - - // If we find that this is in fact the name of a type trait, - // update the token kind in place and parse again to treat it as - // the appropriate kind of type trait. - llvm::SmallDenseMap<IdentifierInfo *, tok::TokenKind>::iterator Known - = RevertibleTypeTraits.find(II); - if (Known != RevertibleTypeTraits.end()) { - Tok.setKind(Known->second); - return ParseCastExpression(ParseKind, isAddressOfOperand, - NotCastExpr, isTypeCast, - isVectorLiteral, NotPrimaryExpression); - } - } - else if ((!ColonIsSacred && Next.is(tok::colon)) || Next.isOneOf(tok::coloncolon, tok::less, tok::l_paren, tok::l_brace)) { diff --git a/clang/test/SemaCXX/libstdcxx_is_pod_hack.cpp b/clang/test/SemaCXX/libstdcxx_is_pod_hack.cpp index a853a484707df..f787ee7092836 100644 --- a/clang/test/SemaCXX/libstdcxx_is_pod_hack.cpp +++ b/clang/test/SemaCXX/libstdcxx_is_pod_hack.cpp @@ -7,27 +7,27 @@ // a keyword *unless* it is introduced following the struct keyword. template<typename T> -struct __is_pod { // expected-warning {{keyword '__is_pod' will be made available as an identifier}} - __is_pod() {} +struct __is_pod { // expected-warning {{using the name of the builtin '__is_pod' outside of a builtin invocation is deprecated}} + __is_pod() {} // expected-error {{expected member name or ';' after declaration specifier}} }; -__is_pod<int> ipi; +__is_pod<int> ipi; // expected-warning {{using the name of the builtin '__is_pod' outside of a builtin invocation is deprecated}} // Ditto for __is_same. template<typename T> -struct __is_same { // expected-warning {{keyword '__is_same' will be made available as an identifier}} +struct __is_same { // expected-warning {{using the name of the builtin '__is_same' outside of a builtin invocation is deprecated}} }; -__is_same<int> isi; +__is_same<int> isi; // expected-warning {{using the name of the builtin '__is_same' outside of a builtin invocation is deprecated}} // Another, similar egregious hack for __is_signed, which is a type // trait in Embarcadero's compiler but is used as an identifier in // libstdc++. struct test_is_signed { - static const bool __is_signed = true; // expected-warning {{keyword '__is_signed' will be made available as an identifier}} + static const bool __is_signed = true; // expected-warning {{using the name of the builtin '__is_signed' outside of a builtin invocation is deprecated}} }; -bool check_signed = test_is_signed::__is_signed; +bool check_signed = test_is_signed::__is_signed; // expected-warning {{using the name of the builtin '__is_signed' outside of a builtin invocation is deprecated}} template<bool B> struct must_be_true {}; template<> struct must_be_true<false>; >From 908f40240cc2fa3d414afdf68d452df7a34b13cf Mon Sep 17 00:00:00 2001 From: Vlad Serebrennikov <serebrennikov.vladis...@gmail.com> Date: Fri, 28 Jun 2024 21:01:46 +0300 Subject: [PATCH 2/3] Fix expected directives in tests --- clang/test/PCH/cxx-traits.cpp | 8 +- clang/test/PCH/cxx-traits.h | 102 ++--- ..._is_trivially_equality_comparable_hack.cpp | 10 +- .../libstdcxx_is_nothrow_convertible_hack.cpp | 11 +- clang/test/SemaObjCXX/arc-libstdcxx.mm | 7 +- clang/test/SemaObjCXX/arc-type-traits.mm | 369 +++++++++--------- .../test/SemaObjCXX/objc-weak-type-traits.mm | 351 ++++++++--------- 7 files changed, 430 insertions(+), 428 deletions(-) diff --git a/clang/test/PCH/cxx-traits.cpp b/clang/test/PCH/cxx-traits.cpp index 01b9e9302d790..ca3f3ba5d35a2 100644 --- a/clang/test/PCH/cxx-traits.cpp +++ b/clang/test/PCH/cxx-traits.cpp @@ -2,14 +2,12 @@ // RUN: %clang_cc1 -fms-extensions -include %S/cxx-traits.h -std=c++11 -fsyntax-only -verify %s // RUN: %clang_cc1 -fms-extensions -x c++-header -std=c++11 -emit-pch -o %t %S/cxx-traits.h -// RUN: %clang_cc1 -fms-extensions -std=c++11 -include-pch %t -DPCH -fsyntax-only -verify %s - -#ifdef PCH -// expected-no-diagnostics -#endif +// RUN: %clang_cc1 -fms-extensions -std=c++11 -include-pch %t -fsyntax-only -verify %s bool _Is_pod_comparator = n::__is_pod<int>::__value; +// expected-warning@-1 {{using the name of the builtin '__is_pod' outside of a builtin invocation is deprecated}} bool _Is_empty_check = n::__is_empty<int>::__value; +// expected-warning@-1 {{using the name of the builtin '__is_empty' outside of a builtin invocation is deprecated}} bool default_construct_int = n::is_trivially_constructible<int>::value; bool copy_construct_int = n::is_trivially_constructible<int, const int&>::value; diff --git a/clang/test/PCH/cxx-traits.h b/clang/test/PCH/cxx-traits.h index 0a4bd09c363e9..26d589b86fdca 100644 --- a/clang/test/PCH/cxx-traits.h +++ b/clang/test/PCH/cxx-traits.h @@ -3,12 +3,12 @@ namespace n { template<typename _Tp> -struct __is_pod { // expected-warning {{keyword '__is_pod' will be made available as an identifier for the remainder of the translation unit}} +struct __is_pod { // expected-warning {{outside of a builtin invocation is deprecated}} enum { __value }; }; template<typename _Tp> -struct __is_empty { // expected-warning {{keyword '__is_empty' will be made available as an identifier for the remainder of the translation unit}} +struct __is_empty { // expected-warning {{outside of a builtin invocation is deprecated}} enum { __value }; }; @@ -17,55 +17,55 @@ struct is_trivially_constructible { static const bool value = __is_trivially_constructible(T, Args...); }; -struct __is_abstract {}; // expected-warning {{made available}} -struct __is_aggregate {}; // expected-warning {{made available}} -struct __is_arithmetic {}; // expected-warning {{made available}} -struct __is_array {}; // expected-warning {{made available}} -struct __is_assignable {}; // expected-warning {{made available}} -struct __is_base_of {}; // expected-warning {{made available}} -struct __is_class {}; // expected-warning {{made available}} -struct __is_complete_type {}; // expected-warning {{made available}} -struct __is_compound {}; // expected-warning {{made available}} -struct __is_const {}; // expected-warning {{made available}} -struct __is_constructible {}; // expected-warning {{made available}} -struct __is_convertible {}; // expected-warning {{made available}} -struct __is_convertible_to {}; // expected-warning {{made available}} -struct __is_destructible {}; // expected-warning {{made available}} -struct __is_enum {}; // expected-warning {{made available}} -struct __is_floating_point {}; // expected-warning {{made available}} -struct __is_final {}; // expected-warning {{made available}} -struct __is_function {}; // expected-warning {{made available}} -struct __is_fundamental {}; // expected-warning {{made available}} -struct __is_integral {}; // expected-warning {{made available}} -struct __is_interface_class {}; // expected-warning {{made available}} -struct __is_literal {}; // expected-warning {{made available}} -struct __is_lvalue_expr {}; // expected-warning {{made available}} -struct __is_lvalue_reference {}; // expected-warning {{made available}} -struct __is_member_function_pointer {}; // expected-warning {{made available}} -struct __is_member_object_pointer {}; // expected-warning {{made available}} -struct __is_member_pointer {}; // expected-warning {{made available}} -struct __is_nothrow_assignable {}; // expected-warning {{made available}} -struct __is_nothrow_constructible {}; // expected-warning {{made available}} -struct __is_nothrow_destructible {}; // expected-warning {{made available}} -struct __is_object {}; // expected-warning {{made available}} -struct __is_pointer {}; // expected-warning {{made available}} -struct __is_polymorphic {}; // expected-warning {{made available}} -struct __is_reference {}; // expected-warning {{made available}} -struct __is_rvalue_expr {}; // expected-warning {{made available}} -struct __is_rvalue_reference {}; // expected-warning {{made available}} -struct __is_same {}; // expected-warning {{made available}} -struct __is_scalar {}; // expected-warning {{made available}} -struct __is_sealed {}; // expected-warning {{made available}} -struct __is_signed {}; // expected-warning {{made available}} -struct __is_standard_layout {}; // expected-warning {{made available}} -struct __is_trivial {}; // expected-warning {{made available}} -struct __is_trivially_assignable {}; // expected-warning {{made available}} -struct __is_trivially_constructible {}; // expected-warning {{made available}} -struct __is_trivially_copyable {}; // expected-warning {{made available}} -struct __is_union {}; // expected-warning {{made available}} -struct __is_unsigned {}; // expected-warning {{made available}} -struct __is_void {}; // expected-warning {{made available}} -struct __is_volatile {}; // expected-warning {{made available}} +struct __is_abstract {}; // expected-warning {{outside of a builtin invocation is deprecated}} +struct __is_aggregate {}; // expected-warning {{outside of a builtin invocation is deprecated}} +struct __is_arithmetic {}; // expected-warning {{outside of a builtin invocation is deprecated}} +struct __is_array {}; // expected-warning {{outside of a builtin invocation is deprecated}} +struct __is_assignable {}; // expected-warning {{outside of a builtin invocation is deprecated}} +struct __is_base_of {}; // expected-warning {{outside of a builtin invocation is deprecated}} +struct __is_class {}; // expected-warning {{outside of a builtin invocation is deprecated}} +struct __is_complete_type {}; // expected-warning {{outside of a builtin invocation is deprecated}} +struct __is_compound {}; // expected-warning {{outside of a builtin invocation is deprecated}} +struct __is_const {}; // expected-warning {{outside of a builtin invocation is deprecated}} +struct __is_constructible {}; // expected-warning {{outside of a builtin invocation is deprecated}} +struct __is_convertible {}; // expected-warning {{outside of a builtin invocation is deprecated}} +struct __is_convertible_to {}; // expected-warning {{outside of a builtin invocation is deprecated}} +struct __is_destructible {}; // expected-warning {{outside of a builtin invocation is deprecated}} +struct __is_enum {}; // expected-warning {{outside of a builtin invocation is deprecated}} +struct __is_floating_point {}; // expected-warning {{outside of a builtin invocation is deprecated}} +struct __is_final {}; // expected-warning {{outside of a builtin invocation is deprecated}} +struct __is_function {}; // expected-warning {{outside of a builtin invocation is deprecated}} +struct __is_fundamental {}; // expected-warning {{outside of a builtin invocation is deprecated}} +struct __is_integral {}; // expected-warning {{outside of a builtin invocation is deprecated}} +struct __is_interface_class {}; // expected-warning {{outside of a builtin invocation is deprecated}} +struct __is_literal {}; // expected-warning {{outside of a builtin invocation is deprecated}} +struct __is_lvalue_expr {}; // expected-warning {{outside of a builtin invocation is deprecated}} +struct __is_lvalue_reference {}; // expected-warning {{outside of a builtin invocation is deprecated}} +struct __is_member_function_pointer {}; // expected-warning {{outside of a builtin invocation is deprecated}} +struct __is_member_object_pointer {}; // expected-warning {{outside of a builtin invocation is deprecated}} +struct __is_member_pointer {}; // expected-warning {{outside of a builtin invocation is deprecated}} +struct __is_nothrow_assignable {}; // expected-warning {{outside of a builtin invocation is deprecated}} +struct __is_nothrow_constructible {}; // expected-warning {{outside of a builtin invocation is deprecated}} +struct __is_nothrow_destructible {}; // expected-warning {{outside of a builtin invocation is deprecated}} +struct __is_object {}; // expected-warning {{outside of a builtin invocation is deprecated}} +struct __is_pointer {}; // expected-warning {{outside of a builtin invocation is deprecated}} +struct __is_polymorphic {}; // expected-warning {{outside of a builtin invocation is deprecated}} +struct __is_reference {}; // expected-warning {{outside of a builtin invocation is deprecated}} +struct __is_rvalue_expr {}; // expected-warning {{outside of a builtin invocation is deprecated}} +struct __is_rvalue_reference {}; // expected-warning {{outside of a builtin invocation is deprecated}} +struct __is_same {}; // expected-warning {{outside of a builtin invocation is deprecated}} +struct __is_scalar {}; // expected-warning {{outside of a builtin invocation is deprecated}} +struct __is_sealed {}; // expected-warning {{outside of a builtin invocation is deprecated}} +struct __is_signed {}; // expected-warning {{outside of a builtin invocation is deprecated}} +struct __is_standard_layout {}; // expected-warning {{outside of a builtin invocation is deprecated}} +struct __is_trivial {}; // expected-warning {{outside of a builtin invocation is deprecated}} +struct __is_trivially_assignable {}; // expected-warning {{outside of a builtin invocation is deprecated}} +struct __is_trivially_constructible {}; // expected-warning {{outside of a builtin invocation is deprecated}} +struct __is_trivially_copyable {}; // expected-warning {{outside of a builtin invocation is deprecated}} +struct __is_union {}; // expected-warning {{outside of a builtin invocation is deprecated}} +struct __is_unsigned {}; // expected-warning {{outside of a builtin invocation is deprecated}} +struct __is_void {}; // expected-warning {{outside of a builtin invocation is deprecated}} +struct __is_volatile {}; // expected-warning {{outside of a builtin invocation is deprecated}} } diff --git a/clang/test/SemaCXX/libcxx_is_trivially_equality_comparable_hack.cpp b/clang/test/SemaCXX/libcxx_is_trivially_equality_comparable_hack.cpp index 37adc5fc0b04b..22bab86f78484 100644 --- a/clang/test/SemaCXX/libcxx_is_trivially_equality_comparable_hack.cpp +++ b/clang/test/SemaCXX/libcxx_is_trivially_equality_comparable_hack.cpp @@ -7,8 +7,14 @@ struct Same { }; template <class T> -struct __is_trivially_equality_comparable { // expected-warning{{keyword '__is_trivially_equality_comparable' will be made available as an identifier for the remainder of the translation unit}} +struct __is_trivially_equality_comparable { + // expected-warning@-1 {{using the name of the builtin '__is_trivially_equality_comparable' outside of a builtin invocation is deprecated}} using type = T; }; -using A = Same<__is_trivially_equality_comparable<int>::type, __is_trivially_equality_comparable<int>::type>; +using A = Same< + __is_trivially_equality_comparable<int>::type, + // expected-warning@-1 {{using the name of the builtin '__is_trivially_equality_comparable' outside of a builtin invocation is deprecated}} + __is_trivially_equality_comparable<int>::type + // expected-warning@-1 {{using the name of the builtin '__is_trivially_equality_comparable' outside of a builtin invocation is deprecated}} +>; diff --git a/clang/test/SemaCXX/libstdcxx_is_nothrow_convertible_hack.cpp b/clang/test/SemaCXX/libstdcxx_is_nothrow_convertible_hack.cpp index 9e84f0ab1c081..a9ef66474d3df 100644 --- a/clang/test/SemaCXX/libstdcxx_is_nothrow_convertible_hack.cpp +++ b/clang/test/SemaCXX/libstdcxx_is_nothrow_convertible_hack.cpp @@ -7,8 +7,15 @@ struct Same { }; template <class T> -struct __is_nothrow_convertible { // expected-warning{{keyword '__is_nothrow_convertible' will be made available as an identifier for the remainder of the translation unit}} +struct __is_nothrow_convertible { + // expected-warning@-1 {{using the name of the builtin '__is_nothrow_convertible' outside of a builtin invocation is deprecated}} using type = T; }; -using A = Same<__is_nothrow_convertible<int>::type, __is_nothrow_convertible<int>::type>; +using A = Same< + __is_nothrow_convertible<int>::type, + // expected-warning@-1 {{using the name of the builtin '__is_nothrow_convertible' outside of a builtin invocation is deprecated}} + __is_nothrow_convertible<int>::type + // expected-warning@-1 {{using the name of the builtin '__is_nothrow_convertible' outside of a builtin invocation is deprecated}} +>; + diff --git a/clang/test/SemaObjCXX/arc-libstdcxx.mm b/clang/test/SemaObjCXX/arc-libstdcxx.mm index 537e6b4279702..eed5bc6c56574 100644 --- a/clang/test/SemaObjCXX/arc-libstdcxx.mm +++ b/clang/test/SemaObjCXX/arc-libstdcxx.mm @@ -1,11 +1,16 @@ // RUN: %clang_cc1 -fsyntax-only -fobjc-arc -fobjc-arc-cxxlib=libstdc++ -fobjc-runtime-has-weak -verify %s -// expected-no-diagnostics @interface A @end int check0[std::__is_scalar<__strong id>::__value? -1 : 1]; +// expected-warning@-1 {{using the name of the builtin '__is_scalar' outside of a builtin invocation is deprecated}} int check1[std::__is_scalar<__weak id>::__value? -1 : 1]; +// expected-warning@-1 {{using the name of the builtin '__is_scalar' outside of a builtin invocation is deprecated}} int check2[std::__is_scalar<__autoreleasing id>::__value? -1 : 1]; +// expected-warning@-1 {{using the name of the builtin '__is_scalar' outside of a builtin invocation is deprecated}} int check3[std::__is_scalar<__strong A*>::__value? -1 : 1]; +// expected-warning@-1 {{using the name of the builtin '__is_scalar' outside of a builtin invocation is deprecated}} int check4[std::__is_scalar<__weak A*>::__value? -1 : 1]; +// expected-warning@-1 {{using the name of the builtin '__is_scalar' outside of a builtin invocation is deprecated}} int check5[std::__is_scalar<__autoreleasing A*>::__value? -1 : 1]; +// expected-warning@-1 {{using the name of the builtin '__is_scalar' outside of a builtin invocation is deprecated}} diff --git a/clang/test/SemaObjCXX/arc-type-traits.mm b/clang/test/SemaObjCXX/arc-type-traits.mm index 25bc8b362140a..fd1fe07a8d58a 100644 --- a/clang/test/SemaObjCXX/arc-type-traits.mm +++ b/clang/test/SemaObjCXX/arc-type-traits.mm @@ -4,229 +4,220 @@ // Check the results of the various type-trait query functions on // lifetime-qualified types in ARC. -#define JOIN3(X,Y) X ## Y -#define JOIN2(X,Y) JOIN3(X,Y) -#define JOIN(X,Y) JOIN2(X,Y) - -#define TRAIT_IS_TRUE(Trait, Type) char JOIN2(Trait,__LINE__)[Trait(Type)? 1 : -1] -#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; }; // __has_nothrow_assign -TRAIT_IS_TRUE(__has_nothrow_assign, __strong id); -TRAIT_IS_TRUE(__has_nothrow_assign, __weak id); -TRAIT_IS_TRUE(__has_nothrow_assign, __autoreleasing id); -TRAIT_IS_TRUE(__has_nothrow_assign, __unsafe_unretained id); -TRAIT_IS_TRUE(__has_nothrow_assign, HasStrong); -TRAIT_IS_TRUE(__has_nothrow_assign, HasWeak); -TRAIT_IS_TRUE(__has_nothrow_assign, HasUnsafeUnretained); +static_assert(__has_nothrow_assign(__strong id), ""); +static_assert(__has_nothrow_assign(__weak id), ""); +static_assert(__has_nothrow_assign(__autoreleasing id), ""); +static_assert(__has_nothrow_assign(__unsafe_unretained id), ""); +static_assert(__has_nothrow_assign(HasStrong), ""); +static_assert(__has_nothrow_assign(HasWeak), ""); +static_assert(__has_nothrow_assign(HasUnsafeUnretained), ""); // __has_nothrow_copy -TRAIT_IS_TRUE(__has_nothrow_copy, __strong id); -TRAIT_IS_TRUE(__has_nothrow_copy, __weak id); -TRAIT_IS_TRUE(__has_nothrow_copy, __autoreleasing id); -TRAIT_IS_TRUE(__has_nothrow_copy, __unsafe_unretained id); -TRAIT_IS_TRUE(__has_nothrow_copy, HasStrong); -TRAIT_IS_TRUE(__has_nothrow_copy, HasWeak); -TRAIT_IS_TRUE(__has_nothrow_copy, HasUnsafeUnretained); +static_assert(__has_nothrow_copy(__strong id), ""); +static_assert(__has_nothrow_copy(__weak id), ""); +static_assert(__has_nothrow_copy(__autoreleasing id), ""); +static_assert(__has_nothrow_copy(__unsafe_unretained id), ""); +static_assert(__has_nothrow_copy(HasStrong), ""); +static_assert(__has_nothrow_copy(HasWeak), ""); +static_assert(__has_nothrow_copy(HasUnsafeUnretained), ""); // __has_nothrow_constructor -TRAIT_IS_TRUE(__has_nothrow_constructor, __strong id); -TRAIT_IS_TRUE(__has_nothrow_constructor, __weak id); -TRAIT_IS_TRUE(__has_nothrow_constructor, __autoreleasing id); -TRAIT_IS_TRUE(__has_nothrow_constructor, __unsafe_unretained id); -TRAIT_IS_TRUE(__has_nothrow_constructor, HasStrong); -TRAIT_IS_TRUE(__has_nothrow_constructor, HasWeak); -TRAIT_IS_TRUE(__has_nothrow_constructor, HasUnsafeUnretained); +static_assert(__has_nothrow_constructor(__strong id), ""); +static_assert(__has_nothrow_constructor(__weak id), ""); +static_assert(__has_nothrow_constructor(__autoreleasing id), ""); +static_assert(__has_nothrow_constructor(__unsafe_unretained id), ""); +static_assert(__has_nothrow_constructor(HasStrong), ""); +static_assert(__has_nothrow_constructor(HasWeak), ""); +static_assert(__has_nothrow_constructor(HasUnsafeUnretained), ""); // __has_trivial_assign -TRAIT_IS_FALSE(__has_trivial_assign, __strong id); -TRAIT_IS_FALSE(__has_trivial_assign, __weak id); -TRAIT_IS_FALSE(__has_trivial_assign, __autoreleasing id); -TRAIT_IS_TRUE(__has_trivial_assign, __unsafe_unretained id); -TRAIT_IS_FALSE(__has_trivial_assign, HasStrong); -TRAIT_IS_FALSE(__has_trivial_assign, HasWeak); -TRAIT_IS_TRUE(__has_trivial_assign, HasUnsafeUnretained); +static_assert(!__has_trivial_assign(__strong id), ""); +static_assert(!__has_trivial_assign(__weak id), ""); +static_assert(!__has_trivial_assign(__autoreleasing id), ""); +static_assert(__has_trivial_assign(__unsafe_unretained id), ""); +static_assert(!__has_trivial_assign(HasStrong), ""); +static_assert(!__has_trivial_assign(HasWeak), ""); +static_assert(__has_trivial_assign(HasUnsafeUnretained), ""); // __has_trivial_copy -TRAIT_IS_FALSE(__has_trivial_copy, __strong id); -TRAIT_IS_FALSE(__has_trivial_copy, __weak id); -TRAIT_IS_FALSE(__has_trivial_copy, __autoreleasing id); -TRAIT_IS_TRUE(__has_trivial_copy, __unsafe_unretained id); -TRAIT_IS_FALSE(__has_trivial_copy, HasStrong); -TRAIT_IS_FALSE(__has_trivial_copy, HasWeak); -TRAIT_IS_TRUE(__has_trivial_copy, HasUnsafeUnretained); +static_assert(!__has_trivial_copy(__strong id), ""); +static_assert(!__has_trivial_copy(__weak id), ""); +static_assert(!__has_trivial_copy(__autoreleasing id), ""); +static_assert(__has_trivial_copy(__unsafe_unretained id), ""); +static_assert(!__has_trivial_copy(HasStrong), ""); +static_assert(!__has_trivial_copy(HasWeak), ""); +static_assert(__has_trivial_copy(HasUnsafeUnretained), ""); // __has_trivial_constructor -TRAIT_IS_FALSE(__has_trivial_constructor, __strong id); -TRAIT_IS_FALSE(__has_trivial_constructor, __weak id); -TRAIT_IS_FALSE(__has_trivial_constructor, __autoreleasing id); -TRAIT_IS_TRUE(__has_trivial_constructor, __unsafe_unretained id); -TRAIT_IS_FALSE(__has_trivial_constructor, HasStrong); -TRAIT_IS_FALSE(__has_trivial_constructor, HasWeak); -TRAIT_IS_TRUE(__has_trivial_constructor, HasUnsafeUnretained); +static_assert(!__has_trivial_constructor(__strong id), ""); +static_assert(!__has_trivial_constructor(__weak id), ""); +static_assert(!__has_trivial_constructor(__autoreleasing id), ""); +static_assert(__has_trivial_constructor(__unsafe_unretained id), ""); +static_assert(!__has_trivial_constructor(HasStrong), ""); +static_assert(!__has_trivial_constructor(HasWeak), ""); +static_assert(__has_trivial_constructor(HasUnsafeUnretained), ""); // __has_trivial_destructor -TRAIT_IS_FALSE(__has_trivial_destructor, __strong id); -TRAIT_IS_FALSE(__has_trivial_destructor, __weak id); -TRAIT_IS_TRUE(__has_trivial_destructor, __autoreleasing id); -TRAIT_IS_TRUE(__has_trivial_destructor, __unsafe_unretained id); -TRAIT_IS_FALSE(__has_trivial_destructor, HasStrong); -TRAIT_IS_FALSE(__has_trivial_destructor, HasWeak); -TRAIT_IS_TRUE(__has_trivial_destructor, HasUnsafeUnretained); +static_assert(!__has_trivial_destructor(__strong id), ""); +static_assert(!__has_trivial_destructor(__weak id), ""); +static_assert(__has_trivial_destructor(__autoreleasing id), ""); +static_assert(__has_trivial_destructor(__unsafe_unretained id), ""); +static_assert(!__has_trivial_destructor(HasStrong), ""); +static_assert(!__has_trivial_destructor(HasWeak), ""); +static_assert(__has_trivial_destructor(HasUnsafeUnretained), ""); // __is_literal -TRAIT_IS_TRUE(__is_literal, __strong id); -TRAIT_IS_TRUE(__is_literal, __weak id); -TRAIT_IS_TRUE(__is_literal, __autoreleasing id); -TRAIT_IS_TRUE(__is_literal, __unsafe_unretained id); +static_assert(__is_literal(__strong id), ""); +static_assert(__is_literal(__weak id), ""); +static_assert(__is_literal(__autoreleasing id), ""); +static_assert(__is_literal(__unsafe_unretained id), ""); // __is_literal_type -TRAIT_IS_TRUE(__is_literal_type, __strong id); -TRAIT_IS_TRUE(__is_literal_type, __weak id); -TRAIT_IS_TRUE(__is_literal_type, __autoreleasing id); -TRAIT_IS_TRUE(__is_literal_type, __unsafe_unretained id); +static_assert(__is_literal_type(__strong id), ""); +static_assert(__is_literal_type(__weak id), ""); +static_assert(__is_literal_type(__autoreleasing id), ""); +static_assert(__is_literal_type(__unsafe_unretained id), ""); // __is_pod -TRAIT_IS_FALSE(__is_pod, __strong id); -TRAIT_IS_FALSE(__is_pod, __weak id); -TRAIT_IS_FALSE(__is_pod, __autoreleasing id); -TRAIT_IS_TRUE(__is_pod, __unsafe_unretained id); -TRAIT_IS_FALSE(__is_pod, HasStrong); -TRAIT_IS_FALSE(__is_pod, HasWeak); -TRAIT_IS_TRUE(__is_pod, HasUnsafeUnretained); +static_assert(!__is_pod(__strong id), ""); +static_assert(!__is_pod(__weak id), ""); +static_assert(!__is_pod(__autoreleasing id), ""); +static_assert(__is_pod(__unsafe_unretained id), ""); +static_assert(!__is_pod(HasStrong), ""); +static_assert(!__is_pod(HasWeak), ""); +static_assert(__is_pod(HasUnsafeUnretained), ""); // __is_trivial -TRAIT_IS_FALSE(__is_trivial, __strong id); -TRAIT_IS_FALSE(__is_trivial, __weak id); -TRAIT_IS_FALSE(__is_trivial, __autoreleasing id); -TRAIT_IS_TRUE(__is_trivial, __unsafe_unretained id); -TRAIT_IS_FALSE(__is_trivial, HasStrong); -TRAIT_IS_FALSE(__is_trivial, HasWeak); -TRAIT_IS_TRUE(__is_trivial, HasUnsafeUnretained); +static_assert(!__is_trivial(__strong id), ""); +static_assert(!__is_trivial(__weak id), ""); +static_assert(!__is_trivial(__autoreleasing id), ""); +static_assert(__is_trivial(__unsafe_unretained id), ""); +static_assert(!__is_trivial(HasStrong), ""); +static_assert(!__is_trivial(HasWeak), ""); +static_assert(__is_trivial(HasUnsafeUnretained), ""); // __is_scalar -TRAIT_IS_FALSE(__is_scalar, __strong id); -TRAIT_IS_FALSE(__is_scalar, __weak id); -TRAIT_IS_FALSE(__is_scalar, __autoreleasing id); -TRAIT_IS_TRUE(__is_scalar, __unsafe_unretained id); +static_assert(!__is_scalar(__strong id), ""); +static_assert(!__is_scalar(__weak id), ""); +static_assert(!__is_scalar(__autoreleasing id), ""); +static_assert(__is_scalar(__unsafe_unretained id), ""); // __is_standard_layout -TRAIT_IS_TRUE(__is_standard_layout, __strong id); -TRAIT_IS_TRUE(__is_standard_layout, __weak id); -TRAIT_IS_TRUE(__is_standard_layout, __autoreleasing id); -TRAIT_IS_TRUE(__is_standard_layout, __unsafe_unretained id); +static_assert(__is_standard_layout(__strong id), ""); +static_assert(__is_standard_layout(__weak id), ""); +static_assert(__is_standard_layout(__autoreleasing id), ""); +static_assert(__is_standard_layout(__unsafe_unretained id), ""); // __is_trivally_assignable -TRAIT_IS_FALSE_2(__is_trivially_assignable, __strong id&, __strong id); -TRAIT_IS_FALSE_2(__is_trivially_assignable, __strong id&, __weak id); -TRAIT_IS_FALSE_2(__is_trivially_assignable, __strong id&, __autoreleasing id); -TRAIT_IS_FALSE_2(__is_trivially_assignable, __strong id&, __unsafe_unretained id); -TRAIT_IS_FALSE_2(__is_trivially_assignable, __strong id&, __strong id&&); -TRAIT_IS_FALSE_2(__is_trivially_assignable, __strong id&, __weak id&&); -TRAIT_IS_FALSE_2(__is_trivially_assignable, __strong id&, __autoreleasing id&&); -TRAIT_IS_FALSE_2(__is_trivially_assignable, __strong id&, __unsafe_unretained id&&); -TRAIT_IS_FALSE_2(__is_trivially_assignable, __weak id&, __strong id); -TRAIT_IS_FALSE_2(__is_trivially_assignable, __weak id&, __weak id); -TRAIT_IS_FALSE_2(__is_trivially_assignable, __weak id&, __autoreleasing id); -TRAIT_IS_FALSE_2(__is_trivially_assignable, __weak id&, __unsafe_unretained id); -TRAIT_IS_FALSE_2(__is_trivially_assignable, __weak id&, __strong id&&); -TRAIT_IS_FALSE_2(__is_trivially_assignable, __weak id&, __weak id&&); -TRAIT_IS_FALSE_2(__is_trivially_assignable, __weak id&, __autoreleasing id&&); -TRAIT_IS_FALSE_2(__is_trivially_assignable, __weak id&, __unsafe_unretained id&&); - -TRAIT_IS_FALSE_2(__is_trivially_assignable, __autoreleasing id&, __strong id); -TRAIT_IS_FALSE_2(__is_trivially_assignable, __autoreleasing id&, __weak id); -TRAIT_IS_FALSE_2(__is_trivially_assignable, __autoreleasing id&, __autoreleasing id); -TRAIT_IS_FALSE_2(__is_trivially_assignable, __autoreleasing id&, __unsafe_unretained id); -TRAIT_IS_FALSE_2(__is_trivially_assignable, __autoreleasing id&, __strong id&&); -TRAIT_IS_FALSE_2(__is_trivially_assignable, __autoreleasing id&, __weak id&&); -TRAIT_IS_FALSE_2(__is_trivially_assignable, __autoreleasing id&, __autoreleasing id&&); -TRAIT_IS_FALSE_2(__is_trivially_assignable, __autoreleasing id&, __unsafe_unretained id&&); - -TRAIT_IS_TRUE_2(__is_trivially_assignable, __unsafe_unretained id&, __strong id); -TRAIT_IS_TRUE_2(__is_trivially_assignable, __unsafe_unretained id&, __weak id); -TRAIT_IS_TRUE_2(__is_trivially_assignable, __unsafe_unretained id&, __autoreleasing id); -TRAIT_IS_TRUE_2(__is_trivially_assignable, __unsafe_unretained id&, __unsafe_unretained id); -TRAIT_IS_TRUE_2(__is_trivially_assignable, __unsafe_unretained id&, __strong id&&); -TRAIT_IS_TRUE_2(__is_trivially_assignable, __unsafe_unretained id&, __weak id&&); -TRAIT_IS_TRUE_2(__is_trivially_assignable, __unsafe_unretained id&, __autoreleasing id&&); -TRAIT_IS_TRUE_2(__is_trivially_assignable, __unsafe_unretained id&, __unsafe_unretained id&&); - -TRAIT_IS_FALSE_2(__is_trivially_assignable, HasStrong&, HasStrong); -TRAIT_IS_FALSE_2(__is_trivially_assignable, HasStrong&, HasStrong&&); -TRAIT_IS_FALSE_2(__is_trivially_assignable, HasWeak&, HasWeak); -TRAIT_IS_FALSE_2(__is_trivially_assignable, HasWeak&, HasWeak&&); -TRAIT_IS_TRUE_2(__is_trivially_assignable, HasUnsafeUnretained&, HasUnsafeUnretained); -TRAIT_IS_TRUE_2(__is_trivially_assignable, HasUnsafeUnretained&, HasUnsafeUnretained&&); +static_assert(!__is_trivially_assignable(__strong id&, __strong id), ""); +static_assert(!__is_trivially_assignable(__strong id&, __weak id), ""); +static_assert(!__is_trivially_assignable(__strong id&, __autoreleasing id), ""); +static_assert(!__is_trivially_assignable(__strong id&, __unsafe_unretained id), ""); +static_assert(!__is_trivially_assignable(__strong id&, __strong id&&), ""); +static_assert(!__is_trivially_assignable(__strong id&, __weak id&&), ""); +static_assert(!__is_trivially_assignable(__strong id&, __autoreleasing id&&), ""); +static_assert(!__is_trivially_assignable(__strong id&, __unsafe_unretained id&&), ""); +static_assert(!__is_trivially_assignable(__weak id&, __strong id), ""); +static_assert(!__is_trivially_assignable(__weak id&, __weak id), ""); +static_assert(!__is_trivially_assignable(__weak id&, __autoreleasing id), ""); +static_assert(!__is_trivially_assignable(__weak id&, __unsafe_unretained id), ""); +static_assert(!__is_trivially_assignable(__weak id&, __strong id&&), ""); +static_assert(!__is_trivially_assignable(__weak id&, __weak id&&), ""); +static_assert(!__is_trivially_assignable(__weak id&, __autoreleasing id&&), ""); +static_assert(!__is_trivially_assignable(__weak id&, __unsafe_unretained id&&), ""); + +static_assert(!__is_trivially_assignable(__autoreleasing id&, __strong id), ""); +static_assert(!__is_trivially_assignable(__autoreleasing id&, __weak id), ""); +static_assert(!__is_trivially_assignable(__autoreleasing id&, __autoreleasing id), ""); +static_assert(!__is_trivially_assignable(__autoreleasing id&, __unsafe_unretained id), ""); +static_assert(!__is_trivially_assignable(__autoreleasing id&, __strong id&&), ""); +static_assert(!__is_trivially_assignable(__autoreleasing id&, __weak id&&), ""); +static_assert(!__is_trivially_assignable(__autoreleasing id&, __autoreleasing id&&), ""); +static_assert(!__is_trivially_assignable(__autoreleasing id&, __unsafe_unretained id&&), ""); + +static_assert(__is_trivially_assignable(__unsafe_unretained id&, __strong id), ""); +static_assert(__is_trivially_assignable(__unsafe_unretained id&, __weak id), ""); +static_assert(__is_trivially_assignable(__unsafe_unretained id&, __autoreleasing id), ""); +static_assert(__is_trivially_assignable(__unsafe_unretained id&, __unsafe_unretained id), ""); +static_assert(__is_trivially_assignable(__unsafe_unretained id&, __strong id&&), ""); +static_assert(__is_trivially_assignable(__unsafe_unretained id&, __weak id&&), ""); +static_assert(__is_trivially_assignable(__unsafe_unretained id&, __autoreleasing id&&), ""); +static_assert(__is_trivially_assignable(__unsafe_unretained id&, __unsafe_unretained id&&), ""); + +static_assert(!__is_trivially_assignable(HasStrong&, HasStrong), ""); +static_assert(!__is_trivially_assignable(HasStrong&, HasStrong&&), ""); +static_assert(!__is_trivially_assignable(HasWeak&, HasWeak), ""); +static_assert(!__is_trivially_assignable(HasWeak&, HasWeak&&), ""); +static_assert(__is_trivially_assignable(HasUnsafeUnretained&, HasUnsafeUnretained), ""); +static_assert(__is_trivially_assignable(HasUnsafeUnretained&, HasUnsafeUnretained&&), ""); // __is_trivally_constructible -TRAIT_IS_FALSE(__is_trivially_constructible, __strong id); -TRAIT_IS_FALSE(__is_trivially_constructible, __weak id); -TRAIT_IS_FALSE(__is_trivially_constructible, __autoreleasing id); -TRAIT_IS_TRUE(__is_trivially_constructible, __unsafe_unretained id); - -TRAIT_IS_FALSE_2(__is_trivially_constructible, __strong id, __strong id); -TRAIT_IS_FALSE_2(__is_trivially_constructible, __strong id, __weak id); -TRAIT_IS_FALSE_2(__is_trivially_constructible, __strong id, __autoreleasing id); -TRAIT_IS_FALSE_2(__is_trivially_constructible, __strong id, __unsafe_unretained id); -TRAIT_IS_FALSE_2(__is_trivially_constructible, __strong id, __strong id&&); -TRAIT_IS_FALSE_2(__is_trivially_constructible, __strong id, __weak id&&); -TRAIT_IS_FALSE_2(__is_trivially_constructible, __strong id, __autoreleasing id&&); -TRAIT_IS_FALSE_2(__is_trivially_constructible, __strong id, __unsafe_unretained id&&); -TRAIT_IS_FALSE_2(__is_trivially_constructible, __weak id, __strong id); -TRAIT_IS_FALSE_2(__is_trivially_constructible, __weak id, __weak id); -TRAIT_IS_FALSE_2(__is_trivially_constructible, __weak id, __autoreleasing id); -TRAIT_IS_FALSE_2(__is_trivially_constructible, __weak id, __unsafe_unretained id); -TRAIT_IS_FALSE_2(__is_trivially_constructible, __weak id, __strong id&&); -TRAIT_IS_FALSE_2(__is_trivially_constructible, __weak id, __weak id&&); -TRAIT_IS_FALSE_2(__is_trivially_constructible, __weak id, __autoreleasing id&&); -TRAIT_IS_FALSE_2(__is_trivially_constructible, __weak id, __unsafe_unretained id&&); - -TRAIT_IS_FALSE_2(__is_trivially_constructible, __autoreleasing id, __strong id); -TRAIT_IS_FALSE_2(__is_trivially_constructible, __autoreleasing id, __weak id); -TRAIT_IS_FALSE_2(__is_trivially_constructible, __autoreleasing id, __autoreleasing id); -TRAIT_IS_FALSE_2(__is_trivially_constructible, __autoreleasing id, __unsafe_unretained id); -TRAIT_IS_FALSE_2(__is_trivially_constructible, __autoreleasing id, __strong id&&); -TRAIT_IS_FALSE_2(__is_trivially_constructible, __autoreleasing id, __weak id&&); -TRAIT_IS_FALSE_2(__is_trivially_constructible, __autoreleasing id, __autoreleasing id&&); -TRAIT_IS_FALSE_2(__is_trivially_constructible, __autoreleasing id, __unsafe_unretained id&&); - -TRAIT_IS_TRUE_2(__is_trivially_constructible, __unsafe_unretained id, __strong id); -TRAIT_IS_TRUE_2(__is_trivially_constructible, __unsafe_unretained id, __weak id); -TRAIT_IS_TRUE_2(__is_trivially_constructible, __unsafe_unretained id, __autoreleasing id); -TRAIT_IS_TRUE_2(__is_trivially_constructible, __unsafe_unretained id, __unsafe_unretained id); -TRAIT_IS_TRUE_2(__is_trivially_constructible, __unsafe_unretained id, __strong id&&); -TRAIT_IS_TRUE_2(__is_trivially_constructible, __unsafe_unretained id, __weak id&&); -TRAIT_IS_TRUE_2(__is_trivially_constructible, __unsafe_unretained id, __autoreleasing id&&); -TRAIT_IS_TRUE_2(__is_trivially_constructible, __unsafe_unretained id, __unsafe_unretained id&&); - -TRAIT_IS_FALSE_2(__is_trivially_constructible, HasStrong, HasStrong); -TRAIT_IS_FALSE_2(__is_trivially_constructible, HasStrong, HasStrong&&); -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&&); +static_assert(!__is_trivially_constructible(__strong id), ""); +static_assert(!__is_trivially_constructible(__weak id), ""); +static_assert(!__is_trivially_constructible(__autoreleasing id), ""); +static_assert(__is_trivially_constructible(__unsafe_unretained id), ""); + +static_assert(!__is_trivially_constructible(__strong id, __strong id), ""); +static_assert(!__is_trivially_constructible(__strong id, __weak id), ""); +static_assert(!__is_trivially_constructible(__strong id, __autoreleasing id), ""); +static_assert(!__is_trivially_constructible(__strong id, __unsafe_unretained id), ""); +static_assert(!__is_trivially_constructible(__strong id, __strong id&&), ""); +static_assert(!__is_trivially_constructible(__strong id, __weak id&&), ""); +static_assert(!__is_trivially_constructible(__strong id, __autoreleasing id&&), ""); +static_assert(!__is_trivially_constructible(__strong id, __unsafe_unretained id&&), ""); +static_assert(!__is_trivially_constructible(__weak id, __strong id), ""); +static_assert(!__is_trivially_constructible(__weak id, __weak id), ""); +static_assert(!__is_trivially_constructible(__weak id, __autoreleasing id), ""); +static_assert(!__is_trivially_constructible(__weak id, __unsafe_unretained id), ""); +static_assert(!__is_trivially_constructible(__weak id, __strong id&&), ""); +static_assert(!__is_trivially_constructible(__weak id, __weak id&&), ""); +static_assert(!__is_trivially_constructible(__weak id, __autoreleasing id&&), ""); +static_assert(!__is_trivially_constructible(__weak id, __unsafe_unretained id&&), ""); + +static_assert(!__is_trivially_constructible(__autoreleasing id, __strong id), ""); +static_assert(!__is_trivially_constructible(__autoreleasing id, __weak id), ""); +static_assert(!__is_trivially_constructible(__autoreleasing id, __autoreleasing id), ""); +static_assert(!__is_trivially_constructible(__autoreleasing id, __unsafe_unretained id), ""); +static_assert(!__is_trivially_constructible(__autoreleasing id, __strong id&&), ""); +static_assert(!__is_trivially_constructible(__autoreleasing id, __weak id&&), ""); +static_assert(!__is_trivially_constructible(__autoreleasing id, __autoreleasing id&&), ""); +static_assert(!__is_trivially_constructible(__autoreleasing id, __unsafe_unretained id&&), ""); + +static_assert(__is_trivially_constructible(__unsafe_unretained id, __strong id), ""); +static_assert(__is_trivially_constructible(__unsafe_unretained id, __weak id), ""); +static_assert(__is_trivially_constructible(__unsafe_unretained id, __autoreleasing id), ""); +static_assert(__is_trivially_constructible(__unsafe_unretained id, __unsafe_unretained id), ""); +static_assert(__is_trivially_constructible(__unsafe_unretained id, __strong id&&), ""); +static_assert(__is_trivially_constructible(__unsafe_unretained id, __weak id&&), ""); +static_assert(__is_trivially_constructible(__unsafe_unretained id, __autoreleasing id&&), ""); +static_assert(__is_trivially_constructible(__unsafe_unretained id, __unsafe_unretained id&&), ""); + +static_assert(!__is_trivially_constructible(HasStrong, HasStrong), ""); +static_assert(!__is_trivially_constructible(HasStrong, HasStrong&&), ""); +static_assert(!__is_trivially_constructible(HasWeak, HasWeak), ""); +static_assert(!__is_trivially_constructible(HasWeak, HasWeak&&), ""); +static_assert(__is_trivially_constructible(HasUnsafeUnretained, HasUnsafeUnretained), ""); +static_assert(__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); +static_assert(__is_trivially_relocatable(__strong id), ""); +static_assert(!__is_trivially_relocatable(__weak id), ""); +static_assert(__is_trivially_relocatable(__autoreleasing id), ""); +static_assert(__is_trivially_relocatable(__unsafe_unretained id), ""); +static_assert(__is_trivially_relocatable(HasStrong), ""); +static_assert(!__is_trivially_relocatable(HasWeak), ""); +static_assert(__is_trivially_relocatable(HasUnsafeUnretained), ""); // __is_bitwise_cloneable -TRAIT_IS_FALSE(__is_bitwise_cloneable, __strong id); -TRAIT_IS_FALSE(__is_bitwise_cloneable, __weak id); -TRAIT_IS_FALSE(__is_bitwise_cloneable, __autoreleasing id); -TRAIT_IS_TRUE(__is_trivial, __unsafe_unretained id); -TRAIT_IS_FALSE(__is_bitwise_cloneable, HasStrong); -TRAIT_IS_FALSE(__is_bitwise_cloneable, HasWeak); -TRAIT_IS_TRUE(__is_bitwise_cloneable, HasUnsafeUnretained); +static_assert(!__is_bitwise_cloneable(__strong id), ""); +static_assert(!__is_bitwise_cloneable(__weak id), ""); +static_assert(!__is_bitwise_cloneable(__autoreleasing id), ""); +static_assert(__is_bitwise_cloneable(__unsafe_unretained id), ""); +static_assert(!__is_bitwise_cloneable(HasStrong), ""); +static_assert(!__is_bitwise_cloneable(HasWeak), ""); +static_assert(__is_bitwise_cloneable(HasUnsafeUnretained), ""); diff --git a/clang/test/SemaObjCXX/objc-weak-type-traits.mm b/clang/test/SemaObjCXX/objc-weak-type-traits.mm index e8f3e637ac272..3e46f4881284c 100644 --- a/clang/test/SemaObjCXX/objc-weak-type-traits.mm +++ b/clang/test/SemaObjCXX/objc-weak-type-traits.mm @@ -4,216 +4,211 @@ // Check the results of the various type-trait query functions on // lifetime-qualified types in ObjC Weak. -#define TRAIT_IS_TRUE(Trait, Type) static_assert(Trait(Type), "") -#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; }; // __has_nothrow_assign -TRAIT_IS_TRUE(__has_nothrow_assign, __strong id); -TRAIT_IS_TRUE(__has_nothrow_assign, __weak id); -TRAIT_IS_TRUE(__has_nothrow_assign, __autoreleasing id); -TRAIT_IS_TRUE(__has_nothrow_assign, __unsafe_unretained id); -TRAIT_IS_TRUE(__has_nothrow_assign, HasStrong); -TRAIT_IS_TRUE(__has_nothrow_assign, HasWeak); -TRAIT_IS_TRUE(__has_nothrow_assign, HasUnsafeUnretained); +static_assert(__has_nothrow_assign(__strong id), ""); +static_assert(__has_nothrow_assign(__weak id), ""); +static_assert(__has_nothrow_assign(__autoreleasing id), ""); +static_assert(__has_nothrow_assign(__unsafe_unretained id), ""); +static_assert(__has_nothrow_assign(HasStrong), ""); +static_assert(__has_nothrow_assign(HasWeak), ""); +static_assert(__has_nothrow_assign(HasUnsafeUnretained), ""); // __has_nothrow_copy -TRAIT_IS_TRUE(__has_nothrow_copy, __strong id); -TRAIT_IS_TRUE(__has_nothrow_copy, __weak id); -TRAIT_IS_TRUE(__has_nothrow_copy, __autoreleasing id); -TRAIT_IS_TRUE(__has_nothrow_copy, __unsafe_unretained id); -TRAIT_IS_TRUE(__has_nothrow_copy, HasStrong); -TRAIT_IS_TRUE(__has_nothrow_copy, HasWeak); -TRAIT_IS_TRUE(__has_nothrow_copy, HasUnsafeUnretained); +static_assert(__has_nothrow_copy(__strong id), ""); +static_assert(__has_nothrow_copy(__weak id), ""); +static_assert(__has_nothrow_copy(__autoreleasing id), ""); +static_assert(__has_nothrow_copy(__unsafe_unretained id), ""); +static_assert(__has_nothrow_copy(HasStrong), ""); +static_assert(__has_nothrow_copy(HasWeak), ""); +static_assert(__has_nothrow_copy(HasUnsafeUnretained), ""); // __has_nothrow_constructor -TRAIT_IS_TRUE(__has_nothrow_constructor, __strong id); -TRAIT_IS_TRUE(__has_nothrow_constructor, __weak id); -TRAIT_IS_TRUE(__has_nothrow_constructor, __autoreleasing id); -TRAIT_IS_TRUE(__has_nothrow_constructor, __unsafe_unretained id); -TRAIT_IS_TRUE(__has_nothrow_constructor, HasStrong); -TRAIT_IS_TRUE(__has_nothrow_constructor, HasWeak); -TRAIT_IS_TRUE(__has_nothrow_constructor, HasUnsafeUnretained); +static_assert(__has_nothrow_constructor(__strong id), ""); +static_assert(__has_nothrow_constructor(__weak id), ""); +static_assert(__has_nothrow_constructor(__autoreleasing id), ""); +static_assert(__has_nothrow_constructor(__unsafe_unretained id), ""); +static_assert(__has_nothrow_constructor(HasStrong), ""); +static_assert(__has_nothrow_constructor(HasWeak), ""); +static_assert(__has_nothrow_constructor(HasUnsafeUnretained), ""); // __has_trivial_assign -TRAIT_IS_TRUE(__has_trivial_assign, __strong id); -TRAIT_IS_FALSE(__has_trivial_assign, __weak id); -TRAIT_IS_TRUE(__has_trivial_assign, __autoreleasing id); -TRAIT_IS_TRUE(__has_trivial_assign, __unsafe_unretained id); -TRAIT_IS_TRUE(__has_trivial_assign, HasStrong); -TRAIT_IS_FALSE(__has_trivial_assign, HasWeak); -TRAIT_IS_TRUE(__has_trivial_assign, HasUnsafeUnretained); +static_assert(__has_trivial_assign(__strong id), ""); +static_assert(!__has_trivial_assign(__weak id), ""); +static_assert(__has_trivial_assign(__autoreleasing id), ""); +static_assert(__has_trivial_assign(__unsafe_unretained id), ""); +static_assert(__has_trivial_assign(HasStrong), ""); +static_assert(!__has_trivial_assign(HasWeak), ""); +static_assert(__has_trivial_assign(HasUnsafeUnretained), ""); // __has_trivial_copy -TRAIT_IS_TRUE(__has_trivial_copy, __strong id); -TRAIT_IS_FALSE(__has_trivial_copy, __weak id); -TRAIT_IS_TRUE(__has_trivial_copy, __autoreleasing id); -TRAIT_IS_TRUE(__has_trivial_copy, __unsafe_unretained id); -TRAIT_IS_TRUE(__has_trivial_copy, HasStrong); -TRAIT_IS_FALSE(__has_trivial_copy, HasWeak); -TRAIT_IS_TRUE(__has_trivial_copy, HasUnsafeUnretained); +static_assert(__has_trivial_copy(__strong id), ""); +static_assert(!__has_trivial_copy(__weak id), ""); +static_assert(__has_trivial_copy(__autoreleasing id), ""); +static_assert(__has_trivial_copy(__unsafe_unretained id), ""); +static_assert(__has_trivial_copy(HasStrong), ""); +static_assert(!__has_trivial_copy(HasWeak), ""); +static_assert(__has_trivial_copy(HasUnsafeUnretained), ""); // __has_trivial_constructor -TRAIT_IS_TRUE(__has_trivial_constructor, __strong id); -TRAIT_IS_FALSE(__has_trivial_constructor, __weak id); -TRAIT_IS_TRUE(__has_trivial_constructor, __autoreleasing id); -TRAIT_IS_TRUE(__has_trivial_constructor, __unsafe_unretained id); -TRAIT_IS_TRUE(__has_trivial_constructor, HasStrong); -TRAIT_IS_FALSE(__has_trivial_constructor, HasWeak); -TRAIT_IS_TRUE(__has_trivial_constructor, HasUnsafeUnretained); +static_assert(__has_trivial_constructor(__strong id), ""); +static_assert(!__has_trivial_constructor(__weak id), ""); +static_assert(__has_trivial_constructor(__autoreleasing id), ""); +static_assert(__has_trivial_constructor(__unsafe_unretained id), ""); +static_assert(__has_trivial_constructor(HasStrong), ""); +static_assert(!__has_trivial_constructor(HasWeak), ""); +static_assert(__has_trivial_constructor(HasUnsafeUnretained), ""); // __has_trivial_destructor -TRAIT_IS_TRUE(__has_trivial_destructor, __strong id); -TRAIT_IS_FALSE(__has_trivial_destructor, __weak id); -TRAIT_IS_TRUE(__has_trivial_destructor, __autoreleasing id); -TRAIT_IS_TRUE(__has_trivial_destructor, __unsafe_unretained id); -TRAIT_IS_TRUE(__has_trivial_destructor, HasStrong); -TRAIT_IS_FALSE(__has_trivial_destructor, HasWeak); -TRAIT_IS_TRUE(__has_trivial_destructor, HasUnsafeUnretained); +static_assert(__has_trivial_destructor(__strong id), ""); +static_assert(!__has_trivial_destructor(__weak id), ""); +static_assert(__has_trivial_destructor(__autoreleasing id), ""); +static_assert(__has_trivial_destructor(__unsafe_unretained id), ""); +static_assert(__has_trivial_destructor(HasStrong), ""); +static_assert(!__has_trivial_destructor(HasWeak), ""); +static_assert(__has_trivial_destructor(HasUnsafeUnretained), ""); // __is_literal -TRAIT_IS_TRUE(__is_literal, __strong id); -TRAIT_IS_TRUE(__is_literal, __weak id); -TRAIT_IS_TRUE(__is_literal, __autoreleasing id); -TRAIT_IS_TRUE(__is_literal, __unsafe_unretained id); +static_assert(__is_literal(__strong id), ""); +static_assert(__is_literal(__weak id), ""); +static_assert(__is_literal(__autoreleasing id), ""); +static_assert(__is_literal(__unsafe_unretained id), ""); // __is_literal_type -TRAIT_IS_TRUE(__is_literal_type, __strong id); -TRAIT_IS_TRUE(__is_literal_type, __weak id); -TRAIT_IS_TRUE(__is_literal_type, __autoreleasing id); -TRAIT_IS_TRUE(__is_literal_type, __unsafe_unretained id); +static_assert(__is_literal_type(__strong id), ""); +static_assert(__is_literal_type(__weak id), ""); +static_assert(__is_literal_type(__autoreleasing id), ""); +static_assert(__is_literal_type(__unsafe_unretained id), ""); // __is_pod -TRAIT_IS_TRUE(__is_pod, __strong id); -TRAIT_IS_FALSE(__is_pod, __weak id); -TRAIT_IS_TRUE(__is_pod, __autoreleasing id); -TRAIT_IS_TRUE(__is_pod, __unsafe_unretained id); -TRAIT_IS_TRUE(__is_pod, HasStrong); -TRAIT_IS_FALSE(__is_pod, HasWeak); -TRAIT_IS_TRUE(__is_pod, HasUnsafeUnretained); +static_assert(__is_pod(__strong id), ""); +static_assert(!__is_pod(__weak id), ""); +static_assert(__is_pod(__autoreleasing id), ""); +static_assert(__is_pod(__unsafe_unretained id), ""); +static_assert(__is_pod(HasStrong), ""); +static_assert(!__is_pod(HasWeak), ""); +static_assert(__is_pod(HasUnsafeUnretained), ""); // __is_trivial -TRAIT_IS_TRUE(__is_trivial, __strong id); -TRAIT_IS_FALSE(__is_trivial, __weak id); -TRAIT_IS_TRUE(__is_trivial, __autoreleasing id); -TRAIT_IS_TRUE(__is_trivial, __unsafe_unretained id); -TRAIT_IS_TRUE(__is_trivial, HasStrong); -TRAIT_IS_FALSE(__is_trivial, HasWeak); -TRAIT_IS_TRUE(__is_trivial, HasUnsafeUnretained); +static_assert(__is_trivial(__strong id), ""); +static_assert(!__is_trivial(__weak id), ""); +static_assert(__is_trivial(__autoreleasing id), ""); +static_assert(__is_trivial(__unsafe_unretained id), ""); +static_assert(__is_trivial(HasStrong), ""); +static_assert(!__is_trivial(HasWeak), ""); +static_assert(__is_trivial(HasUnsafeUnretained), ""); // __is_scalar -TRAIT_IS_TRUE(__is_scalar, __strong id); -TRAIT_IS_FALSE(__is_scalar, __weak id); -TRAIT_IS_TRUE(__is_scalar, __autoreleasing id); -TRAIT_IS_TRUE(__is_scalar, __unsafe_unretained id); +static_assert(__is_scalar(__strong id), ""); +static_assert(!__is_scalar(__weak id), ""); +static_assert(__is_scalar(__autoreleasing id), ""); +static_assert(__is_scalar(__unsafe_unretained id), ""); // __is_standard_layout -TRAIT_IS_TRUE(__is_standard_layout, __strong id); -TRAIT_IS_TRUE(__is_standard_layout, __weak id); -TRAIT_IS_TRUE(__is_standard_layout, __autoreleasing id); -TRAIT_IS_TRUE(__is_standard_layout, __unsafe_unretained id); +static_assert(__is_standard_layout(__strong id), ""); +static_assert(__is_standard_layout(__weak id), ""); +static_assert(__is_standard_layout(__autoreleasing id), ""); +static_assert(__is_standard_layout(__unsafe_unretained id), ""); // __is_trivally_assignable -TRAIT_IS_TRUE_2(__is_trivially_assignable, __strong id&, __strong id); -TRAIT_IS_TRUE_2(__is_trivially_assignable, __strong id&, __weak id); -TRAIT_IS_TRUE_2(__is_trivially_assignable, __strong id&, __autoreleasing id); -TRAIT_IS_TRUE_2(__is_trivially_assignable, __strong id&, __unsafe_unretained id); -TRAIT_IS_TRUE_2(__is_trivially_assignable, __strong id&, __strong id&&); -TRAIT_IS_TRUE_2(__is_trivially_assignable, __strong id&, __weak id&&); -TRAIT_IS_TRUE_2(__is_trivially_assignable, __strong id&, __autoreleasing id&&); -TRAIT_IS_TRUE_2(__is_trivially_assignable, __strong id&, __unsafe_unretained id&&); -TRAIT_IS_FALSE_2(__is_trivially_assignable, __weak id&, __strong id); -TRAIT_IS_FALSE_2(__is_trivially_assignable, __weak id&, __weak id); -TRAIT_IS_FALSE_2(__is_trivially_assignable, __weak id&, __autoreleasing id); -TRAIT_IS_FALSE_2(__is_trivially_assignable, __weak id&, __unsafe_unretained id); -TRAIT_IS_FALSE_2(__is_trivially_assignable, __weak id&, __strong id&&); -TRAIT_IS_FALSE_2(__is_trivially_assignable, __weak id&, __weak id&&); -TRAIT_IS_FALSE_2(__is_trivially_assignable, __weak id&, __autoreleasing id&&); -TRAIT_IS_FALSE_2(__is_trivially_assignable, __weak id&, __unsafe_unretained id&&); - -TRAIT_IS_TRUE_2(__is_trivially_assignable, __autoreleasing id&, __strong id); -TRAIT_IS_TRUE_2(__is_trivially_assignable, __autoreleasing id&, __weak id); -TRAIT_IS_TRUE_2(__is_trivially_assignable, __autoreleasing id&, __autoreleasing id); -TRAIT_IS_TRUE_2(__is_trivially_assignable, __autoreleasing id&, __unsafe_unretained id); -TRAIT_IS_TRUE_2(__is_trivially_assignable, __autoreleasing id&, __strong id&&); -TRAIT_IS_TRUE_2(__is_trivially_assignable, __autoreleasing id&, __weak id&&); -TRAIT_IS_TRUE_2(__is_trivially_assignable, __autoreleasing id&, __autoreleasing id&&); -TRAIT_IS_TRUE_2(__is_trivially_assignable, __autoreleasing id&, __unsafe_unretained id&&); - -TRAIT_IS_TRUE_2(__is_trivially_assignable, __unsafe_unretained id&, __strong id); -TRAIT_IS_TRUE_2(__is_trivially_assignable, __unsafe_unretained id&, __weak id); -TRAIT_IS_TRUE_2(__is_trivially_assignable, __unsafe_unretained id&, __autoreleasing id); -TRAIT_IS_TRUE_2(__is_trivially_assignable, __unsafe_unretained id&, __unsafe_unretained id); -TRAIT_IS_TRUE_2(__is_trivially_assignable, __unsafe_unretained id&, __strong id&&); -TRAIT_IS_TRUE_2(__is_trivially_assignable, __unsafe_unretained id&, __weak id&&); -TRAIT_IS_TRUE_2(__is_trivially_assignable, __unsafe_unretained id&, __autoreleasing id&&); -TRAIT_IS_TRUE_2(__is_trivially_assignable, __unsafe_unretained id&, __unsafe_unretained id&&); - -TRAIT_IS_TRUE_2(__is_trivially_assignable, HasStrong&, HasStrong); -TRAIT_IS_TRUE_2(__is_trivially_assignable, HasStrong&, HasStrong&&); -TRAIT_IS_FALSE_2(__is_trivially_assignable, HasWeak&, HasWeak); -TRAIT_IS_FALSE_2(__is_trivially_assignable, HasWeak&, HasWeak&&); -TRAIT_IS_TRUE_2(__is_trivially_assignable, HasUnsafeUnretained&, HasUnsafeUnretained); -TRAIT_IS_TRUE_2(__is_trivially_assignable, HasUnsafeUnretained&, HasUnsafeUnretained&&); +static_assert(__is_trivially_assignable(__strong id&, __strong id), ""); +static_assert(__is_trivially_assignable(__strong id&, __weak id), ""); +static_assert(__is_trivially_assignable(__strong id&, __autoreleasing id), ""); +static_assert(__is_trivially_assignable(__strong id&, __unsafe_unretained id), ""); +static_assert(__is_trivially_assignable(__strong id&, __strong id&&), ""); +static_assert(__is_trivially_assignable(__strong id&, __weak id&&), ""); +static_assert(__is_trivially_assignable(__strong id&, __autoreleasing id&&), ""); +static_assert(__is_trivially_assignable(__strong id&, __unsafe_unretained id&&), ""); +static_assert(!__is_trivially_assignable(__weak id&, __strong id), ""); +static_assert(!__is_trivially_assignable(__weak id&, __weak id), ""); +static_assert(!__is_trivially_assignable(__weak id&, __autoreleasing id), ""); +static_assert(!__is_trivially_assignable(__weak id&, __unsafe_unretained id), ""); +static_assert(!__is_trivially_assignable(__weak id&, __strong id&&), ""); +static_assert(!__is_trivially_assignable(__weak id&, __weak id&&), ""); +static_assert(!__is_trivially_assignable(__weak id&, __autoreleasing id&&), ""); +static_assert(!__is_trivially_assignable(__weak id&, __unsafe_unretained id&&), ""); + +static_assert(__is_trivially_assignable(__autoreleasing id&, __strong id), ""); +static_assert(__is_trivially_assignable(__autoreleasing id&, __weak id), ""); +static_assert(__is_trivially_assignable(__autoreleasing id&, __autoreleasing id), ""); +static_assert(__is_trivially_assignable(__autoreleasing id&, __unsafe_unretained id), ""); +static_assert(__is_trivially_assignable(__autoreleasing id&, __strong id&&), ""); +static_assert(__is_trivially_assignable(__autoreleasing id&, __weak id&&), ""); +static_assert(__is_trivially_assignable(__autoreleasing id&, __autoreleasing id&&), ""); +static_assert(__is_trivially_assignable(__autoreleasing id&, __unsafe_unretained id&&), ""); + +static_assert(__is_trivially_assignable(__unsafe_unretained id&, __strong id), ""); +static_assert(__is_trivially_assignable(__unsafe_unretained id&, __weak id), ""); +static_assert(__is_trivially_assignable(__unsafe_unretained id&, __autoreleasing id), ""); +static_assert(__is_trivially_assignable(__unsafe_unretained id&, __unsafe_unretained id), ""); +static_assert(__is_trivially_assignable(__unsafe_unretained id&, __strong id&&), ""); +static_assert(__is_trivially_assignable(__unsafe_unretained id&, __weak id&&), ""); +static_assert(__is_trivially_assignable(__unsafe_unretained id&, __autoreleasing id&&), ""); +static_assert(__is_trivially_assignable(__unsafe_unretained id&, __unsafe_unretained id&&), ""); + +static_assert(__is_trivially_assignable(HasStrong&, HasStrong), ""); +static_assert(__is_trivially_assignable(HasStrong&, HasStrong&&), ""); +static_assert(!__is_trivially_assignable(HasWeak&, HasWeak), ""); +static_assert(!__is_trivially_assignable(HasWeak&, HasWeak&&), ""); +static_assert(__is_trivially_assignable(HasUnsafeUnretained&, HasUnsafeUnretained), ""); +static_assert(__is_trivially_assignable(HasUnsafeUnretained&, HasUnsafeUnretained&&), ""); // __is_trivally_constructible -TRAIT_IS_TRUE(__is_trivially_constructible, __strong id); -TRAIT_IS_FALSE(__is_trivially_constructible, __weak id); -TRAIT_IS_TRUE(__is_trivially_constructible, __autoreleasing id); -TRAIT_IS_TRUE(__is_trivially_constructible, __unsafe_unretained id); - -TRAIT_IS_TRUE_2(__is_trivially_constructible, __strong id, __strong id); -TRAIT_IS_TRUE_2(__is_trivially_constructible, __strong id, __weak id); -TRAIT_IS_TRUE_2(__is_trivially_constructible, __strong id, __autoreleasing id); -TRAIT_IS_TRUE_2(__is_trivially_constructible, __strong id, __unsafe_unretained id); -TRAIT_IS_TRUE_2(__is_trivially_constructible, __strong id, __strong id&&); -TRAIT_IS_TRUE_2(__is_trivially_constructible, __strong id, __weak id&&); -TRAIT_IS_TRUE_2(__is_trivially_constructible, __strong id, __autoreleasing id&&); -TRAIT_IS_TRUE_2(__is_trivially_constructible, __strong id, __unsafe_unretained id&&); -TRAIT_IS_FALSE_2(__is_trivially_constructible, __weak id, __strong id); -TRAIT_IS_FALSE_2(__is_trivially_constructible, __weak id, __weak id); -TRAIT_IS_FALSE_2(__is_trivially_constructible, __weak id, __autoreleasing id); -TRAIT_IS_FALSE_2(__is_trivially_constructible, __weak id, __unsafe_unretained id); -TRAIT_IS_FALSE_2(__is_trivially_constructible, __weak id, __strong id&&); -TRAIT_IS_FALSE_2(__is_trivially_constructible, __weak id, __weak id&&); -TRAIT_IS_FALSE_2(__is_trivially_constructible, __weak id, __autoreleasing id&&); -TRAIT_IS_FALSE_2(__is_trivially_constructible, __weak id, __unsafe_unretained id&&); - -TRAIT_IS_TRUE_2(__is_trivially_constructible, __autoreleasing id, __strong id); -TRAIT_IS_TRUE_2(__is_trivially_constructible, __autoreleasing id, __weak id); -TRAIT_IS_TRUE_2(__is_trivially_constructible, __autoreleasing id, __autoreleasing id); -TRAIT_IS_TRUE_2(__is_trivially_constructible, __autoreleasing id, __unsafe_unretained id); -TRAIT_IS_TRUE_2(__is_trivially_constructible, __autoreleasing id, __strong id&&); -TRAIT_IS_TRUE_2(__is_trivially_constructible, __autoreleasing id, __weak id&&); -TRAIT_IS_TRUE_2(__is_trivially_constructible, __autoreleasing id, __autoreleasing id&&); -TRAIT_IS_TRUE_2(__is_trivially_constructible, __autoreleasing id, __unsafe_unretained id&&); - -TRAIT_IS_TRUE_2(__is_trivially_constructible, __unsafe_unretained id, __strong id); -TRAIT_IS_TRUE_2(__is_trivially_constructible, __unsafe_unretained id, __weak id); -TRAIT_IS_TRUE_2(__is_trivially_constructible, __unsafe_unretained id, __autoreleasing id); -TRAIT_IS_TRUE_2(__is_trivially_constructible, __unsafe_unretained id, __unsafe_unretained id); -TRAIT_IS_TRUE_2(__is_trivially_constructible, __unsafe_unretained id, __strong id&&); -TRAIT_IS_TRUE_2(__is_trivially_constructible, __unsafe_unretained id, __weak id&&); -TRAIT_IS_TRUE_2(__is_trivially_constructible, __unsafe_unretained id, __autoreleasing id&&); -TRAIT_IS_TRUE_2(__is_trivially_constructible, __unsafe_unretained id, __unsafe_unretained id&&); - -TRAIT_IS_TRUE_2(__is_trivially_constructible, HasStrong, HasStrong); -TRAIT_IS_TRUE_2(__is_trivially_constructible, HasStrong, HasStrong&&); -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&&); +static_assert(__is_trivially_constructible(__strong id), ""); +static_assert(!__is_trivially_constructible(__weak id), ""); +static_assert(__is_trivially_constructible(__autoreleasing id), ""); +static_assert(__is_trivially_constructible(__unsafe_unretained id), ""); + +static_assert(__is_trivially_constructible(__strong id, __strong id), ""); +static_assert(__is_trivially_constructible(__strong id, __weak id), ""); +static_assert(__is_trivially_constructible(__strong id, __autoreleasing id), ""); +static_assert(__is_trivially_constructible(__strong id, __unsafe_unretained id), ""); +static_assert(__is_trivially_constructible(__strong id, __strong id&&), ""); +static_assert(__is_trivially_constructible(__strong id, __weak id&&), ""); +static_assert(__is_trivially_constructible(__strong id, __autoreleasing id&&), ""); +static_assert(__is_trivially_constructible(__strong id, __unsafe_unretained id&&), ""); +static_assert(!__is_trivially_constructible(__weak id, __strong id), ""); +static_assert(!__is_trivially_constructible(__weak id, __weak id), ""); +static_assert(!__is_trivially_constructible(__weak id, __autoreleasing id), ""); +static_assert(!__is_trivially_constructible(__weak id, __unsafe_unretained id), ""); +static_assert(!__is_trivially_constructible(__weak id, __strong id&&), ""); +static_assert(!__is_trivially_constructible(__weak id, __weak id&&), ""); +static_assert(!__is_trivially_constructible(__weak id, __autoreleasing id&&), ""); +static_assert(!__is_trivially_constructible(__weak id, __unsafe_unretained id&&), ""); + +static_assert(__is_trivially_constructible(__autoreleasing id, __strong id), ""); +static_assert(__is_trivially_constructible(__autoreleasing id, __weak id), ""); +static_assert(__is_trivially_constructible(__autoreleasing id, __autoreleasing id), ""); +static_assert(__is_trivially_constructible(__autoreleasing id, __unsafe_unretained id), ""); +static_assert(__is_trivially_constructible(__autoreleasing id, __strong id&&), ""); +static_assert(__is_trivially_constructible(__autoreleasing id, __weak id&&), ""); +static_assert(__is_trivially_constructible(__autoreleasing id, __autoreleasing id&&), ""); +static_assert(__is_trivially_constructible(__autoreleasing id, __unsafe_unretained id&&), ""); + +static_assert(__is_trivially_constructible(__unsafe_unretained id, __strong id), ""); +static_assert(__is_trivially_constructible(__unsafe_unretained id, __weak id), ""); +static_assert(__is_trivially_constructible(__unsafe_unretained id, __autoreleasing id), ""); +static_assert(__is_trivially_constructible(__unsafe_unretained id, __unsafe_unretained id), ""); +static_assert(__is_trivially_constructible(__unsafe_unretained id, __strong id&&), ""); +static_assert(__is_trivially_constructible(__unsafe_unretained id, __weak id&&), ""); +static_assert(__is_trivially_constructible(__unsafe_unretained id, __autoreleasing id&&), ""); +static_assert(__is_trivially_constructible(__unsafe_unretained id, __unsafe_unretained id&&), ""); + +static_assert(__is_trivially_constructible(HasStrong, HasStrong), ""); +static_assert(__is_trivially_constructible(HasStrong, HasStrong&&), ""); +static_assert(!__is_trivially_constructible(HasWeak, HasWeak), ""); +static_assert(!__is_trivially_constructible(HasWeak, HasWeak&&), ""); +static_assert(__is_trivially_constructible(HasUnsafeUnretained, HasUnsafeUnretained), ""); +static_assert(__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); +static_assert(__is_trivially_relocatable(__strong id), ""); +static_assert(!__is_trivially_relocatable(__weak id), ""); +static_assert(__is_trivially_relocatable(__autoreleasing id), ""); +static_assert(__is_trivially_relocatable(__unsafe_unretained id), ""); +static_assert(__is_trivially_relocatable(HasStrong), ""); +static_assert(!__is_trivially_relocatable(HasWeak), ""); +static_assert(__is_trivially_relocatable(HasUnsafeUnretained), ""); >From f860bb65f8fe82aa1d5b727abb20de1cb8164b7e Mon Sep 17 00:00:00 2001 From: Vlad Serebrennikov <serebrennikov.vladis...@gmail.com> Date: Sat, 29 Jun 2024 15:35:23 +0300 Subject: [PATCH 3/3] Prevent the warning from being issued in `__has_builtin` --- clang/include/clang/Lex/Preprocessor.h | 3 +++ clang/lib/Lex/PPMacroExpansion.cpp | 2 ++ clang/lib/Lex/Preprocessor.cpp | 2 +- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index 9d8a1aae23df3..810059cd47d03 100644 --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -1107,6 +1107,9 @@ class Preprocessor { /// Whether tokens are being skipped until the through header is seen. bool SkippingUntilPCHThroughHeader = false; + /// Whether we're evaluating __has_builtin(). + bool EvaluatingHasBuiltinMacro = false; + /// \{ /// Cache of macro expanders to reduce malloc traffic. enum { TokenLexerCacheSize = 8 }; diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp index f085b94371644..9b9d06c738aa8 100644 --- a/clang/lib/Lex/PPMacroExpansion.cpp +++ b/clang/lib/Lex/PPMacroExpansion.cpp @@ -1673,6 +1673,7 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) { return II && HasExtension(*this, II->getName()); }); } else if (II == Ident__has_builtin) { + EvaluatingHasBuiltinMacro = true; EvaluateFeatureLikeBuiltinMacro(OS, Tok, II, *this, false, [this](Token &Tok, bool &HasLexedNextToken) -> int { IdentifierInfo *II = ExpectFeatureIdentifierInfo(Tok, *this, @@ -1734,6 +1735,7 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) { .Default(false); } }); + EvaluatingHasBuiltinMacro = false; } else if (II == Ident__has_constexpr_builtin) { EvaluateFeatureLikeBuiltinMacro( OS, Tok, II, *this, false, diff --git a/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp index 7fb1e4db3b87e..e734183fbdbcb 100644 --- a/clang/lib/Lex/Preprocessor.cpp +++ b/clang/lib/Lex/Preprocessor.cpp @@ -837,7 +837,7 @@ bool Preprocessor::HandleIdentifier(Token &Identifier) { II.setIsFutureCompatKeyword(false); } - if (II.isReusableBuiltinName() && !isNextPPTokenLParen()) { + if (II.isReusableBuiltinName() && !isNextPPTokenLParen() && !EvaluatingHasBuiltinMacro) { Identifier.setKind(tok::identifier); Diag(Identifier, diag::warn_deprecated_builtin_replacement) << II.getName(); } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits