[clang] 90d98a3 - Revert "[Clang] Added explanation why `is_constructible` evaluated to false. " (#144127)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Jun 13 12:05:47 PDT 2025
Author: Corentin Jabot
Date: 2025-06-13T21:05:44+02:00
New Revision: 90d98a38b273f5d62424a3815447675860947927
URL: https://github.com/llvm/llvm-project/commit/90d98a38b273f5d62424a3815447675860947927
DIFF: https://github.com/llvm/llvm-project/commit/90d98a38b273f5d62424a3815447675860947927.diff
LOG: Revert "[Clang] Added explanation why `is_constructible` evaluated to false. " (#144127)
Reverts llvm/llvm-project#143309
Someone needs to go through the libc++ tests and update the diagnostics
checks in those tests (ie, i don't believe there was anything wrong with
the PR, but it impacts libc++ tests nonetheless
Added:
Modified:
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/Sema/SemaTypeTraits.cpp
clang/test/CXX/drs/cwg18xx.cpp
clang/test/SemaCXX/overload-resolution-deferred-templates.cpp
clang/test/SemaCXX/type-traits-unsatisfied-diags-std.cpp
clang/test/SemaCXX/type-traits-unsatisfied-diags.cpp
Removed:
################################################################################
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<TraitName>{"
"%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<TypeTrait> 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<clang::QualType, 1> &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<Expr *, 2> 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>())
- 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 at -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 <typename T>
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 at -1 {{static assertion failed due to requirement '__is_constructible(Movable, const Movable &)'}} \
-// expected-error at -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 at -1 {{static assertion failed due to requirement '__is_constructible(Movable, const Movable &)'}}
static_assert(__is_constructible(Movable, int));
-// expected-error at -1 {{static assertion failed due to requirement '__is_constructible(Movable, int)'}} \
-// expected-error at -1 {{no matching constructor for initialization of 'Movable'}} \
+// expected-error at -1{{static assertion failed due to requirement '__is_constructible(Movable, int)'}} \
// expected-note at -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 <typename T>
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 <typename T>
constexpr bool is_trivially_copyable_v = __is_trivially_copyable(T);
-
-template <typename... Args>
-struct is_constructible {
- static constexpr bool value = __is_constructible(Args...);
-};
-
-template <typename... Args>
-constexpr bool is_constructible_v = __is_constructible(Args...);
#endif
#ifdef STD2
@@ -52,17 +44,6 @@ using is_trivially_copyable = __details_is_trivially_copyable<T>;
template <typename T>
constexpr bool is_trivially_copyable_v = __is_trivially_copyable(T);
-
-template <typename... Args>
-struct __details_is_constructible{
- static constexpr bool value = __is_constructible(Args...);
-};
-
-template <typename... Args>
-using is_constructible = __details_is_constructible<Args...>;
-
-template <typename... Args>
-constexpr bool is_constructible_v = __is_constructible(Args...);
#endif
@@ -92,15 +73,6 @@ using is_trivially_copyable = __details_is_trivially_copyable<T>;
template <typename T>
constexpr bool is_trivially_copyable_v = is_trivially_copyable<T>::value;
-
-template <typename... Args>
-struct __details_is_constructible : bool_constant<__is_constructible(Args...)> {};
-
-template <typename... Args>
-using is_constructible = __details_is_constructible<Args...>;
-
-template <typename... Args>
-constexpr bool is_constructible_v = is_constructible<Args...>::value;
#endif
}
@@ -128,15 +100,6 @@ static_assert(std::is_trivially_copyable_v<int&>);
// expected-note at -1 {{because it is a reference type}}
-static_assert(std::is_constructible<int, int>::value);
-
-static_assert(std::is_constructible<void>::value);
-// expected-error-re at -1 {{static assertion failed due to requirement 'std::{{.*}}is_constructible<void>::value'}} \
-// expected-note at -1 {{because it is a cv void type}}
-static_assert(std::is_constructible_v<void>);
-// expected-error at -1 {{static assertion failed due to requirement 'std::is_constructible_v<void>'}} \
-// expected-note at -1 {{because it is a cv void type}}
-
namespace test_namespace {
using namespace std;
static_assert(is_trivially_relocatable<int&>::value);
@@ -156,13 +119,6 @@ namespace test_namespace {
// expected-error at -1 {{static assertion failed due to requirement 'is_trivially_copyable_v<int &>'}} \
// expected-note at -1 {{'int &' is not trivially copyable}} \
// expected-note at -1 {{because it is a reference type}}
-
- static_assert(is_constructible<void>::value);
- // expected-error-re at -1 {{static assertion failed due to requirement '{{.*}}is_constructible<void>::value'}} \
- // expected-note at -1 {{because it is a cv void type}}
- static_assert(is_constructible_v<void>);
- // expected-error at -1 {{static assertion failed due to requirement 'is_constructible_v<void>'}} \
- // expected-note at -1 {{because it is a cv void type}}
}
@@ -183,15 +139,6 @@ concept C2 = std::is_trivially_copyable_v<T>; // #concept4
template <C2 T> void g2(); // #cand4
-template <typename... Args>
-requires std::is_constructible<Args...>::value void f3(); // #cand5
-
-template <typename... Args>
-concept C3 = std::is_constructible_v<Args...>; // #concept6
-
-template <C3 T> void g3(); // #cand6
-
-
void test() {
f<int&>();
// expected-error at -1 {{no matching function for call to 'f'}} \
@@ -222,19 +169,6 @@ void test() {
// expected-note@#concept4 {{because 'std::is_trivially_copyable_v<int &>' evaluated to false}} \
// expected-note@#concept4 {{'int &' is not trivially copyable}} \
// expected-note@#concept4 {{because it is a reference type}}
-
- f3<void>();
- // expected-error at -1 {{no matching function for call to 'f3'}} \
- // expected-note@#cand5 {{candidate template ignored: constraints not satisfied [with Args = <void>]}} \
- // expected-note-re@#cand5 {{because '{{.*}}is_constructible<void>::value' evaluated to false}} \
- // expected-note@#cand5 {{because it is a cv void type}}
-
- g3<void>();
- // expected-error at -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<void>' 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 at -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 at -1 {{static assertion failed due to requirement '__is_constructible(constructible::S1, char *)'}} \
-// expected-error at -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 at -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 at -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 at -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 at -1{{because it is a cv void type}} \
-// expected-error at -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 at -1 {{static assertion failed due to requirement '__is_constructible(int[])'}} \
-// expected-note at -1 {{because it is an incomplete array type}}
-
-static_assert(__is_constructible(void));
-// expected-error at -1 {{static assertion failed due to requirement '__is_constructible(void)'}} \
-// expected-note at -1 {{because it is a cv void type}}
-
-static_assert(__is_constructible(void, void));
-// expected-error at -1 {{static assertion failed due to requirement '__is_constructible(void, void)'}} \
-// expected-note at -1 {{because it is a cv void type}}
-
-static_assert(__is_constructible(const void));
-// expected-error at -1 {{static assertion failed due to requirement '__is_constructible(const void)'}} \
-// expected-note at -1 {{because it is a cv void type}}
-
-static_assert(__is_constructible(volatile void));
-// expected-error at -1 {{static assertion failed due to requirement '__is_constructible(volatile void)'}} \
-// expected-note at -1 {{because it is a cv void type}}
-
-static_assert(__is_constructible(int ()));
-// expected-error at -1 {{static assertion failed due to requirement '__is_constructible(int ())'}} \
-// expected-note at -1 {{because it is a function type}}
-
-static_assert(__is_constructible(void (int, float)));
-// expected-error at -1 {{static assertion failed due to requirement '__is_constructible(void (int, float))'}} \
-// expected-note at -1 {{because it is a function type}}
-}
More information about the cfe-commits
mailing list