Skip to content

Commit ecb0edd

Browse files
committed
Appended new C23 scoping rules in documendation
1 parent debe0f6 commit ecb0edd

File tree

1 file changed

+33
-15
lines changed

1 file changed

+33
-15
lines changed

clang/docs/LanguageExtensions.rst

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)