@@ -6526,34 +6526,52 @@ Clang allows additional identifiers to be declared in the following cases:
65266526
65276527* A compound literal may introduce a new type. e.g .,
65286528
6529- .. code-block :: c
6529+ .. code-block :: c
65306530
6531- auto x = (struct S { int x, y; }){ 1, 2 }; // Accepted by Clang
6532- constexpr int i = (struct T { int x; }){ 1 }.x; // Accepted by Clang
6531+ auto x = (struct S { int x, y; }){ 1, 2 }; // Accepted by Clang
6532+ constexpr int i = (struct T { int x; }){ 1 }.x; // Accepted by Clang
65336533
65346534 * The type specifier for a ``constexpr `` declaration may define a new type.
65356535 e.g .,
65366536
6537- .. code-block :: c
6537+ .. code-block :: c
65386538
6539- constexpr struct S { int x; } s = { 1 }; // Accepted by Clang
6539+ constexpr struct S { int x; } s = { 1 }; // Accepted by Clang
65406540
65416541 * A function declarator may be declared with parameters, including parameters
65426542 which introduce a new type. e.g .,
65436543
6544- .. code-block :: c
6544+ .. code-block :: c
65456545
6546- constexpr int (*fp)(int x) = nullptr; // Accepted by Clang
6547- auto f = (void (*)(struct S { int x; } s))nullptr; // Accepted by Clang
6546+ constexpr int (*fp)(int x) = nullptr; // Accepted by Clang
6547+ auto f = (void (*)(struct S { int x; } s))nullptr; // Accepted by Clang
65486548
65496549 * The initializer may contain a GNU statement expression which defines new
65506550 types or objects. e.g .,
65516551
6552- .. code-block :: c
6552+ .. code-block :: c
6553+
6554+ constexpr int i = ({ // Accepted by Clang
6555+ constexpr int x = 12;
6556+ constexpr struct S { int x; } s = { x };
6557+ s.x;
6558+ });
6559+ auto x = ({ struct S { int x; } s = { 0 }; s; }); // Accepted by Clang
6560+
6561+ Clang intentionally does not implement the changed scoping rules from C23
6562+ for underspecified declarations. Doing so would significantly complicate the
6563+ implementation in order to get reasonable diagnostic behavior and also means
6564+ Clang fails to reject some code that should be rejected. e.g .,
6565+
6566+ .. code-block :: c
6567+
6568+ // This should be rejected because 'x' is not in scope within the initializer
6569+ // of an underspecified declaration. Clang accepts because it treats the scope
6570+ // of the identifier as beginning immediately after the declarator, same as with
6571+ // a non-underspecified declaration.
6572+ constexpr int x = sizeof(x);
65536573
6554- constexpr int i = ({ // Accepted by Clang
6555- constexpr int x = 12;
6556- constexpr struct S { int x; } s = { x };
6557- s.x;
6558- });
6559- auto x = ({ struct S { int x; } s = { 0 }; s; }); // Accepted by Clang
6574+ // Clang rejects this code with a diagnostic about using the variable within its
6575+ // own initializer rather than rejecting the code with an undeclared identifier
6576+ // diagnostic.
6577+ auto x = x;
0 commit comments