[clang] [Clang] Diagnose unsatisfied `std::is_assignable`. (PR #144836)
@@ -99,6 +127,14 @@ static_assert(std::is_trivially_copyable_v); // expected-note@-1 {{'int &' is not trivially copyable}} \ // expected-note@-1 {{because it is a reference type}} +static_assert(std::is_assignable::value); + +static_assert(std::is_assignable::value); +// expected-error-re@-1 {{static assertion failed due to requirement 'std::{{.*}}is_assignable::value'}} \ +// expected-error@-1 {{assigning to 'int' from incompatible type 'void'}} rkirsling wrote: Right, at first I wondered if I needed to recapitulate all of these existing diagnostic messages somehow, just to ensure that it would all be `note`s against a single `error`. But it [appears](https://github.com/llvm/llvm-project/pull/144220/files#diff-9e681885bce5b9efd3dba53a469fb788e863d7d5f76c657232ea4c62a4147ab4) that `is_constructible` is also incurring a second `error` (via `InitializationSequence::Diagnose`). https://github.com/llvm/llvm-project/pull/144836 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Diagnose unsatisfied `std::is_assignable`. (PR #144836)
https://github.com/rkirsling edited https://github.com/llvm/llvm-project/pull/144836 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Fix typo in is_replaceable diagnostic (PR #144247)
rkirsling wrote: @ojhunt Thanks! Could you hit the green button for me as well? https://github.com/llvm/llvm-project/pull/144247 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Diagnose unsatisfied `std::is_assignable`. (PR #144836)
rkirsling wrote: Seems like I don't have the ability to add reviewers yet; pinging @cor3ntin and @AaronBallman for visibility. https://github.com/llvm/llvm-project/pull/144836 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [libcxx] [libc++][Clang] Added explanation why is_constructible evaluated to false. Updated the diagnostics checks in libc++ tests. (PR #144220)
@@ -1767,7 +1767,8 @@ def note_unsatisfied_trait : Note<"%0 is not %enum_select{" "%TriviallyRelocatable{trivially relocatable}|" "%Replaceable{replaceable}|" - "%TriviallyCopyable{trivially copyable}" + "%TriviallyCopyable{trivially copyable}|" + "%Constructible{constructible with provided types}" rkirsling wrote: Looks like this is no longer used in the latest version of the patch? https://github.com/llvm/llvm-project/pull/144220 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Diagnose unsatisfied `std::is_assignable`. (PR #144836)
https://github.com/rkirsling created https://github.com/llvm/llvm-project/pull/144836 Part of the work for #141911. Checking `is_assignable` boils down to checking the well-formedness of `declval() = declval()`; this PR recycles logic from EvaluateBinaryTypeTrait in order to produce the relevant diagnostics. >From ac74e32ad2045c27c5807ba880c0285872be3f43 Mon Sep 17 00:00:00 2001 From: Ross Kirsling Date: Wed, 18 Jun 2025 21:54:35 -0700 Subject: [PATCH] [Clang] Diagnose unsatisfied `std::is_assignable`. Part of the work for #141911. Checking `is_assignable` boils down to checking the well-formedness of `declval() = declval()`; this PR recycles logic from EvaluateBinaryTypeTrait in order to produce the relevant diagnostics. --- clang/lib/Sema/SemaTypeTraits.cpp | 29 .../type-traits-unsatisfied-diags-std.cpp | 65 + .../SemaCXX/type-traits-unsatisfied-diags.cpp | 71 +++ 3 files changed, 165 insertions(+) diff --git a/clang/lib/Sema/SemaTypeTraits.cpp b/clang/lib/Sema/SemaTypeTraits.cpp index 22c690bedc1ed..aa3208fe51271 100644 --- a/clang/lib/Sema/SemaTypeTraits.cpp +++ b/clang/lib/Sema/SemaTypeTraits.cpp @@ -1949,6 +1949,7 @@ static std::optional StdNameToTypeTrait(StringRef Name) { .Case("is_replaceable", TypeTrait::UTT_IsReplaceable) .Case("is_trivially_copyable", TypeTrait::UTT_IsTriviallyCopyable) .Case("is_constructible", TypeTrait::TT_IsConstructible) + .Case("is_assignable", TypeTrait::BTT_IsAssignable) .Default(std::nullopt); } @@ -2340,6 +2341,31 @@ static void DiagnoseNonTriviallyCopyableReason(Sema &SemaRef, SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D; } +static void DiagnoseNonAssignableReason(Sema &SemaRef, SourceLocation Loc, +QualType T, QualType U) { + const CXXRecordDecl *D = T->getAsCXXRecordDecl(); + + if (T->isObjectType() || T->isFunctionType()) +T = SemaRef.Context.getRValueReferenceType(T); + if (U->isObjectType() || U->isFunctionType()) +U = SemaRef.Context.getRValueReferenceType(U); + OpaqueValueExpr LHS(Loc, T.getNonLValueExprType(SemaRef.Context), + Expr::getValueKindForType(T)); + OpaqueValueExpr RHS(Loc, U.getNonLValueExprType(SemaRef.Context), + Expr::getValueKindForType(U)); + + EnterExpressionEvaluationContext Unevaluated( + SemaRef, Sema::ExpressionEvaluationContext::Unevaluated); + Sema::ContextRAII TUContext(SemaRef, + SemaRef.Context.getTranslationUnitDecl()); + SemaRef.BuildBinOp(/*S=*/nullptr, Loc, BO_Assign, &LHS, &RHS); + + if (!D || D->isInvalidDecl()) +return; + + SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D; +} + void Sema::DiagnoseTypeTraitDetails(const Expr *E) { E = E->IgnoreParenImpCasts(); if (E->containsErrors()) @@ -2363,6 +2389,9 @@ void Sema::DiagnoseTypeTraitDetails(const Expr *E) { case TT_IsConstructible: DiagnoseNonConstructibleReason(*this, E->getBeginLoc(), Args); break; + case BTT_IsAssignable: +DiagnoseNonAssignableReason(*this, E->getBeginLoc(), Args[0], Args[1]); +break; default: break; } diff --git a/clang/test/SemaCXX/type-traits-unsatisfied-diags-std.cpp b/clang/test/SemaCXX/type-traits-unsatisfied-diags-std.cpp index a403a0450607a..23391a799282f 100644 --- a/clang/test/SemaCXX/type-traits-unsatisfied-diags-std.cpp +++ b/clang/test/SemaCXX/type-traits-unsatisfied-diags-std.cpp @@ -28,6 +28,14 @@ struct is_constructible { template constexpr bool is_constructible_v = __is_constructible(Args...); + +template +struct is_assignable { +static constexpr bool value = __is_assignable(T, U); +}; + +template +constexpr bool is_assignable_v = __is_assignable(T, U); #endif #ifdef STD2 @@ -63,6 +71,17 @@ using is_constructible = __details_is_constructible; template constexpr bool is_constructible_v = __is_constructible(Args...); + +template +struct __details_is_assignable { +static constexpr bool value = __is_assignable(T, U); +}; + +template +using is_assignable = __details_is_assignable; + +template +constexpr bool is_assignable_v = __is_assignable(T, U); #endif @@ -101,6 +120,15 @@ using is_constructible = __details_is_constructible; template constexpr bool is_constructible_v = is_constructible::value; + +template +struct __details_is_assignable : bool_constant<__is_assignable(T, U)> {}; + +template +using is_assignable = __details_is_assignable; + +template +constexpr bool is_assignable_v = is_assignable::value; #endif } @@ -137,6 +165,15 @@ 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}} +static_assert(std::is_assignable::value); + +static_assert(std::is_assignable::value); +// expected-error-re@-1 {{static assertion failed due to require
[clang] [Clang] Diagnose unsatisfied `std::is_assignable`. (PR #144836)
https://github.com/rkirsling updated https://github.com/llvm/llvm-project/pull/144836 >From 580750339643b627552a1c726909dd5d12f3c9af Mon Sep 17 00:00:00 2001 From: Ross Kirsling Date: Wed, 18 Jun 2025 21:54:35 -0700 Subject: [PATCH] [Clang] Diagnose unsatisfied `std::is_assignable`. Part of the work for #141911. Checking `is_assignable` boils down to checking the well-formedness of `declval() = declval()`; this PR recycles logic from EvaluateBinaryTypeTrait in order to produce the relevant diagnostics. --- clang/lib/Sema/SemaTypeTraits.cpp | 29 .../type-traits-unsatisfied-diags-std.cpp | 64 + .../SemaCXX/type-traits-unsatisfied-diags.cpp | 71 +++ 3 files changed, 164 insertions(+) diff --git a/clang/lib/Sema/SemaTypeTraits.cpp b/clang/lib/Sema/SemaTypeTraits.cpp index 4dbb2450857e0..1d4b6b7f34775 100644 --- a/clang/lib/Sema/SemaTypeTraits.cpp +++ b/clang/lib/Sema/SemaTypeTraits.cpp @@ -1956,6 +1956,7 @@ static std::optional StdNameToTypeTrait(StringRef Name) { TypeTrait::UTT_IsCppTriviallyRelocatable) .Case("is_replaceable", TypeTrait::UTT_IsReplaceable) .Case("is_trivially_copyable", TypeTrait::UTT_IsTriviallyCopyable) + .Case("is_assignable", TypeTrait::BTT_IsAssignable) .Default(std::nullopt); } @@ -2285,6 +2286,31 @@ static void DiagnoseNonTriviallyCopyableReason(Sema &SemaRef, SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D; } +static void DiagnoseNonAssignableReason(Sema &SemaRef, SourceLocation Loc, +QualType T, QualType U) { + const CXXRecordDecl *D = T->getAsCXXRecordDecl(); + + if (T->isObjectType() || T->isFunctionType()) +T = SemaRef.Context.getRValueReferenceType(T); + if (U->isObjectType() || U->isFunctionType()) +U = SemaRef.Context.getRValueReferenceType(U); + OpaqueValueExpr LHS(Loc, T.getNonLValueExprType(SemaRef.Context), + Expr::getValueKindForType(T)); + OpaqueValueExpr RHS(Loc, U.getNonLValueExprType(SemaRef.Context), + Expr::getValueKindForType(U)); + + EnterExpressionEvaluationContext Unevaluated( + SemaRef, Sema::ExpressionEvaluationContext::Unevaluated); + Sema::ContextRAII TUContext(SemaRef, + SemaRef.Context.getTranslationUnitDecl()); + SemaRef.BuildBinOp(/*S=*/nullptr, Loc, BO_Assign, &LHS, &RHS); + + if (!D || D->isInvalidDecl()) +return; + + SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D; +} + void Sema::DiagnoseTypeTraitDetails(const Expr *E) { E = E->IgnoreParenImpCasts(); if (E->containsErrors()) @@ -2305,6 +2331,9 @@ void Sema::DiagnoseTypeTraitDetails(const Expr *E) { case UTT_IsTriviallyCopyable: DiagnoseNonTriviallyCopyableReason(*this, E->getBeginLoc(), Args[0]); break; + case BTT_IsAssignable: +DiagnoseNonAssignableReason(*this, E->getBeginLoc(), Args[0], Args[1]); +break; default: break; } diff --git a/clang/test/SemaCXX/type-traits-unsatisfied-diags-std.cpp b/clang/test/SemaCXX/type-traits-unsatisfied-diags-std.cpp index 329b60c1d..33b92326aec21 100644 --- a/clang/test/SemaCXX/type-traits-unsatisfied-diags-std.cpp +++ b/clang/test/SemaCXX/type-traits-unsatisfied-diags-std.cpp @@ -20,6 +20,14 @@ struct is_trivially_copyable { template constexpr bool is_trivially_copyable_v = __is_trivially_copyable(T); + +template +struct is_assignable { +static constexpr bool value = __is_assignable(T, U); +}; + +template +constexpr bool is_assignable_v = __is_assignable(T, U); #endif #ifdef STD2 @@ -44,6 +52,17 @@ using is_trivially_copyable = __details_is_trivially_copyable; template constexpr bool is_trivially_copyable_v = __is_trivially_copyable(T); + +template +struct __details_is_assignable { +static constexpr bool value = __is_assignable(T, U); +}; + +template +using is_assignable = __details_is_assignable; + +template +constexpr bool is_assignable_v = __is_assignable(T, U); #endif @@ -73,6 +92,15 @@ using is_trivially_copyable = __details_is_trivially_copyable; template constexpr bool is_trivially_copyable_v = is_trivially_copyable::value; + +template +struct __details_is_assignable : bool_constant<__is_assignable(T, U)> {}; + +template +using is_assignable = __details_is_assignable; + +template +constexpr bool is_assignable_v = is_assignable::value; #endif } @@ -99,6 +127,14 @@ static_assert(std::is_trivially_copyable_v); // expected-note@-1 {{'int &' is not trivially copyable}} \ // expected-note@-1 {{because it is a reference type}} +static_assert(std::is_assignable::value); + +static_assert(std::is_assignable::value); +// expected-error-re@-1 {{static assertion failed due to requirement 'std::{{.*}}is_assignable::value'}} \ +// expected-error@-1 {{assigning to 'int' from incompatible type 'void'}} +static_assert(std::is_assignable_v); +// expected-error@-1 {{static assertion failed due to req
[clang] [Clang] Diagnose unsatisfied `std::is_assignable`. (PR #144836)
https://github.com/rkirsling updated https://github.com/llvm/llvm-project/pull/144836 >From 580750339643b627552a1c726909dd5d12f3c9af Mon Sep 17 00:00:00 2001 From: Ross Kirsling Date: Wed, 18 Jun 2025 21:54:35 -0700 Subject: [PATCH 1/3] [Clang] Diagnose unsatisfied `std::is_assignable`. Part of the work for #141911. Checking `is_assignable` boils down to checking the well-formedness of `declval() = declval()`; this PR recycles logic from EvaluateBinaryTypeTrait in order to produce the relevant diagnostics. --- clang/lib/Sema/SemaTypeTraits.cpp | 29 .../type-traits-unsatisfied-diags-std.cpp | 64 + .../SemaCXX/type-traits-unsatisfied-diags.cpp | 71 +++ 3 files changed, 164 insertions(+) diff --git a/clang/lib/Sema/SemaTypeTraits.cpp b/clang/lib/Sema/SemaTypeTraits.cpp index 4dbb2450857e0..1d4b6b7f34775 100644 --- a/clang/lib/Sema/SemaTypeTraits.cpp +++ b/clang/lib/Sema/SemaTypeTraits.cpp @@ -1956,6 +1956,7 @@ static std::optional StdNameToTypeTrait(StringRef Name) { TypeTrait::UTT_IsCppTriviallyRelocatable) .Case("is_replaceable", TypeTrait::UTT_IsReplaceable) .Case("is_trivially_copyable", TypeTrait::UTT_IsTriviallyCopyable) + .Case("is_assignable", TypeTrait::BTT_IsAssignable) .Default(std::nullopt); } @@ -2285,6 +2286,31 @@ static void DiagnoseNonTriviallyCopyableReason(Sema &SemaRef, SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D; } +static void DiagnoseNonAssignableReason(Sema &SemaRef, SourceLocation Loc, +QualType T, QualType U) { + const CXXRecordDecl *D = T->getAsCXXRecordDecl(); + + if (T->isObjectType() || T->isFunctionType()) +T = SemaRef.Context.getRValueReferenceType(T); + if (U->isObjectType() || U->isFunctionType()) +U = SemaRef.Context.getRValueReferenceType(U); + OpaqueValueExpr LHS(Loc, T.getNonLValueExprType(SemaRef.Context), + Expr::getValueKindForType(T)); + OpaqueValueExpr RHS(Loc, U.getNonLValueExprType(SemaRef.Context), + Expr::getValueKindForType(U)); + + EnterExpressionEvaluationContext Unevaluated( + SemaRef, Sema::ExpressionEvaluationContext::Unevaluated); + Sema::ContextRAII TUContext(SemaRef, + SemaRef.Context.getTranslationUnitDecl()); + SemaRef.BuildBinOp(/*S=*/nullptr, Loc, BO_Assign, &LHS, &RHS); + + if (!D || D->isInvalidDecl()) +return; + + SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D; +} + void Sema::DiagnoseTypeTraitDetails(const Expr *E) { E = E->IgnoreParenImpCasts(); if (E->containsErrors()) @@ -2305,6 +2331,9 @@ void Sema::DiagnoseTypeTraitDetails(const Expr *E) { case UTT_IsTriviallyCopyable: DiagnoseNonTriviallyCopyableReason(*this, E->getBeginLoc(), Args[0]); break; + case BTT_IsAssignable: +DiagnoseNonAssignableReason(*this, E->getBeginLoc(), Args[0], Args[1]); +break; default: break; } diff --git a/clang/test/SemaCXX/type-traits-unsatisfied-diags-std.cpp b/clang/test/SemaCXX/type-traits-unsatisfied-diags-std.cpp index 329b60c1d..33b92326aec21 100644 --- a/clang/test/SemaCXX/type-traits-unsatisfied-diags-std.cpp +++ b/clang/test/SemaCXX/type-traits-unsatisfied-diags-std.cpp @@ -20,6 +20,14 @@ struct is_trivially_copyable { template constexpr bool is_trivially_copyable_v = __is_trivially_copyable(T); + +template +struct is_assignable { +static constexpr bool value = __is_assignable(T, U); +}; + +template +constexpr bool is_assignable_v = __is_assignable(T, U); #endif #ifdef STD2 @@ -44,6 +52,17 @@ using is_trivially_copyable = __details_is_trivially_copyable; template constexpr bool is_trivially_copyable_v = __is_trivially_copyable(T); + +template +struct __details_is_assignable { +static constexpr bool value = __is_assignable(T, U); +}; + +template +using is_assignable = __details_is_assignable; + +template +constexpr bool is_assignable_v = __is_assignable(T, U); #endif @@ -73,6 +92,15 @@ using is_trivially_copyable = __details_is_trivially_copyable; template constexpr bool is_trivially_copyable_v = is_trivially_copyable::value; + +template +struct __details_is_assignable : bool_constant<__is_assignable(T, U)> {}; + +template +using is_assignable = __details_is_assignable; + +template +constexpr bool is_assignable_v = is_assignable::value; #endif } @@ -99,6 +127,14 @@ static_assert(std::is_trivially_copyable_v); // expected-note@-1 {{'int &' is not trivially copyable}} \ // expected-note@-1 {{because it is a reference type}} +static_assert(std::is_assignable::value); + +static_assert(std::is_assignable::value); +// expected-error-re@-1 {{static assertion failed due to requirement 'std::{{.*}}is_assignable::value'}} \ +// expected-error@-1 {{assigning to 'int' from incompatible type 'void'}} +static_assert(std::is_assignable_v); +// expected-error@-1 {{static assertion failed due to
[clang] [Clang] Diagnose unsatisfied `std::is_assignable`. (PR #144836)
https://github.com/rkirsling updated https://github.com/llvm/llvm-project/pull/144836 >From 580750339643b627552a1c726909dd5d12f3c9af Mon Sep 17 00:00:00 2001 From: Ross Kirsling Date: Wed, 18 Jun 2025 21:54:35 -0700 Subject: [PATCH 1/2] [Clang] Diagnose unsatisfied `std::is_assignable`. Part of the work for #141911. Checking `is_assignable` boils down to checking the well-formedness of `declval() = declval()`; this PR recycles logic from EvaluateBinaryTypeTrait in order to produce the relevant diagnostics. --- clang/lib/Sema/SemaTypeTraits.cpp | 29 .../type-traits-unsatisfied-diags-std.cpp | 64 + .../SemaCXX/type-traits-unsatisfied-diags.cpp | 71 +++ 3 files changed, 164 insertions(+) diff --git a/clang/lib/Sema/SemaTypeTraits.cpp b/clang/lib/Sema/SemaTypeTraits.cpp index 4dbb2450857e0..1d4b6b7f34775 100644 --- a/clang/lib/Sema/SemaTypeTraits.cpp +++ b/clang/lib/Sema/SemaTypeTraits.cpp @@ -1956,6 +1956,7 @@ static std::optional StdNameToTypeTrait(StringRef Name) { TypeTrait::UTT_IsCppTriviallyRelocatable) .Case("is_replaceable", TypeTrait::UTT_IsReplaceable) .Case("is_trivially_copyable", TypeTrait::UTT_IsTriviallyCopyable) + .Case("is_assignable", TypeTrait::BTT_IsAssignable) .Default(std::nullopt); } @@ -2285,6 +2286,31 @@ static void DiagnoseNonTriviallyCopyableReason(Sema &SemaRef, SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D; } +static void DiagnoseNonAssignableReason(Sema &SemaRef, SourceLocation Loc, +QualType T, QualType U) { + const CXXRecordDecl *D = T->getAsCXXRecordDecl(); + + if (T->isObjectType() || T->isFunctionType()) +T = SemaRef.Context.getRValueReferenceType(T); + if (U->isObjectType() || U->isFunctionType()) +U = SemaRef.Context.getRValueReferenceType(U); + OpaqueValueExpr LHS(Loc, T.getNonLValueExprType(SemaRef.Context), + Expr::getValueKindForType(T)); + OpaqueValueExpr RHS(Loc, U.getNonLValueExprType(SemaRef.Context), + Expr::getValueKindForType(U)); + + EnterExpressionEvaluationContext Unevaluated( + SemaRef, Sema::ExpressionEvaluationContext::Unevaluated); + Sema::ContextRAII TUContext(SemaRef, + SemaRef.Context.getTranslationUnitDecl()); + SemaRef.BuildBinOp(/*S=*/nullptr, Loc, BO_Assign, &LHS, &RHS); + + if (!D || D->isInvalidDecl()) +return; + + SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D; +} + void Sema::DiagnoseTypeTraitDetails(const Expr *E) { E = E->IgnoreParenImpCasts(); if (E->containsErrors()) @@ -2305,6 +2331,9 @@ void Sema::DiagnoseTypeTraitDetails(const Expr *E) { case UTT_IsTriviallyCopyable: DiagnoseNonTriviallyCopyableReason(*this, E->getBeginLoc(), Args[0]); break; + case BTT_IsAssignable: +DiagnoseNonAssignableReason(*this, E->getBeginLoc(), Args[0], Args[1]); +break; default: break; } diff --git a/clang/test/SemaCXX/type-traits-unsatisfied-diags-std.cpp b/clang/test/SemaCXX/type-traits-unsatisfied-diags-std.cpp index 329b60c1d..33b92326aec21 100644 --- a/clang/test/SemaCXX/type-traits-unsatisfied-diags-std.cpp +++ b/clang/test/SemaCXX/type-traits-unsatisfied-diags-std.cpp @@ -20,6 +20,14 @@ struct is_trivially_copyable { template constexpr bool is_trivially_copyable_v = __is_trivially_copyable(T); + +template +struct is_assignable { +static constexpr bool value = __is_assignable(T, U); +}; + +template +constexpr bool is_assignable_v = __is_assignable(T, U); #endif #ifdef STD2 @@ -44,6 +52,17 @@ using is_trivially_copyable = __details_is_trivially_copyable; template constexpr bool is_trivially_copyable_v = __is_trivially_copyable(T); + +template +struct __details_is_assignable { +static constexpr bool value = __is_assignable(T, U); +}; + +template +using is_assignable = __details_is_assignable; + +template +constexpr bool is_assignable_v = __is_assignable(T, U); #endif @@ -73,6 +92,15 @@ using is_trivially_copyable = __details_is_trivially_copyable; template constexpr bool is_trivially_copyable_v = is_trivially_copyable::value; + +template +struct __details_is_assignable : bool_constant<__is_assignable(T, U)> {}; + +template +using is_assignable = __details_is_assignable; + +template +constexpr bool is_assignable_v = is_assignable::value; #endif } @@ -99,6 +127,14 @@ static_assert(std::is_trivially_copyable_v); // expected-note@-1 {{'int &' is not trivially copyable}} \ // expected-note@-1 {{because it is a reference type}} +static_assert(std::is_assignable::value); + +static_assert(std::is_assignable::value); +// expected-error-re@-1 {{static assertion failed due to requirement 'std::{{.*}}is_assignable::value'}} \ +// expected-error@-1 {{assigning to 'int' from incompatible type 'void'}} +static_assert(std::is_assignable_v); +// expected-error@-1 {{static assertion failed due to
[clang] [Clang] Diagnose unsatisfied `std::is_assignable`. (PR #144836)
@@ -1725,14 +1725,15 @@ static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, // Build expressions that emulate the effect of declval() and // declval(). -if (LhsT->isObjectType() || LhsT->isFunctionType()) - LhsT = Self.Context.getRValueReferenceType(LhsT); -if (RhsT->isObjectType() || RhsT->isFunctionType()) - RhsT = Self.Context.getRValueReferenceType(RhsT); -OpaqueValueExpr Lhs(KeyLoc, LhsT.getNonLValueExprType(Self.Context), -Expr::getValueKindForType(LhsT)); -OpaqueValueExpr Rhs(KeyLoc, RhsT.getNonLValueExprType(Self.Context), -Expr::getValueKindForType(RhsT)); +auto createOpaqueExpr = [&](QualType Ty) -> OpaqueValueExpr { rkirsling wrote: Oh, sure. No worries! https://github.com/llvm/llvm-project/pull/144836 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Diagnose unsatisfied `std::is_assignable`. (PR #144836)
@@ -2285,6 +2286,31 @@ static void DiagnoseNonTriviallyCopyableReason(Sema &SemaRef, SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D; } +static void DiagnoseNonAssignableReason(Sema &SemaRef, SourceLocation Loc, +QualType T, QualType U) { + const CXXRecordDecl *D = T->getAsCXXRecordDecl(); + + if (T->isObjectType() || T->isFunctionType()) rkirsling wrote: Sounds great! Updated. https://github.com/llvm/llvm-project/pull/144836 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Fix fix-it hint regression from #143460 (PR #144069)
https://github.com/rkirsling updated https://github.com/llvm/llvm-project/pull/144069 >From be121c500684e971ad696be8d53db732665d851c Mon Sep 17 00:00:00 2001 From: Ross Kirsling Date: Fri, 13 Jun 2025 21:51:25 +0900 Subject: [PATCH 1/3] [Clang] Fix fix-it hint regression from #143460 `:` began displaying as `colon` in the fix-it hint for a `case` with a missing colon. --- clang/lib/Parse/ParseStmt.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index 434ea68442819..c0c9bbc2e15c6 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -836,8 +836,7 @@ StmtResult Parser::ParseCaseStatement(ParsedStmtContext StmtCtx, Diag(ExpectedLoc, diag::err_expected_after) << "'case'" << tok::colon - << FixItHint::CreateInsertion(ExpectedLoc, -tok::getTokenName(tok::colon)); + << FixItHint::CreateInsertion(ExpectedLoc, ":"); ColonLoc = ExpectedLoc; } >From 26f4db70221b106b286566c1434530848567e849 Mon Sep 17 00:00:00 2001 From: Ross Kirsling Date: Fri, 13 Jun 2025 22:08:26 +0900 Subject: [PATCH 2/3] Update test case. --- clang/test/Parser/switch-recovery.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/clang/test/Parser/switch-recovery.cpp b/clang/test/Parser/switch-recovery.cpp index 40712799933c2..b84c3f0a9865e 100644 --- a/clang/test/Parser/switch-recovery.cpp +++ b/clang/test/Parser/switch-recovery.cpp @@ -236,6 +236,9 @@ namespace GH143216 { int f(int x) { switch (x) { case FOO // expected-error {{expected ':' after 'case'}} + // CHECK: {{^}} case FOO + // CHECK: {{^}} ^ + // CHECK: {{^}} : return 0; default: return 1; >From 425228fcf90c068dd05620ee4c57e6075e25430a Mon Sep 17 00:00:00 2001 From: Ross Kirsling Date: Sat, 14 Jun 2025 00:31:12 +0900 Subject: [PATCH 3/3] Move test to new file. --- clang/test/FixIt/fixit-punctuator-spelling.cpp | 10 ++ clang/test/Parser/switch-recovery.cpp | 3 --- 2 files changed, 10 insertions(+), 3 deletions(-) create mode 100644 clang/test/FixIt/fixit-punctuator-spelling.cpp diff --git a/clang/test/FixIt/fixit-punctuator-spelling.cpp b/clang/test/FixIt/fixit-punctuator-spelling.cpp new file mode 100644 index 0..3cba0e7b64594 --- /dev/null +++ b/clang/test/FixIt/fixit-punctuator-spelling.cpp @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: not %clang_cc1 -fsyntax-only -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s + +void f(int x) { + switch (x) { +case 1 // expected-error {{expected ':' after 'case'}} + break; + } +} +// CHECK: fix-it:"{{.*}}":{6:11-6:11}:":" diff --git a/clang/test/Parser/switch-recovery.cpp b/clang/test/Parser/switch-recovery.cpp index b84c3f0a9865e..40712799933c2 100644 --- a/clang/test/Parser/switch-recovery.cpp +++ b/clang/test/Parser/switch-recovery.cpp @@ -236,9 +236,6 @@ namespace GH143216 { int f(int x) { switch (x) { case FOO // expected-error {{expected ':' after 'case'}} - // CHECK: {{^}} case FOO - // CHECK: {{^}} ^ - // CHECK: {{^}} : return 0; default: return 1; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Fix fix-it hint regression from #143460 (PR #144069)
rkirsling wrote: @AaronBallman Looks like this is the PR we're going with after all—could I have you merge it for me? Thanks! :bow: https://github.com/llvm/llvm-project/pull/144069 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] use colon char instead of token name (PR #144068)
rkirsling wrote: Ohh, you beat me by a minute. 😆 I can close #144069 then. https://github.com/llvm/llvm-project/pull/144068 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] fix missing source location for errors in macro-expanded (PR #143460)
@@ -832,10 +832,13 @@ StmtResult Parser::ParseCaseStatement(ParsedStmtContext StmtCtx, << "'case'" << tok::colon << FixItHint::CreateReplacement(ColonLoc, ":"); } else { - SourceLocation ExpectedLoc = PP.getLocForEndOfToken(PrevTokLocation); + SourceLocation ExpectedLoc = getEndOfPreviousToken(); + Diag(ExpectedLoc, diag::err_expected_after) << "'case'" << tok::colon - << FixItHint::CreateInsertion(ExpectedLoc, ":"); + << FixItHint::CreateInsertion(ExpectedLoc, +tok::getTokenName(tok::colon)); rkirsling wrote: Opened #144069, since it's such a quick fix. https://github.com/llvm/llvm-project/pull/143460 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Fix fix-it hint regression from #143460 (PR #144069)
https://github.com/rkirsling created https://github.com/llvm/llvm-project/pull/144069 Following #143460, `:` began displaying as `colon` in the fix-it hint for a `case` with a missing colon, as is visible in the description of (the separate bug) #144052. This PR simply reverts a line that didn't need to be changed. >From be121c500684e971ad696be8d53db732665d851c Mon Sep 17 00:00:00 2001 From: Ross Kirsling Date: Fri, 13 Jun 2025 21:51:25 +0900 Subject: [PATCH] [Clang] Fix fix-it hint regression from #143460 `:` began displaying as `colon` in the fix-it hint for a `case` with a missing colon. --- clang/lib/Parse/ParseStmt.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index 434ea68442819..c0c9bbc2e15c6 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -836,8 +836,7 @@ StmtResult Parser::ParseCaseStatement(ParsedStmtContext StmtCtx, Diag(ExpectedLoc, diag::err_expected_after) << "'case'" << tok::colon - << FixItHint::CreateInsertion(ExpectedLoc, -tok::getTokenName(tok::colon)); + << FixItHint::CreateInsertion(ExpectedLoc, ":"); ColonLoc = ExpectedLoc; } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Fix fix-it hint regression from #143460 (PR #144069)
https://github.com/rkirsling updated https://github.com/llvm/llvm-project/pull/144069 >From be121c500684e971ad696be8d53db732665d851c Mon Sep 17 00:00:00 2001 From: Ross Kirsling Date: Fri, 13 Jun 2025 21:51:25 +0900 Subject: [PATCH 1/2] [Clang] Fix fix-it hint regression from #143460 `:` began displaying as `colon` in the fix-it hint for a `case` with a missing colon. --- clang/lib/Parse/ParseStmt.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index 434ea68442819..c0c9bbc2e15c6 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -836,8 +836,7 @@ StmtResult Parser::ParseCaseStatement(ParsedStmtContext StmtCtx, Diag(ExpectedLoc, diag::err_expected_after) << "'case'" << tok::colon - << FixItHint::CreateInsertion(ExpectedLoc, -tok::getTokenName(tok::colon)); + << FixItHint::CreateInsertion(ExpectedLoc, ":"); ColonLoc = ExpectedLoc; } >From 26f4db70221b106b286566c1434530848567e849 Mon Sep 17 00:00:00 2001 From: Ross Kirsling Date: Fri, 13 Jun 2025 22:08:26 +0900 Subject: [PATCH 2/2] Update test case. --- clang/test/Parser/switch-recovery.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/clang/test/Parser/switch-recovery.cpp b/clang/test/Parser/switch-recovery.cpp index 40712799933c2..b84c3f0a9865e 100644 --- a/clang/test/Parser/switch-recovery.cpp +++ b/clang/test/Parser/switch-recovery.cpp @@ -236,6 +236,9 @@ namespace GH143216 { int f(int x) { switch (x) { case FOO // expected-error {{expected ':' after 'case'}} + // CHECK: {{^}} case FOO + // CHECK: {{^}} ^ + // CHECK: {{^}} : return 0; default: return 1; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] use colon char instead of token name (PR #144068)
rkirsling wrote: I believe I'd need somebody to hit the merge button for me regardless, so I think we can just merge whichever one and close the other. 😅 The two approaches are mostly the same, I just figured that the surrounding code was consistent in using a literal `":"`, while there doesn't seem to be a precedent for using `tok::getPunctuatorSpelling` with a constant. Either way, sorry to cause a run-around! https://github.com/llvm/llvm-project/pull/144068 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] use colon char instead of token name (PR #144068)
rkirsling wrote: Oh oops! Thanks for the correction. https://github.com/llvm/llvm-project/pull/144068 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] fix missing source location for errors in macro-expanded (PR #143460)
@@ -832,10 +832,13 @@ StmtResult Parser::ParseCaseStatement(ParsedStmtContext StmtCtx, << "'case'" << tok::colon << FixItHint::CreateReplacement(ColonLoc, ":"); } else { - SourceLocation ExpectedLoc = PP.getLocForEndOfToken(PrevTokLocation); + SourceLocation ExpectedLoc = getEndOfPreviousToken(); + Diag(ExpectedLoc, diag::err_expected_after) << "'case'" << tok::colon - << FixItHint::CreateInsertion(ExpectedLoc, ":"); + << FixItHint::CreateInsertion(ExpectedLoc, +tok::getTokenName(tok::colon)); rkirsling wrote: Whoops, looks like this caused the word `colon` to be displayed instead of `:`. https://godbolt.org/z/rjzdsKqqh https://github.com/llvm/llvm-project/pull/143460 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] fix missing source location for errors in macro-expanded (PR #143460)
@@ -832,10 +832,13 @@ StmtResult Parser::ParseCaseStatement(ParsedStmtContext StmtCtx, << "'case'" << tok::colon << FixItHint::CreateReplacement(ColonLoc, ":"); } else { - SourceLocation ExpectedLoc = PP.getLocForEndOfToken(PrevTokLocation); + SourceLocation ExpectedLoc = getEndOfPreviousToken(); + Diag(ExpectedLoc, diag::err_expected_after) << "'case'" << tok::colon - << FixItHint::CreateInsertion(ExpectedLoc, ":"); + << FixItHint::CreateInsertion(ExpectedLoc, +tok::getTokenName(tok::colon)); rkirsling wrote: Sure! Checking locally, it looks like this line could be safely reverted. Lemme know if you'd prefer me to submit the fix instead. https://github.com/llvm/llvm-project/pull/143460 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Fix fix-it hint regression from #143460 (PR #144069)
rkirsling wrote: (This seems to be an intermittent existing failure.) https://github.com/llvm/llvm-project/pull/144069 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Fix typo in is_replaceable diagnostic (PR #144247)
https://github.com/rkirsling created https://github.com/llvm/llvm-project/pull/144247 Adjustment to #143265; `because it not` should be `because it is not`. >From 9bd2d17ddcbcdfaf4236ce4e4eadf0f5724a478e Mon Sep 17 00:00:00 2001 From: Ross Kirsling Date: Sat, 14 Jun 2025 21:42:47 -0700 Subject: [PATCH] [Clang] Fix typo in is_replaceable diagnostic. Adjustment to #143265; `because it not` should be `because it is not`. --- clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 +- clang/test/SemaCXX/type-traits-unsatisfied-diags.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index a2cf84d024193..c502f816512c5 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -1780,7 +1780,7 @@ def note_unsatisfied_trait_reason "%HasArcLifetime{has an ARC lifetime qualifier}|" "%VLA{is a variably-modified type}|" "%VBase{has a virtual base %1}|" - "%NotScalarOrClass{not %select{a|an array of objects of}1 scalar or " + "%NotScalarOrClass{is not %select{a|an array of objects of}1 scalar or " "class type}|" "%NTRBase{has a non-trivially-relocatable base %1}|" "%NTRField{has a non-trivially-relocatable member %1 of type %2}|" diff --git a/clang/test/SemaCXX/type-traits-unsatisfied-diags.cpp b/clang/test/SemaCXX/type-traits-unsatisfied-diags.cpp index d0b3f294fbcab..c431c364bb1c9 100644 --- a/clang/test/SemaCXX/type-traits-unsatisfied-diags.cpp +++ b/clang/test/SemaCXX/type-traits-unsatisfied-diags.cpp @@ -166,7 +166,7 @@ static_assert(__builtin_is_replaceable(const volatile int)); static_assert(__builtin_is_replaceable(void())); // expected-error@-1 {{static assertion failed due to requirement '__builtin_is_replaceable(void ())}} \ // expected-note@-1 {{'void ()' is not replaceable}} \ -// expected-note@-1 {{because it not a scalar or class type}} +// expected-note@-1 {{because it is not a scalar or class type}} struct B { virtual ~B(); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits