From ffb2291555f2c6ba5e6d76a68557f3820747e254 Mon Sep 17 00:00:00 2001 From: Corentin Jabot Date: Fri, 13 Jun 2025 19:30:01 +0200 Subject: [PATCH] =?UTF-8?q?Revert=20"[Clang]=20Added=20explanation=20why?= =?UTF-8?q?=20`is=5Fconstructible`=20evaluated=20to=20false.=20=E2=80=A6"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 02b6ed0bf139518c704a2996418e66f3a93260a1. --- .../clang/Basic/DiagnosticSemaKinds.td | 8 +-- clang/lib/Sema/SemaTypeTraits.cpp | 71 +------------------ clang/test/CXX/drs/cwg18xx.cpp | 3 +- ...overload-resolution-deferred-templates.cpp | 19 ++--- .../type-traits-unsatisfied-diags-std.cpp | 66 ----------------- .../SemaCXX/type-traits-unsatisfied-diags.cpp | 62 ---------------- 6 files changed, 10 insertions(+), 219 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 95d24e9f1e6b5..8fe7ad6138aa0 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -1767,8 +1767,7 @@ def note_unsatisfied_trait : Note<"%0 is not %enum_select{" "%TriviallyRelocatable{trivially relocatable}|" "%Replaceable{replaceable}|" - "%TriviallyCopyable{trivially copyable}|" - "%Constructible{constructible with provided types}" + "%TriviallyCopyable{trivially copyable}" "}1">; def note_unsatisfied_trait_reason @@ -1798,10 +1797,7 @@ def note_unsatisfied_trait_reason "%DeletedAssign{has a deleted %select{copy|move}1 " "assignment operator}|" "%UnionWithUserDeclaredSMF{is a union with a user-declared " - "%sub{select_special_member_kind}1}|" - "%FunctionType{is a function type}|" - "%CVVoidType{is a cv void type}|" - "%IncompleteArrayType{is an incomplete array type}" + "%sub{select_special_member_kind}1}" "}0">; def warn_consteval_if_always_true : Warning< diff --git a/clang/lib/Sema/SemaTypeTraits.cpp b/clang/lib/Sema/SemaTypeTraits.cpp index 22c690bedc1ed..1738ab4466001 100644 --- a/clang/lib/Sema/SemaTypeTraits.cpp +++ b/clang/lib/Sema/SemaTypeTraits.cpp @@ -11,7 +11,6 @@ //===----------------------------------------------------------------------===// #include "clang/AST/DeclCXX.h" -#include "clang/AST/TemplateBase.h" #include "clang/AST/Type.h" #include "clang/Basic/DiagnosticParse.h" #include "clang/Basic/DiagnosticSema.h" @@ -1948,7 +1947,6 @@ static std::optional StdNameToTypeTrait(StringRef Name) { TypeTrait::UTT_IsCppTriviallyRelocatable) .Case("is_replaceable", TypeTrait::UTT_IsReplaceable) .Case("is_trivially_copyable", TypeTrait::UTT_IsTriviallyCopyable) - .Case("is_constructible", TypeTrait::TT_IsConstructible) .Default(std::nullopt); } @@ -1985,16 +1983,8 @@ static ExtractedTypeTraitInfo ExtractTypeTraitFromExpression(const Expr *E) { Trait = StdNameToTypeTrait(Name); if (!Trait) return std::nullopt; - for (const auto &Arg : VD->getTemplateArgs().asArray()) { - if (Arg.getKind() == TemplateArgument::ArgKind::Pack) { - for (const auto &InnerArg : Arg.pack_elements()) - Args.push_back(InnerArg.getAsType()); - } else if (Arg.getKind() == TemplateArgument::ArgKind::Type) { - Args.push_back(Arg.getAsType()); - } else { - llvm_unreachable("Unexpected kind"); - } - } + for (const auto &Arg : VD->getTemplateArgs().asArray()) + Args.push_back(Arg.getAsType()); return {{Trait.value(), std::move(Args)}}; } @@ -2267,60 +2257,6 @@ static void DiagnoseNonTriviallyCopyableReason(Sema &SemaRef, } } -static void DiagnoseNonConstructibleReason( - Sema &SemaRef, SourceLocation Loc, - const llvm::SmallVector &Ts) { - if (Ts.empty()) { - return; - } - - bool ContainsVoid = false; - for (const QualType &ArgTy : Ts) { - ContainsVoid |= ArgTy->isVoidType(); - } - - if (ContainsVoid) - SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason) - << diag::TraitNotSatisfiedReason::CVVoidType; - - QualType T = Ts[0]; - if (T->isFunctionType()) - SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason) - << diag::TraitNotSatisfiedReason::FunctionType; - - if (T->isIncompleteArrayType()) - SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason) - << diag::TraitNotSatisfiedReason::IncompleteArrayType; - - const CXXRecordDecl *D = T->getAsCXXRecordDecl(); - if (!D || D->isInvalidDecl() || !D->hasDefinition()) - return; - - llvm::BumpPtrAllocator OpaqueExprAllocator; - SmallVector ArgExprs; - ArgExprs.reserve(Ts.size() - 1); - for (unsigned I = 1, N = Ts.size(); I != N; ++I) { - QualType ArgTy = Ts[I]; - if (ArgTy->isObjectType() || ArgTy->isFunctionType()) - ArgTy = SemaRef.Context.getRValueReferenceType(ArgTy); - ArgExprs.push_back( - new (OpaqueExprAllocator.Allocate()) - OpaqueValueExpr(Loc, ArgTy.getNonLValueExprType(SemaRef.Context), - Expr::getValueKindForType(ArgTy))); - } - - EnterExpressionEvaluationContext Unevaluated( - SemaRef, Sema::ExpressionEvaluationContext::Unevaluated); - Sema::ContextRAII TUContext(SemaRef, - SemaRef.Context.getTranslationUnitDecl()); - InitializedEntity To(InitializedEntity::InitializeTemporary(T)); - InitializationKind InitKind(InitializationKind::CreateDirect(Loc, Loc, Loc)); - InitializationSequence Init(SemaRef, To, InitKind, ArgExprs); - - Init.Diagnose(SemaRef, To, InitKind, ArgExprs); - SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D; -} - static void DiagnoseNonTriviallyCopyableReason(Sema &SemaRef, SourceLocation Loc, QualType T) { SemaRef.Diag(Loc, diag::note_unsatisfied_trait) @@ -2360,9 +2296,6 @@ void Sema::DiagnoseTypeTraitDetails(const Expr *E) { case UTT_IsTriviallyCopyable: DiagnoseNonTriviallyCopyableReason(*this, E->getBeginLoc(), Args[0]); break; - case TT_IsConstructible: - DiagnoseNonConstructibleReason(*this, E->getBeginLoc(), Args); - break; default: break; } diff --git a/clang/test/CXX/drs/cwg18xx.cpp b/clang/test/CXX/drs/cwg18xx.cpp index 9948075852135..5b4551ba0143b 100644 --- a/clang/test/CXX/drs/cwg18xx.cpp +++ b/clang/test/CXX/drs/cwg18xx.cpp @@ -564,12 +564,11 @@ struct A { namespace ex2 { #if __cplusplus >= 201103L struct Bar { - struct Baz { // #cwg1890-Baz + struct Baz { int a = 0; }; static_assert(__is_constructible(Baz), ""); // since-cxx11-error@-1 {{static assertion failed due to requirement '__is_constructible(cwg1890::ex2::Bar::Baz)'}} - // since-cxx11-note@#cwg1890-Baz {{'Baz' defined here}} }; #endif } // namespace ex2 diff --git a/clang/test/SemaCXX/overload-resolution-deferred-templates.cpp b/clang/test/SemaCXX/overload-resolution-deferred-templates.cpp index 46c3670848529..7cb71e075d50e 100644 --- a/clang/test/SemaCXX/overload-resolution-deferred-templates.cpp +++ b/clang/test/SemaCXX/overload-resolution-deferred-templates.cpp @@ -80,30 +80,21 @@ struct ImplicitlyCopyable { static_assert(__is_constructible(ImplicitlyCopyable, const ImplicitlyCopyable&)); -struct Movable { // #Movable +struct Movable { template requires __is_constructible(Movable, T) // #err-self-constraint-1 - explicit Movable(T op) noexcept; // #Movable1 - Movable(Movable&&) noexcept = default; // #Movable2 + explicit Movable(T op) noexcept; // #1 + Movable(Movable&&) noexcept = default; // #2 }; static_assert(__is_constructible(Movable, Movable&&)); static_assert(__is_constructible(Movable, const Movable&)); -// expected-error@-1 {{static assertion failed due to requirement '__is_constructible(Movable, const Movable &)'}} \ -// expected-error@-1 {{call to implicitly-deleted copy constructor of 'Movable'}} \ -// expected-note@#Movable {{'Movable' defined here}} \ -// expected-note@#Movable {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'int' to 'const Movable' for 1st argument}} \ -// expected-note@#Movable2 {{copy constructor is implicitly deleted because 'Movable' has a user-declared move constructor}} \ -// expected-note@#Movable2 {{candidate constructor not viable: no known conversion from 'int' to 'Movable' for 1st argument}} \ -// expected-note@#Movable1 {{candidate template ignored: constraints not satisfied [with T = int]}} - +// expected-error@-1 {{static assertion failed due to requirement '__is_constructible(Movable, const Movable &)'}} static_assert(__is_constructible(Movable, int)); -// expected-error@-1 {{static assertion failed due to requirement '__is_constructible(Movable, int)'}} \ -// expected-error@-1 {{no matching constructor for initialization of 'Movable'}} \ +// expected-error@-1{{static assertion failed due to requirement '__is_constructible(Movable, int)'}} \ // expected-note@-1 2{{}} // expected-error@#err-self-constraint-1{{satisfaction of constraint '__is_constructible(Movable, T)' depends on itself}} // expected-note@#err-self-constraint-1 4{{}} -// expected-note@#Movable {{'Movable' defined here}} template struct Members { diff --git a/clang/test/SemaCXX/type-traits-unsatisfied-diags-std.cpp b/clang/test/SemaCXX/type-traits-unsatisfied-diags-std.cpp index a403a0450607a..329b611110c1d 100644 --- a/clang/test/SemaCXX/type-traits-unsatisfied-diags-std.cpp +++ b/clang/test/SemaCXX/type-traits-unsatisfied-diags-std.cpp @@ -20,14 +20,6 @@ struct is_trivially_copyable { template constexpr bool is_trivially_copyable_v = __is_trivially_copyable(T); - -template -struct is_constructible { - static constexpr bool value = __is_constructible(Args...); -}; - -template -constexpr bool is_constructible_v = __is_constructible(Args...); #endif #ifdef STD2 @@ -52,17 +44,6 @@ using is_trivially_copyable = __details_is_trivially_copyable; template constexpr bool is_trivially_copyable_v = __is_trivially_copyable(T); - -template -struct __details_is_constructible{ - static constexpr bool value = __is_constructible(Args...); -}; - -template -using is_constructible = __details_is_constructible; - -template -constexpr bool is_constructible_v = __is_constructible(Args...); #endif @@ -92,15 +73,6 @@ using is_trivially_copyable = __details_is_trivially_copyable; template constexpr bool is_trivially_copyable_v = is_trivially_copyable::value; - -template -struct __details_is_constructible : bool_constant<__is_constructible(Args...)> {}; - -template -using is_constructible = __details_is_constructible; - -template -constexpr bool is_constructible_v = is_constructible::value; #endif } @@ -128,15 +100,6 @@ static_assert(std::is_trivially_copyable_v); // expected-note@-1 {{because it is a reference type}} -static_assert(std::is_constructible::value); - -static_assert(std::is_constructible::value); -// expected-error-re@-1 {{static assertion failed due to requirement 'std::{{.*}}is_constructible::value'}} \ -// expected-note@-1 {{because it is a cv void type}} -static_assert(std::is_constructible_v); -// expected-error@-1 {{static assertion failed due to requirement 'std::is_constructible_v'}} \ -// expected-note@-1 {{because it is a cv void type}} - namespace test_namespace { using namespace std; static_assert(is_trivially_relocatable::value); @@ -156,13 +119,6 @@ namespace test_namespace { // expected-error@-1 {{static assertion failed due to requirement 'is_trivially_copyable_v'}} \ // expected-note@-1 {{'int &' is not trivially copyable}} \ // expected-note@-1 {{because it is a reference type}} - - static_assert(is_constructible::value); - // expected-error-re@-1 {{static assertion failed due to requirement '{{.*}}is_constructible::value'}} \ - // expected-note@-1 {{because it is a cv void type}} - static_assert(is_constructible_v); - // expected-error@-1 {{static assertion failed due to requirement 'is_constructible_v'}} \ - // expected-note@-1 {{because it is a cv void type}} } @@ -183,15 +139,6 @@ concept C2 = std::is_trivially_copyable_v; // #concept4 template void g2(); // #cand4 -template -requires std::is_constructible::value void f3(); // #cand5 - -template -concept C3 = std::is_constructible_v; // #concept6 - -template void g3(); // #cand6 - - void test() { f(); // expected-error@-1 {{no matching function for call to 'f'}} \ @@ -222,19 +169,6 @@ void test() { // expected-note@#concept4 {{because 'std::is_trivially_copyable_v' evaluated to false}} \ // expected-note@#concept4 {{'int &' is not trivially copyable}} \ // expected-note@#concept4 {{because it is a reference type}} - - f3(); - // expected-error@-1 {{no matching function for call to 'f3'}} \ - // expected-note@#cand5 {{candidate template ignored: constraints not satisfied [with Args = ]}} \ - // expected-note-re@#cand5 {{because '{{.*}}is_constructible::value' evaluated to false}} \ - // expected-note@#cand5 {{because it is a cv void type}} - - g3(); - // expected-error@-1 {{no matching function for call to 'g3'}} \ - // expected-note@#cand6 {{candidate template ignored: constraints not satisfied [with T = void]}} \ - // expected-note@#cand6 {{because 'void' does not satisfy 'C3'}} \ - // expected-note@#concept6 {{because 'std::is_constructible_v' evaluated to false}} \ - // expected-note@#concept6 {{because it is a cv void type}} } } diff --git a/clang/test/SemaCXX/type-traits-unsatisfied-diags.cpp b/clang/test/SemaCXX/type-traits-unsatisfied-diags.cpp index d0b3f294fbcab..a8c78f6304ca9 100644 --- a/clang/test/SemaCXX/type-traits-unsatisfied-diags.cpp +++ b/clang/test/SemaCXX/type-traits-unsatisfied-diags.cpp @@ -488,65 +488,3 @@ static_assert(__is_trivially_copyable(S12)); // expected-note@-1 {{'S12' is not trivially copyable}} \ // expected-note@#tc-S12 {{'S12' defined here}} } - -namespace constructible { - -struct S1 { // #c-S1 - S1(int); // #cc-S1 -}; -static_assert(__is_constructible(S1, char*)); -// expected-error@-1 {{static assertion failed due to requirement '__is_constructible(constructible::S1, char *)'}} \ -// expected-error@-1 {{no matching constructor for initialization of 'S1'}} \ -// expected-note@#c-S1 {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'char *' to 'const S1' for 1st argument}} \ -// expected-note@#c-S1 {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'char *' to 'S1' for 1st argument}} \ -// expected-note@#cc-S1 {{candidate constructor not viable: no known conversion from 'char *' to 'int' for 1st argument; dereference the argument with *}} \ -// expected-note@#c-S1 {{'S1' defined here}} - -struct S2 { // #c-S2 - S2(int, float, double); // #cc-S2 -}; -static_assert(__is_constructible(S2, float)); -// expected-error@-1 {{static assertion failed due to requirement '__is_constructible(constructible::S2, float)'}} \ -// expected-note@#c-S2 {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'float' to 'const S2' for 1st argument}} \ -// expected-note@#c-S2 {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'float' to 'S2' for 1st argument}} \ -// expected-error@-1 {{no matching constructor for initialization of 'S2'}} \ -// expected-note@#cc-S2 {{candidate constructor not viable: requires 3 arguments, but 1 was provided}} \ -// expected-note@#c-S2 {{'S2' defined here}} - -static_assert(__is_constructible(S2, float, void)); -// expected-error@-1 {{static assertion failed due to requirement '__is_constructible(constructible::S2, float, void)'}} \ -// expected-note@#c-S2 {{candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 2 were provided}} \ -// expected-note@#c-S2 {{candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 2 were provided}} \ -// expected-note@-1{{because it is a cv void type}} \ -// expected-error@-1 {{no matching constructor for initialization of 'S2'}} \ -// expected-note@#cc-S2 {{candidate constructor not viable: requires 3 arguments, but 2 were provided}} \ -// expected-note@#c-S2 {{'S2' defined here}} - -static_assert(__is_constructible(int[])); -// expected-error@-1 {{static assertion failed due to requirement '__is_constructible(int[])'}} \ -// expected-note@-1 {{because it is an incomplete array type}} - -static_assert(__is_constructible(void)); -// expected-error@-1 {{static assertion failed due to requirement '__is_constructible(void)'}} \ -// expected-note@-1 {{because it is a cv void type}} - -static_assert(__is_constructible(void, void)); -// expected-error@-1 {{static assertion failed due to requirement '__is_constructible(void, void)'}} \ -// expected-note@-1 {{because it is a cv void type}} - -static_assert(__is_constructible(const void)); -// expected-error@-1 {{static assertion failed due to requirement '__is_constructible(const void)'}} \ -// expected-note@-1 {{because it is a cv void type}} - -static_assert(__is_constructible(volatile void)); -// expected-error@-1 {{static assertion failed due to requirement '__is_constructible(volatile void)'}} \ -// expected-note@-1 {{because it is a cv void type}} - -static_assert(__is_constructible(int ())); -// expected-error@-1 {{static assertion failed due to requirement '__is_constructible(int ())'}} \ -// expected-note@-1 {{because it is a function type}} - -static_assert(__is_constructible(void (int, float))); -// expected-error@-1 {{static assertion failed due to requirement '__is_constructible(void (int, float))'}} \ -// expected-note@-1 {{because it is a function type}} -}