This patch mechanically replaces None with std::nullopt where the
compiler would warn if None were deprecated. The intent is to reduce
the amount of manual work required in migrating from Optional to
std::optional.
This is part of an effort to migrate from llvm::Optional to
std::optional:
https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
Based on discussion on the core reflector, it was made clear that a
concept that depends on itself should be a hard error, not a constraint
failure. This patch implements a stack of constraint-checks-in-progress
to make sure we quit, rather than hitting stack-exhaustion.
Note that we DO need to be careful to make sure we still check
constraints properly that are caused by a previous constraint, but not
derived from (such as when a check causes us to check special member
function generation), so we cannot use the existing logic to see if this
is being instantiated.
This fixes https://github.com/llvm/llvm-project/issues/44304 and
https://github.com/llvm/llvm-project/issues/50891.
Differential Revision: https://reviews.llvm.org/D136975
concept
When we failed the lookup of the function, we tried to form a
RecoveryExpr that caused us to recursively re-check the same constraint,
which caused us to try to double-insert the satisfaction into the cache.
This patch makes us just return the inner-cached version instead. We DO
end up double-evaluating thanks to the recovery-expr, but there isn't a
good way around that.
template-template parameters. Although it effects whether a template can be
used as an argument for another template, the constraint seems not to
be checked, nor other major implementations (GCC, MSVC, et al.) check it.
Additionally, Part-A of the document seems to have been implemented.
So mark P0857R0 as completed.
Differential Revision: https://reviews.llvm.org/D134128
Since we don't unique specializations for concepts, we can just instantiate
them with the sugared template arguments, at negligible cost.
If we don't track their specializations, we can't resugar them later
anyway, and that would be more expensive than just instantiating them
sugared in the first place since it would require an additional pass.
Signed-off-by: Matheus Izvekov <mizvekov@gmail.com>
Differential Revision: https://reviews.llvm.org/D136566
Implements the changes required to perform substitution with
non-canonical template arguments, and to 'finalize' them
by not placing 'Subst' nodes.
A finalized substitution means we won't resugar them later,
because these templates themselves were eagerly substituted
with the intended arguments at the point of use. We may still
resugar other templates used within those, though.
This patch does not actually implement any uses of this
functionality, those will be added in subsequent patches,
so expect no changes to existing tests.
Signed-off-by: Matheus Izvekov <mizvekov@gmail.com>
Differential Revision: https://reviews.llvm.org/D134604
Since we don't unique specializations for concepts, we can just instantiate
them with the sugared template arguments, at negligible cost.
If we don't track their specializations, we can't resugar them later
anyway, and that would be more expensive than just instantiating them
sugared in the first place since it would require an additional pass.
Signed-off-by: Matheus Izvekov <mizvekov@gmail.com>
Differential Revision: https://reviews.llvm.org/D136566
Implements the changes required to perform substitution with
non-canonical template arguments, and to 'finalize' them
by not placing 'Subst' nodes.
A finalized substitution means we won't resugar them later,
because these templates themselves were eagerly substituted
with the intended arguments at the point of use. We may still
resugar other templates used within those, though.
This patch does not actually implement any uses of this
functionality, those will be added in subsequent patches,
so expect no changes to existing tests.
Signed-off-by: Matheus Izvekov <mizvekov@gmail.com>
Differential Revision: https://reviews.llvm.org/D134604
This reverts commit cecc9a92cf.
The problem ended up being how we were handling the lambda-context in
code generation: we were assuming any decl context here would be a
named-decl, but that isn't the case. Instead, we just replace it with
the concept's owning context.
Differential Revision: https://reviews.llvm.org/D136451
This reverts commit b876f6e2f2.
Still getting build failures on PPC AIX that aren't obvious what is causing
them, so reverting while I try to figure this out.
This reverts commit b7c922607c.
This seems to cause some problems with some modules related things,
which makes me think I should have updated the version-major in
ast-bit-codes? Going to revert to confirm this was a problem, then
change that and re-try a commit.
As that bug reports, the problem here is that the lambda's
'context-decl' was not set to the concept, and the lambda picked up
template arguments from the concept. SO, we failed to get the correct
template arguments in SemaTemplateInstantiate.
However, a Concept Specialization is NOT a decl, its an expression, so
we weren't able to put the concept in the decl tree like we needed.
This patch introduces a ConceptSpecializationDecl, which is the smallest
type possible to use for this purpose, containing only the template
arguments.
The net memory impliciation of this is turning a
trailing-objects into a pointer to a type with trailing-objects, so it
should be minor.
As future work, we may consider giving this type more responsibility, or
figuring out how to better merge duplicates, but as this is just a
template-argument collection at the moment, there isn't much value to
it.
Differential Revision: https://reviews.llvm.org/D136451
`|| fold` is not disjunction; `&& fold` is not conjunction. Both are atomic per
current wording. See http://cplusplus.github.io/concepts-ts/ts-active.html#28.
D128750 accidentally tried to partially addresss this which is not desirable.
This patch reverts that part and associated test cases.
For some reason the initial deferred concepts patch didn't add this
check, which someone noticed could cause a problem with other patches
applied. This makes sure we check these, so that an error condition
cannot cause us to crash.
This is a change to how we represent type subsitution in the AST.
Instead of only storing the replaced type, we track the templated
entity we are substituting, plus an index.
We modify MLTAL to track the templated entity at each level.
Otherwise, it's much more expensive to go from the template parameter back
to the templated entity, and not possible to do in some cases, as when
we instantiate outer templates, parameters might still reference the
original entity.
This also allows us to very cheaply lookup the templated entity we saw in
the naming context and find the corresponding argument it was replaced
from, such as for implementing template specialization resugaring.
Signed-off-by: Matheus Izvekov <mizvekov@gmail.com>
Differential Revision: https://reviews.llvm.org/D131858
As another regression from the Deferred Concepts Instantiation patch, we
weren't properly detecting that a friend referenced its containing
Record when it referred to it without its template parameters. This
patch makes sure that we do.
As fallout of the Deferred Concept Instantiation patch (babdef27c5), we
got a number of reports of a regression, where we asserted when
instantiating a constraint on a generic lambda inside of a variable
template. See: https://github.com/llvm/llvm-project/issues/57958
The problem was that getTemplateInstantiationArgs function only walked
up declaration contexts, and missed that this is not necessarily the
case with a lambda (which can ALSO be in a separate context).
This patch refactors the getTemplateInstantiationArgs function in a way
that is hopefully more readable, and fixes the problem with the concepts
on a generic lambda.
Differential Revision: https://reviews.llvm.org/D134874
As reported in GH #57945, this would crash because the decl context for
the lambda was being loaded via 'getNonClosureContext', which only gets
CODE contexts, so a global lambda was getting 'nullptr' here instead.
This patch does some work to make sure we get a valid/valuable
declcontext here instead.
This reverts commit 192d69f7e6.
This fixes the condition to check whether this is a situation where we
are in a recovery-expr'ed concept a little better, so we don't access an
inactive member of a union, which should make the bots happy.
Differential Revision: https://reviews.llvm.org/D134542
This reverts commit e3d14bee23.
There are apparently a large number of crashes in libcxx and some JSON
Parser thing, so clearly this has some sort of serious issue. Reverting
so I can take some time to figure out what is going on.
Discovered by reducing a different problem, we currently assert because
we failed to make the constraint expressions not dependent, since a
RecoveryExpr cannot be transformed.
This patch fixes that, and gets reasonably nice diagnostics by
introducing a concept (hah!) of "ContainsErrors" to the Satisfaction
types, which causes us to treat the candidate as non-viable.
However, just making THAT candidate non-viable would result in choosing
the 'next best' canddiate, which can result in awkward errors, where we
start evaluating a candidate that is not intended to be selected.
Because of this, and to make diagnostics more relevant, we now just
cause the entire lookup to result in a 'no-viable-candidates'.
This means we will only emit the list of candidates, rather than any
cascading failures.
This reverts commit 95d94a6775.
This implements the deferred concepts instantiation, which should allow
the libstdc++ ranges to properly compile, and for the CRTP to work for
constrained functions.
Since the last attempt, this has fixed the issues from @wlei and
@mordante.
Differential Revision: https://reviews.llvm.org/D126907
This reverts commit d483730d8c.
This allegedly breaks a significant part of facebooks internal build.
Reverting while we wait for them to provide a reproducer of this from
@wlei.
This reverts commit 258c3aee54.
This should fix the libc++ issue that caused the revert, by re-designing
slightly how we determined when we should evaluate the constraints.
Additionally, many of the other components to the original patch (the
NFC parts) were committed separately to shrink the size of this patch
for review.
Differential Revision: https://reviews.llvm.org/D126907
In preperation of the deferred instantation progress, this patch
propagates the multi-level template argument lists further through the
API to reduce the size of that patch.
This reverts commit d4d47e574e.
This fixes the lldb crash that was observed by ensuring that our
friend-'template contains reference to' TreeTransform properly handles a
TemplateDecl.
This reverts commit 2f20743952 because it
triggers an assertion when building an LLDB test program:
Assertion failed: (InstantiatingSpecializations.empty() && "failed to
clean up an InstantiatingTemplate?"), function ~Sema, file
/Users/buildslave/jenkins/workspace/lldb-cmake/llvm-project/clang/lib/Sema/Sema.cpp,
line 458.
More details in https://reviews.llvm.org/D126907.
Fixes#54629.
The crash is is caused by the double template instantiation.
See the added test. Here is what happens:
- Template arguments for the partial specialization get instantiated.
- This causes instantitation into the corrensponding requires
expression.
- `TemplateInsantiator` correctly handles instantiation of parameters
inside `RequiresExprBody` and instantiates the constraint expression
inside the `NestedRequirement`.
- To build the substituted `NestedRequirement`, `TemplateInsantiator`
calls `Sema::BuildNestedRequirement` calls
`CheckConstraintSatisfaction`, which results in another template
instantiation (with empty template arguments). This seem to be an
implementation detail to handle constraint satisfaction and is not
required by the standard.
- The recursive template instantiation tries to find the parameter
inside `RequiresExprBody` and fails with the corresponding assertion.
Note that this only happens as both instantiations happen with the class
partial template specialization set as `Sema.CurContext`, which is
considered a dependent `DeclContext`.
To fix the assertion, avoid doing the recursive template instantiation
and instead evaluate resulting expressions in-place.
Reviewed By: erichkeane
Differential Revision: https://reviews.llvm.org/D127487
This includes a fix for the libc++ issue I ran across with friend
declarations not properly being identified as overloads.
This reverts commit 45c07db31c.
The flag was added when the C++20 draft did not allow for concept
caching. The final C++20 standard permits the caching, so flag is
redundant. See http://wg21.link/p2104r0.
Reviewed By: sammccall
Differential Revision: https://reviews.llvm.org/D125014
- Exit early when constraint caching is disabled.
- Use unique_ptr to manage temporary lifetime.
- Fix a typo in a comment (InsertPos instead of InsertNode).
The new code duplicates the forwarding call to CheckConstraintSatisfaction,
but reduces the number of interconnected if statements and simplifies lifetime
management.
This increases the overall readability.
Reviewed By: sammccall
Differential Revision: https://reviews.llvm.org/D124923
This reverts commit a97899108e.
The patch caused some problems with the libc++ `__range_adaptor_closure`
that I haven't been able to figure out the cause of, so I am reverting
while I figure out whether this is a solvable problem/issue with the
CFE, or libc++ depending on an older 'incorrect' behavior.
This reverts commit 0c31da4838.
I've solved the issue with the PointerUnion by making the
`FunctionTemplateDecl` pointer be a NamedDecl, that could be a
`FunctionDecl` or `FunctionTemplateDecl` depending. This is enforced
with an assert.
This reverts commit 4b6c2cd647.
The patch caused numerous ARM 32 bit build failures, since we added a
5th item to the PointerUnion, and went over the 2-bits available in the
32 bit pointers.
As reported here: https://github.com/llvm/llvm-project/issues/44178
Concepts are not supposed to be instantiated until they are checked, so
this patch implements that and goes through significant amounts of work
to make sure we properly re-instantiate the concepts correctly.
Differential Revision: https://reviews.llvm.org/D119544
This is a Sema function that now no longer depends on any of the
functionality in SemaTemplateInstantiateDecl.cpp (as the static function
was moved to Sema in a previous NFC). Moving it to SemaConcept means
that it and CheckFunctionConstraints can be changed to share more.