Commit Graph

3 Commits

Author SHA1 Message Date
Richard Smith 5030928d60 [c++20] Implement semantic restrictions for C++20 designated
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
2019-08-30 22:52:55 +00:00
Artem Dergachev 161e4753b9 [analyzer] Canonicalize declarations within variable regions.
Memory region that correspond to a variable is identified by the variable's
declaration and, in case of local variables, the stack frame it belongs to.

The declaration needs to be canonical, otherwise we'd have two different
memory regions that correspond to the same variable.

Fix such bug for global variables with forward declarations and assert
that no other problems of this kind happen.

Differential Revision: https://reviews.llvm.org/D57619

llvm-svn: 353353
2019-02-07 00:30:20 +00:00
Artem Dergachev a2e053638b [analyzer] Treat more const variables and fields as known contants.
When loading from a variable or a field that is declared as constant,
the analyzer will try to inspect its initializer and constant-fold it.
Upon success, the analyzer would skip normal load and return the respective
constant.

The new behavior also applies to fields/elements of brace-initialized structures
and arrays.

Patch by Rafael Stahl!

Differential Revision: https://reviews.llvm.org/D45774

llvm-svn: 331556
2018-05-04 20:52:39 +00:00