Fix#177741
Overload candidate diagnostics reserve a conversion slot for the object
argument. For static methods this slot does not correspond to a real
parameter, and for ill-formed declarations with an explicit object
parameter we could index past the parameter list and crash in assert
builds.
Use isExplicitObjectMemberFunction() when mapping conversion slots to
parameters and guard parameter-range computation to keep notes robust.
We ensure immediate access control checking when evaluating the
enable_if attribute to rule out inaccessible constructors during
potential overload resolution, treating them as SFINAE errors rather
than hard errors, making the behavior more preferable with the nature of
the enable_if attribute.
Compared to the last patch, we now avoid switching the DC directly
because there are cases where we're checking enable_if attribute within
a lambda and getCurLambda() requires a lambda context to distinguish
from template instantiation.
This reapplies #175899
Fixes https://github.com/llvm/llvm-project/issues/175895
A ContextRAII here ensures immediate access control checking within the
current context, allowing us to rule out inaccessible constructors
during potential overload resolution, where access diagnostics are
converted from hard errors into SFINAE errors, making the behavior more
preferrable with the nature of the enable_if attribute.
Fixes https://github.com/llvm/llvm-project/issues/175895
Fixes#173847
---
This patch addresses an assertion failure during compilation of C23 code
involving floating-point conversions.
As part of the C23 constexpr support introduced in PR #73099, Clang
began reusing parts of the C++ constant evaluation and narrowing logic.
In C23 mode, a failed constant evaluation caused the condition to
proceed to C++ constant-expression checks, resulting in an assertion
failure.
This change evaluates constants using `EvaluateAsRValue` in C23 mode and
restricts C++ constant-expression checks to C++ mode.
fixes#168960
Adds `ICK_HLSL_Matrix_Splat` and hooks it up to
`PerformImplicitConversion` and `IsMatrixConversion`. Map these to
`CK_HLSLAggregateSplatCast`.
fixes#168737fixes#168755
This change fixes adds support for Matrix truncations via the
ICK_HLSL_Matrix_Truncation enum. That ends up being most of the files
changed.
It also allows Matrix as an HLSL Elementwise cast as long as the cast
does not perform a shape transformation ie 3x2 to 2x3.
Tests for the new elementwise and truncation behavior were added. As
well as sema tests to make sure we error n the shape transformation
cast.
I am punting right now on the ConstExpr Matrix support. That will need
to be addressed later. Will file a seperate issue for that if reviewers
agree it can wait.
This change adds resource handle type `__hlsl_resource_t` to the list of types recognized in the Clang's built-in functions prototype string.
HLSL has built-in resource classes and some of them have many methods, such as
[Texture2D](https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/sm5-object-texture2d).
Most of these methods will be implemented by built-in functions that will take resource handle as an argument. This change enables us to move from generic `void(...)` prototype string for these methods and explicit argument checking in `SemaHLSL.cpp` to a prototype string with explicit argument types. Argument checking in `SemaHLSL.cpp` can be reduced to handle just the rules that cannot be expressed in the prototype string (for example verifying that the offset value in `__builtin_hlsl_buffer_update_counter` is `1` or `-1`).
In order to make this work, we now allow conversions from attributed resource handle type such as `__hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::contained_type(float)]]` to a plain non-attributed `__hlsl_resource_t` type.
Commit b194cf1e401a changed this function for the case where attribute
`cfi_unchecked_callee` is added in a function conversion. But this
introduces a hole (issue #162798), and it seems the change was
unnecessary: the preceding `TryFunctionConversion` will already allow
adding the `cfi_unchecked_callee` attribute, and will update `FromType`
if it succeeds. So we revert the changes to `IsStandardConversion`. We
also remove the helper function `AddingCFIUncheckedCallee` which is no
longer needed, and simplify the corresponding
`DiscardingCFIUncheckedCallee`.
Fixes: #162798
The `DeferHint` was misused at several callsites, where a `Decl*` was
implicitly casted to `bool`.
This patch proposes removing the `DeferHint` parameter and relying on
`DeferDiagsRAII` to set if Clang should defer the diagnostics.
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.
To raise -Wincompatible-function-pointer-type for extended function type
information conversions in C mode, checkPointerTypesForAssignment
contained an invocation of IsFunctionConversion that is quite dubious:
it verifies the conversion from LHS to RHS, while we are converting from
RHS to LHS. Presumably, this was done because result and argument types
don't have to match exactly in C mode (compatible types is sufficient),
while IsFunctionConversion checks that an exact match in function types
can be obtained by transforming extended function type information. As a
result of the dubious invocation, the diagnostic for incompatible
extended function type changes was incomplete and would illogically
disappear when other changes to the function type were involved (this
was already raised in 2019 but left unsolved). Newer additions of
extended function type information such as "cfi_unchecked_callee", ARM
CMSE attributes, ARM SME attributes, and function effect attributes,
worked around the issue by introducing either holes or additional checks
which complicates the logic.
Here, we solve this longstanding issue by using IsFunctionConversion to
verify the extended function type information conversion in the correct
direction (from RHS to LHS), after first removing other differences in
the function type (argument and result type mismatch, prototype vs. no
prototype) to allow IsFunctionConversion to obtain an exact match. The
complications introduced for checking newer attributes are removed.
Fixes#41465Fixes#85415
With lazy template loading, it is possible to find non-canonical
FunctionDecls, depending on when redecl chains are completed. This
is a problem for templated conversion operators that would allow to
call either the copy assignment or the move assignment operator.
This ambiguity is resolved by isBetterReferenceBindingKind (called
from CompareStandardConversionSequences) ranking rvalue refs over
lvalue refs.
Unfortunately, this fix is hard to test in isolation without the
changes in https://github.com/llvm/llvm-project/pull/133057 that
make lazy template loading more likely to complete redecl chains
at "inconvenient" times. The added reproducer passes before and
after this commit, but would have failed with the proposed changes
of the linked PR.
Kudos to Maksim Ivanov for providing an initial version of the
reproducer that I further simplified.
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>
Summary:
Clang supports boolean vectors as an extension to the vector model.
These are commonly used to represent mask vectors in many vector ISAs.
Currently, using these is quite difficult because all of the vector
comparison operations use integral bitmasks. C / C++ has a long history
of allowing implicit conversions to bool, and I think that we should be
able to do the same here, especially because boolean vectors often work
as wrappers around a bitfield.
This patch adds the minimal changes to enable integral to boolean
conversions for vectors. Because LLVM already handles comparison to zero
for vectors natively, minimal changes are required. We are not bound to
the OpenCL standard at all here because it explicitly forbids boolean
vectors anyway, so these are simply clang extensions.
Resolves#157067
APFloat::convertToInteger returns opInvalidOp when the conversion has
unspecified value. The int-to-float narrowing detection logic doesn't
check for this when comparing the converted-back integer with the
original integer.
PR adds a check for this, and test cases.
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.
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.