This patch removes on-stack `TemplateArgumentList`'s. They were primary used
to pass an `ArrayRef<TemplateArgument>` to
`Sema::getTemplateInstantiationArgs`, which had a `const
TemplateArgumentList*` parameter for the innermost template argument
list. Changing this parameter to an
`std::optional<ArrayRef<TemplateArgument>>` eliminates the need for
on-stack `TemplateArgumentList`'s, which in turn eliminates the need for
`TemplateArgumentList` to store a pointer to its template argument
storage (which is redundant in almost all cases, as it is an AST
allocated type).
…lt align crash (#78400)"
This reverts commit 7b3389980ddbd84f72ccc4776889c67519cc2c14.
A regression was discovered here:
https://github.com/llvm/llvm-project/pull/78400
and the author requested a revert to give time to review.
Try to fix [issue](https://github.com/llvm/llvm-project/issues/68490)
and some extented problem. Root cause of current issue is that error
handling in instantiation of function parameter with default
initialization on sizeof or align expression. When instance an
out-of-line template member function, depth of `TemplateTypeParmDecl` in
default initialization doesn't change while depth of other template
parameter does and this will lead to some template parameter
uninstanced. Also, sometime it will leader to wrong instantiation when
it uses the template parameter of class.
Fix it by add template args of context when it's out-of-line. This will
make `MultiLevelTemplateArgumentList::getNumLevels` matching the depth
of template parameter. Testcase with some `static_assert` demonstrates
the template parameter has been instanced correctly.
Co-authored-by: huqizhi <836744285@qq.com>
Previously committed as 9e08e51a20d0d2b1c5724bb17e969d036fced4cd, and
reverted because a dependency commit was reverted, then committed again
as 4b574008aef5a7235c1f894ab065fe300d26e786 and reverted again because
"dependency commit" 5a391d38ac6c561ba908334d427f26124ed9132e was
reverted. But it doesn't seem that 5a391d38ac6c was a real dependency
for this.
This commit incorporates 4b574008aef5a7235c1f894ab065fe300d26e786 and
18e093faf726d15f210ab4917142beec51848258 by Richard Smith (@zygoloid),
with some minor fixes, most notably:
- `UncommonValue` renamed to `StructuralValue`
- `VK_PRValue` instead of `VK_RValue` as default kind in lvalue and
member pointer handling branch in
`BuildExpressionFromNonTypeTemplateArgumentValue`;
- handling of `StructuralValue` in `IsTypeDeclaredInsideVisitor`;
- filling in `SugaredConverted` along with `CanonicalConverted`
parameter in `Sema::CheckTemplateArgument`;
- minor cleanup in
`TemplateInstantiator::transformNonTypeTemplateParmRef`;
- `TemplateArgument` constructors refactored;
- `ODRHash` calculation for `UncommonValue`;
- USR generation for `UncommonValue`;
- more correct MS compatibility mangling algorithm (tested on MSVC ver.
19.35; toolset ver. 143);
- IR emitting fixed on using a subobject as a template argument when the
corresponding template parameter is used in an lvalue context;
- `noundef` attribute and opaque pointers in `template-arguments` test;
- analysis for C++17 mode is turned off for templates in
`warn-bool-conversion` test; in C++17 and C++20 mode, array reference
used as a template argument of pointer type produces template argument
of UncommonValue type, and
`BuildExpressionFromNonTypeTemplateArgumentValue` makes
`OpaqueValueExpr` for it, and `DiagnoseAlwaysNonNullPointer` cannot see
through it; despite of "These cases should not warn" comment, I'm not
sure about correct behavior; I'd expect a suggestion to replace `if` by
`if constexpr`;
- `temp.arg.nontype/p1.cpp` and `dr18xx.cpp` tests fixed.
Fixes a crash where the template argument depth computed in the semantic
context for a friend FunctionDecl with a constrained parameter is
compared against arguments in the lexical context for the purpose of
checking if the constraint depends on enclosing template parameters.
Since getTemplateInstantiationArgs in this case follows the semantic DC
for friend FunctionDecls, the resulting depth is incorrect and trips an
assertion.
Fixes#75426
This fixes the bug introduced by
6db007a065.
We construct placeholder template arguments for template-template
parameters to avoid mismatching argument substitution since they have
different depths with their corresponding template arguments. In this
case,
```cpp
template <template <Concept C> class T> void foo(T<int>);
```
T lies at the depth 0, and C lies at 1. The corresponding argument, of
which there is exactly one, int, is at depth 0. If we consider the
argument as the outermost one, then we would end up substituting 'int'
into the wrong parameter T.
We used to perform such placeholder construction during the context
walk-up. In the previous patch, we slipped through that inadvertently
because we would walk up to the parent, which is precisely a FileContext
for template-template parameters, after adding innermost arguments.
Besides, this patch moves the sanity check up to the context switch.
That way, we avoid dereferencing null pointers if ND is unspecified.
Closes https://github.com/llvm/llvm-project/issues/57410.
Closes https://github.com/llvm/llvm-project/issues/76604. (The case is
slightly different than that in #57410. We should *not* assume the
surrounding context to be a file-scope one.)
Fixes: #77071
`SubstituteDeducedTypeTransform` will transform type and it will visit
uninstantiated `ExceptionSpecInfo`, which will cause odd behavior.
Currently, due to the incomplete implementation of p0588r1, the
instantiation of lambda expressions leads to the instantiation of the
body. And `EvaluateConstraints` is false during the instantiation of the
body, which causes crashes during the instantiation of the return type
requirement:
```cpp
template<typename T> concept doesnt_matter = true;
template<class T>
concept test =
[]{
return requires(T t) {
{ t } -> doesnt_matter; // crash
};
}();
static_assert(test<int>);
```
Although a complete implementation of p0588r1 can solve these crashes,
it will take some time. Therefore, this pull request aims to fix these
crashes first.
Fixes https://github.com/llvm/llvm-project/issues/63808
Fixes https://github.com/llvm/llvm-project/issues/64607
Fixes https://github.com/llvm/llvm-project/issues/64086
... and only look at equivalence of substituted expressions, not results
of constraint satisfaction.
This is required by the standard when matching redeclarations.
Fixes#74314.
There is already some existing machinery for that in
`TemplateInstantiator` and `Sema` exposed separate functions for
substituting expressions with intention to do that:
- `Sema::SubstExpr` should not evaluate constraints.
- `Sema::SubstConstraintExpr` should.
However, both functions used to be equivalent. Introduce a new function
that does not evaluate constraint and use it when matching declarations.
Also change implementation of `SubstConstraintExpr` to call `SubstExpr`
directly so it's obvious they behave in the same way and add a FIXME to
call out that we might need to revamp this approach in the future.
This patch adds support for new loop attribute:
[[clang::code_align(N)]].
This attribute applies to a loop and specifies the byte alignment for a
loop.
The attribute accepts a positive integer constant initialization
expression
indicating the number of bytes for the minimum alignment boundary.
Its value must be a power of 2, between 1 and 4096 (inclusive).
This patch moves ElaboratedTypeKeyword before `Type` definition so that the enum is complete where bit-field for it is declared. It also converts it to scoped enum and removes `ETK_` prefix.
Out of line class template declaration specializations aren't created at
the time they have their template arguments checked, so we previously
weren't doing any amount of work to substitute the constraints before
comparison. This resulted in the out of line definition's difference in
'depth' causing the constraints to compare differently.
This patch corrects that. Additionally, it handles ClassTemplateDecl
when collecting template arguments.
Fixes: #61763
In some cases where ill-formed code could be interpreted as a deduction
guide we can crash because we reach an unreachable path. This fixes this
issue by introducing a diagnostic instead.
Fixes: https://github.com/llvm/llvm-project/issues/65522
This implements proposals from:
- https://github.com/itanium-cxx-abi/cxx-abi/issues/24: mangling for
constraints, requires-clauses, requires-expressions.
- https://github.com/itanium-cxx-abi/cxx-abi/issues/31: requires-clauses and
template parameters in a lambda expression are mangled into the <lambda-sig>.
- https://github.com/itanium-cxx-abi/cxx-abi/issues/47 (STEP 3): mangling for
template argument is prefixed by mangling of template parameter declaration
if it's not "obvious", for example because the template parameter is
constrained (we already implemented STEP 1 and STEP 2).
This changes the manglings for a few cases:
- Functions and function templates with constraints.
- Function templates with template parameters with deduced types:
`typename<auto N> void f();`
- Function templates with template template parameters where the argument has a
different template-head:
`template<template<typename...T>> void f(); f<std::vector>();`
In each case where a mangling changed, the change fixes a mangling collision.
Note that only function templates are affected, not class templates or variable
templates, and only new constructs (template parameters with deduced types,
constrained templates) and esoteric constructs (templates with template
template parameters with non-matching template template arguments, most of
which Clang still does not accept by default due to
`-frelaxed-template-template-args` not being enabled by default), so the risk
to ABI stability from this change is relatively low. Nonetheless,
`-fclang-abi-compat=17` can be used to restore the old manglings for cases
which we could successfully but incorrectly mangle before.
Fixes#48216, #49884, #61273
Reviewed By: erichkeane, #libc_abi
Differential Revision: https://reviews.llvm.org/D147655
As reported in GH65810, we don't properly collect ALL of the template
parameters in a nested name specifier, and were only doing the 'inner
level'.
This patch makes sure we collect from all levels.
Fixes: #65810
This patch adds a concept AST node (`ConceptLoc`) and uses it at the corresponding places.
There are three objects that might have constraints via concepts:
`TypeConstraint`, `ConceptSpecializationExpr` and `AutoTypeLoc`.
The first two inherit from `ConceptReference` while the latter has
the information about a possible constraint directly stored in `AutoTypeLocInfo`. It would be nice if the concept information would be stored the same way in all three cases.
Moreover the current structure makes it difficult to deal with these concepts. For example in Clangd accessing the locations of constraints of a `AutoTypeLoc` can only be done with quite ugly hacks.
So we think that it makes sense to create a new AST node for such concepts.
In details we propose the following:
- Rename `ConceptReference` to `ConceptLoc` (or something else what is approriate)
and make it the new AST node.
- `TypeConstraint` and `ConceptSpecializationExpr` do not longer inherit from `ConceptReference` but store a pointer to a `ConceptLoc`.
- `AutoTypeLoc` stores a pointer to `ConceptLoc` instead of storing the concept info in `AutoTypeLocInfo`.
This patch implements a first version of this idea which compiles and where the existing tests pass.
To make this patch as small as possible we keep the existing member functions to access concept data. Later these can be replaced by directly calling the corresponding functions of the `ConceptLoc`s.
Differential Revision: https://reviews.llvm.org/D155858
Explicit specialization doesn't increase depth of template parameters,
so need to be careful when gathering template parameters for
instantiation.
For the case:
```
template<typename T>
struct X {
struct impl;
};
template <>
struct X<int>::impl {
template<int ct>
int f() { return ct; };
};
```
instantiation of `f` used to crash because type template parameter
`int` of explicit specialization was taken into account, but non-type
template parameter `ct` had zero depth and index so wrong parameter
ended up inside of a wrong handler.
Fixes https://github.com/llvm/llvm-project/issues/61159
Reviewed By: aaron.ballman, shafik
Differential Revision: https://reviews.llvm.org/D155705
In preparation for removing the `#include "llvm/ADT/StringExtras.h"`
from the header to source file of `llvm/Support/Error.h`, first add in
all the missing includes that were previously included transitively
through this header.
Fixes#60778.
When instantiating the body of a class template specialization that was
instantiated from a partial specialization, we were incorrectly
collecting template arguments from the primary template, which resulted
in the template arguments list being inaccurate. In the example from
the issue, we were trying to substitute the boolean 'false' into the
type on Nested, which caused an assertion.
Differential Revision: https://reviews.llvm.org/D150285
This diff switches the approach to comparison of constraint expressions
to the new one based on template args substitution.
It continues the effort to fix our handling of out-of-line definitions
of constrained templates.
This is a recommit of 3a54022934.
Differential revision: https://reviews.llvm.org/D146178
This commit implements [temp.deduct]p9.
Test updates include:
- New notes in `cxx1y-init-captures.cpp`, `lambda-expressions.cpp`
and 'warn-unused-lambda-capture.cpp'.
This seems to be caused by diagnosing errors earlier (during
deduction) that were previously surfaced later (during
instantiation).
- New error `lambda-unevaluated.cpp` is in line with [temp.deduct]p9.
Reviewed By: erichkeane, #clang-language-wg
Differential Revision: https://reviews.llvm.org/D148802
Sema.h is huge. This makes a small reduction to it by moving
EnterExpressionEvaluationContext into a new header, since it is an
independent component.
Differential Revision: https://reviews.llvm.org/D149796
This diff switches the approach to comparison of constraint expressions
to the new one based on template args substitution.
It continues the effort to fix our handling of out-of-line definitions
of constrained templates.
This is a recommit of e3b1083e00.
Differential revision: https://reviews.llvm.org/D146178
This reverts commit e3b1083e00e62f5d157d15cb8c63a1c3dfdf12e2.
This was reverted because it breaks a number of libstdc++ examples, AND
required a workaround that causes hiding of legitimate bugs.
This diff switches the approach to comparison of constraint expressions
to the new one based on template args substitution.
It continues the effort to fix our handling of out-of-line definitions
of constrained templates.
This is a recommit of 60bee9ff5445.
Differential revision: https://reviews.llvm.org/D146178
This temporarily reverts commit
60bee9ff544541e83ffbd4be31923d0e8b644690.
The diff will be recommitted once the newly discovered
regressions are fixed.
This also reverts 282cae0b9a602267ad7ef622f770066491332a11 as the
particular crash is now handled by the new code.
Before this change Clang would always leave declarations inside the
type-locs as `null` if the declarator had an invalid type. This patch
populates declarations even for invalid types if the structure of the
type and the type-locs match.
There are certain cases that may still cause crashes. These happen when
Clang recovers the type in a way that is not reflected in the
declarator's structure, e.g. adding a pointer when it was not present in
the code for ObjC interfaces or ignoring pointers written in the code
in C++ with auto return type (`auto* foo() -> int`). Those cases look
fixable with a better recovery strategy and I plan to follow up with
more patches to address those.
The first attempt caused 31 tests from `check-clang` to crash due to
different structure of the types and type-locs after certain errors. The
good news is that the failure is localized and mismatch in structures is
discovered by assertions inside `DeclaratorLocFiller`. Some notable
cases caught by existing tests:
- Invalid chunks when type is fully ignored and replace with int or now.
Crashed in `C/C2x/n2838.c`.
- Invalid return types in lambdas. Crashed in `CXX/drs/dr6xx.cpp`.
- Invalid member pointers. Crashed in `CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-generic-lambda-1y.cpp`
- ObjC recovery that adds pointers. Crashed in `SemaObjC/blocks.m`
This change also updates the output of `Index/complete-blocks.m`.
Not entirely sure what causes the change, but the new function signature
is closer to the source code, so this seems like an improvement.
Reviewed By: aaron.ballman, erichkeane
Differential Revision: https://reviews.llvm.org/D146971
This diff switches the approach to comparison of constraint expressions
to the new one based on template args substitution.
It continues the effort to fix our handling of out-of-line definitions
of constrained templates.
The associated GitHub issue: https://github.com/llvm/llvm-project/issues/61414
Test plan:
1/ ninja check-all
2/ bootstrapped Clang passes tests
Differential revision: https://reviews.llvm.org/D146178
D146089's author discovered that our diagnostics for always/no inline
would null-dereference when used in a template. He fixed that by
skipping in the dependent case.
This patch makes sure we diagnose these after a template instantiation.
It also adds infrastructure for other statement attributes to add
checking/transformation.
Differential Revision: https://reviews.llvm.org/D146323
Fixes#61441.
Currently, Clang stores `nullptr` in the parameter lists inside
`FunctionProtoTypeLoc` if `__fp16` is used without pointer qualifiers.
Any code path that calls `Declarator::setInvalidType()` before
`GetFullTypeForDeclarator` will lead to the same problem downstream.
The relevant code is:
```cpp
if (D.isInvalidType())
return Context.getTrivialTypeSourceInfo(T);
return GetTypeSourceInfoForDeclarator(state, T, TInfo);
```
`GetTypeSourceInfoForDeclarator` sets the parameter `Decl`, but we can't
call it when `isInvalidType() == true` as this causes other assertion
failures that seem harder to fix.
Reviewed By: kadircet
Differential Revision: https://reviews.llvm.org/D146426
This implements P2036R3 and P2579R0.
That is, explicit, int, and implicit capture become visible
at the start of the parameter head.
Reviewed By: aaron.ballman, rupprecht, shafik
Differential Revision: https://reviews.llvm.org/D124351
This reverts commit d708a186b6a9b050d09558163dd353d9f738c82d (and typo fix e4bc9898ddbeb70bc49d713bbf863f050f21e03f). It causes a compilation error for this:
```
struct StringLiteral {
template <int N>
StringLiteral(const char (&array)[N])
__attribute__((enable_if(N > 0 && N == __builtin_strlen(array) + 1,
"invalid string literal")));
};
struct Message {
Message(StringLiteral);
};
void Func1() {
auto x = Message("x"); // Note: this is fine
// Note: "xx\0" to force a different type, StringLiteral<3>, otherwise this
// successfully builds.
auto y = [&](decltype(Message("xx"))) {};
// ^ fails with: repro.cc:18:13: error: reference to local variable 'array'
// declared in enclosing function 'StringLiteral::StringLiteral<3>'
(void)x;
(void)y;
}
```
More details posted to D124351.
This implements P2036R3 and P2579R0.
That is, explicit, int, and implicit capture become visible
at the start of the parameter head.
Reviewed By: aaron.ballman
Differential Revision: https://reviews.llvm.org/D124351
> Dependent access checks.
Fixes: https://github.com/llvm/llvm-project/issues/53364
We previously ignored dependent access checks to private members.
These are visible only to the `RequiresExprBodyExpr` (through `PerformDependentDiagnositcs`) and not to the individual requirements.
---
> Non-dependent access checks.
Fixes: https://github.com/llvm/llvm-project/issues/53334
Access to members in a non-dependent context would always yield an
invalid expression. When it appears in a requires-expression, then this
is a hard error as this would always result in a substitution failure.
https://eel.is/c++draft/expr.prim.req#general-note-1
> Note 1: If a requires-expression contains invalid types or expressions in its requirements, and it does not appear within the declaration of a templated entity, then the program is ill-formed. — end note]
> If the substitution of template arguments into a requirement would always result in a substitution failure, the program is ill-formed; no diagnostic required.
The main issue here is the delaying of the diagnostics.
Use a `ParsingDeclRAIIObject` creates a separate diagnostic pool for diagnositcs associated to the `RequiresExprBodyDecl`.
This is important because dependent diagnostics should not be leaked/delayed to higher scopes (Eg. inside a template function or in a trailing requires). These dependent diagnostics must be attached to the `DeclContext` of the parameters of `RequiresExpr` (which is the `RequiresExprBodyDecl` in this case).
Non dependent diagnostics, on the other hand, should not delayed and surfaced as hard errors.
Differential Revision: https://reviews.llvm.org/D140547