In the crash example, when performing typo correction for a qualified
name lookup (`::a`), clang suggests a template template parameter from
an outer scope.
However, template template parameters can not be qualified by any scope.
Attempting to combine the qualifier with the suggested template template
parameter resulted in an assertion failure in
`ASTContext::getQualifiedTemplateName`:
This patch is to update the typo correction filter to reject
`TemplateTemplateParmDecl` candidates when a qualifier is present . This
prevents the invalid suggestion from being generated and avoids the
assertion violation.
Fixes#183983
This adds a way to attach source locations to trivially created template
arguments such as packs, or converted expressions when there is no
expression available.
This also avoids crashes due to missing source locations.
In a few places where this matters, we already create expressions from
the converted arguments, but this requires access to Sema, where
currently creating trivial typelocs only requires access to to the
ASTContext.
So this creates a new storage kind for TemplateArgumentLocs, where a
single SourceLocation is stored, embedded in the pointer where possible.
As a drive-by, strenghten asserts by enforcing the TemplateArgumentLocs
are created with the right kinds of locations.
Fixes#186655
This is a small refactor of how DeducedType and it's derived types are
represented.
The different deduction kinds are spelled out in an enum, and how this
is tracked is simplified, to allow easier profiling.
How these types are constructed and canonicalized is also brought more
in line with how it works for the other types.
This fixes a crash reported here:
https://github.com/llvm/llvm-project/issues/167513#issuecomment-3692962115
When a non-type template parameter has a type containing an undeduced
placeholder type that is invalid (e.g., a function returning a
function), `SubstAutoTypeSourceInfoDependent` can return null if the
type is invalid. `CheckNonTypeTemplateParameterType` was not handling
this case and would dereference the null pointer.
Fixes#177545
Fixes#168935
This PR adds basic support for matrix APValues and a ConstExpr evaluator
for matrices.
- ConstExpr evaluation changes:
- Matrix initializer list
- Matrix HLSL elementwise cast
- Matrix HLSL aggregate splat
- Vector HLSL matrix truncation
- Int HLSL matrix truncation
- Float HLSL matrix truncation
- Matrix APValue:
- AST dumper and serialization
- Value flattening
Note that APValue matrices hold its elements in row-major order
irrespective of the `-fmatrix-memory-layout` flag.
The `-fmatrix-memory-layout` is for codegen, not semantics, so the
decision of which memory layout to use for the matrix APValue can be
independent of the memory layout for codegen.
There are also a number of places expecting switch case coverage over
all APValues but which do not currently support matrix APValues. I have
added placeholder llvm_unreachables to these places for the matrix
APValue, as these places can not currently be exercised in clang tests
(AFAIK).
Assisted-by: claude-opus-4.5
dependent pack expansions in __type_pack_element can result in
single-element template argument lists. When performing semantic
analysis for these builtins, the compiler needs to account for the
dependent expansions and handle them without triggering strict size
assertions. The patch adds this analysis and ensures we either defer
evaluation for dependent cases or report clear out-of-bounds diagnostics
instead of crashing
Ai was used for test generation and CI debugging
fixes#180307
Introduce `OverflowBehaviorType` (OBT), a new type attribute in Clang
that provides developers with fine-grained control over the overflow
behavior of integer types. This feature allows for a more nuanced
approach to integer safety, achieving better granularity than global
compiler flags like `-fwrapv` and `-ftrapv`. Type specifiers are also
available as keywords `__ob_wrap` and `__ob_trap`.
These can be applied to integer types (both signed and unsigned) as well
as typedef declarations, where the behavior is one of the following:
* `wrap`: Guarantees that arithmetic operations on the type will wrap on
overflow, similar to `-fwrapv`. This suppresses UBSan's integer overflow
checks for the attributed type and prevents eager compiler
optimizations.
* `trap`: Enforces overflow checking for the type, even when global
flags like `-fwrapv` would otherwise suppress it.
A key aspect of this feature is its interaction with existing
mechanisms. `OverflowBehaviorType` takes precedence over global flags
and, notably, over entries in the Sanitizer Special Case List (SSCL).
This allows developers to "allowlist" critical types for overflow
instrumentation, even if they are disabled by a broad rule in an SSCL.
Signed-off-by: Justin Stitt <justinstitt@google.com>
MinGW and Win32 disagree on where the `__declspec(dllexport)` should be
placed on extern template instantiations. However, there doesn't
fundamentally seem to be a problem with putting the annotation in both
places. This patch adds a new diagnostic group and `-Wattribute-ignored`
warnings about where the attribute is placed if the attribute is
different on the declaration and definition. There is another new
warning group `-Wdllexport-explicit-instantiation` that also diagnoses
places where the attribute is technically ignored, even though the
correct place is also annotated. This makes it possible to significantly
simplify libc++'s visibility annotations (see #133704).
Fixes#165346
This patch renames stale variable names where `TypeSourceInfo` objects
were still using the old `DI` (`DeclaratorInfo`) naming convention.
Specifically, variables of type `TypeSourceInfo` have been updated from
`DI` to `TSI` to improve code clarity and maintain consistency with the
current naming.
This rename was made as part of
https://github.com/llvm/llvm-project/pull/147835 in order to ease
rebasing the PR, and give a nice window for other patches to get rebased
as well.
It has been a while already, so lets go ahead and rename it back.
Static analysis flagged that when calling ActOnTemplateName, `S` can be
a `nullptr`
and we call `isTemplateName` which unconditionally dereferences the `S`
argument at
some point. I added a `nullptr` check to assure we don't dereference `S`
in
`isTemplateName` if it is a `nullptr`.
The redundant notes were introduced with the workaround for finding the
template instantiationa args for lambdas inside template type aliases.
This removes the notes for the cases where we are simply instantiating
an outer template, and when diagnosing uses of the alias template.
Also adds comments calling the workaround explicitly.
In the standard, constraint satisfaction checking is done on the
normalized form of a constraint.
Clang instead substitutes on the non-normalized form, which causes us to
report substitution failures in template arguments or concept ids, which
is non-conforming but unavoidable without a parameter mapping
This patch normalizes before satisfaction checking. However, we preserve
concept-id nodes in the normalized form, solely for diagnostics
purposes.
This addresses https://github.com/llvm/llvm-project/issues/61811 and
related concepts conformance bugs, ideally to make the remaining
implementation of concept template parameters easier
Fixes https://github.com/llvm/llvm-project/issues/135190
Fixes https://github.com/llvm/llvm-project/issues/61811
Co-authored-by: Younan Zhang
[zyn7109@gmail.com](mailto:zyn7109@gmail.com)
---------
Co-authored-by: Younan Zhang <zyn7109@gmail.com>
In the standard, constraint satisfaction checking is done on the
normalized form of a constraint.
Clang instead substitutes on the non-normalized form, which causes us to
report substitution failures in template arguments or concept ids, which
is non-conforming but unavoidable without a parameter mapping
This patch normalizes before satisfaction checking. However, we preserve
concept-id nodes in the normalized form, solely for diagnostics
purposes.
This addresses #61811 and related concepts conformance bugs, ideally to
make the remaining implementation of concept template parameters easier
Fixes#135190
Fixes #61811
Co-authored-by: Younan Zhang <zyn7109@gmail.com>
The AutoType's deduced-as-dependent mechanism is not really used for
constant template parameters, but this is currently harmless to ignore
because when dealing which such types, they will have been transformed,
turning them back to plain undeduced AutoTypes.
This should be NFC for current main users, but
https://github.com/llvm/llvm-project/pull/141776 will depend on this.
This simplifies those transforms a lot, removing a bunch of workarounds
which were introducing problems.
The transforms become independent of the template instantiator, so they
are moved to TreeTransform instead.
Fixes#131342
This PR was already reviewed and approved at
https://github.com/llvm/llvm-project/pull/160777, but I accidentally
merged that into another PR, instead of main.
This makes the deduction for dependent types operate in more similar
ways to the non-dependent one, such as when matching template template
parameters, making errors in those generate similar diagnostics to the
non-dependent ones. This also removes some superfluous implicit casts,
simplifying the resulting AST a little bit.
This patch makes sure constant template parameters are checked even in
dependent contexts.
This can for example diagnose narrowings earlier, but this is permitted
as these templates would have no valid instantiations.
This is a follow-up to #134461, reverting some unnecessary changes.
This cleans up some checks around the assumption that a pack expansion
on the argument side could appear when checking non-type template
arguments when handling the pre-C++17 rules, but all of these cases are
being handled using the C++17 rules anyway.
This reverts those changes and adds an assert confirming these cases are
not possible.
A DependentTemplateSpecializationType (DTST) is basically just a
TemplateSpecializationType (TST) with a hardcoded DependentTemplateName
(DTN) as its TemplateName.
This removes the DTST and replaces all uses of it with a TST, removing a
lot of duplication in the implementation.
Technically the hardcoded DTN is an optimization for a most common case,
but the TST implementation is in better shape overall and with other
optimizations, so this patch ends up being an overall performance
positive:
<img width="1465" height="38" alt="image"
src="https://github.com/user-attachments/assets/084b0694-2839-427a-b664-eff400f780b5"
/>
A DTST also didn't allow a template name representing a DTN that was
substituted, such as from an alias template, while the TST does allow it
by the simple fact it can hold an arbitrary TemplateName, so this patch
also increases the amount of sugar retained, while still being faster
overall.
Example (from included test case):
```C++
template<template<class> class TT> using T1 = TT<int>;
template<class T> using T2 = T1<T::template X>;
```
Here we can now represent in the AST that `TT` was substituted for the
dependent template name `T::template X`.
We previously employed a TreeTransform to perform a task that should
have been achieved by RAV. The TreeTransform approach was a bit
wasteful, as we discarded the transform result and incurred some
incorrect semantic analysis.
Fixes https://github.com/llvm/llvm-project/issues/156225
`VarTemplateSpecializationDecl::getTemplateArgsAsWritten()` function
should return `nullptr` in the case of implicit instantiation, as its
`ClassTemplateSpecializationDecl` counterpart does, and not the
arguments written in `DeclRefExpr` referencing the specialization in the
first place. Otherwise, for such code:
```cpp
template <typename>
int VarTpl;
template <typename T>
void tplFn() {
(void)VarTpl<T>; // (1)
}
void fn() {
tplFn<char>();
}
```
Clang treats the `char` argument of the `VarTpl` specialization as if it
were written in the line marked as (1), which is misleading and hardly
makes sense.
Moreover, "template args as written" are stored inside `ExplicitInfo`
field of `VarTemplateSpecializationDecl`, but it is
[documented](13357e8a12/clang/include/clang/AST/DeclTemplate.h (L2653))
that it is not for implicit instantiations.
Moreover, it is assumed in `TraverseVarTemplateSpecializationDecl`
method of `RecursiveASTVisitor` that `getTemplateArgsAsWritten()`
returns `nullptr` for implicit instantiations, as it is stated in the
comment
[there](13357e8a12/clang/include/clang/AST/RecursiveASTVisitor.h (L2196)).
That said, `setTemplateArgsAsWritten` should be called only for variable
template explicit specializations (it is [already done inside
`Sema::ActOnVarTemplateSpecialization`](4c91627304/clang/lib/Sema/SemaTemplate.cpp (L4459)))
and explicit instantiations (hence `true` is passed to the new
`SetWrittenArgs` parameter of `CheckVarTemplateId` function inside
`Sema::ActOnExplicitInstantiation`, but not when handling expressions
referencing a variable template specialization).
`InstantiateVariableDefinition` function just passes the arguments from
the corresponding declaration. I'm not sure about instantiating a class
template containing a variable template explicit specialization and thus
have tried to leave the logic of the first overload of
`TemplateDeclInstantiator::VisitVarTemplateSpecializationDecl` as it
was.
This reintroduces `Type.h`, having earlier been renamed to `TypeBase.h`,
as a redirection to `TypeBase.h`, and redirects most users to include
the former instead.
This is a preparatory patch for being able to provide inline definitions
for `Type` methods which would otherwise cause a circular dependency
with `Decl{,CXX}.h`.
Doing these operations into their own NFC patch helps the git rename
detection logic work, preserving the history.
This patch makes clang just a little slower to build (~0.17%), just
because it makes more code indirectly include `DeclCXX.h`.
This is a preparatory patch, to be able to provide inline definitions
for `Type` functions which depend on `Decl{,CXX}.h`. As the latter also
depends on `Type.h`, this would not be possible without some
reorganizing.
Splitting this rename into its own patch allows git to track this as a
rename, and preserve all git history, and not force any code
reformatting.
A later NFC patch will reintroduce `Type.h` as redirection to
`TypeBase.h`, rewriting most places back to directly including `Type.h`
instead of `TypeBase.h`, leaving only a handful of places where this is
necessary.
Then yet a later patch will exploit this by making more stuff inline.
This changes a bunch of places which use getAs<TagType>, including
derived types, just to obtain the tag definition.
This is preparation for #155028, offloading all the changes that PR used
to introduce which don't depend on any new helpers.
The new builtin `__builtin_dedup_pack` removes duplicates from list of
types.
The added builtin is special in that they produce an unexpanded pack
in the spirit of P3115R0 proposal.
Produced packs can be used directly in template argument lists and get
immediately expanded as soon as results of the computation are
available.
It allows to easily combine them, e.g.:
```cpp
template <class ...T>
struct Normalize {
// Note: sort is not included in this PR, it illustrates the idea.
using result = std::tuple<
__builtin_sort_pack<
__builtin_dedup_pack<int, double, T...>...
>...>;
}
;
```
Limitations:
- only supported in template arguments and bases,
- can only be used inside the templates, even if non-dependent,
- the builtins cannot be assigned to template template parameters.
The actual implementation proceeds as follows:
- When the compiler encounters a `__builtin_dedup_pack` or other
type-producing
builtin with dependent arguments, it creates a dependent
`TemplateSpecializationType`.
- During substitution, if the template arguments are non-dependent, we
will produce: a new type `SubstBuiltinTemplatePackType`, which stores
an argument pack that needs to be substituted. This type is similar to
the existing `SubstTemplateParmPack` in that it carries the argument
pack that needs to be expanded further. The relevant code is shared.
- On top of that, Clang also wraps the resulting type into
`TemplateSpecializationType`, but this time only as a sugar.
- To actually expand those packs, we collect the produced
`SubstBuiltinTemplatePackType` inside `CollectUnexpandedPacks`.
Because we know the size of the produces packs only after the initial
substitution, places that do the actual expansion will need to have a
second run over the substituted type to finalize the expansions (in
this patch we only support this for template arguments, see
`ExpandTemplateArgument`).
If the expansion are requested in the places we do not currently
support, we will produce an error.
More follow-up work will be needed to fully shape this:
- adding the builtin that sorts types,
- remove the restrictions for expansions,
- implementing P3115R0 (scheduled for C++29, see
https://github.com/cplusplus/papers/issues/2300).
The import and include problem is a long-standing issue with the use of
C++20 modules. This patch tried to improve this by skipping parsing
class and functions if their declaration is already defined in modules.
The scale of the patch itself is small as the patch reuses previous
optimization. Maybe we can skip parsing other declarations in the
future. But the patch itself should be good.
If a template argument in a partial specialization of a variable
template directly refers to a NTTP of the specialization without
implicit type conversion it was assumed that the NTTP is identical to
that of the primary template.
This doesn't hold if the primary template's NTTP uses a deduced type, so
instead compare the types explicitly as well.
The affected function is used only to provide an improved early error if
the partial specialization has identical template arguments to the
primary template. The actual check that the partial specialization is
more specialized happens later.
Fixes#118190Fixes#152750
This is a major change on how we represent nested name qualifications in
the AST.
* The nested name specifier itself and how it's stored is changed. The
prefixes for types are handled within the type hierarchy, which makes
canonicalization for them super cheap, no memory allocation required.
Also translating a type into nested name specifier form becomes a no-op.
An identifier is stored as a DependentNameType. The nested name
specifier gains a lightweight handle class, to be used instead of
passing around pointers, which is similar to what is implemented for
TemplateName. There is still one free bit available, and this handle can
be used within a PointerUnion and PointerIntPair, which should keep
bit-packing aficionados happy.
* The ElaboratedType node is removed, all type nodes in which it could
previously apply to can now store the elaborated keyword and name
qualifier, tail allocating when present.
* TagTypes can now point to the exact declaration found when producing
these, as opposed to the previous situation of there only existing one
TagType per entity. This increases the amount of type sugar retained,
and can have several applications, for example in tracking module
ownership, and other tools which care about source file origins, such as
IWYU. These TagTypes are lazily allocated, in order to limit the
increase in AST size.
This patch offers a great performance benefit.
It greatly improves compilation time for
[stdexec](https://github.com/NVIDIA/stdexec). For one datapoint, for
`test_on2.cpp` in that project, which is the slowest compiling test,
this patch improves `-c` compilation time by about 7.2%, with the
`-fsyntax-only` improvement being at ~12%.
This has great results on compile-time-tracker as well:

This patch also further enables other optimziations in the future, and
will reduce the performance impact of template specialization resugaring
when that lands.
It has some other miscelaneous drive-by fixes.
About the review: Yes the patch is huge, sorry about that. Part of the
reason is that I started by the nested name specifier part, before the
ElaboratedType part, but that had a huge performance downside, as
ElaboratedType is a big performance hog. I didn't have the steam to go
back and change the patch after the fact.
There is also a lot of internal API changes, and it made sense to remove
ElaboratedType in one go, versus removing it from one type at a time, as
that would present much more churn to the users. Also, the nested name
specifier having a different API avoids missing changes related to how
prefixes work now, which could make existing code compile but not work.
How to review: The important changes are all in
`clang/include/clang/AST` and `clang/lib/AST`, with also important
changes in `clang/lib/Sema/TreeTransform.h`.
The rest and bulk of the changes are mostly consequences of the changes
in API.
PS: TagType::getDecl is renamed to `getOriginalDecl` in this patch, just
for easier to rebasing. I plan to rename it back after this lands.
Fixes#136624
Fixes https://github.com/llvm/llvm-project/issues/43179
Fixes https://github.com/llvm/llvm-project/issues/68670
Fixes https://github.com/llvm/llvm-project/issues/92757
This is a first pass at implementing
[P2841R7](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2841r7.pdf).
The implementation is far from complete; however, I'm aiming to do that
in chunks, to make our lives easier.
In particular, this does not implement
- Subsumption
- Mangling
- Satisfaction checking is minimal as we should focus on #141776 first
(note that I'm currently very stuck)
FTM, release notes, status page, etc, will be updated once the feature
is more mature. Given the state of the feature, it is not yet allowed in
older language modes.
Of note:
- Mismatches between template template arguments and template template
parameters are a bit wonky. This is addressed by #130603
- We use `UnresolvedLookupExpr` to model template-id. While this is
pre-existing, I have been wondering if we want to introduce a different
OverloadExpr subclass for that. I did not make the change in this patch.
We allowed implicit this access when checking associated constraints
after CWG2369. As a result, some of the invalid function call
expressions were not properly SFINAE'ed out and ended up as hard errors
at evaluation time.
We tried fixing that by mucking around the CurContext, but that spawned
additional breakages and I think it's probably safe to revert to the
previous behavior to avoid churns.
Though there is CWG2589, which justifies the previous change, it's not
what we're pursuing now.
Fixes https://github.com/llvm/llvm-project/issues/151271
Fixes https://github.com/llvm/llvm-project/issues/145505
Add `NamespaceBaseDecl` as common base class of `NamespaceDecl` and
`NamespaceAliasDecl`. This simplifies `NestedNameSpecifier` a bit.
Co-authored-by: Matheus Izvekov <mizvekov@gmail.com>
ArrayRef now has a new constructor that takes a parameter whose type
has data() and size(). This patch migrates:
ArrayRef<T>(X.data(), X.size()
to:
ArrayRef<T>(X)
CWG2369 revealed another case where we were SFINAE'ing out the invalid
result of substitution, but the expression now makes the way into evaluation.
We switch to the concept specialization's context before we check it.
This ensures that we're able to realize the invalid expression earlier,
so we can avoid evaluating invalid expression, which is a hard error.
This also fixes#115838
Reland with debug traces to try to understand a bug that only happens on
one CI configuration
===
This introduces a way detect the libstdc++ version,
use that to enable workarounds.
The version is cached.
This should make it easier in the future to find and remove
these hacks.
I did not find the need for enabling a hack between or after
specific versions, so it's left as a future exercise.
We can extend this fature to other libraries as the need arise.
===
This introduces a way detect the libstdc++ version, use that to enable
workarounds.
The version is cached.
This should make it easier in the future to find and remove these hacks.
I did not find the need for enabling a hack between or after specific
versions, so it's left as a future exercise.
We can extend this fature to other libraries as the need arise.
There are several type traits that produce a boolean value or type based
on the well-formedness of some expression (more precisely, the immediate
context, i.e. for example excluding nested template instantiation):
* `__is_constructible` and variants,
* `__is_convertible` and variants,
* `__is_assignable` and variants,
* `__reference_{binds_to,{constructs,converts}_from}_temporary`,
* `__is_trivially_equality_comparable`,
* `__builtin_common_type`.
(It should be noted that the standard doesn't always base this on the
immediate context being well-formed: for `std::common_type` it's based
on whether some expression "denotes a valid type." But I assume that's
an editorial issue and means the same thing.)
Errors in the immediate context are suppressed, instead the type traits
return another value or produce a different type if the expression is
not well-formed. This is achieved using an `SFINAETrap` with
`AccessCheckingSFINAE` set to true. If the type trait is used outside of
an SFINAE context, errors are discarded because in that case the
`SFINAETrap` sets `InNonInstantiationSFINAEContext`, which makes
`isSFINAEContext` return an `optional(nullptr)`, which causes the errors
to be discarded in `EmitDiagnostic`. However, in an SFINAE context this
doesn't happen, and errors are added to `SuppressedDiagnostics` in the
`TemplateDeductionInfo` returned by `isSFINAEContext`. Once we're done
with deducing template arguments and have decided which template is
going to be instantiated, the errors corresponding to the chosen
template are then emitted. At this point we get errors from those type
traits that we wouldn't have seen if used with the same arguments
outside of an SFINAE context. That doesn't seem right.
So what we want to do is always set `InNonInstantiationSFINAEContext`
when evaluating these well-formed-testing type traits, regardless of
whether we're in an SFINAE context or not. This should only affect the
immediate context, as nested contexts add a new `CodeSynthesisContext`
that resets `InNonInstantiationSFINAEContext` for the time it's active.
Going through uses of `SFINAETrap` with `AccessCheckingSFINAE` = `true`,
it occurred to me that all of them want this behavior and we can just
use this parameter to decide whether to use a non-instantiation context.
The uses are precisely the type traits mentioned above plus the
`TentativeAnalysisScope`, where I think it is also fine. (Though I think
we don't do tentative analysis in SFINAE contexts anyway.)
Because the parameter no longer just sets `AccessCheckingSFINAE` in Sema
but also `InNonInstantiationSFINAEContext`, I think it should be renamed
(along with uses, which also point the reviewer to the affected places).
Since we're testing for validity of some expression, `ForValidityCheck`
seems to be a good name.
The added tests should more or less correspond to the users of
`SFINAETrap` with `AccessCheckingSFINAE` = `true`. I added a test for
errors outside of the immediate context for only one type trait, because
it requires some setup and is relatively noisy.
We put the `ForValidityCheck` condition first because it's constant in
all uses and this would then allow the compiler to prune the call to
`isSFINAEContext` when true.
Fixes#132044.