Skip to content

[C2y] Claim conformance and add test coverage for WG14 N3346 #115516

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,11 @@ C2y Feature Support
undefined. Clang has always accepted ``const`` and ``volatile`` qualified
function types by ignoring the qualifiers.

- Updated conformance for `N3346 <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3346.pdf>`_
which changes some undefined behavior around initialization to instead be
constraint violations. This paper adopts Clang's existing practice, so there
were no changes to compiler behavior.

C23 Feature Support
^^^^^^^^^^^^^^^^^^^

Expand Down
68 changes: 68 additions & 0 deletions clang/test/C/C2y/n3346.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// RUN: %clang_cc1 -verify -std=c2y -Wall -pedantic -ffreestanding %s
// RUN: %clang_cc1 -verify=expected,ped -Wall -pedantic -ffreestanding %s

/* WG14 N3346: Yes
* Slay Some Earthly Demons VIII
*
* Updates some undefined behavior during initialization to instead be a
* constraint violation.
*/

// The initializer for a scalar shall be a single expression, optionally
// enclosed in braces, or it shall be an empty initializer.
int i = 12, j = {12}, k = {}; // ped-warning {{use of an empty initializer is a C23 extension}}

struct S {
int i;
float f;
int : 0;
char c;
};

void test1(void) {
// The initializer for an object that has structure or union type shall be
// either a single expression that has compatible type or a brace-enclosed
// list of initializers for the elements or named members.
struct S s1 = { 1, 1.2f, 'a' };
struct S s2 = s1;

// Despite being structurally identical to S, T is not compatible with S.
struct T { int i; float f; int : 0; char c; } t;
struct S s3 = t; // expected-error {{initializing 'struct S' with an expression of incompatible type 'struct T'}}
}

void test2(void) {
typedef __WCHAR_TYPE__ wchar_t;
typedef __CHAR16_TYPE__ char16_t;
typedef __CHAR32_TYPE__ char32_t;

// The initializer for an array shall be either a string literal, optionally
// enclosed in braces, or a brace-enclosed list of initializers for the
// elements. An array initialized by character string literal or UTF-8 string
// literal shall have a character type as element type. An array initialized
// with a wide string literal shall have element type compatible with a
// qualified or unqualified wchar_t, char16_t, or char32_t, and the string
// literal shall have the corresponding encoding prefix (L, u, or U,
// respectively).
char str1[] = "string literal";
char str2[] = { "string literal" };
char str3[] = u8"string literal";
char str4[] = { u8"string literal" };

int str5[] = "this doesn't work"; // expected-error {{array initializer must be an initializer list}}
int str6[] = { "this also doesn't work" }; // expected-error {{incompatible pointer to integer conversion initializing 'int' with an expression of type 'char[23]'}}

wchar_t str7[] = L"string literal";
wchar_t str8[] = { L"string literal" };
char16_t str9[] = u"string literal";
char16_t str10[] = { u"string literal" };
char32_t str11[] = U"string literal";
char32_t str12[] = { U"string literal" };

wchar_t str13[] = "nope"; // expected-error {{initializing wide char array with non-wide string literal}}
wchar_t str14[] = { "nope" }; // expected-error-re {{incompatible pointer to integer conversion initializing 'wchar_t' (aka '{{.*}}') with an expression of type 'char[5]'}}
char16_t str15[] = "nope"; // expected-error {{initializing wide char array with non-wide string literal}}
char16_t str16[] = { "nope" }; // expected-error-re {{incompatible pointer to integer conversion initializing 'char16_t' (aka '{{.*}}') with an expression of type 'char[5]'}}
char32_t str17[] = "nope"; // expected-error {{initializing wide char array with non-wide string literal}}
char32_t str18[] = { "nope" }; // expected-error-re {{incompatible pointer to integer conversion initializing 'char32_t' (aka '{{.*}}') with an expression of type 'char[5]'}}
}
2 changes: 1 addition & 1 deletion clang/www/c_status.html
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ <h2 id="c2y">C2y implementation status</h2>
<tr>
<td>Slay Some Earthly Demons VIII</td>
<td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3346.pdf">N3346</a></td>
<td class="unknown" align="center">Unknown</td>
<td class="full" align="center">Yes</td>
</tr>
<tr>
<td>Introduce complex literals v. 2</td>
Expand Down
Loading