When a destroying delete overload is selected, the destructor is not
automatically called. Therefore, the destructor can be deleted without
causing the program to be ill-formed.
Fixes#46818
We already support vector types, and since matrix element types have to
be scalar types, there should be no problem w/ just enabling this.
This now also allows matrix types to be stored in STL containers.
Get inout/out parameters working for HLSL Arrays.
Utilizes the fix from #109323, and corrects the assignment behavior
slightly to allow for Non-LValues on the RHS.
Closes#106917
---------
Co-authored-by: Chris B <beanz@abolishcrlf.org>
This PR is step one on the journey to implement resource element type
validation via C++20 concepts. The PR sets up the infrastructure for
injecting implicit concept decls / concept specialization expressions
into the AST, which will then be evaluated after template arguments are
instantiated. This is not meant to be a complete implementation of the
desired validation for HLSL,
there are a couple of missing elements:
We need the __builtin_hlsl_is_typed_resource_element_compatible builtin
to be implemented.
We need other constraints, like is_intangible
We need to put the first 2 points together, and construct a finalized
constraint expression, which should differ between typed and raw buffers
This is just an initial PR that puts some of the core infrastructure in
place.
This PR is an edit of #112600, so that new tests that were put into main
don't fail
Fixes#75676
Summary:
Address spaces are used in several embedded and GPU targets to describe
accesses to different types of memory. Currently we use the address
space enumerations to control which address spaces are considered
supersets of eachother, however this is also a target level property as
described by the C standard's passing mentions. This patch allows the
address space checks to use the target information to decide if a
pointer conversion is legal. For AMDGPU and NVPTX, all supported address
spaces can be converted to the default address space.
More semantic checks can be added on top of this, for now I'm mainly
looking to get more standard semantics working for C/C++. Right now the
address space conversions must all be done explicitly in C/C++ unlike
the offloading languages which define their own custom address spaces
that just map to the same target specific ones anyway. The main question
is if this behavior is a function of the target or the language.
This PR implements a new type trait as a builtin,
__builtin_hlsl_is_typed_resource_element_compatible
This type traits verifies that the given input type is suitable as a
typed resource element type.
It checks that the given input type is homogeneous, has no more than 4
sub elements, does not exceed 16 bytes, and does not contain any arrays,
booleans, or enums.
Fixes an issue in https://github.com/llvm/llvm-project/pull/113730 that
needed to cause that PR to be reverted.
Fixes https://github.com/llvm/llvm-project/issues/113223
Reverts llvm/llvm-project#113730
Reverting because test compiler-rt default failed, with:
error: comparison of different enumeration types ('Kind' and
'clang::Type::TypeClass')
This PR implements a new type trait as a builtin,
`__builtin_hlsl_is_typed_resource_element_compatible`
This type traits verifies that the given input type is suitable as a
typed resource element type.
It checks that the given input type is homogeneous, has no more than 4
sub elements, does not exceed 16 bytes, and does not contain any arrays,
booleans, or enums.
Fixes#113223
Moves `IsIntangibleType` from SemaHLSL to Type class and renames it to
`isHLSLIntangibleType`. The existing `isHLSLIntangibleType` is renamed
to `isHLSLBuiltinIntangibleType` and updated to return true only for the
builtin `__hlsl_resource_t` type.
This change makes `isHLSLIntangibleType` functionality accessible
outside of Sema, for example from clang CodeGen.
This fixes layering violation introduced in
2fd01d75a863184766ee0c82b5c0fc8be172448a. The declaration is moved to
`SemaTemplateInstantiate` section of `Sema.h`, after the file where it's
implemented.
When parsing its function parameters, we don't change the CurContext to
the lambda's function declaration. However,
CheckIfAnyEnclosingLambdasMustCaptureAnyPotentialCaptures() has not
yet adapted to such behavior when nested lambdas come into play.
Consider the following case,
struct Foo {};
template <int, Foo f> struct Arr {};
constexpr void foo() {
constexpr Foo F;
[&]<int I>() {
[&](Arr<I, F>) {};
}.template operator()<42>();
}
As per [basic.def.odr]p5.2, the use of F constitutes an ODR-use. And
per [basic.def.odr]p10, F should be ODR-usable in that interleaving
scope.
We failed to accept the case because the call to tryCaptureVariable()
in getStackIndexOfNearestEnclosingCaptureCapableLambda() suggested
that F is needlessly captureable. That was due to a missed handling
for AfterParameterList in FunctionScopeIndexToStopAt, where it still
presumed DC and LSI matched.
Fixes#47400Fixes#90896
It would be nice to see what our users think about this change, as this
is something that WG21/EWG quite wants to fix a handful of questionable
issues with UB. Depending on the outcome of this after being committed,
we might instead suggest EWG undeprecate this, and require a bit of
'magic' from the lexer.
Additionally, this patch makes it so we emit this diagnostic ALSO in
cases where the literal name is reserved. It doesn't make sense to limit
that.
---------
Co-authored-by: Vlad Serebrennikov <serebrennikov.vladislav@gmail.com>
This patch is a follow-up to #109831. In the discussion, we agreed that
having parameter checks scattered across different areas isn't ideal.
Therefore, I suggest merging the check from #88974 into the void
parameter check. This change won't impact functionality and will enhance
maintainability.
Fixes#109538.
In this patch, we introduce diagnostic for required expression
parameters in the same way as function parameters, fix the issue of
handling void type parameters, and align the behavior with GCC and other
compilers.
The PR reapply https://github.com/llvm/llvm-project/pull/97308.
- Implement [CWG1815](https://wg21.link/CWG1815): Support lifetime
extension of temporary created by aggregate initialization using a
default member initializer.
- Fix crash that introduced in
https://github.com/llvm/llvm-project/pull/97308. In
`InitListChecker::FillInEmptyInitForField`, when we enter
rebuild-default-init context, we copy all the contents of the parent
context to the current context, which will cause the `MaybeODRUseExprs`
to be lost. But we don't need to copy the entire context, only the
`DelayedDefaultInitializationContext` was required, which is used to
build `SourceLocExpr`, etc.
---------
Signed-off-by: yronglin <yronglin777@gmail.com>
HLSL allows implicit conversions to truncate vectors to scalar
pr-values. These conversions are scored as vector truncations and should
warn appropriately.
This change allows forming a truncation cast to a pr-value, but not an
l-value. Truncating a vector to a scalar is performed by loading the
first element of the vector and disregarding the remaining elements.
Fixes#102964
Currently, clang erroneously rejects the following:
```
struct A
{
template<typename T>
void f();
};
template<typename T>
struct B
{
void g()
{
(*this)->template f<int>(); // error: no member named 'f' in 'B<T>'
}
A* operator->();
};
```
This happens because `Sema::ActOnStartCXXMemberReference` does not adjust the `ObjectType` parameter when `ObjectType` is a dependent type (except when the type is a `PointerType` and the class member access is the `->` form). Since the (possibly adjusted) `ObjectType` parameter (`B<T>` in the above example) is passed to `Parser::ParseOptionalCXXScopeSpecifier`, we end up looking up `f` in `B` rather than `A`.
This patch fixes the issue by identifying cases where the type of the object expression `T` is a dependent, non-pointer type and:
- `T` is the current instantiation and lookup for `operator->` finds a member of the current instantiation, or
- `T` has at least one dependent base case, and `operator->` is not found in the current instantiation
and using `ASTContext::DependentTy` as the type of the object expression when the optional _nested-name-specifier_ is parsed.
Fixes#104268.
This reverts commit 45c8766973bb3bb73dd8d996231e114dcf45df9f
and 049512e39d96995cb373a76cf2d009a86eaf3aab.
This change triggers failed asserts on inputs like this:
struct a {
} constexpr b;
class c {
public:
c(a);
};
class B {
public:
using d = int;
struct e {
enum { f } g;
int h;
c i;
d j{};
};
};
B::e k{B::e::f, int(), b};
Compiled like this:
clang -target x86_64-linux-gnu -c repro.cpp
clang: ../../clang/lib/CodeGen/CGExpr.cpp:3105: clang::CodeGen::LValue
clang::CodeGen::CodeGenFunction::EmitDeclRefLValue(const clang::DeclRefExpr*):
Assertion `(ND->isUsed(false) || !isa<VarDecl>(ND) || E->isNonOdrUse() ||
!E->getLocation().isValid()) && "Should not use decl without marking it used!"' failed.
Implements `__builtin_hlsl_is_intangible` type trait.
HLSL intangible types are special implementation-defined types such as
resource handles or samplers. Any class that is an array of intangible
type or contains base class or members of intangible types is also an
intangible type.
Fixes #[102954](https://github.com/llvm/llvm-project/issues/102954)
The primary motivation behind this is to allow the enum type to be
referred to earlier in the Sema.h file which is needed for #106321.
It was requested in #106321 that a scoped enum be used (rather than
moving the enum declaration earlier in the Sema class declaration).
Unfortunately doing this creates a lot of churn as all use sites of the
enum constants had to be changed. Appologies to all downstream forks in
advanced.
Note the AA_ prefix has been dropped from the enum value names as they
are now redundant.
HLSL tends to rely pretty aggressively on scalarization occuring in the
complier, which allows for some relaxed language behaviors when types
are fully sclarized to equivalent scalar representations.
This change adds a new queryable trait builtin for scalarized layout
compatability.
Resolves#100614
---------
Co-authored-by: Aaron Ballman <aaron@aaronballman.com>
Per [CWG2351](https://wg21.link/CWG2351), allow `void{}`, treated the
same as `void()`: a prvalue expression of type `void` that performs no
initialization.
Note that the AST for the expression `T{}` looks like:
```
// using T = int;
CXXFunctionalCastExpr 'T':'int' functional cast to T <NoOp>
`-InitListExpr 'T':'int'
// using T = const int;
CXXFunctionalCastExpr 'int' functional cast to T <NoOp>
`-InitListExpr 'int'
// using T = void;
CXXFunctionalCastExpr 'T':'void' functional cast to T <ToVoid>
`-InitListExpr 'void'
// using T = const void;
CXXFunctionalCastExpr 'void' functional cast to T <ToVoid>
`-InitListExpr 'void'
```
As for `void()`/`T() [T = const void]`, that looked like
`CXXScalarValueInitExpr 'void'` and is unchanged after this.
For reference, C++98 [5.2.3p2] says:
> The expression `T()`, where `T` is a simple-type-specifier (7.1.5.2)
for a non-array complete object type or the (possibly cv-qualified) void
type, creates an rvalue of the specified type, whose value is determined
by default-initialization (8.5; no initialization is done for the
`void()` case). [*Note:* if `T` is a non-class type that is
*cv-qualified*, the `cv-qualifiers` are ignored when determining the
type of the resulting rvalue (3.10). ]
Though it is a bit of a misnomer that, for `T = void`,
`CXXScalarValueInitExpr` does not perform value initialization, it would
be a breaking change to change the AST node for `void()`, so I simply
reworded the doc comment.
`is_null_pointer` can be implemented very efficiently as
`__is_same(__remove_cv(T), decltype(nullptr))`. Since GCC supports both
of these builtins as well, libc++ has no interest in using
`__is_nullptr` instead. Furthermore, I could find only a single use in
the wild
(https://sourcegraph.com/search?q=context:global+__is_nullptr%28+-file:clang&patternType=keyword&sm=0).
Because of these reasons I don't think it's worth keeping this builtin
around.
This patch adds compiler support for
[P2985R0](https://wg21.link/p2985r0) "A type trait for detecting virtual
base classes".
Like we recently did with `__is_layout_compatible()` and
`__is_pointer_interconvertible_base_of()`, we support it only in C++
mode, and reject VLAs.
Resolves#98310.
Fixes#95311
Previous behaviour was that `false` was silently returned, templated
classes were not instantiated and incomplete classes did not issue an
error.
---------
Co-authored-by: cor3ntin <corentinjabot@gmail.com>
This PR reworks HLSL's implicit conversion sequences. Initially I was
seeking to match DXC's behavior more closely, but that was leading to a
pile of special case rules to tie-break ambiguous cases that should
really be left as ambiguous. We've decided that we're going to break
compatibility with DXC here, and we may port this new behavior over to
DXC instead.
This change is a bit closer to C++'s overload resolution rules, but it
does have a bit of nuance around how dimension adjustment conversions
are ranked. Conversion sequence ranks for HLSL are:
* Exact match
* Scalar Widening (i.e. splat)
* Promotion
* Scalar Widening with Promotion
* Conversion
* Scalar Widening with Conversion
* Dimension Reduction (i.e. truncation)
* Dimension Reduction with Promotion
* Dimension Reduction with Conversion
In this implementation I've folded the disambiguation into the
conversion sequence ranks which does add some complexity as compared to
C++, however this avoids needing to add special casing in
`CompareStandardConversionSequences`. I believe the added conversion
rank values provide a simpler approach, but feedback is appreciated.
The HLSL language spec updates are in the PR here:
https://github.com/microsoft/hlsl-specs/pull/261
This patch implements (not yet published)
[P3144R2](https://wiki.edg.com/pub/Wg21stlouis2024/StrawPolls/p3144r2.pdf)
"Deleting a Pointer to an Incomplete Type Should be Ill-formed". Wording
changes (not yet merged into the working draft) read:
> 7.6.2.9 [expr.delete] Delete
> If the object being deleted has incomplete class type at the point of
deletion <del>and the complete class has a
non-trivial destructor or a deallocation function, the behavior is
undefined</del>, <ins>the program is ill-formed</ins>.
We preserve status quo of emitting a warning when deleting a pointer to
incomplete type up to, and including, C++23, but make it ill-formed
since C++26. Same goes for deleting pointers to `void`, which has been
allowed as an extension.
This patch moves documentation of `Sema` functions from `.cpp` files to `Sema.h` when there was no documentation in the latter, or it can be trivially subsumed. More complicated cases when there's less trivial divergence between documentation attached to declaration and the one attached to implementation are left for a later PR that would require review.
It appears that doxygen can find the documentation for a function defined out-of-line even if it's attached to an implementation, and not declaration. But other tools, e.g. clangd, are not as powerful. So this patch significantly improves autocompletion experience for (at least) clangd-based IDEs.
This changes `__is_trivially_equality_comparable` to do overload
resolution instead, which fixes a couple of false-positives (and a
false-negative as a drive-by).
Fixes#89293
This patch implements a `__is_bitwise_cloneable` builtin in clang.
The builtin is used as a guard to check a type can be safely bitwise
copied by memcpy. It's functionally similar to
`__is_trivially_copyable`, but covers a wider range of types (e.g.
classes with virtual functions). The compiler guarantees that after
copy, the destination object has the same object representations as the
source object. And it is up to user to guarantee that program semantic
constraints are satisfied.
Context:
https://discourse.llvm.org/t/extension-for-creating-objects-via-memcpy
This patch introduces `SemaAMDGPU`, `SemaARM`, `SemaBPF`, `SemaHexagon`,
`SemaLoongArch`, `SemaMIPS`, `SemaNVPTX`, `SemaPPC`, `SemaSystemZ`,
`SemaWasm`. This continues previous efforts to split Sema up. Additional
context can be found in #84184 and #92682.
I decided to bundle target-specific components together because of their
low impact on `Sema`. That said, their impact on `SemaChecking.cpp` is
far from low, and I consider it a success.
Somewhat accidentally, I also moved Wasm- and AMDGPU-specific function
from `SemaDeclAttr.cpp`, because they were exposed in `Sema`. That went
well, and I consider it a success, too. I'd like to move the rest of
static target-specific functions out of `SemaDeclAttr.cpp` like we're
doing with built-ins in `SemaChecking.cpp` .
Skip explicit this check in non-valid scopes due to `null` type in
lambdas with invalid captures or incomplete parameter lists during
parsing
Fixes#91536