Skip to content

Commit dbf9d54

Browse files
committed
- rebase to main
- add release note for __is_deducible - implement diagnostics for bad argument types for __is_deducible
1 parent 9583811 commit dbf9d54

File tree

8 files changed

+29
-23
lines changed

8 files changed

+29
-23
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,10 @@ C++20 Feature Support
114114
to update the ``__cpp_concepts`` macro to `202002L`. This enables
115115
``<expected>`` from libstdc++ to work correctly with Clang.
116116

117+
- Implemented the `__is_deducible` builtin to check if the template arguments of
118+
a class/alias template can be deduced from a specific type,
119+
[over.match.class.deduct]p4.
120+
117121
C++23 Feature Support
118122
^^^^^^^^^^^^^^^^^^^^^
119123

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9156,6 +9156,10 @@ def note_inequality_comparison_to_or_assign : Note<
91569156
def err_incomplete_type_used_in_type_trait_expr : Error<
91579157
"incomplete type %0 used in type trait expression">;
91589158

9159+
def err_deducible_non_class_or_alias_types : Error<
9160+
"%0 is not a class or alias template; __is_deducible only supports class or "
9161+
"alias templates">;
9162+
91599163
// C++20 constinit and require_constant_initialization attribute
91609164
def warn_cxx20_compat_constinit : Warning<
91619165
"'constinit' specifier is incompatible with C++ standards before C++20">,

clang/lib/Sema/SemaExprCXX.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6109,7 +6109,9 @@ static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, const TypeSourceI
61096109
TSTToBeDeduced->getTemplateName().getAsTemplateDecl(), RhsT,
61106110
Info) == TemplateDeductionResult::Success;
61116111
}
6112-
// FIXME: emit a diagnostic.
6112+
Self.Diag(Lhs->getTypeLoc().getBeginLoc(),
6113+
diag::err_deducible_non_class_or_alias_types)
6114+
<< LhsT << Lhs->getTypeLoc().getSourceRange();
61136115
return false;
61146116
}
61156117
default: llvm_unreachable("not a BTT");

clang/lib/Sema/SemaTemplate.cpp

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3055,19 +3055,6 @@ void DeclareImplicitDeductionGuidesForTypeAlias(
30553055
RequireClause);
30563056

30573057
auto *GG = cast<CXXDeductionGuideDecl>(FPrime);
3058-
// Substitute new template parameters into requires-clause if present.
3059-
Expr *RequiresClause =
3060-
transformRequireClause(SemaRef, F, TemplateArgsForBuildingFPrime);
3061-
// FIXME: implement the is_deducible constraint per C++
3062-
// [over.match.class.deduct]p3.3:
3063-
// ... and a constraint that is satisfied if and only if the arguments
3064-
// of A are deducible (see below) from the return type.
3065-
auto *FPrimeTemplateParamList = TemplateParameterList::Create(
3066-
Context, AliasTemplate->getTemplateParameters()->getTemplateLoc(),
3067-
AliasTemplate->getTemplateParameters()->getLAngleLoc(),
3068-
FPrimeTemplateParams,
3069-
AliasTemplate->getTemplateParameters()->getRAngleLoc(),
3070-
/*RequiresClause=*/RequiresClause);
30713058

