This patch fixes a crash that happens when '`this`' is referenced
(implicitly or explicitly) in a dependent class scope function template
specialization that instantiates to a static member function. For
example:
```
template<typename T>
struct A
{
template<typename U>
static void f();
template<>
void f<int>()
{
this; // causes crash during instantiation
}
};
template struct A<int>;
```
This happens because during instantiation of the function body,
`Sema::getCurrentThisType` will return a null `QualType` which we
rebuild the `CXXThisExpr` with. A similar problem exists for implicit
class member access expressions in such contexts (which shouldn't really
happen within templates anyways per [class.mfct.non.static]
p2, but changing that is non-trivial). This patch fixes the crash by building
`UnresolvedLookupExpr`s instead of `MemberExpr`s for these implicit
member accesses, which will then be correctly rebuilt as `MemberExpr`s
during instantiation.
This is a follow-up to #81506. As discussed in #87737, we're rejecting
incomplete types, save for exceptions listed in the C++ standard (`void`
and arrays of unknown bound). Note that arrays of unknown bound of
incomplete types are accepted.
Since we're happy with the current behavior of this intrinsic for
flexible array members
(https://github.com/llvm/llvm-project/pull/87737#discussion_r1553652570),
I added a couple of tests for that as well.
This is a follow-up to #81506. Since `__is_layout_compatible()` is a C++
intrinsic
(ff1e72d68d/clang/include/clang/Basic/TokenKinds.def (L523)),
I don't think we should define how it interacts with VLA extension
unless we have a compelling reason to.
Since #81506 was merged after 18 cut-off, we don't have to follow any
kind of deprecation process.
HLSL constant sized array function parameters do not decay to pointers.
Instead constant sized array types are preserved as unique types for
overload resolution, template instantiation and name mangling.
This implements the change by adding a new `ArrayParameterType` which
represents a non-decaying `ConstantArrayType`. The new type behaves the
same as `ConstantArrayType` except that it does not decay to a pointer.
Values of `ConstantArrayType` in HLSL decay during overload resolution
via a new `HLSLArrayRValue` cast to `ArrayParameterType`.
`ArrayParamterType` values are passed indirectly by-value to functions
in IR generation resulting in callee generated memcpy instructions.
The behavior of HLSL function calls is documented in the [draft language
specification](https://microsoft.github.io/hlsl-specs/specs/hlsl.pdf)
under the Expr.Post.Call heading.
Additionally the design of this implementation approach is documented in
[Clang's
documentation](https://clang.llvm.org/docs/HLSL/FunctionCalls.html)
Resolves#70123
In PR #79382, I need to add a new type that derives from
ConstantArrayType. This means that ConstantArrayType can no longer use
`llvm::TrailingObjects` to store the trailing optional Expr*.
This change refactors ConstantArrayType to store a 60-bit integer and
4-bits for the integer size in bytes. This replaces the APInt field
previously in the type but preserves enough information to recreate it
where needed.
To reduce the number of places where the APInt is re-constructed I've
also added some helper methods to the ConstantArrayType to allow some
common use cases that operate on either the stored small integer or the
APInt as appropriate.
Resolves#85124.
Fix#84064
According to http://eel.is/c++draft/dcl.fct.def.coroutine#9 the first
parameter for overload resolution of `operator new` is `size_t` followed
by the arguments of the coroutine function.
http://eel.is/c++draft/dcl.fct.def.coroutine#4 states that the first
argument is the lvalue of `*this` if the coroutine is a member function.
Before this patch, Clang handled class types correctly but ignored
lambdas. This patch adds support for lambda coroutines with a
`promise_type` that implements a custom `operator new`.
The patch does consider C++23 `static operator()`, which already worked
as there is no `this` parameter.
Exception handling SHOULD be possible depending on codegen (and if not,
we can make it trap and add a warning when we make that decision), but
throwing out of a compute construct is ill formed.
This patch adds an error for a 'throw' that isn't in a 'try' scope. This
error is imperfect as it won't diagnose a 'throw' that escapes its
'try', or one in a separate function, but it catches the obvious
mistakes. The other cases will need to be handled as runtime failures.
When resolving the type of `this` inside a member function, we were
attaching all qualifiers present on the member function to the class
type and then making it a pointer; however, `__restrict`, unlike `const`
and `volatile`, needs to be attached to the pointer type rather than the
pointee type.
This fixes#82941, #42411, and #18121.
There are two issues here. first `ICK_Floating_Integral` were always
defaulting to `CK_FloatingToIntegral` for vectors regardless of
direction of cast. Check was scalar only so added a vec float check to
the conditional.
Second issue was float to int casts were resolving to
ICK_Integral_Promotion when they need to be resolving to
CK_FloatingToIntegral. This was fixed by changing the ordering of
conversion checks.
This fixes#82826
This patch implements `__is_layout_compatible` intrinsic, which supports
`std::is_layout_compatible` type trait introduced in C++20
([P0466R5](https://wg21.link/p0466r5) "Layout-compatibility and
Pointer-interconvertibility Traits"). Name matches GCC and MSVC
intrinsic.
Basically, this patch exposes our existing machinery for checking for
layout compatibility and figuring out common initial sequences. Said
machinery is a bit outdated, as it doesn't implement
[CWG1719](https://cplusplus.github.io/CWG/issues/1719.html) "Layout
compatibility and cv-qualification revisited" and
[CWG2759](https://cplusplus.github.io/CWG/issues/2759.html)
"`[[no_unique_address]` and common initial sequence". Those defect
reports are considered out of scope of of this PR, but will be
implemented in subsequent PRs.
Partially addresses #48204
HLSL supports vector truncation and element conversions as part of
standard conversion sequences. The vector truncation conversion is a C++
second conversion in the conversion sequence. If a vector truncation is
in a conversion sequence an element conversion may occur after it before
the standard C++ third conversion.
Vector element conversions can be boolean conversions, floating point or
integral conversions or promotions.
[HLSL Draft
Specification](https://microsoft.github.io/hlsl-specs/specs/hlsl.pdf)
---------
Co-authored-by: Aaron Ballman <aaron@aaronballman.com>
This patch converts `Sema::TemplateDeductionResult` into a scoped enum
in namespace scope, making it eligible for forward declaring. This is
useful in certain contexts, such as `preferred_type` annotations on
bit-fields.
This patch removes on-stack `TemplateArgumentList`'s. They were primary used
to pass an `ArrayRef<TemplateArgument>` to
`Sema::getTemplateInstantiationArgs`, which had a `const
TemplateArgumentList*` parameter for the innermost template argument
list. Changing this parameter to an
`std::optional<ArrayRef<TemplateArgument>>` eliminates the need for
on-stack `TemplateArgumentList`'s, which in turn eliminates the need for
`TemplateArgumentList` to store a pointer to its template argument
storage (which is redundant in almost all cases, as it is an AST
allocated type).
Implements https://isocpp.org/files/papers/P2662R3.pdf
The feature is exposed as an extension in older language modes.
Mangling is not yet supported and that is something we will have to do before release.
[Sema] Add `-fvisibility-global-new-delete=` option (#75364)
By default the implicitly declared replaceable global new and delete
operators are given a default visibility attribute. Previous work, see:
https://reviews.llvm.org/D53787, added
`-fvisibility-global-new-delete-hidden` to change this to a hidden
visibility attribute.
This change adds `-fvisibility-global-new-delete=` which controls
whether (or not) to add an implicit visibility attribute to the implicit
declarations for these functions, and what visibility that attribute
will specify. The option takes 4 values: `force-hidden`,
`force-protected`, `force-default` and `source`. Option values
`force-hidden`, `force-protected` and `force-default` assign hidden,
protected, and default visibilities respectively; the use of the term
force in the value names is designed to imply to a user that the semantics
of this option differ significantly from `-fvisibility=`. An option
value of `source` implies that no implicit attribute is added; without
the attribute the replaceable global new and delete operators behave
normally (like other functions) with respect to visibility attributes,
pragmas and options.
The motivation for the `source` value is to facilitate users who intend
to replace these functions either for a single linkage unit or a limited
set of linkage units. `-fvisibility-global-new-delete=source` can be
applied globally to the compilations in a build where the existing
`-fvisibility-global-new-delete-hidden` cannot, as it conflicts with a
common pattern where these functions are dynamically imported.
The existing `-fvisibility-global-new-delete-hidden` is now a deprecated
spelling of `-fvisibility-global-new-delete=force-hidden`
A release note has been added for these changes.
`-fvisibility-global-new-delete=source` will be set by default for PS5.
PS5 users that want the normal toolchain behaviour will be able to
supply `-fvisibility-global-new-delete=force-default`.
This is a follow up to https://github.com/llvm/llvm-project/pull/71417 ,
which aims to resolve concerns brought up there. Namely, this patch
replaces `CXXNewInitializationStyle::Implicit` with a dedicated
`HasInitializer` flag. This makes `CXXNewInitializationStyle` to model
syntax again. This patch also renames `Call` and `List` to less
confusing `Parens` and `Braces`.
This bug is caused by parenthesized list initialization not being
implemented in `CodeGenFunction::EmitNewArrayInitializer(...)`.
Parenthesized list initialization of `struct`s with `operator new`
already works in Clang and is not affected by this bug.
Additionally, fix the test new-delete.cpp as it incorrectly assumes that
using parentheses with operator new to initialize arrays is illegal for
C++ versions >= C++17.
Fixes#68198
It seems we were forgetting to call `checkArgsForPlaceholders` on the
placement arguments of new-expressions in Sema. I don't think that was
intended—at least doing so doesn't seem to break anything—so this pr
adds that.
This also fixes#65053
---------
Co-authored-by: Erich Keane <ekeane@nvidia.com>
This patch converts CXXNewExpr::InitializationStyle into a scoped enumat namespace scope. It also affirms the status quo by adding a new enumerator to represent implicit initializer.
This is a re-land of https://github.com/llvm/llvm-project/pull/71322 ace4489397d17abfb20d36de1404cfbe102401a7
This patch converts `CXXNewExpr::InitializationStyle` into a scoped enum at namespace scope. It also affirms the status quo by adding a new enumerator to represent implicit initializer.
This patch converts `CXXConstructExpr::ConstructionKind` into a scoped enum in namespace scope, making it eligible for forward declaring. This is useful in cases like annotating bit-fields with `preferred_type`.
This patch converts `StringLiteral::StringKind` to a scoped enum in namespace scope. This enabled forward-declarations of this enum where necessary, e.g. for `preferred_type` annotation for bit-fields.
Link: https://lists.llvm.org/pipermail/cfe-dev/2021-August/068740.html ("[Exception Handling] Could we mark __cxa_end_catch as nounwind conditionally?"
Link: https://github.com/llvm/llvm-project/issues/57375
A catch handler calls `__cxa_begin_catch` and `__cxa_end_catch`. For a catch-all
clause or a catch clause matching a record type, we:
* assume that the exception object may have a throwing destructor
* emit `invoke void @__cxa_end_catch` (as the call is not marked as the `nounwind` attribute).
* emit a landing pad to destroy local variables and call `_Unwind_Resume`
```
struct A { ~A(); };
struct B { int x; };
void opaque();
void foo() {
A a;
try { opaque(); } catch (...) { } // the exception object has an unknown type and may throw
try { opaque(); } catch (B b) { } // B::~B is nothrow, but we do not utilize this
}
```
Per C++ [dcl.fct.def.coroutine], a coroutine's function body implies a `catch (...)`.
Our code generation pessimizes even simple code, like:
```
UserFacing foo() {
A a;
opaque();
co_return;
// For `invoke void @__cxa_end_catch()`, the landing pad destroys the
// promise_type and deletes the coro frame.
}
```
Throwing destructors are typically discouraged. In many environments, the
destructors of exception objects are guaranteed to never throw, making our
conservative code generation approach seem wasteful.
Furthermore, throwing destructors tend not to work well in practice:
* GCC does not emit call site records for the region containing `__cxa_end_catch`. This has been a long time, since 2000.
* If a catch-all clause catches an exception object that throws, both GCC and Clang using libstdc++ leak the allocated exception object.
To avoid code generation pessimization, add an opt-in driver option
-fassume-nothrow-exception-dtor to assume that `__cxa_end_catch` calls have the
`nounwind` attribute. This implies that thrown exception objects' destructors
will never throw.
To detect misuses, diagnose throw expressions with a potentially-throwing
destructor. Technically, it is possible that a potentially-throwing destructor
never throws when called transitively by `__cxa_end_catch`, but these cases seem
rare enough to justify a relaxed mode.
Reviewed By: ChuanqiXu
Differential Revision: https://reviews.llvm.org/D108905
This patch moves ElaboratedTypeKeyword before `Type` definition so that the enum is complete where bit-field for it is declared. It also converts it to scoped enum and removes `ETK_` prefix.
This patch moves `ArraySizeModifier` before `Type` declaration so that it's complete at `ArrayTypeBitfields` declaration. It's also converted to scoped enum along the way.
This implements proposals from:
- https://github.com/itanium-cxx-abi/cxx-abi/issues/24: mangling for
constraints, requires-clauses, requires-expressions.
- https://github.com/itanium-cxx-abi/cxx-abi/issues/31: requires-clauses and
template parameters in a lambda expression are mangled into the <lambda-sig>.
- https://github.com/itanium-cxx-abi/cxx-abi/issues/47 (STEP 3): mangling for
template argument is prefixed by mangling of template parameter declaration
if it's not "obvious", for example because the template parameter is
constrained (we already implemented STEP 1 and STEP 2).
This changes the manglings for a few cases:
- Functions and function templates with constraints.
- Function templates with template parameters with deduced types:
`typename<auto N> void f();`
- Function templates with template template parameters where the argument has a
different template-head:
`template<template<typename...T>> void f(); f<std::vector>();`
In each case where a mangling changed, the change fixes a mangling collision.
Note that only function templates are affected, not class templates or variable
templates, and only new constructs (template parameters with deduced types,
constrained templates) and esoteric constructs (templates with template
template parameters with non-matching template template arguments, most of
which Clang still does not accept by default due to
`-frelaxed-template-template-args` not being enabled by default), so the risk
to ABI stability from this change is relatively low. Nonetheless,
`-fclang-abi-compat=17` can be used to restore the old manglings for cases
which we could successfully but incorrectly mangle before.
Fixes#48216, #49884, #61273
Reviewed By: erichkeane, #libc_abi
Differential Revision: https://reviews.llvm.org/D147655
As reported in #66612, we aren't correctly treating the placeholder
expression type correctly, so we ended up trying to get a reference
version of it, and this resulted in an assertion, since the placeholder
type cannot have a reference added.
Fixes: #66612
This is information that the compiler already has, and should be exposed
so that the library doesn't need to reimplement the exact same
functionality.
Differential Revision: https://reviews.llvm.org/D135341
I'm reverting this on principle, since it didn't get the Phabricator
approval I thought it had (only an informal LGTM). Will re-apply once
it has been properly approved.
This reverts commit e1bfeb6bcc627a94c5ab3a5417d290c7dc516d54.
This is information that the compiler already has, and should be exposed
so that the library doesn't need to reimplement the exact same
functionality.
Differential Revision: https://reviews.llvm.org/D135341
The goal of this change is to clean up some of the code surrounding
HLSL using CXXThisExpr as a non-pointer l-value. This change cleans up
a bunch of assumptions and inconsistencies around how the type of
`this` is handled through the AST and code generation.
This change is be mostly NFC for HLSL, and completely NFC for other
language modes.
This change introduces a new member to query for the this object's type
and seeks to clarify the normal usages of the this type.
With the introudction of HLSL to clang, CXXThisExpr may now be an
l-value and behave like a reference type rather than C++'s normal
method of it being an r-value of pointer type.
With this change there are now three ways in which a caller might need
to query the type of `this`:
* The type of the `CXXThisExpr`
* The type of the object `this` referrs to
* The type of the implicit (or explicit) `this` argument
This change codifies those three ways you may need to query
respectively as:
* CXXMethodDecl::getThisType()
* CXXMethodDecl::getThisObjectType()
* CXXMethodDecl::getThisArgType()
This change then revisits all uses of `getThisType()`, and in cases
where the only use was to resolve the pointee type, it replaces the
call with `getThisObjectType()`. In other cases it evaluates whether
the desired returned type is the type of the `this` expr, or the type
of the `this` function argument. The `this` expr type is used for
creating additional expr AST nodes and for member lookup, while the
argument type is used mostly for code generation.
Additionally some cases that used `getThisType` in simple queries could
be substituted for `getThisObjectType`. Since `getThisType` is
implemented in terms of `getThisObjectType` calling the later should be
more efficient if the former isn't needed.
Reviewed By: aaron.ballman, bogner
Differential Revision: https://reviews.llvm.org/D159247
The motivation for this patch is that many code bases use exception handling. As GPUs are not expected to support exception handling in the near future, we can experiment with compiling the code for GPU targets anyway. This will
allow us to run the code, as long as no exception is thrown.
The overall idea is very simple:
- If a throw expression is compiled to AMDGCN or NVPTX, it is replaced with a trap during code generation.
- If a try/catch statement is compiled to AMDGCN or NVPTX, we generate code for the try statement as if it were a basic block.
With this patch, the compilation of the following example
```
int gaussian_sum(int a,int b){
if ((a + b) % 2 == 0) {throw -1;};
return (a+b) * ((a+b)/2);
}
int main(void) {
int gauss = 0;
#pragma omp target map(from:gauss)
{
try {
gauss = gaussian_sum(1,100);
}
catch (int e){
gauss = e;
}
}
std::cout << "GaussianSum(1,100)="<<gauss<<std::endl;
#pragma omp target map(from:gauss)
{
try {
gauss = gaussian_sum(1,101);
}
catch (int e){
gauss = e;
}
}
std::cout << "GaussianSum(1,101)="<<gauss<<std::endl;
return (gauss > 1) ? 0 : 1;
}
```
with offloading to `gfx906` results in
```
./bin/target_try_minimal_fail
GaussianSum(1,100)=5050
AMDGPU fatal error 1: Received error in queue 0x155555506000: HSA_STATUS_ERROR_EXCEPTION: An HSAIL operation resulted in a hardware exception.
zsh: abort (core dumped)
```
Reviewed By: jdoerfert
Differential Revision: https://reviews.llvm.org/D153924