initializers.
This has some interesting interactions with our existing extensions to
support C99 designated initializers as an extension in C++. Those are
resolved as follows:
* We continue to permit the full breadth of C99 designated initializers
in C++, with the exception that we disallow a partial overwrite of an
initializer with a non-trivially-destructible type. (Full overwrite
is OK, because we won't run the first initializer at all.)
* The C99 extensions are disallowed in SFINAE contexts and during
overload resolution, where they could change the meaning of valid
programs.
* C++20 disallows reordering of initializers. We only check for that for
the simple cases that the C++20 rules permit (designators of the form
'.field_name =' and continue to allow reordering in other cases).
It would be nice to improve this behavior in future.
* All C99 designated initializer extensions produce a warning by
default in C++20 mode. People are going to learn the C++ rules based
on what Clang diagnoses, so it's important we diagnose these properly
by default.
* In C++ <= 17, we apply the C++20 rules rather than the C99 rules, and
so still diagnose C99 extensions as described above. We continue to
accept designated C++20-compatible initializers in C++ <= 17 silently
by default (but naturally still reject under -pedantic-errors).
This is not a complete implementation of P0329R4. In particular, that
paper introduces new non-C99-compatible syntax { .field { init } }, and
we do not support that yet.
This is based on a previous patch by Don Hinton, though I've made
substantial changes when addressing the above interactions.
Differential Revision: https://reviews.llvm.org/D59754
llvm-svn: 370544
accessible from the context where aggregate initialization occurs.
rdar://problem/38168772
Differential Revision: https://reviews.llvm.org/D45898
llvm-svn: 341629
It caused asserts, see PR37560.
> Use zeroinitializer for (trailing zero portion of) large array initializers
> more reliably.
>
> Clang has two different ways it emits array constants (from InitListExprs and
> from APValues), and both had some ability to emit zeroinitializer, but neither
> was able to catch all cases where we could use zeroinitializer reliably. In
> particular, emitting from an APValue would fail to notice if all the explicit
> array elements happened to be zero. In addition, for large arrays where only an
> initial portion has an explicit initializer, we would emit the complete
> initializer (which could be huge) rather than emitting only the non-zero
> portion. With this change, when the element would have a suffix of more than 8
> zero elements, we emit the array constant as a packed struct of its initial
> portion followed by a zeroinitializer constant for the trailing zero portion.
>
> In passing, I found a bug where SemaInit would sometimes walk the entire array
> when checking an initializer that only covers the first few elements; that's
> fixed here to unblock testing of the rest.
>
> Differential Revision: https://reviews.llvm.org/D47166
llvm-svn: 333067
more reliably.
Clang has two different ways it emits array constants (from InitListExprs and
from APValues), and both had some ability to emit zeroinitializer, but neither
was able to catch all cases where we could use zeroinitializer reliably. In
particular, emitting from an APValue would fail to notice if all the explicit
array elements happened to be zero. In addition, for large arrays where only an
initial portion has an explicit initializer, we would emit the complete
initializer (which could be huge) rather than emitting only the non-zero
portion. With this change, when the element would have a suffix of more than 8
zero elements, we emit the array constant as a packed struct of its initial
portion followed by a zeroinitializer constant for the trailing zero portion.
In passing, I found a bug where SemaInit would sometimes walk the entire array
when checking an initializer that only covers the first few elements; that's
fixed here to unblock testing of the rest.
Differential Revision: https://reviews.llvm.org/D47166
llvm-svn: 333044
In C++, such initialization of std::array<T, N> types is guaranteed to work by
the standard, is completely idiomatic, and the "suggested" alternative from
Clang was technically invalid.
llvm-svn: 314838
effect they would have in C++11. In particular, they do not prevent
value-initialization from performing zero-initialization, nor do they prevent a
struct from being an aggregate.
llvm-svn: 290229
When an object of class type is initialized from a prvalue of the same type
(ignoring cv qualifications), use the prvalue to initialize the object directly
instead of inserting a redundant elidable call to a copy constructor.
llvm-svn: 288866
Fixes <rdar://problem/15584219> and <rdar://problem/12241361>.
This change looks large, but all it does is reuse and consolidate
the delayed diagnostic logic for deprecation warnings with unavailability
warnings. By doing so, it showed various inconsistencies between the
diagnostics, which were close, but not consistent. It also revealed
some missing "note:"'s in the deprecated diagnostics that were showing
up in the unavailable diagnostics, etc.
This change also changes the wording of the core deprecation diagnostics.
Instead of saying "function has been explicitly marked deprecated"
we now saw "'X' has been been explicitly marked deprecated". It
turns out providing a bit more context is useful, and often we
got the actual term wrong or it was not very precise
(e.g., "function" instead of "destructor"). By just saying the name
of the thing that is deprecated/deleted/unavailable we define
this issue away. This diagnostic can likely be further wordsmithed
to be shorter.
llvm-svn: 197627
Revert "For C++11, do more checking of initializer lists up-front, enabling some subset of the final functionality. C just leaves the function early. C++98 runs through the same code path, but has no changed functionality either."
This reverts commit ac420c5053d6aa41d59f782caad9e46e5baaf2c2.
llvm-svn: 135210
This is a first baby step towards supporting generalized initializer lists. This also removes an aggregate
test case that was just plain wrong, assuming that non-aggregates couldn't be initialized with initializer lists
in C++11 mode.
llvm-svn: 135177
hasTrivialDefaultConstructor() really really means it now.
Also implement a fun standards bug regarding aggregates. Doug, if you'd
like, I can un-implement that bug if you think it is truly a defect.
The bug is that non-special-member constructors are never considered
user-provided, so the following is an aggregate:
struct foo {
foo(int);
};
It's kind of bad, but the solution isn't obvious - should
struct foo {
foo (int) = delete;
};
be an aggregate or not?
Lastly, add a missing initialization to FunctionDecl.
llvm-svn: 131101
thing. Audit all uses of Type::isStructure(), changing those calls to
isStructureOrClassType() as needed (which is alsmost
everywhere). Fixes the remaining failure in Boost.Utility/Swap.
llvm-svn: 102386
resolution. There are two sources of problems involving user-defined
conversions that this change eliminates, along with providing simpler
interfaces for checking implicit conversions:
- It eliminates a case of infinite recursion found in Boost.
- It eliminates the search for the constructor needed to copy a temporary
generated by an implicit conversion from overload
resolution. Overload resolution assumes that, if it gets a value
of the parameter's class type (or a derived class thereof), there
is a way to copy if... even if there isn't. We now model this
properly.
llvm-svn: 101680
therefore not creating ElaboratedTypes, which are still pretty-printed
with the written tag).
Most of these testcase changes were done by script, so don't feel too
sorry for my fingers.
llvm-svn: 98149
- This is designed to make it obvious that %clang_cc1 is a "test variable"
which is substituted. It is '%clang_cc1' instead of '%clang -cc1' because it
can be useful to redefine what gets run as 'clang -cc1' (for example, to set
a default target).
llvm-svn: 91446