Static analysis flagged this code b/c ToFPT could be nullptr but we were
not checking it even though in the previous if statement we did. It
looks like this was a mistaken refactor from:
https://github.com/llvm/llvm-project/pull/135836
In the older code ToFPT was set using a cast which would have asserted
but no longer in the new code.
Allow CCEKind::ExplicitBool in BuildConvertedConstantExpression for
pre-C++11 contexts, similar to the existing TempArgStrict exception.
This enables explicit(bool) to work as a C++20 extension in earlier
language modes without triggering assertion failures.
Fixes#152729
---------
Co-authored-by: Jongmyeong Choi <cheesechoi@gmail.com>
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
Reverts llvm/llvm-project#148613
Considering object argument conversion qualifications perfect leads to
situations where we prefer a non-template const qualified function over
a non-qualified template function, which is very wrong indeed.
I explored solutions to work around that, but instead, we might want to
go the GCC road and prefer the friend overload in the #147374 example,
as this seems a lot more consistent and reliable
For implicit object arguments.
This fixes a regression introduced by the "perfect match" overload
resolution mechanism introduced in 8c5a307.
Note that GCC allows the ambiguity between a const and non-const
candidate to be resolved. But this patch focuses on restoring the Clang
20 behavior, and to fix the cases which we did resolve incorrectly.
Fixes#147374
When an overload is invalid, we try to initialize each conversion
sequence for the purpose of diagmostics, but we failed to initialize
explicit objects, leading to a crash
Fixes#147121
When implementing #93430, I failed to consider some cases involving
function templates.
```
struct A {
template <typename T>
void a(this T self);
};
(&A::a<A>)(A{});
```
This fixes that
Add parentheses around the assert conditions.
Without this gcc warned like
../lib/Target/AMDGPU/GCNSchedStrategy.cpp:2250: warning: suggest parentheses around '&&' within '||' [-Wparentheses]
2250 | NewMI != RegionBounds.second && "cannot remove at region end");
and
../../clang/lib/Sema/SemaOverload.cpp:11326:39: warning: suggest parentheses around '&&' within '||' [-Wparentheses]
11326 | DeferredCandidatesCount == 0 &&
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
11327 | "Unexpected deferred template candidates");
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
fix https://github.com/llvm/llvm-project/issues/107629
After some more debugging, I find out that we will check access here at
8e010ac5a1/clang/lib/Sema/SemaInit.cpp (L7807)
And for `f()` inside code below, `Found.getAccess()` is `AS_none` hence
`CheckAddressOfMemberAccess` return `AR_accessible` directly.
```cpp
struct Base {
public:
int f(int);
private:
int f(); // expect-note {{declared private here}}
};
struct Derived : public Base {};
void f() {
int(Derived::* public_f)(int) = &Derived::f;
int(Derived::* private_f)() = &Derived::f; // expect-error {{'f' is a private member of 'Base'}}
}
```
I think the `Found.getAccess()` is intended to be `AS_none` so I just
add one more access check for the `UnresolvedLookupExpr` when
`Found.getAccess()` is `AS_none`. If add the check unconditionally clang
will report lots of duplicate errors and cause several unit tests to
fail.
I also test the UB mentioned in
https://github.com/llvm/llvm-project/issues/107629 and clang now display
4 `false` as expecetd.
Co-authored-by: Erich Keane <ekeane@nvidia.com>
https://cplusplus.github.io/CWG/issues/2496.html
We failed to diagnose the following in C++23 mode
```
struct S {
virtual void f(); // expected-note {{previous declaration is here}}
};
struct T : S {
virtual void f() &;
};
```
This introduces the attribute discussed in
https://discourse.llvm.org/t/rfc-function-type-attribute-to-prevent-cfi-instrumentation/85458.
The proposed name has been changed from `no_cfi` to
`cfi_unchecked_callee` to help differentiate from `no_sanitize("cfi")`
more easily. The proposed attribute has the following semantics:
1. Indirect calls to a function type with this attribute will not be
instrumented with CFI. That is, the indirect call will not be checked.
Note that this only changes the behavior for indirect calls on pointers
to function types having this attribute. It does not prevent all
indirect function calls for a given type from being checked.
2. All direct references to a function whose type has this attribute
will always reference the true function definition rather than an entry
in the CFI jump table.
3. When a pointer to a function with this attribute is implicitly cast
to a pointer to a function without this attribute, the compiler will
give a warning saying this attribute is discarded. This warning can be
silenced with an explicit C-style cast or C++ static_cast.
The previous approach broke code generation for the MS ABI due to an
unintended code path during constraint substitution. This time we
address the issue by inspecting the evaluation contexts and thereby
avoiding that code path.
This reapplies 96eced624 (#102857).
The bulk of the changes are in `CallExpr`
We cache Begin/End source locs in the trailing objects, in the space
left by making the offset to the trailing objects static.
We also set a flag to indicate that we are calling an explicit object
member function, further reducing the cost of getBeginLoc.
Fixes#140876
A bunch of uses of IsFunctionConversion don't use the third argument and
just make a dummy QualType to pass. This splits IsFunctionConversion
into 2 functions, one that just takes 2 arguments and does the check,
and one that does the actual conversion using the 3rd argument. Both
functions can be const and replace current uses appropriately.
This patch adds templated `operator<<` for diagnostics that pass scoped
enums, saving people from `llvm::to_underlying()` clutter on the side of
emitting the diagnostic. This eliminates 80 out of 220 usages of
`llvm::to_underlying()` in Clang.
I also backported `std::is_scoped_enum_v` from C++23.
This introduces a new diagnostic group (-Wimplicit-void-ptr-cast),
grouped under -Wc++-compat, which diagnoses implicit conversions from
void * to another pointer type in C. It's a common source of
incompatibility with C++ and is something GCC diagnoses (though GCC does
not have a specific warning group for this).
Fixes#17792
In a lambda function, a call of a function may
resolve to host and device functions with different
signatures. Especially, a constexpr local variable may
be passed by value by the device function and
passed by reference by the host function, which
will cause the constexpr variable captured by
the lambda function in host compilation but
not in the device compilation. The discrepancy
in the lambda captures will violate ODR and
causes UB for kernels using these lambdas.
This PR fixes the issue by identifying
discrepancy of ODR/non-ODR usages of constexpr
local variables passed to host/device functions
and conservatively capture them.
Fixes: https://github.com/llvm/llvm-project/issues/132068
Reland #134174
Update Sema Checking to always do an HLSL Array RValue cast in the case
we are dealing with hlsl constant array types
Instead of comparing canonical types, compare canonical unqualified
types
Add a test to show it is possible to assign an array from a cbuffer.
Closes https://github.com/llvm/llvm-project/issues/133767
Update Sema Checking to always do an HLSL Array RValue cast in the case
we are dealing with hlsl constant array types
Instead of comparing canonical types, compare canonical unqualified
types
Add a test to show it is possible to assign an array from a cbuffer.
Closes#133767
This implements the same overload resolution behavior as GCC,
as described in https://wg21.link/p3606 (section 1-2, not 3)
If during overload resolution, there is a non-template candidate
that would be always be picked - because each of the argument
is a perfect match (ie the source and target types are the same),
we do not perform deduction for any template candidate
that might exists.
The goal is to be able to merge
https://github.com/llvm/llvm-project/pull/122423 without being too
disruptive.
This change means that the selection of the best viable candidate and
template argument deduction become interleaved.
To avoid rewriting half of Clang we store in `OverloadCandidateSet`
enough information to be able to deduce template candidates from
`OverloadCandidateSet::BestViableFunction`. Which means
the lifetime of any object used by template argument must outlive
a call to `Add*Template*Candidate`.
This two phase resolution is not performed for some initialization
as there are cases where template candidate are better match
in these cases per the standard. It's also bypassed for code completion.
The change has a nice impact on compile times
https://llvm-compile-time-tracker.com/compare.php?from=719b029c16eeb1035da522fd641dfcc4cee6be74&to=bf7041045c9408490c395230047c5461de72fc39&stat=instructions%3Au
Fixes https://github.com/llvm/llvm-project/issues/62096
Fixes https://github.com/llvm/llvm-project/issues/74581
Reapplies #133426
This implements the same overload resolution behavior as GCC,
as described in https://wg21.link/p3606 (sections 1-2, not 3)
If, during overload resolution, a non-template candidate is always
picked because each argument is a perfect match (i.e., the source and
target types are the same), we do not perform deduction for any template
candidate that might exist.
The goal is to be able to merge #122423 without being too disruptive.
This change means that the selection of the best viable candidate and
template argument deduction become interleaved.
To avoid rewriting half of Clang, we store in `OverloadCandidateSet`
enough information to deduce template candidates from
`OverloadCandidateSet::BestViableFunction`. This means the lifetime of
any object used by the template argument must outlive a call to
`Add*Template*Candidate`.
This two-phase resolution is not performed for some initialization as
there are cases where template candidates are a better match per the
standard. It's also bypassed for code completion.
The change has a nice impact on compile times
https://llvm-compile-time-tracker.com/compare.php?from=edc22c64e527171041876f26a491bb1d03d905d5&to=8170b860bd4b70917005796c05a9be013a95abb2&stat=instructions%3AuFixes#62096Fixes#74581Fixes#53454
The qualifier allows programmer to directly control how pointers are
signed when they are stored in a particular variable.
The qualifier takes three arguments: the signing key, a flag specifying
whether address discrimination should be used, and a non-negative
integer that is used for additional discrimination.
```
typedef void (*my_callback)(const void*);
my_callback __ptrauth(ptrauth_key_process_dependent_code, 1, 0xe27a) callback;
```
Co-Authored-By: John McCall rjmccall@apple.com
Static analysis flagged 1 - ArgIdx in Sema::AddOverloadCandidate for its
potential to overflow.
Turns out this is intentional since when PO ==
OverloadCandidateParamOrder::Reversed Args.size() is always two, so this
will never overflow.
We document using an assert.
Fixes: https://github.com/llvm/llvm-project/issues/135086
This fixes partial ordering of pack expansions of NTTPs, by procedding
with the check using the pattern of the NTTP through the rules of the
non-pack case.
This also unifies almost all of the different versions of
FinishTemplateArgumentDeduction (except the function template case).
This makes sure they all follow the rules consistently, instantiating
the parameters and comparing those with the argument.
Fixes#132562
This introduces a new class 'UnsignedOrNone', which models a lite
version of `std::optional<unsigned>`, but has the same size as
'unsigned'.
This replaces most uses of `std::optional<unsigned>`, and similar
schemes utilizing 'int' and '-1' as sentinel.
Besides the smaller size advantage, this is simpler to serialize, as its
internal representation is a single unsigned int as well.
This reverts an earlier attempt
(adb0d8ddceb143749c519d14b8b31b481071da77 and
50e5411e4247421fd606f0a206682fcdf0303ae3) to support these expansions,
which was limited to type arguments and which subverted the purpose
of SubstTemplateTypeParmType.
This propagates the ArgumentPackSubstitutionIndex along with the
AssociatedConstraint, so that the pack expansion works, without
needing any new transforms or otherwise any changes to the template
instantiation process.
This keeps the tests from the reverted commits, and adds a few more
showing the new solution also works for NTTPs.
Fixes https://github.com/llvm/llvm-project/issues/131798
Original PR: #130537
Originally reverted due to revert of dependent commit. Relanding with no
changes.
This changes the MemberPointerType representation to use a
NestedNameSpecifier instead of a Type to represent the base class.
Since the qualifiers are always parsed as nested names, there was an
impedance mismatch when converting these back and forth into types, and
this led to issues in preserving sugar.
The nested names are indeed a better match for these, as the differences
which a QualType can represent cannot be expressed syntatically, and
they represent the use case more exactly, being either dependent or
referring to a CXXRecord, unqualified.
This patch also makes the MemberPointerType able to represent sugar for
a {up/downcast}cast conversion of the base class, although for now the
underlying type is canonical, as preserving the sugar up to that point
requires further work.
As usual, includes a few drive-by fixes in order to make use of the
improvements.
The `UnresolvedLookupExpr` doesn't get looked up and resolved again
while it is inside the non-dependent context. It propagates into the
codegen phase, causing the assertion failure.
We attempt to determine if the current context is dependent before
moving on with the substitution introduced in the
20a05677f9.
This fixes https://github.com/llvm/llvm-project/issues/122892.
---------
Co-authored-by: Sirraide <aeternalmail@gmail.com>