1136 Commits

Author SHA1 Message Date
offsetof
5105ecc413
[clang] Refine handling of C++20 aggregate initialization (#131320)
* Move parts of `InitializationSequence::InitializeFrom` corresponding
to C++ [dcl.init.general] p16.6.1 and p16.6.2 into a separate
function,`TryConstructorOrParenListInitialization`
* Use it in `TryListInitialization` to implement [dcl.init.list] p3.2
* Fix parenthesized aggregate initialization being attempted in
copy-initialization contexts or when the constructor call is ambiguous

Co-authored-by: cor3ntin <corentinjabot@gmail.com>
2025-03-25 15:30:16 +01:00
Mariya Podchishchaeva
8c6f309023
[clang] Introduce "binary" StringLiteral for #embed data (#127629)
StringLiteral is used as internal data of EmbedExpr and we directly use
it as an initializer if a single EmbedExpr appears in the initializer
list of a char array. It is fast and convenient, but it is causing
problems when string literal character values are checked because #embed
data values are within a range [0-2^(char width)] but ordinary
StringLiteral is of maybe signed char type.
This PR introduces new kind of StringLiteral to hold binary data coming
from an embedded resource to mitigate these problems. The new kind of
StringLiteral is not assumed to have signed char type. The new kind of
StringLiteral also helps to prevent crashes when trying to find
StringLiteral token locations since these simply do not exist for binary
data.

Fixes https://github.com/llvm/llvm-project/issues/119256
2025-03-20 13:02:29 +01:00
Nikita Popov
07f3388fff Revert "[clang] Implement instantiation context note for checking template parameters (#126088)"
This reverts commit a24523ac8dc07f3478311a5969184b922b520395.

This is causing significant compile-time regressions for C++ code, see:
https://github.com/llvm/llvm-project/pull/126088#issuecomment-2704874202
2025-03-10 10:32:08 +01:00
Matheus Izvekov
a24523ac8d
[clang] Implement instantiation context note for checking template parameters (#126088)
Instead of manually adding a note pointing to the relevant template
parameter to every relevant error, which is very easy to miss, this
patch adds a new instantiation context note, so that this can work using
RAII magic.

This fixes a bunch of places where these notes were missing, and is more
future-proof.

Some diagnostics are reworked to make better use of this note:
- Errors about missing template arguments now refer to the parameter
which is missing an argument.
- Template Template parameter mismatches now refer to template
parameters as parameters instead of arguments.

It's likely this will add the note to some diagnostics where the
parameter is not super relevant, but this can be reworked with time and
the decrease in maintenance burden makes up for it.

This bypasses the templight dumper for the new context entry, as the
tests are very hard to update.

This depends on #125453, which is needed to avoid losing the context
note for errors occuring during template argument deduction.
2025-03-06 14:58:42 -03:00
Mariya Podchishchaeva
59169036ca
[clang] Fix crash when #embed data does not fit into an array (#129567)
Tune SemaInit code handling #embed to take into account how many array
elements remains to initialize.
Also issue a warning/error message when the array/struct is at the end
but there is still #embed data left.

Fixes https://github.com/llvm/llvm-project/issues/128987
2025-03-05 11:04:52 +01:00
Mariya Podchishchaeva
2871f69052
[clang] Fix issues with #embed and intializer lists/template arguments (#128890)
Sometimes number of expressions in InitListExpr is used for template
argument deduction. So, in these cases we need to pay attention to real
number of expressions including expanded #embed data.

Fixes https://github.com/llvm/llvm-project/issues/122306
2025-02-28 09:35:59 +01:00
Lukacma
741d7fab4e
[Clang][Sema] Add special handling of mfloat8 in initializer lists (#125097)
This patch fixes assertion failures in clang, caused by unique
properties of _mfp8 type, namely it not being either scalar or vector
type and it not being either integer or float type.
2025-02-27 11:32:02 +00:00
Mariya Podchishchaeva
0cd5a1f309
[NFC][clang] Cleanup in APValue and SemaInit (#127790)
APValue:
Additional assignment of AllowConstexprUnknown is not required since it
will be handled by copy constructor called above.
SemaInit:
Remove unnecessary null check. DestRecordDecl can't be null due to being
obtained using `cast` and assertion that DestRecordType is present.

Spotted by a static analysis tool.
2025-02-20 09:45:46 +01:00
Chris B
715edd70fd
[HLSL] Allow arrays to copy-initialize (#127557)
This change allows array variables to copy-initialize from other arrays.
It also corrects a small error in HLSL C-Style casting that did not
error on casting to arrays if elementwise and splat conversions fail.

Fixes #127551
2025-02-18 20:13:23 -06:00
Chris B
761d422441
[HLSL] Implement HLSL intialization list support (#123141)
This PR implements HLSL's initialization list behvaior as specified in
the draft language specifcation under

[*Decl.Init.Agg*](https://microsoft.github.io/hlsl-specs/specs/hlsl.html#Decl.Init.Agg).

This behavior is a bit unusual for C/C++ because intermediate braces in
initializer lists are ignored and a whole array of additional
conversions occur unintuitively to how initializaiton works in C.

The implementaiton in this PR generates a valid C/C++ initialization
list AST for the HLSL initializer so that there are no changes required
to Clang's CodeGen to support this. This design will also allow us to
use Clang's rewrite to convert HLSL initializers to valid C/C++
initializers that are equivalent. It does have the downside that it will
generate often redundant accesses during codegen. The IR optimizer is
extremely good at eliminating those so this will have no impact on the
final executable performance.

There is some opportunity for optimizing the initializer list generation
that we could consider in subsequent commits. One notable opportunity
would be to identify aggregate objects that occur in the same place in
both initializers and do not require converison, those aggregates could
be initialized as aggregates rather than fully scalarized.

Closes #56067

---------

Co-authored-by: Finn Plummer <50529406+inbelic@users.noreply.github.com>
Co-authored-by: Helena Kotas <hekotas@microsoft.com>
Co-authored-by: Justin Bogner <mail@justinbogner.com>
2025-02-15 13:21:36 -06:00
higher-performance
90192e8872
Fix false positive of [[clang::require_explicit_initialization]] on copy/move constructors (#126553)
Fixes #126490
2025-02-11 07:52:13 +01:00
Yanzuo Liu
6f241e3683
[Clang][Sema] Fix wrong initialization kind when handling initializing structured bindings from an array with direct-list-initialization (#124793)
In 377257f063c, elements of structured bindings are copy-initialized.
They should be direct-initialized because the form of the initializer of
the whole structured bindings is a direct-list-initialization.

> [dcl.struct.bind]/1:
> ... and each element is copy-initialized or direct-initialized from
the corresponding element of the assignment-expression as specified by
the form of the initializer. ...

For example,

```cpp
  int arr[2]{};
  // elements of `[a, b]` should be direct-initialized
  auto [a, b]{arr};
```
2025-02-08 14:31:47 +08:00
Brian Foley
39879e4f40
[Sema] Note member decl when initializer list default constructs member (#121854)
Recently I had a scenario where I had:
1. A class C with many members m_1...m_n of the same type T
2. T's default constructor was deleted
3. I accidentally omitted an explicitly constructed member in the
initializer list C() : m_1(foo), m_2(bar), ... { }

Clang told me that T's default constructor was deleted, and told me that
the call to T() was in C() (which it implicitly was), but didn't tell me
which member was being default constructed.

It was difficult to fix this problem because I had no easy way to list
all the members of type T in C and C's superclasses which would have let
me find which member was missing,

clang/test/CXX/class/class.init/p1.cpp is a simplified version of this
problem (a2 is missing from the initializer list of B)
2025-02-03 19:57:37 +01:00
higher-performance
20fd7df0b8
Fix false negative when value initializing a field annotated with [[clang::require_field_initialization]] (#124329)
It turns out we weren't handling one case: the value-initialization of a
field inside a struct.

I'm not sure why this falls under `IK_Direct` rather than `IK_Value` in
Clang, but it seems to work.
2025-01-30 15:34:08 -05:00
higher-performance
1594413d5e
Add Clang attribute to ensure that fields are initialized explicitly (#102040)
This is a new Clang-specific attribute to ensure that field
initializations are performed explicitly.

For example, if we have
```
struct B {
  [[clang::explicit]] int f1;
};
```
then the diagnostic would trigger if we do `B b{};`:
```
field 'f1' is left uninitialized, but was marked as requiring initialization
```

This prevents callers from accidentally forgetting to initialize fields,
particularly when new fields are added to the class.
2025-01-14 13:31:12 -05:00
Mariya Podchishchaeva
cdad183194
[clang] Fix #embed "fast path" (#121479)
When a single #embed directive is used to initialize a char array, the
case is optimized via swap of EmbedExpr to underlying StringLiteral,
resulting in better performance in AST consumers.
While browsing through the code, I realized that
7122b70cfc8e23a069410215c363da76d842bda4
which changed type of EmbedExpr made the "fast path" unreachable. This
patch fixes this unfortunate situation.
2025-01-03 11:17:16 +01:00
yronglin
740861d69c
[clang] Fix a crash issue that caused by handling of fields with initializers in nested anonymous unions (#113049)
Fixes: https://github.com/llvm/llvm-project/issues/112560

This PR create an RecoveryExpr for invalid in-class-initializer.

---------

Signed-off-by: yronglin <yronglin777@gmail.com>
2024-12-10 20:56:52 +08:00
Utkarsh Saxena
c22bb6f5b1
[clang] Implement lifetime analysis for lifetime_capture_by(X) (#115921)
This PR uses the existing lifetime analysis for the `capture_by`
attribute.

The analysis is behind `-Wdangling-capture` warning and is disabled by
default for now. Once it is found to be stable, it will be default
enabled.

Planned followup:
- add implicit inference of this attribute on STL container methods like
`std::vector::push_back`.
- (consider) warning if capturing `X` cannot capture anything. It should
be a reference, pointer or a view type.
- refactoring temporary visitors and other related handlers.
- start discussing `__global` vs `global` in the annotation in a
separate PR.

---------

Co-authored-by: Boaz Brickner <brickner@google.com>
2024-11-20 15:17:00 +01:00
Kazu Hirata
46d750be2e
[Sema] Remove unused includes (NFC) (#116461)
Identified with misc-include-cleaner.
2024-11-16 07:37:33 -08:00
Joseph Huber
b9d678d22f
[Clang] Use TargetInfo when deciding if an address space is compatible (#115777)
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.
2024-11-15 06:58:36 -06:00
Krystian Stasiowski
44ab3805b5
Revert "Reapply "[Clang][Sema] Refactor collection of multi-level template argument lists (#106585, #111173)" (#111852)" (#115159)
This reverts commit 2bb3d3a3f32ffaef3d9b6a27db7f1941f0cb1136.
2024-11-06 09:25:29 -05:00
Krystian Stasiowski
79f4d8f014
Revert "Reapply "[Clang][Sema] Always use latest redeclaration of primary template" (#114569)" (#115156)
This reverts commit b24650e814e55d90acfc40acf045456c98f32b9c.
2024-11-06 08:38:59 -05:00
Congcong Cai
2f1a0df72a
[clang][sema] Fixed a crash when mixture of designated and non-designated initializers in union (#114424)
Fixed: #113855
When the first init element is invalid, StructuredList can be empty.
It cause illegal state if we still set initialized field.
2024-11-04 22:28:07 +08:00
Krystian Stasiowski
b24650e814
Reapply "[Clang][Sema] Always use latest redeclaration of primary template" (#114569)
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.
2024-11-01 16:15:33 -04:00
Felipe de Azevedo Piovezan
4afa978756
Revert "[Clang][Sema] Always use latest redeclaration of primary template" (#114304)
Clang importer doesn't seem to work well with this change, see
discussion in the original PR.

Reverts llvm/llvm-project#114258
2024-10-30 14:04:26 -07:00
Krystian Stasiowski
90786adade
[Clang][Sema] Always use latest redeclaration of primary template (#114258)
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
```
2024-10-30 14:50:40 -04:00
Jay Foad
4dd55c567a
[clang] Use {} instead of std::nullopt to initialize empty ArrayRef (#109399)
Follow up to #109133.
2024-10-24 10:23:40 +01:00
Krystian Stasiowski
2bb3d3a3f3
Reapply "[Clang][Sema] Refactor collection of multi-level template argument lists (#106585, #111173)" (#111852)
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.
2024-10-11 14:08:06 -04:00
yronglin
25d9688c43
[Clang] Extend lifetime of temporaries in mem-default-init for P2718R0 (#86960)
Depends on [CWG1815](https://github.com/llvm/llvm-project/pull/108039).
Fixes https://github.com/llvm/llvm-project/issues/85613.

In [[Clang] Implement P2718R0 "Lifetime extension in range-based for
loops"](https://github.com/llvm/llvm-project/pull/76361), we've not
implement the lifetime extensions for the temporaries which in
`CXXDefaultInitExpr`. As the confirmation in
https://github.com/llvm/llvm-project/issues/85613, we should extend
lifetime for that.

To avoid modifying current CodeGen rules, in a lifetime extension
context, the cleanup of `CXXDefaultInitExpr` was ignored.

---------

Signed-off-by: yronglin <yronglin777@gmail.com>
2024-10-11 00:04:02 +08:00
Joshua Batista
c098435eaa
Add cross builtins and cross HLSL function to DirectX and SPIR-V backend (#109180)
This PR adds the step intrinsic and an HLSL function that uses it.
The SPIRV backend is also implemented.

Used https://github.com/llvm/llvm-project/pull/106471 as a reference.
Fixes https://github.com/llvm/llvm-project/issues/99095
2024-10-03 10:24:09 -07:00
Chris B
6eb3519fd7
[HLSL] Allow narrowing in initialization lists (#108035)
HLSL's initialization lists are _extremely_ generous about allowing
conversions. This change demotes the C++11 warning to the legacy warning
when in HLSL mode.

Required for #56067
2024-09-12 12:03:25 -05:00
yronglin
060137038a
Reapply "[Clang][CWG1815] Support lifetime extension of temporary created by aggregate initialization using a default member initializer" (#108039)
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>
2024-09-12 06:29:48 +08:00
Martin Storsjö
cca54e347a Revert "Reapply "[Clang][CWG1815] Support lifetime extension of temporary created by aggregate initialization using a default member initializer" (#97308)"
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.
2024-09-09 15:09:45 +03:00
yronglin
45c8766973
Reapply "[Clang][CWG1815] Support lifetime extension of temporary created by aggregate initialization using a default member initializer" (#97308)
The PR reapply https://github.com/llvm/llvm-project/pull/92527.
Implemented CWG1815 and fixed the bugs mentioned in the comments of
https://github.com/llvm/llvm-project/pull/92527 and
https://github.com/llvm/llvm-project/pull/87933.

The reason why the original PR was reverted was that errors might occur
during the rebuild.

---------

Signed-off-by: yronglin <yronglin777@gmail.com>
2024-09-08 22:36:49 +08:00
Dan Liew
ff04c5b2e6
[NFC][Sema] Move Sema::AssignmentAction into its own scoped enum (#106453)
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.
2024-08-29 12:00:28 -07:00
Yanzuo Liu
377257f063
[Clang] Support initializing structured bindings from an array with direct-list-initialization (#102581)
When initializing structured bindings from an array with
direct-list-initialization, array copy will be performed, which is a
special case not following list-initialization.

This PR adds support for this case.

Fixes #31813.
2024-08-27 23:18:20 +02:00
Mital Ashok
9d739e54f4
[Clang] Implement CWG2351 void{} (#78060)
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.
2024-08-21 10:09:08 +02:00
Mital Ashok
a760df3165
[Clang] Implement CWG2137 (list-initialization from objects of the same type) (#94355)
[CWG2137](https://cplusplus.github.io/CWG/issues/2137.html)

This was previously implemented and then reverted in Clang 18 as #77768

This also implements a workaround for
[CWG2311](https://cplusplus.github.io/CWG/issues/2311.html), similarly
to the 2024-03-01 comment for
[CWG2742](https://cplusplus.github.io/CWG/issues/2742.html).

The exact wording this tries to implement, relative to the C++26 draft:

[over.match.list]p(1.2)

> Otherwise, or if no viable initializer-list constructor is found
<ins>and the initializer list does not consist of exactly a single
element with the same cv-unqualified class type as `T`</ins>, overload
resolution is performed again, [...]

[dcl.init.list]p(3.7)

> Otherwise, if `T` is a class type, constructors are considered. The
applicable constructors are enumerated and the best one is chosen
through overload resolution. <ins>If no constructor is found and the
initializer list consists of exactly a single element with the same
cv-unqualified class type as `T`, the object is initialized from that
element (by copy-initialization for copy-list-initialization, or by
direct-initialization for direct-list-initialization). Otherwise,</ins>
if a narrowing conversion (see below) is required [...]
2024-08-08 11:11:21 -04:00
Mariya Podchishchaeva
3606d69d0b
[clang] Fix crash when #embed used in a compound literal (#102304)
Fixes https://github.com/llvm/llvm-project/issues/102248
2024-08-08 08:51:56 +02:00
Oleksandr T.
ee57ce57d8
[Clang] prevent checking destructor reference with an invalid initializer (#97860)
Fixes #97230
2024-07-29 18:39:30 +02:00
Mariya Podchishchaeva
7122b70cfc
[clang] Fix underlying type of EmbedExpr (#99050)
This patch makes remaining cases of #embed to emit int type since there
is an agreement to do that for C. C++ is being discussed, but in general
we don't want to produce different types for C and C++.
2024-07-19 14:24:05 +02:00
Mital Ashok
554febd3aa
[Clang] Fix some assertions not looking through type sugar (#92299)
Fixes #92284

Co-authored-by: cor3ntin <corentinjabot@gmail.com>
2024-07-17 16:42:02 +02:00
Mariya Podchishchaeva
a5b5208ba6
[clang] Be careful when choosing "fast path" for initialization with #embed (#99023)
When #embed appears in an initializer list, we may choose a "fast path"
if the target declaration is a char array. We simply initialize it with
string literal that contains embedded data. However we need to be
careful when checking that we actually can use this "fast path" since
char array may be nested in a struct.
2024-07-17 10:00:47 +02:00
Yuxuan Chen
6f13c71d31
[clang] fix sema init crashing on initialization sequences (#98102)
We ran into a FE crash and root caused to `ER.get()` on line 5584 here
being nullptr. I think this is a result of not checking if ER here is
invalid.

Example of crash-on-valid C++
https://gist.github.com/yuxuanchen1997/576dce964666f0f8713fccacf5847138

Note that this crash happens only with `-std=c++20`.
2024-07-10 11:24:23 -07:00
Gábor Spaits
de88b2cb16
[Clang] Simplify release notes and remove irrelevant comment (#96407)
As discussed before with @cor3ntin before
(https://github.com/llvm/llvm-project/pull/94752) here is the
simplification of the release note written for the previously mentioned
PR and the removal of a comment that is no longer useful.

(Sorry for creating this PR this late.)

Co-authored-by: Gabor Spaits <Gabor.Spaits@hightec-rt.com>
2024-07-06 15:22:51 +02:00
Vlad Serebrennikov
bae2c54912 [clang][NFC] Move documentation of Sema functions into Sema.h
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.
2024-07-01 20:55:57 +03:00
Haojian Wu
8a43dc3efd
[clang][Sema] Move the initializer lifetime checking code from SemaInit.cpp to a new place, NFC (#96758)
This is a refactoring change for better code isolation and reuse, the
first step to extend it for assignments.
2024-06-27 10:56:06 +02:00
Mital Ashok
482c41e992
[Clang] [Sema] Diagnose unknown std::initializer_list layout in SemaInit (#95580)
This checks if the layout of `std::initializer_list` is something Clang
can handle much earlier and deduplicates the checks in
CodeGen/CGExprAgg.cpp and AST/ExprConstant.cpp

Also now diagnose `union initializer_list` (Fixes #95495), bit-field for
the size (Fixes a crash that would happen during codegen if it were
unnamed), base classes (that wouldn't be initialized) and polymorphic
classes (whose vtable pointer wouldn't be initialized).
2024-06-20 19:44:06 +02:00
Mariya Podchishchaeva
41c6e43792
Reland [clang][Sema, Lex, Parse] Preprocessor embed in C and C++ (#95802)
This commit implements the entirety of the now-accepted [N3017
-Preprocessor
Embed](https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3017.htm) and
its sister C++ paper [p1967](https://wg21.link/p1967). It implements
everything in the specification, and includes an implementation that
drastically improves the time it takes to embed data in specific
scenarios (the initialization of character type arrays). The mechanisms
used to do this are used under the "as-if" rule, and in general when the
system cannot detect it is initializing an array object in a variable
declaration, will generate EmbedExpr AST node which will be expanded by
AST consumers (CodeGen or constant expression evaluators) or expand
embed directive as a comma expression.

This reverts commit
682d461d5a.

---------

Co-authored-by: The Phantom Derpstorm <phdofthehouse@gmail.com>
Co-authored-by: Aaron Ballman <aaron@aaronballman.com>
Co-authored-by: cor3ntin <corentinjabot@gmail.com>
Co-authored-by: H. Vetinari <h.vetinari@gmx.com>
2024-06-20 14:38:46 +02:00
Gábor Spaits
f80bd9b8a8
[Sema][CTAD] Allow user defined conversion for copy-list-initialization (#94752)
Fixes #62925.

The following code:
```cpp
#include <map>

int main() {
   std::map m1 = {std::pair{"foo", 2}, {"bar", 3}}; // guide #2
   std::map m2(m1.begin(), m1.end()); // guide #1
}
```
Is rejected by clang, but accepted by both gcc and msvc:
https://godbolt.org/z/6v4fvabb5 .

So basically CTAD with copy-list-initialization is rejected.

Note that this exact code is also used in a cppreference article:
https://en.cppreference.com/w/cpp/container/map/deduction_guides

I checked the C++11 and C++20 standard drafts to see whether suppressing
user conversion is the correct thing to do for user conversions. Based
on the standard I don't think that it is correct.

```
13.3.1.4 Copy-initialization of class by user-defined conversion [over.match.copy]
Under the conditions specified in 8.5, as part of a copy-initialization of an object of class type, a user-defined
conversion can be invoked to convert an initializer expression to the type of the object being initialized.
Overload resolution is used to select the user-defined conversion to be invoked
```
So we could use user defined conversions according to the standard.

```
If a narrowing conversion is required to initialize any of the elements, the
program is ill-formed.
```
We should not do narrowing.

```
In copy-list-initialization, if an explicit constructor is chosen, the initialization is ill-formed.
```
We should not use explicit constructors.
2024-06-18 20:45:23 +02:00