See discussion in https://github.com/llvm/llvm-project/issues/125071.
Makes the note clearer for the unreachable case:
Before:
```
./hoge.h:5:12: warning: instantiation of function 'x<int>' required here, but no definition is available [-Wundefined-func-template]
5 | void f() { x<int>(); }
| ^
./shared_ptr2.h:4:6: note: forward declaration of template entity is here
4 | void x() { T t; (void)t; }
| ^
./hoge.h:5:12: note: add an explicit instantiation declaration to suppress this warning if 'x<int>' is explicitly instantiated in another translation unit
5 | void f() { x<int>(); }
|
```
After:
```
./hoge.h:5:12: warning: instantiation of function 'x<int>' required here, but no definition is available [-Wundefined-func-template]
5 | void f() { x<int>(); }
| ^
./shared_ptr2.h:4:6: note: declaration of template entity is unreachable here
4 | void x() { T t; (void)t; }
| ^
1 warning generated.
```
Seemingly I managed to not give this a name, and not notice that it
didn't properly introduce the scope it was supposed to! This patch
gives it a name which should hopefully/presumably fix any cases where we
don't properly introduce the 'this' scope. I presume that previous
callers to this might also do this in most cases so that this is a
redundant scope, but we have to make sure it happens.
FIXES: #130846
When checking the template template parameters of template template
parameters, the PartialOrdering context was not correctly propagated.
This also has a few drive-by fixes, such as checking the template
parameter lists of template template parameters, which was previously
missing and would have been it's own bug, but we need to fix it in order
to prevent crashes in error recovery in a simple way.
Fixes#130362
This caused incorrect -Wunguarded-availability warnings. See comment on
the pull request.
> We were missing a call to DiagnoseUseOfDecl when performing typename
> access.
>
> This refactors the code so that TypeDecl lookups funnel through a helper
> which performs all the necessary checks, removing some related
> duplication on the way.
>
> Fixes#58547
>
> Differential Revision: https://reviews.llvm.org/D136533
This reverts commit 4c4fd6b03149348cf11af245ad2603d24144a9d5.
This clears up the printing of a NestedNameSpecifier so a trailing '::'
is not printed, unless it refers into the global scope.
This fixes a bunch of diagnostics where the trailing :: was awkward.
This also prints the NNS quoted consistenty.
There is a drive-by improvement to error recovery, where now we print
the actual type instead of `<dependent type>`.
This will clear up further uses of NNS printing in further patches.
Instead of manually adding a note pointing to the relevant template
parameter to every relevant error, which is very easy to miss, this
patch adds a new instantiation context note, so that this can work using
RAII magic.
This fixes a bunch of places where these notes were missing, and is more
future-proof.
Some diagnostics are reworked to make better use of this note:
- Errors about missing template arguments now refer to the parameter
which is missing an argument.
- Template Template parameter mismatches now refer to template
parameters as parameters instead of arguments.
It's likely this will add the note to some diagnostics where the
parameter is not super relevant, but this can be reworked with time and
the decrease in maintenance burden makes up for it.
This bypasses the templight dumper for the new context entry, as the
tests are very hard to update.
This depends on #125453, which is needed to avoid losing the context
note for errors occuring during template argument deduction.
Fixes#46386
---
When an abbreviated function template appears in an `extern "C"` block
and all template parameters are invented,
`TemplateParams->getTemplateLoc()` becomes invalid, leading to an
incorrect error location. These changes ensure that the error points to
the parameter's location when the template location is invalid.
We were missing a call to DiagnoseUseOfDecl when performing typename
access.
This refactors the code so that TypeDecl lookups funnel through a helper
which performs all the necessary checks, removing some related
duplication on the way.
Fixes#58547
Differential Revision: https://reviews.llvm.org/D136533
When substituting for rewrite purposes, as in rebuilding constraints for
a synthesized deduction guide, it assumed that packs were in
PackExpansion* form, such that the instantiator could extract a pattern.
For type aliases CTAD, while rebuilding their associated constraints,
this might not be the case because we'll call
`TransformTemplateArgument()` for the alias template arguments, where
there might be cases e.g. a non-pack expansion type into a pack
expansion, so the assumption wouldn't hold.
This patch fixes that by making it treat the non-pack expansions as
direct patterns when rewriting.
Fixes#124715
Class templates might be only instantiated when they are required to be
complete, but checking the template args against the primary template is
immediate.
This result is cached so that later when the class is instantiated,
checking against the primary template is not repeated.
The 'MatchedPackOnParmToNonPackOnArg' flag is also produced upon
checking against the primary template, so it needs to be cached in the
specialziation as well.
This fixes a bug which has not been in any release, so there are no
release notes.
Fixes#125290
This flag has been deprecated since Clang 19, having been the default
since then.
It has remained because its negation was still useful to work around
backwards compatibility breaking changes from P0522.
However, in Clang 20 we have landed various changes which implemented
P3310R2 and beyond, which solve almost all of the expected issues, the
known remaining few being a bit obscure.
So this change removes the flag completely and all of its implementation
and support code.
Hopefully any remaining users can just stop using the flag. If there are
still important issues remaining, this removal will also shake the tree
and help us know.
Converted template arguments need to be converted again, if the
corresponding template parameter changed, as different conversions might
apply in that case.
This fixes the core issue described in P3579, following the design
intent of P0522 to not introduce any new cases where a template template
parameter match is allowed for a template which is not valid for all
possible uses.
With this patch, narrowing conversions are disallowed for TTP matching.
This reuses the existing machinery for diagnosing narrowing in a
converted constant expression.
Since P0522 is a DR and we apply it all the way back to C++98, this
brings that machinery to use in older standards, in this very narrow
scope of TTP matching.
This still doesn't solve the ambiguity when partial ordering NTTPs of
different integral types, this is blocked by a different bug which will
be fixed in a subsequent patch (but the test cases are added).
This patch relands the following PRs:
* #111711
* #107350
* #111457
All of these patches were reverted due to an issue reported in
https://github.com/llvm/llvm-project/pull/111711#issuecomment-2406491485,
due to interdependencies.
---
[clang] Finish implementation of P0522
This finishes the clang implementation of P0522, getting rid
of the fallback to the old, pre-P0522 rules.
Before this patch, when partial ordering template template parameters,
we would perform, in order:
* If the old rules would match, we would accept it. Otherwise, don't
generate diagnostics yet.
* If the new rules would match, just accept it. Otherwise, don't
generate any diagnostics yet again.
* Apply the old rules again, this time with diagnostics.
This situation was far from ideal, as we would sometimes:
* Accept some things we shouldn't.
* Reject some things we shouldn't.
* Only diagnose rejection in terms of the old rules.
With this patch, we apply the P0522 rules throughout.
This needed to extend template argument deduction in order
to accept the historial rule for TTP matching pack parameter to non-pack
arguments.
This change also makes us accept some combinations of historical and P0522
allowances we wouldn't before.
It also fixes a bunch of bugs that were documented in the test suite,
which I am not sure there are issues already created for them.
This causes a lot of changes to the way these failures are diagnosed,
with related test suite churn.
The problem here is that the old rules were very simple and
non-recursive, making it easy to provide customized diagnostics,
and to keep them consistent with each other.
The new rules are a lot more complex and rely on template argument
deduction, substitutions, and they are recursive.
The approach taken here is to mostly rely on existing diagnostics,
and create a new instantiation context that keeps track of this context.
So for example when a substitution failure occurs, we use the error
produced there unmodified, and just attach notes to it explaining
that it occurred in the context of partial ordering this template
argument against that template parameter.
This diverges from the old diagnostics, which would lead with an
error pointing to the template argument, explain the problem
in subsequent notes, and produce a final note pointing to the parameter.
---
[clang] CWG2398: improve overload resolution backwards compat
With this change, we discriminate if the primary template and which partial
specializations would have participated in overload resolution prior to
P0522 changes.
We collect those in an initial set. If this set is not empty, or the
primary template would have matched, we proceed with this set as the
candidates for overload resolution.
Otherwise, we build a new overload set with everything else, and proceed
as usual.
---
[clang] Implement TTP 'reversed' pack matching for deduced function template calls.
Clang previously missed implementing P0522 pack matching
for deduced function template calls.
If a C++ class template is annotated via API Notes, the instantiations
had the attributes repeated twice. This is because Clang was adding the
attribute twice while processing the same class template. This change
makes sure we don't try to add attributes from API Notes twice.
There is currently no way to annotate specific instantiations using API
Notes.
rdar://142539959
After 0dedd6fe1 and 03229e7c0, invalid concept declarations might lack
expressions for evaluation and normalization. This could make it crash
in certain scenarios, apart from the one of evaluation concepts showed
in 03229e7c0, there's also an issue when checking specializations where
the normalization also relies on a non-null expression.
This patch prevents that by avoiding building up a type constraint in
such situations, thereafter the template parameter wouldn't have a
concept specialization of a null expression.
With this patch, the assumption in ASTWriterDecl is no longer valid.
Namely, HasConstraint and TypeConstraintInitialized must now represent
different meanings for both source fidelity and semantic requirements.
Fixes https://github.com/llvm/llvm-project/issues/115004
Fixes https://github.com/llvm/llvm-project/issues/121980
In the case where a type-constraint on an NTTP contains a pack, we form
a PackExpansionType to model it. However, there are a few places
expecting it to be a non-pack expansion, and luckily only small changes
could make them work.
Fixes https://github.com/llvm/llvm-project/issues/88866
This can be used to inform users when a template should not be
specialized. For example, this is the case for the standard type traits
(except for `common_type` and `common_reference`, which have more
complicated rules).
Consider the following:
```
template<typename T>
struct A {
template<typename U>
struct B {
static constexpr int x = 0; // #1
};
template<typename U>
struct B<U*> {
static constexpr int x = 1; // #2
};
};
template<>
template<typename U>
struct A<long>::B {
static constexpr int x = 2; // #3
};
static_assert(A<short>::B<int>::y == 0); // uses #1
static_assert(A<short>::B<int*>::y == 1); // uses #2
static_assert(A<long>::B<int>::y == 2); // uses #3
static_assert(A<long>::B<int*>::y == 2); // uses #3
```
According to [temp.spec.partial.member] p2:
> If the primary member template is explicitly specialized for a given
(implicit) specialization of the enclosing class template, the partial
specializations of the member template are ignored for this
specialization of the enclosing class template.
If a partial specialization of the member template is explicitly
specialized for a given (implicit) specialization of the enclosing class
template, the primary member template and its other partial
specializations are still considered for this specialization of the
enclosing class template.
The example above fails to compile because we currently don't implement
[temp.spec.partial.member] p2. This patch implements the wording, fixing #51051.
Translates `RWBuffer` and `StructuredBuffer` resources buffer types to
DirectX target types `dx.TypedBuffer` and `dx.RawBuffer`.
Includes a change of `HLSLAttributesResourceType` from 'sugar' type to
full canonical type. This is required for codegen and other clang
infrastructure to work property on HLSL resource types.
Fixes#95952 (part 2/2)
This patch reapplies #111173, fixing a bug when instantiating dependent
expressions that name a member template that is later explicitly
specialized for a class specialization that is implicitly instantiated.
The bug is addressed by adding the `hasMemberSpecialization` function,
which return `true` if _any_ redeclaration is a member specialization.
This is then used when determining the instantiation pattern for a
specialization of a template, and when collecting template arguments for
a specialization of a template.
Consider #109148:
```c++
template <typename ...Ts>
void f() {
[] {
(^Ts);
};
}
```
When we encounter `^Ts`, we try to parse a block and subsequently call
`DiagnoseUnexpandedParameterPack()` (in `ActOnBlockArguments()`), which
sees `Ts` and sets `ContainsUnexpandedParameterPack` to `true` in the
`LambdaScopeInfo` of the enclosing lambda. However, the entire block is
subsequently discarded entirely because it isn’t even syntactically
well-formed. As a result, `ContainsUnexpandedParameterPack` is `true`
despite the lambda’s body no longer containing any unexpanded packs,
which causes an assertion the next time
`DiagnoseUnexpandedParameterPack()` is called.
This pr moves handling of unexpanded parameter packs into
`CapturingScopeInfo` instead so that the same logic is used for both
blocks and lambdas. This fixes this issue since the
`ContainsUnexpandedParameterPack` flag is now part of the block (and
before that, its `CapturingScopeInfo`) and no longer affects the
surrounding lambda directly when the block is parsed. Moreover, this
change makes blocks actually usable with pack expansion.
This fixes#109148.
With this change, we discriminate if the primary template and which
partial specializations would have participated in overload resolution
prior to P0522 changes.
We collect those in an initial set. If this set is not empty, or the
primary template would have matched, we proceed with this set as the
candidates for overload resolution.
Otherwise, we build a new overload set with everything else, and proceed
as usual.
This finishes the clang implementation of P0522, getting rid of the
fallback to the old, pre-P0522 rules.
Before this patch, when partial ordering template template parameters,
we would perform, in order:
* If the old rules would match, we would accept it. Otherwise, don't
generate diagnostics yet.
* If the new rules would match, just accept it. Otherwise, don't
generate any diagnostics yet again.
* Apply the old rules again, this time with diagnostics.
This situation was far from ideal, as we would sometimes:
* Accept some things we shouldn't.
* Reject some things we shouldn't.
* Only diagnose rejection in terms of the old rules.
With this patch, we apply the P0522 rules throughout.
This needed to extend template argument deduction in order to accept the
historial rule for TTP matching pack parameter to non-pack arguments.
This change also makes us accept some combinations of historical and
P0522 allowances we wouldn't before.
It also fixes a bunch of bugs that were documented in the test suite,
which I am not sure there are issues already created for them.
This causes a lot of changes to the way these failures are diagnosed,
with related test suite churn.
The problem here is that the old rules were very simple and
non-recursive, making it easy to provide customized diagnostics, and to
keep them consistent with each other.
The new rules are a lot more complex and rely on template argument
deduction, substitutions, and they are recursive.
The approach taken here is to mostly rely on existing diagnostics, and
create a new instantiation context that keeps track of this context.
So for example when a substitution failure occurs, we use the error
produced there unmodified, and just attach notes to it explaining that
it occurred in the context of partial ordering this template argument
against that template parameter.
This diverges from the old diagnostics, which would lead with an error
pointing to the template argument, explain the problem in subsequent
notes, and produce a final note pointing to the parameter.
Reapplies #106585, fixing an issue where non-dependent names of member
templates appearing prior to that member template being explicitly
specialized for an implicitly instantiated class template specialization
would incorrectly use the definition of the explicitly specialized
member template.
This finishes the clang implementation of P0522, getting rid of the
fallback to the old, pre-P0522 rules.
Before this patch, when partial ordering template template parameters,
we would perform, in order:
* If the old rules would match, we would accept it. Otherwise, don't
generate diagnostics yet.
* If the new rules would match, just accept it. Otherwise, don't
generate any diagnostics yet again.
* Apply the old rules again, this time with diagnostics.
This situation was far from ideal, as we would sometimes:
* Accept some things we shouldn't.
* Reject some things we shouldn't.
* Only diagnose rejection in terms of the old rules.
With this patch, we apply the P0522 rules throughout.
This needed to extend template argument deduction in order to accept the
historial rule for TTP matching pack parameter to non-pack arguments.
This change also makes us accept some combinations of historical and
P0522 allowances we wouldn't before.
It also fixes a bunch of bugs that were documented in the test suite,
which I am not sure there are issues already created for them.
This causes a lot of changes to the way these failures are diagnosed,
with related test suite churn.
The problem here is that the old rules were very simple and
non-recursive, making it easy to provide customized diagnostics, and to
keep them consistent with each other.
The new rules are a lot more complex and rely on template argument
deduction, substitutions, and they are recursive.
The approach taken here is to mostly rely on existing diagnostics, and
create a new instantiation context that keeps track of things.
So for example when a substitution failure occurs, we use the error
produced there unmodified, and just attach notes to it explaining that
it occurred in the context of partial ordering this template argument
against that template parameter.
This diverges from the old diagnostics, which would lead with an error
pointing to the template argument, explain the problem in subsequent
notes, and produce a final note pointing to the parameter.
(This continues the effort of #86265, fixing another piece of issue in
constraint evaluation on variadic lambdas.)
We need the depth of the primary template parameters for constraint
substitution. To that end, we avoided substituting type constraints by
copying the constraint expression when instantiating a template. This,
however, has left an issue in that for lambda's parameters, they can
reference outer template packs that would be expanded in the process of
an instantiation, where these parameters would make their way into the
constraint evaluation, wherein we have no other way to expand them later
in evaluation. For example,
template <class... Ts> void foo() {
bar([](C<Ts> auto value) {}...);
}
The lambda references a pack `Ts` that should be expanded when
instantiating `foo()`. The `Ts` along with the constraint expression
would not be transformed until constraint evaluation, and at that point,
we would have no chance to expand `Ts` anyhow.
This patch takes an approach that transforms `Ts` from an unexpanded
TemplateTypeParmType into a SubstTemplateTypeParmType with the current
pack substitution index, such that we could use that to expand the type
during evaluation.
Fixes#101754
This implements the logic of the `common_type` base template as a
builtin alias. If there should be no `type` member, an empty class is
returned. Otherwise a specialization of a `type_identity`-like class is
returned. The base template (i.e. `std::common_type`) as well as the
empty class and `type_identity`-like struct are given as arguments to
the builtin.
Currently, clang rejects the following explicit specialization of `f`
due to the constraints not being equivalent:
```
template<typename T>
struct A
{
template<bool B>
void f() requires B;
};
template<>
template<bool B>
void A<int>::f() requires B { }
```
This happens because, in most cases, we do not set the flag indicating
whether a `RedeclarableTemplate` is an explicit specialization of a
member of an implicitly instantiated class template specialization until
_after_ we compare constraints for equivalence. This patch addresses the
issue (and a number of other issues) by:
- storing the flag indicating whether a declaration is a member
specialization on a per declaration basis, and
- significantly refactoring `Sema::getTemplateInstantiationArgs` so we
collect the right set of template argument in all cases.
Many of our declaration matching & constraint evaluation woes can be
traced back to bugs in `Sema::getTemplateInstantiationArgs`. This
change/refactor should fix a lot of them. It also paves the way for
fixing #101330 and #105462 per my suggestion in #102267 (which I have
implemented on top of this patch but will merge in a subsequent PR).
When rebuilding immediate invocations inside
`RemoveNestedImmediateInvocation()`, we employed a `TreeTransform` to
exercise the traversal. The transformation has a side effect that, for
template specialization types, their default template arguments are
substituted separately, and if any lambdas are present, they will be
transformed into distinct types than those used to instantiate the
templates right before the `consteval` handling.
This resulted in `B::func()` getting redundantly instantiated for the
case in question. Since we're also in an immediate evaluation context,
the body of `foo()` would also get instantiated, so we end up with a
spurious friend redefinition error.
Like what we have done in `ComplexRemove`, this patch also avoids the
lambda's transformation in TemplateInstantiator if we know we're
rebuilding immediate calls. In addition, this patch also consolidates
the default argument substitution logic in
`CheckTemplateArgumentList()`.
Fixes#107175
Since #93433, we have switched to `QualifiedTemplateName`s in more
situations to preserve sugars in diagnostics. However, there is one
missed case in typo correction that might not meet the expectation in
`CheckDeductionGuideDeclarator()`.
Fixes https://github.com/llvm/llvm-project/issues/107887