Currently, Clang only checks arrays and structures for size at a
top-level view, that is it does not consider whether they will fit in
the address space when applying the address space attribute. This can
lead to situations where a variable is declared in an address space but
its type is too large to fit in that address space, leading to
potentially invalid modules.
This patch proposes a fix for this by checking the size of the type
against the maximum size that can be addressed in the given address
space when applying the address space attribute.
This does not currently handle instantiations of dependent variables, as
the attributes are not re-processesd at that time. This is planned for
further investigation and a follow-up patch.
---------
Signed-off-by: Steffen Holst Larsen <HolstLarsen.Steffen@amd.com>
Co-authored-by: Steffen Holst Larsen <HolstLarsen.Steffen@amd.com>
Add a Clang driver option -fms-anonymous-structs and
-fno-ms-anonymous-structs
to enable or disable Microsoft anonymous struct/union support
independently of -fms-extensions.
**Motivation**:
- On some platforms (e.g. AIX), enabling `-fms-extensions` can conflict
with system headers (such as usage of `__ptr32`).
- Some codebases rely specifically on Microsoft anonymous struct/union
behavior without requiring other Microsoft extensions.
This change allows users to selectively enable the anonymous
struct/union
extension at the driver level without enabling full Microsoft
compatibility
mode.
**Behavior**:
- -fms-anonymous-structs enables the feature explicitly.
- The feature is implicitly enabled by `-fms-extensions `or
`-fms-compatibility`.
- When multiple flags are present, the last flag on the command line
wins.
For example (last option wins):
`-fms-extensions` `-fno-ms-anonymous-structs` -> Disable the feature.
` -fno-ms-anonymous-structs` `-fms-anonymous-structs` -> Enables the
feature.
`-fno-ms-anonymous-structs`` -fms-extensions` -> Enables the feature.
Note: When using CC1 directly (clang -cc1) or -Xclang, explicit
`-f[no-]ms-anonymous-structs` flags
take precedence over implicit enablement from -fms-extensions or
-fms-compatibility.
For example:
` -Xclang -fno-ms-anonymous-structs -Xclang -fms-extensions `-> Disable
the feature.
**Implementation**:
- Added driver-level options `-fms-anonymous-structs `and
`-fno-ms-anonymous-structs`.
- Forwarded the option from the driver to CC1.
- Added driver and frontend tests to verify option interactions.
---------
Co-authored-by: Riyaz Ahmad <riyaz.ahmad@ibm.com>
Fix a bug in a deferred call which was supposed to clear the `DeclForInitializer` field but was doing so incorrectly because the emptiness check needs to be inverted.
This PR implements support for automatically suggesting and inferring
`[[clang::lifetimebound]]` annotations for the implicit `this`.
The analysis now models the implicit this object as an implicit
parameter that carries a "placeholder loan" from the caller's scope. By
tracking this loan through the method body, the analysis can identify if
this reaches an escape point, such as a return statement.
Key Changes:
- Updated `PlaceholderLoan` to hold a union of `ParmVarDecl*` and
`CXXMethodDecl*`
- Extended `OriginManager` to handle `CXXThisExpr` and create a
dedicated origin list for the implicit this parameter
- Modified `FactsGenerator::issuePlaceholderLoans` to create a
placeholder loan for this at the entry of non-static member functions
- Updated `implicitObjectParamIsLifetimeBound` in
`LifetimeAnnotations.cpp` to check for the attribute on the method
declaration itself
- Added logic to skip implicit methods and standard assignment operators
to avoid redundant warnings on boilerplate code
Example:
```cpp
struct ReturnsSelf {
const ReturnsSelf& get() const {
return *this;
}
};
void test_get_on_temporary() {
const ReturnsSelf& s_ref = ReturnsSelf().get();
(void)s_ref;
}
```
Warning:
```
a7.cpp:5:33: warning: implict this in intra-TU function should be marked [[clang::lifetimebound]] [-Wexperimental-lifetime-safety-intra-tu-suggestions]
5 | const ReturnsSelf& get() const {
| ~~~ ^
| [[clang::lifetimebound]]
a7.cpp:6:12: note: param returned here
6 | return *this;
| ^~~~~
a7.cpp:11:30: warning: temporary bound to local reference 's_ref' will be destroyed at the end of the full-expression [-Wdangling]
11 | const ReturnsSelf& s_ref = ReturnsSelf().get();
| ^~~~~~~~~~~~~
```
Fixes https://github.com/llvm/llvm-project/issues/169941
OpenCL spec restricts that variable in local address space can only be
declared at kernel function scope.
Add a Clang internal extension __cl_clang_function_scope_local_variables
to lift the restriction.
To expose static local allocations at kernel scope, targets can either
force-inline non-kernel functions that declare local memory or pass a
kernel-allocated local buffer to those functions via an implicit argument.
Motivation: support local memory allocation in libclc's implementation
of work-group collective built-ins, see example at:
https://github.com/intel/llvm/blob/41455e305117/libclc/libspirv/lib/amdgcn-amdhsa/group/collectives_helpers.llhttps://github.com/intel/llvm/blob/41455e305117/libclc/libspirv/lib/amdgcn-amdhsa/group/collectives.cl#L182
Right now this is a Clang-only OpenCL extension intended for compiling
OpenCL libraries with Clang. It could be proposed as a standard OpenCL
extension in the future.
Implement the export pragma that is used in the z/OS XL C/C++ compiler
to indicate that an external symbol is to be exported from the shared
library. The syntax for the pragma is:
```
'#pragma' 'export' '(' name ')'
```
For C++ if `name` is a function it needs to be declared `extern "C"`.
See the following for the XL documentation:
- https://www.ibm.com/docs/en/zos/3.1.0?topic=descriptions-pragma-export
This code was originally in PR
https://github.com/llvm/llvm-project/pull/111035. I have split it out
into separate PRs so the code for #pragma export is in one PR and the
code for _Export keyword is in another. See that original PR for earlier
comments.
In C static variables should have constant expressions in initializers
so we were checking this twice for constexpr variables and failing with
an assertion that was makes sure we don't do it.
This patch postpones the check just like it is done for file
scope constexpr variables in C already.
Fixes https://github.com/llvm/llvm-project/issues/173605
This caused assertion failures, see comment on the PR:
clang/lib/Sema/TypeLocBuilder.cpp:89:
TypeLoc clang::TypeLocBuilder::pushImpl(QualType, size_t, unsigned int):
Assertion `TLast == LastTy && "mismatch between last type and new type's inner type"' failed.
> Followup on https://github.com/llvm/llvm-project/pull/107627
> Fixes https://github.com/llvm/llvm-project/issues/62072
> Fixes https://github.com/llvm/llvm-project/issues/172013
> Fixes https://github.com/llvm/llvm-project/issues/175391
>
> This PR adds support for merging the `lifetimebound` attribute on the implicit `this` parameter when merging method declarations. Previously, if a method was declared with `lifetimebound` on its function type (which represents the implicit `this` parameter), this attribute would not be propagated to the method definition, causing lifetime safety warnings to be missed.
>
> The implementation adds helper functions to extract the `lifetimebound` attribute from a function type and to merge this attribute from an old method declaration to a new one when appropriate.
This reverts commit ef90ba684d012790c86ac1b5e7c6b325abe78803.
Followup on https://github.com/llvm/llvm-project/pull/107627
Fixes https://github.com/llvm/llvm-project/issues/62072
Fixes https://github.com/llvm/llvm-project/issues/172013
Fixes https://github.com/llvm/llvm-project/issues/175391
This PR adds support for merging the `lifetimebound` attribute on the implicit `this` parameter when merging method declarations. Previously, if a method was declared with `lifetimebound` on its function type (which represents the implicit `this` parameter), this attribute would not be propagated to the method definition, causing lifetime safety warnings to be missed.
The implementation adds helper functions to extract the `lifetimebound` attribute from a function type and to merge this attribute from an old method declaration to a new one when appropriate.
In Kona, WG21 decided to revert trivial relocation (P2786).
Keep the notion of relocatability
(used in the wild and likely to come back),
but remove the keyword which is no longer conforming
Fixes#172118
---
This patch resolves an issue where C23 fixed-underlying enum constants
were incorrectly treated as the underlying integer type instead of the
enumeration type.
According to C23 `6.7.2.2p15`:
> The enumeration member type of an enumerated type with a fixed
underlying type is the same as the type itself.
If a C++ class template `A` is annotated via API Notes and another class
`B` has a field of type `A`, we would apply the attributes from the API
Notes twice. This happened during `ActOnFields`, so this change makes
sure we stop processing API Notes for class template instantiations in
this function.
rdar://166179307
The `err_sycl_entry_point_invalid` diagnostic has a selection field for
which there are already many options with more expected to be added. Use
of `%enum_select` avoids the need for magic numbers with associated
comments at source locations where the diagnostic is issued.
Implements initial support for vk::push_constant.
As is, this allows handling simple push constants, but has one
main issue: layout can be incorrect (See #168401). The layout
issue being not only push-constant related, it's ignored for this PR.
The frontend part of the implementation is straightforward:
- adding a new attribute
- when targeting vulkan/spirv, we process it
- global variables with this attribute gets a new AS:
hlsl_push_constant
The IR has nothing specific, only some RO globals in this new AS.
On the SPIR-V side, we not convert this AS into a PushConstant storage
class. But this creates some issues: the variables in this storage class
must have a specific set of decoration to define their layout.
Current infra to create the SPIR-V types lacks the context required to
make this decision: no indication on the AS or context around the type
being created. Refactoring this would be a heavy task as it would
require getting this information in every place using the GR for type
creation.
Instead, we do something similar to CBuffers:
- find all globals with this address space, and change their type to
a target-specific type.
- insert a new intrinsic in place of every reference to this global
variable.
This allow the backend to handle both layout variables loads and type
lowering independently.
Type lowering has nothing specific: when we encounter a target extension
type with spirv.PushConstant, we lower this to the correct SPIR-V type
with the proper offset & block decorations.
As for the intrinsic, it's mostly a no-op, but required since we have
this target-specific type.
Note: this implementation prevents the static declaration of multiple
push constants in a single shader module. The actual specification is
more relaxed: there can be only one **used** push constant block per
entrypoint. To correctly implement this, we'd require to keep some
additional state to determine the list of statically used resources per
entrypoint. This shall be addressed as a follow-up (see #170310)
In Kona, WG21 decided to revert trivial relocation (P2786).
Given that the notion of replaceability that was introduced at the same
time does not appear to be used by clang 21 users, and is less likely to
come back, it is easier to fully remove wholesale.
Subsequent patches will deal with relocation.
This commit implements gcc_struct attribute with the behavior similar to
one in GCC. Current behavior is as follows:
When ItaniumRecordLayoutBuilder is used, [[gcc_struct]] will locally
cancel the effect of -mms-bitfields on a record. If -mms-bitfields is
not supplied and is not a default behavior on a target, [[gcc_struct]]
will be a no-op. This should provide enough compatibility with GCC.
If C++ ABI is "Microsoft", [[gcc_struct]] will currently always produce
a diagnostic, since support for it is not yet implemented in
MicrosoftRecordLayoutBuilder. Note, however, that all the infrastructure
is ready for the future implementation.
In particular, check for default value of -mms-bitfields is moved from a
driver to ASTContext, since it now non-trivially depends on other
supplied flags. This also, unfortunately, makes it impossible to use
usual argument parsing for `-m{no-,}ms-bitfields`.
The patch doesn't introduce any backwards-incompatible changes, except
for situations when cc1 is called directly with `-mms-bitfields` option.
Work towards #24757
---------
Co-authored-by: Martin Storsjö <martin@martin.st>
Annotate printf/scanf and related builtins with the nonnull attribute on
their format string parameters. This enables diagnostics when NULL is
passed, matching GCC behavior. Updated existing Sema tests and added new
ones for coverage. Closes issue #33923
This provides a C language `modular_format` attribute. This combines
with information from the existing `format` to set the new IR
`modular-format` attribute.
The purpose of these attributes is to enable "modular printf". A
statically linked libc can provide a modular variant of printf that only
weakly references implementation routines. The link-time symbol `printf`
would strongly reference aspect symbols (e.g. for float, fixed point,
etc.) that are provided by those routines, restoring the status quo.
However, the compiler could transform calls with constant format strings
to calls to the modular printf instead, and at the same time, it would
emit strong references to the aspect symbols that are needed to
implement the format string. Then, the printf implementation would
contain only the union of the aspects requested.
See issue #146159 for context.
Fixes#163224
---
This patch addresses the issue by correcting the caret insertion
location for attributes incorrectly positioned before an enum. The
location is now derived from the associated `EnumDecl`: for named enums,
the attribute is placed before the identifier, while for anonymous enum
definitions, it is placed before the opening brace, with a fallback to
the semicolon when no brace is present.
For example:
```cpp
[[nodiscard]] enum class E1 {};
```
is now suggested as:
```cpp
enum class [[nodiscard]] E1 {};
```
- CUDA's dynamic parallelism extension allows device-side kernel
launches, which share the identical syntax to host-side launches, e.g.,
kernel<<<Dg, Db, Ns, S>>>(arguments);
but differ from the code generation. That device-side kernel launches is
eventually translated into the following sequence
config = cudaGetParameterBuffer(alignment, size);
// setup arguments by copying them into `config`.
cudaLaunchDevice(func, config, Dg, Db, Ns, S);
- To support the device-side kernel launch, 'CUDAKernelCallExpr' is
reused but its config expr is set to a call to 'cudaLaunchDevice'.
During the code generation, 'CUDAKernelCallExpr' is expanded into the
sequence aforementioned.
- As the device-side kernel launch requires the source to be compiled as
relocatable device code and linked with '-lcudadevrt'. Linkers are
changed to pass relevant link options to 'nvlink'.
This patch adds a case to `CheckMultiVersionAdditionalDecl()` that
detects redeclarations of `target_clones` functions which omit the
attribute, and makes sure they are marked as redeclarations. It also
updates the comment at the call site of
`CheckMultiVersionAdditionalDecl()` to reflect this.
Previously, `target_clones` multiversioned functions that omitted the
attribute from subsequent declarations would cause Clang to hit an
`llvm_unreachable` and crash. In the following example, the second
declaration (the function definition) should inherit the `target_clones`
attribute from the first declaration (the forward declaration):
```
__attribute__((target_clones("arch=atom", "default")))
void foo(void);
void foo(void) { /* ... */ }
```
However, `CheckMultiVersionAdditionalDecl()` was not recognizing the
function definition as a redeclaration of the forward declaration, which
prevented `Sema::MergeFunctionDecl()` from automatically inheriting the
attribute.
A side effect of this fix is that Clang now catches redeclarations of
`target_clones` functions that have conflicting types, which previously
caused Clang to crash by hitting that same `llvm_unreachable`. The
`bad_overload1` case in `clang/test/Sema/attr-target-clones.c` has been
updated to reflect this.
Fixes#165517Fixes#129483
Previously, the handling of the `cleanup` attribute had some checks
based on the type, but we were deducing the type after handling the
attribute.
This PR fixes the way the are dealing with type checks for the `cleanup`
attribute by delaying these checks after we are deducing the type.
It is also fixed in a way that the solution can be adapted for other
attributes that does some type based checks.
This is the list of C/C++ attributes that are doing type based checks
and will need to be fixed in additional PRs:
- CUDAShared
- MutualExclusions
- PassObjectSize
- InitPriority
- Sentinel
- AcquireCapability
- RequiresCapability
- LocksExcluded
- AcquireHandle
NB: Some attributes could have been missed in my shallow search.
Fixes#129631
Fixes#163731
---
This PR addresses false-positive shadow diagnostics for lambdas inside
explicit object member functions
```cpp
struct S {
int x;
void m(this S &self) {
auto lambda = [](int x) { return x; }; // ok
}
};
```
Previously, clang's SemaDecl processed `asm` attributes after every
other attribute in the Decl, unlike gcc and clang's own parser which
requires `asm` attributes to be the first one in the declaration (see
#162556). Therefore, move the processing of `asm` attributes to be the
first one in the attributes list.
Closes#162126
Signed-off-by: Giuliano Belinassi <gbelinassi@suse.de>
weak and selectany are mechanisms for allowing the linker to resolve ODR
violations. [module.import/6] states
> A header unit shall not contain a definition of a non-inline function
or variable whose name has external linkage.
But this prevents compiling any headers with such weak symbols defined.
These occur in eg. some Windows SDK headers like `DirectXMath.h`.
```
#ifndef XMGLOBALCONST
#if defined(__GNUC__) && !defined(__MINGW32__)
#define XMGLOBALCONST extern const __attribute__((weak))
#else
#define XMGLOBALCONST extern const __declspec(selectany)
#endif
#endif
XMGLOBALCONST XMVECTORF32 g_XMSinCoefficients0 = { { { -0.16666667f, +0.0083333310f, -0.00019840874f, +2.7525562e-06f } } };
```
Proposed solution: Do not emit `diag::err_extern_def_in_header_unit` if
the `FD` or `VDecl` have either `SelectAnyAttr` or `WeakAttr`.
This renames some attribute list related functions, to make callers
think about whether they want to append or prepend to the list, instead
of defaulting to prepending which is often not the desired behaviour
(for the cases where it matters, sometimes we're just adding to an empty
list). Then it adjusts some of these calls to append where they were
previously prepending. This has the effect of making
`err_attributes_are_not_compatible` consistent in emitting diagnostics
as `<new-attr> and <existing-attr> are not compatible`, regardless of
the syntax used to apply the attributes.
Variadic argument for NVPTX has been support in
486d00eca6
We can remove `CUDAAllowVariadicFunctions` option and its sema check. The CC1 option
`fcuda_allow_variadic_functions` is retained to not break the existing code building.
---------
Co-authored-by: Yuanke Luo <ykluo@birentech.com>
This adds an `operator<<` overload for `StreamingDiagnostic` that takes
an `APInt`/`APSInt` and formats it with default options, including
adding separators.
This is still an opt-in mechanism since all callers that want to use
this feature need to be changed from
```c++
Diag() << toString(MyInt, 10);
```
to
```c++
Diag() << MyInt;
```
This patch contains one example of a diagnostic making use of this.
We only display this diagnostic with large numbers, so add the
separators.
Not sure if `295'147'905'179'352'825'841` is much better than
`295147905179352825841` but I think it would be nice to have separators
in more diagnostics.
Clang would complain about conflicting types between a function
declaration and definition if the declaraion was marked with the
attribute but the definition wasn't. Do not treat this as an error. It
should only be necessary to mark the declaration with the attribute.
Previously, lambda init captures of structured bindings were incorrectly
classified as regular shadow warnings (shown with `-Wshadow`), while
regular parameter captures were correctly classified as
`uncaptured-local` warnings (shown only with `-Wshadow-all`). This
created inconsistent behavior:
```cpp
void foo1(std::pair<int, int> val) {
[val = std::move(val)](){}(); // No warning with -Wshadow (correct)
}
void foo2(std::pair<int, int> val) {
auto [a, b] = val;
[a = std::move(a)](){}(); // Warning with -Wshadow (incorrect)
}
```
The fix extends the existing lambda capture classification logic in
`CheckShadow()` to handle `BindingDecl` consistently with `VarDecl`,
ensuring both cases show no warnings with `-Wshadow` and
`uncaptured-local` warnings with `-Wshadow-all`.
Fixes#68605.
---------
Co-authored-by: Mariya Podchishchaeva <mariya.podchishchaeva@intel.com>
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`.
See the attached example for motivation. Although it is not sure how
should we treat the modules ownership of the implicit instantiations,
it makes no sense to diagnose redeclaration of implicit instantiations
in different modules.
Fix an error in the logic meant to handle a redeclaration such as:
```C++
struct A {
struct __attribute__((foo)) A *ptr;
};
```
In the declaration of ptr, we must introduce a new redeclaration of A in
order for it to carry the new attribute. This is a redeclaration of the
existing A, but it is only lexically contained in A, still semantically
belonging to the TU. This is the same deal as happens with friend
declarations, and the logic used to handle that is reused here.
But this was going haywire with a class indirectly nested within a class
of the same name.
The fix limits this logic to only apply when the tag use is just a
simple reference.
Since this regression was never released, there are no release notes.
Fixes#155936
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.
A number of builtins report some variation of "this type is compatibile
with some bitwise equivalent operation", but this is not true for
address discriminated values. We had address a number of cases, but not
all of them. This PR corrects the remaining builtins.
Fixes#154394
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.
This patch is part of the upstreaming effort for supporting SYCL
language front end.
It makes the following changes:
1. Adds sycl_external attribute for functions with external linkage,
which is intended for use to implement the SYCL_EXTERNAL macro as
specified by the SYCL 2020 specification
2. Adds checks to avoid emitting device code when sycl_external and
sycl_kernel_entry_point attributes are not enabled
3. Fixes test failures caused by the above changes
This patch is missing diagnostics for the following diagnostics listed
in the SYCL 2020 specification's section 5.10.1, which will be addressed
in a subsequent PR:
Functions that are declared using SYCL_EXTERNAL have the following
additional restrictions beyond those imposed on other device functions:
1. If the SYCL backend does not support the generic address space then
the function cannot use raw pointers as parameter or return types.
Explicit pointer classes must be used instead;
2. The function cannot call group::parallel_for_work_item;
3. The function cannot be called from a parallel_for_work_group scope.
In addition to that, the subsequent PR will also implement diagnostics
for inline functions including virtual functions defined as inline.
---------
Co-authored-by: Mariya Podchishchaeva <mariya.podchishchaeva@intel.com>