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
Fixes https://github.com/llvm/llvm-project/issues/85192
Fixes https://github.com/llvm/llvm-project/issues/84492
This patch implements the "IsDeducible" constraint where the template
arguments of the alias template can be deduced from the returned type of
the synthesized deduction guide, per C++ [over.match.class.deduct]p4. In
the implementation, we perform the deduction directly, which is more
efficient than the way specified in the standard.
Also update relevant CTAD tests which were incorrectly compiled due to
the missing constraint.
Reapplies #84050, addressing a bug which cases a crash when an
expression with the type of the current instantiation is used as the
_postfix-expression_ in a class member access expression (arrow form).
Consider the following:
```cpp
template<typename T>
struct A
{
auto f()
{
return this->x;
}
};
```
Although `A` has no dependent base classes and the lookup context for
`x` is the current instantiation, we currently do not diagnose the
absence of a member `x` until `A<T>::f` is instantiated. This patch
moves the point of diagnosis for such expressions to occur at the point
of definition (i.e. prior to instantiation).
Reapplies #87541 and #88311 (again) addressing the bug which caused
expressions naming overload sets to be incorrectly rebuilt, as well as
the bug which caused base class members to always be treated as overload
sets.
The primary change since #88311 is `UnresolvedLookupExpr::Create` is called directly in `BuildPossibleImplicitMemberExpr` with `KnownDependent` as `true` (which causes the expression type to be set to `ASTContext::DependentTy`). This ensures that any further semantic analysis involving the type of the potentially implicit class member access expression is deferred until instantiation.
This patch converts the enum into scoped enum, and moves it into its own header for the time being. It's definition is needed in `Sema.h`, and is going to be needed in upcoming `SemaObjC.h`. `Lookup.h` can't hold it, because it includes `Sema.h`.
This PR remove `InMaterializeTemporaryObjectContext` , because it's
redundant, materialize non-cv void prvalue temporaries in discarded
expressions can only appear under lifetime-extension context.
Signed-off-by: yronglin <yronglin777@gmail.com>
This patch implements intrinsic that supports
`std::is_pointer_interconvertible_base_of` type trait from
[P0466R5](https://wg21.link/p0466r5) "Layout-compatibility and
Pointer-interconvertibility Traits".
Normative wording:
> Comment: If `Base` and Derived are non-union class types and are not
(possibly _cv_-qualified) versions of the same type, `Derived` is a
complete type.
> Condition: `Derived` is unambiguously derived from `Base` without
regard to _cv_-qualifiers, and each object of type `Derived` is
pointer-interconvertible (6.7.2 [basic.compound]) with its `Base`
subobject, or `Base` and `Derived` are not unions and name the same
class type without regard to _cv_-qualifiers.
The paper also express the following intent:
> Note that `is_pointer_interconvertible_base_of_v<T,T>` is always true
under this wording, even though `T` is not derived from itself.
I find the treatment of unions in the wording contradictory to this
intent, and I'm not able to find anything relevant in minutes or on the
reflector. That said, this patch implements what the wording says, since
it's very explicit about unions.
This fixes a bug introduced by #84473: if a lambda’s type is type sugar
(e.g. an `AttributedType`), we need to use `getAs()` instead of `cast()`
to retrieve the `FunctionProtoType`.
This patch takes advantage of a recent NFC change that refactored
`EvaluateBinaryTypeTrait()` to accept `TypeSourceInfo` instead of
`QualType` c7db450e5c1a83ea768765dcdedfd50f3358d418.
Before:
```
test2.cpp:105:55: error: variable length arrays are not supported in '__is_layout_compatible'
105 | static_assert(!__is_layout_compatible(int[n], int[n]));
| ^
test2.cpp:125:76: error: incomplete type 'CStructIncomplete' where a complete type is required
125 | static_assert(__is_layout_compatible(CStructIncomplete, CStructIncomplete));
| ^
```
After:
```
test2.cpp:105:41: error: variable length arrays are not supported in '__is_layout_compatible'
105 | static_assert(!__is_layout_compatible(int[n], int[n]));
| ^
test2.cpp:125:40: error: incomplete type 'CStructIncomplete' where a complete type is required
125 | static_assert(__is_layout_compatible(CStructIncomplete, CStructIncomplete));
| ^
```
This fixes some problems wrt dependence of captures in lambdas with
an explicit object parameter.
[temp.dep.expr] states that
> An id-expression is type-dependent if [...] its terminal name is
> - associated by name lookup with an entity captured by copy
> ([expr.prim.lambda.capture]) in a lambda-expression that has
> an explicit object parameter whose type is dependent [dcl.fct].
There were several issues with our implementation of this:
1. we were treating by-reference captures as dependent rather than
by-value captures;
2. tree transform wasn't checking whether referring to such a
by-value capture should make a DRE dependent;
3. when checking whether a DRE refers to such a by-value capture, we
were only looking at the immediately enclosing lambda, and not
at any parent lambdas;
4. we also forgot to check for implicit by-value captures;
5. lastly, we were attempting to determine whether a lambda has an
explicit object parameter by checking the `LambdaScopeInfo`'s
`ExplicitObjectParameter`, but it seems that that simply wasn't
set (yet) by the time we got to the check.
All of these should be fixed now.
This fixes#70604, #79754, #84163, #84425, #86054, #86398, and #86399.