30723059
buildDeductionGuide(SemaRef, AliasTemplate, FPrimeTemplateParamList,
30733060
GG->getCorrespondingConstructor(),

clang/lib/Sema/SemaTemplateDeduction.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3256,8 +3256,7 @@ Sema::DeduceTemplateArgumentsFromType(TemplateDecl *TD, QualType FromType,
32563256
->getUnderlyingType()
32573257
.getCanonicalType();
32583258
} else {
3259-
// FIXME: emit a diagnostic, we only only support alias and class templates.
3260-
return TemplateDeductionResult::Invalid;
3259+
assert(false && "Expected a class or alias template");
32613260
}
32623261

32633262
// Unevaluated SFINAE context.

clang/test/SemaCXX/cxx20-ctad-type-alias.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ struct Foo {
111111
template <typename X, int Y>
112112
using Bar = Foo<X, sizeof(X)>; // expected-note {{candidate template ignored: couldn't infer template argument 'X'}} \
113113
// expected-note {{candidate template ignored: constraints not satisfied [with X = int]}} \
114-
// expected-note {{because '__is_deducible(Bar, Foo<int, 4UL>)' evaluated to false}}
114+
// expected-note {{because '__is_deducible}}
115115

116116

117117
Bar s = {{1}}; // expected-error {{no viable constructor or deduction guide }}

clang/test/SemaCXX/type-traits-is-deducible.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
// RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify %s
2-
// expected-no-diagnostics
32

43
template<typename T>
54
struct Foo {};
@@ -45,3 +44,12 @@ template <class T, T N>
4544
using AArrary = int[N];
4645
static_assert (__is_deducible(AArrary, int[42]));
4746
static_assert (!__is_deducible(AArrary, double[42]));
47+
48+
// error cases
49+
bool e1 = __is_deducible(int, int); // expected-error {{'int' is not a class or alias template; __is_deducible only supports class or alias templates}}
50+
template<typename T> T func();
51+
bool e2 = __is_deducible(func, int); // expected-error {{type name requires a specifier or qualifier}} \
52+
expected-error {{type-id cannot have a name}}
53+
template<typename T> T var = 1;
54+
bool e3 = __is_deducible(var, int); // expected-error {{type name requires a specifier or qualifier}} \
55+
expected-error {{type-id cannot have a name}}

clang/test/SemaTemplate/deduction-guide.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -275,11 +275,13 @@ using AFoo = Foo<G<U>>;
275275
// CHECK-LABEL: Dumping <deduction guide for AFoo>
276276
// CHECK: FunctionTemplateDecl {{.*}} implicit <deduction guide for AFoo>
277277
// CHECK-NEXT: |-TemplateTypeParmDecl {{.*}} typename depth 0 index 0 U
278-
// CHECK-NEXT: |-ParenExpr {{.*}} 'bool'
279-
// CHECK-NEXT: | `-BinaryOperator {{.*}} 'bool' '=='
280-
// CHECK-NEXT: | |-UnaryExprOrTypeTraitExpr {{.*}} 'G<type-parameter-0-0>'
281-
// CHECK-NEXT: | `-ImplicitCastExpr {{.*}}
282-
// CHECK-NEXT: | `-IntegerLiteral {{.*}}
278+
// CHECK-NEXT: |-BinaryOperator {{.*}} '&&'
279+
// CHECK-NEXT: | |-ParenExpr {{.*}} 'bool'
280+
// CHECK-NEXT: | | `-BinaryOperator {{.*}} 'bool' '=='
281+
// CHECK-NEXT: | | |-UnaryExprOrTypeTraitExpr {{.*}} 'G<type-parameter-0-0>'
282+
// CHECK-NEXT: | | `-ImplicitCastExpr {{.*}}
283+
// CHECK-NEXT: | | `-IntegerLiteral {{.*}}
284+
// CHECK-NEXT: | `-TypeTraitExpr {{.*}} 'bool' __is_deducible
283285
// CHECK-NEXT: |-CXXDeductionGuideDecl {{.*}} implicit <deduction guide for AFoo> 'auto (G<type-parameter-0-0>) -> Foo<G<type-parameter-0-0>>'
284286
// CHECK-NEXT: | `-ParmVarDecl {{.*}} 'G<type-parameter-0-0>'
285287
// CHECK-NEXT: `-CXXDeductionGuideDecl {{.*}} implicit used <deduction guide for AFoo> 'auto (G<int>) -> Foo<G<int>>' implicit_instantiation

0 commit comments

Comments
 (0)