https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3344.pdf
This paper disallows a single `void` parameter from having qualifiers or
storage class specifiers. Clang has diagnosed most of these as an error
for a long time, but `register void` was previously accepted in all C
language modes and is now being rejected in all C language modes.
LLVM support for the attribute has been implemented already, so it just
plumbs it through to the CUDA front-end.
One notable difference from NVCC is that the attribute can be used
regardless of the targeted GPU. On the older GPUs it will just be
ignored. The attribute is a performance hint, and does not warrant a
hard error if compiler can't benefit from it on a particular GPU
variant.
The `sycl_kernel_entry_point` attribute is used to declare a function that
defines a pattern for an offload kernel to be emitted. The attribute requires
a single type argument that specifies the type used as a SYCL kernel name as
described in section 5.2, "Naming of kernels", of the SYCL 2020 specification.
Properties of the offload kernel are collected when a function declared with
the `sycl_kernel_entry_point` attribute is parsed or instantiated. These
properties, such as the kernel name type, are stored in the AST context where
they are (or will be) used for diagnostic purposes and to facilitate reflection
to a SYCL run-time library. These properties are not serialized with the AST
but are recreated upon deserialization.
The `sycl_kernel_entry_point` attribute is intended to replace the existing
`sycl_kernel` attribute which is intended to be deprecated in a future change
and removed following an appropriate deprecation period. The new attribute
differs in that it is enabled for both SYCL host and device compilation, may
be used with non-template functions, explicitly indicates the type used as
the kernel name type, and will impact AST generation.
This change adds the basic infrastructure for the new attribute. Future
changes will add diagnostics and new AST support that will be used to drive
generation of the corresponding offload kernel.
This patch reapplies #114258, fixing an infinite recursion bug in
`ASTImporter` that occurs when importing the primary template of a class
template specialization when the latest redeclaration of that template
is a friend declaration in the primary template.
This PR resolves a crash triggered by a forward reference to an enum
type in a function parameter list. The fix includes setting `Invalid`
when `TagUseKind` is `Declaration` to ensure correct error handling.
Fixes#112208
Swift ClangImporter now supports concurrency annotations on imported
declarations and their parameters/results, to make it possible to use
imported APIs in Swift safely there has to be a way to annotate
individual parameters and result types with relevant attributes that
indicate that e.g. a block is called on a particular actor or it accepts
a `Sendable` parameter.
To faciliate that `SwiftAttr` is switched from `InheritableAttr` which
is a declaration attribute to `DeclOrTypeAttr`. To support this
attribute in type context we need access to its "Attribute" argument
which requires `AttributedType` to be extended to include `Attr *` when
available instead of just `attr::Kind` otherwise it won't be possible to
determine what attribute should be imported.
This patch fixes a couple of regressions introduced in #111852.
Consider:
```
template<typename T>
struct A
{
template<bool U>
static constexpr bool f() requires U
{
return true;
}
};
template<>
template<bool U>
constexpr bool A<short>::f() requires U
{
return A<long>::f<U>();
}
template<>
template<bool U>
constexpr bool A<long>::f() requires U
{
return true;
}
static_assert(A<short>::f<true>()); // crash here
```
This crashes because when collecting template arguments from the _first_
declaration of `A<long>::f<true>` for constraint checking, we don't add
the template arguments from the enclosing class template specialization
because there exists another redeclaration that is a member
specialization.
This also fixes the following example, which happens for a similar
reason:
```
// input.cppm
export module input;
export template<int N>
constexpr int f();
template<int N>
struct A {
template<int J>
friend constexpr int f();
};
template struct A<0>;
template<int N>
constexpr int f() {
return N;
}
```
```
// input.cpp
import input;
static_assert(f<1>() == 1); // error: static assertion failed
```
Scans each global variable declaration and its members and collects all
required resource bindings in a new `SemaHLSL` data member `Bindings`.
New fields are added `HLSLResourceBindingAttr` for storing processed
binding information so that it can be used by CodeGen (`Bindings` or any
other Sema information is not accessible from CodeGen.)
Adjusts the existing register binding attribute handling and diagnostics
to:
- do not create HLSLResourceBindingAttribute if it is not valid
- diagnose only the simple/local errors when a register binding
attribute is parsed
- additional diagnostic of binding type mismatches is done later and
uses the new `Bindings` data
Fixes#110719
This PR would fix#16855 .
The correct lookup to use for class names is Tag name lookup,
because it does not take namespaces into account. The lookup before
does and because of this some valid programs are not accepted.
An example scenario of a valid program being declined is when you have a struct (let's call it `y`) inheriting from another struct with a name `x` but the struct `y` is in a namespace that is also called `x`:
```
struct x
{};
namespace
{
namespace x
{
struct y : x
{};
}
}
```
This shall be accepted because:
```
C++ [class.derived]p2 (wrt lookup in a base-specifier): The lookup for
// the component name of the type-name or simple-template-id is type-only.
```
This patch reapplies #111173, fixing a bug when instantiating dependent
expressions that name a member template that is later explicitly
specialized for a class specialization that is implicitly instantiated.
The bug is addressed by adding the `hasMemberSpecialization` function,
which return `true` if _any_ redeclaration is a member specialization.
This is then used when determining the instantiation pattern for a
specialization of a template, and when collecting template arguments for
a specialization of a template.
Consider #109148:
```c++
template <typename ...Ts>
void f() {
[] {
(^Ts);
};
}
```
When we encounter `^Ts`, we try to parse a block and subsequently call
`DiagnoseUnexpandedParameterPack()` (in `ActOnBlockArguments()`), which
sees `Ts` and sets `ContainsUnexpandedParameterPack` to `true` in the
`LambdaScopeInfo` of the enclosing lambda. However, the entire block is
subsequently discarded entirely because it isn’t even syntactically
well-formed. As a result, `ContainsUnexpandedParameterPack` is `true`
despite the lambda’s body no longer containing any unexpanded packs,
which causes an assertion the next time
`DiagnoseUnexpandedParameterPack()` is called.
This pr moves handling of unexpanded parameter packs into
`CapturingScopeInfo` instead so that the same logic is used for both
blocks and lambdas. This fixes this issue since the
`ContainsUnexpandedParameterPack` flag is now part of the block (and
before that, its `CapturingScopeInfo`) and no longer affects the
surrounding lambda directly when the block is parsed. Moreover, this
change makes blocks actually usable with pack expansion.
This fixes#109148.
This is maybe a personal take but I expect "bad" to either mean:
* Allowed but not ideal, like a "bad" memory alignment might work but it
is slow.
* The tool won't allow it but is going to tell me why it didn't.
The current error doesn't elaborate so I think it's best we just say
"unsupported" instead. This is clear that the type used is not allowed
at all.
Reapplies #106585, fixing an issue where non-dependent names of member
templates appearing prior to that member template being explicitly
specialized for an implicitly instantiated class template specialization
would incorrectly use the definition of the explicitly specialized
member template.
...not the register keyword. Fixes#109776.
Until now the error was only tested in clang/test/Sema/asm.c, where you
can't check for the "^" character. I've added a new caret test file as I
see has been done for other error types.
- In Sema, when encountering Decls with function effects needing
verification, add them to a vector, DeclsWithEffectsToVerify.
- Update AST serialization to include DeclsWithEffectsToVerify.
- In AnalysisBasedWarnings, use DeclsWithEffectsToVerify as a work
queue, verifying functions with declared effects, and inferring (when
permitted and necessary) whether their callees have effects.
---------
Co-authored-by: Doug Wyatt <dwyatt@apple.com>
Co-authored-by: Sirraide <aeternalmail@gmail.com>
Co-authored-by: Erich Keane <ekeane@nvidia.com>
It is common practice in C to declare anonymous tags that are
immediately given a typedef name, e.g.,
typedef enum { ... } MyType;
At present, one can only express API notes on the typedef. However, that
excludes the possibility of tag-specific notes like EnumExtensibility.
For these anonymous declarations, process API notes using the typedef
name as the tag name, so that one can add API notes to `MyType` via the
`Tags` section.
Fixes#110558.
In this patch, we will emit a diagnostic note pointing to the class
declaration when a method definition does not match any declaration.
This approach, similar to what GCC does, makes the diagnostic more
user-friendly.
---------
Co-authored-by: Vlad Serebrennikov <serebrennikov.vladislav@gmail.com>
Reworked handling of implicit inline marking for member and friend
function defined in class.
Now, we handle it in an additive manner, i.e. if such in-class functions
are inline implicitly by language rules,
we mark the as `setImplicitInline`, and perform no action otherwise.
As we never remove inline specifier, the implementation is orthogonal to
other sources of inline
(like `inline`, `constexpr`, e.t.c), and we do not need to handle them
specially.
Also included test for `constexpr`, `consteval` and global module cases.
Currently, clang rejects the following explicit specialization of `f`
due to the constraints not being equivalent:
```
template<typename T>
struct A
{
template<bool B>
void f() requires B;
};
template<>
template<bool B>
void A<int>::f() requires B { }
```
This happens because, in most cases, we do not set the flag indicating
whether a `RedeclarableTemplate` is an explicit specialization of a
member of an implicitly instantiated class template specialization until
_after_ we compare constraints for equivalence. This patch addresses the
issue (and a number of other issues) by:
- storing the flag indicating whether a declaration is a member
specialization on a per declaration basis, and
- significantly refactoring `Sema::getTemplateInstantiationArgs` so we
collect the right set of template argument in all cases.
Many of our declaration matching & constraint evaluation woes can be
traced back to bugs in `Sema::getTemplateInstantiationArgs`. This
change/refactor should fix a lot of them. It also paves the way for
fixing #101330 and #105462 per my suggestion in #102267 (which I have
implemented on top of this patch but will merge in a subsequent PR).
Basically clang already implemented 90% of the feature as an extension.
This commit disables warnings for C23 and aligns types of enumerators
according to the recent wording.
Fixes#80235
When trying to overload a function within `extern "C"`, the diagnostic
`functions that differ only in their return type cannot be overloaded`
is given. This diagnostic is inappropriate because overloading is
basically not allowed in the C language. However, if the redeclared
function has the `((overloadable))` attribute, it should be diagnosed as
`functions that differ only in their return type cannot be overloaded`.
This patch uses `isExternC()` to provide an appropriate diagnostic
during the diagnostic process. `isExternC()` updates the linkage
information cache internally, so calling it before merging functions can
cause clang to crash. An example is declaring `static void foo()` and
`void foo()` within an `extern "C"` block. Therefore, I decided to call
`isExternC()` after the compilation error is confirmed and select the
diagnostic message. The diagnostic message is `conflicting types for
'func'` similar to the diagnostic in C, and `functions that differ only
in their return type cannot be overloaded` if the `((overloadable))`
attribute is given.
Regression tests verify that the expected diagnostics are given when
trying to overload functions within `extern "C"` and when the
`((overloadable))` attribute is present.
---------
Co-authored-by: Sirraide <aeternalmail@gmail.com>
HLSL output parameters are denoted with the `inout` and `out` keywords
in the function declaration. When an argument to an output parameter is
constructed a temporary value is constructed for the argument.
For `inout` pamameters the argument is initialized via copy-initialization
from the argument lvalue expression to the parameter type. For `out`
parameters the argument is not initialized before the call.
In both cases on return of the function the temporary value is written
back to the argument lvalue expression through an implicit assignment
binary operator with casting as required.
This change introduces a new HLSLOutArgExpr ast node which represents
the output argument behavior. The OutArgExpr has three defined children:
- An OpaqueValueExpr of the argument lvalue expression.
- An OpaqueValueExpr of the copy-initialized parameter.
- A BinaryOpExpr assigning the first with the value of the second.
Fixes#87526
---------
Co-authored-by: Damyan Pepper <damyanp@microsoft.com>
Co-authored-by: John McCall <rjmccall@gmail.com>
Control flow analysis performed by a static analysis tool revealed the
potential for null pointer dereferences to occur in conjunction with the
`Init` parameter in `Sema::AddInitializerToDecl()`. On entry to the
function, `Init` is required to be non-null as there are multiple
potential branches that unconditionally dereference it. However, there
were two places where `Init` is compared to null thus implying that
`Init` is expected to be null in some cases. These checks appear to be
purely defensive checks and thus unnecessary. Further, there were
several cases where code checked `Result`, a variable of type
`ExprResult`, for an invalid value, but did not check for a valid but
null value and then proceeded to unconditionally dereference the
potential null result. This change elides the unnecessary defensive
checks and changes some checks for an invalid result to instead branch
on an unusable result (either an invalid result or a valid but null
result).
With this patch, clang now automatically adds
``[[clang::lifetimebound]]`` to the parameters of `std::span,
std::string_view` constructors, this enables Clang to capture more cases
where the returned reference outlives the object.
Fixes#100567
We need to rebuild the template parameters of out-of-line
definitions/specializations of member templates in the context of the
current instantiation for the purposes of declaration matching. We
already do this for function templates and class templates, but not
variable templates, partial specializations of variable template, and
partial specializations of class templates. This patch fixes the latter
cases.
Previously, `[[clang::lifetimebound]]` applied to an explicit object
member function did nothing and was silently ignored.
Now issue the error diagnostic `'lifetimebound' attribute cannot be
applied; explicit object member function has no implicit object
parameter`
When various `Sema*.h` and `Sema*.cpp` files were created, cleanup of
`Sema.h` includes and forward declarations was left for the later.
Now's the time. This commit touches `Sema.h` and Sema components:
1. Unused includes are removed.
2. Unused forward declarations are removed.
3. Missing includes are added (those files are largely IWYU-clean now).
4. Includes were converted into forward declarations where possible.
As this commit focuses on headers, all changes to `.cpp` files were
minimal, and were aiming at keeping everything buildable.
Reland https://github.com/llvm/llvm-project/pull/75912
The differences of this PR between
https://github.com/llvm/llvm-project/pull/75912 are:
- Fixed a regression in `Decl::isInAnotherModuleUnit()` in DeclBase.cpp
pointed by @mizvekov and add the corresponding test.
- Fixed the regression in windows
https://github.com/llvm/llvm-project/issues/97447. The changes are in
`CodeGenModule::getVTableLinkage` from
`clang/lib/CodeGen/CGVTables.cpp`. According to the feedbacks from MSVC
devs, the linkage of vtables won't affected by modules. So I simply
skipped the case for MSVC.
Given this is more or less fundamental to the use of modules. I hope we
can backport this to 19.x.
A class member named by an expression in a member function that may instantiate to a static _or_ non-static member is represented by a `UnresolvedLookupExpr` in order to defer the implicit transformation to a class member access expression until instantiation. Since `ASTContext::getDecltypeType` only creates a `DecltypeType` that has a `DependentDecltypeType` as its canonical type when the operand is instantiation dependent, and since we do not transform types unless they are instantiation dependent, we need to mark the `UnresolvedLookupExpr` as instantiation dependent in order to correctly build a `DecltypeType` using the expression as its operand with a `DependentDecltypeType` canonical type. Fixes#99873.
The selection of the most constrained candidate for member function
explicit specializations introduced in #88963 does not check whether the
selected candidate is more constrained than all other candidates, which
can result in ambiguities being undiagnosed. This patch addresses the
issue.