Skip to content

Commit 5a9ac55

Browse files
committed
[C2y] Add test coverage and documentation for WG14 N3341
This paper made empty structures and unions implementation-defined. We have always supported this as a GNU extension, so now we're documenting our behavior and removing the extension warning in C2y mode.
1 parent 0daca80 commit 5a9ac55

File tree

4 files changed

+37
-5
lines changed

4 files changed

+37
-5
lines changed

clang/docs/LanguageExtensions.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5974,3 +5974,12 @@ Clang guarantees the following behaviors:
59745974
padding bits are initialized to zero.
59755975
59765976
Currently, the above extension only applies to C source code, not C++.
5977+
5978+
Empty Objects in C
5979+
==================
5980+
The declaration of a structure or union type which has no named members is
5981+
undefined behavior (C23 and earlier) or implementation-defined behavior (C2y).
5982+
Clang allows the declaration of a structure or union type with no named members
5983+
in all C language modes. `sizeof` for such a type returns `0`, which is
5984+
different behavior than in C++ (where the size of such an object is typically
5985+
`1`).

clang/docs/ReleaseNotes.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,12 @@ C2y Feature Support
298298
paper adopts Clang's existing practice, so there were no changes to compiler
299299
behavior.
300300

301+
- Implemented support for `N3341 <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3341.pdf>`_
302+
which makes empty structure and union objects implementation-defined in C.
303+
``-Wgnu-empty-struct`` will be emitted in C23 and earlier modes because the
304+
behavior is a conforming GNU extension in those modes, but will no longer
305+
have an effect in C2y mode.
306+
301307
C23 Feature Support
302308
^^^^^^^^^^^^^^^^^^^
303309

clang/lib/Sema/SemaDecl.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19365,11 +19365,12 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
1936519365
}
1936619366

1936719367
// Structs without named members are extension in C (C99 6.7.2.1p7),
19368-
// but are accepted by GCC.
19369-
if (NonBitFields == 0 && !getLangOpts().CPlusPlus) {
19370-
Diag(RecLoc, IsEmpty ? diag::ext_empty_struct_union :
19371-
diag::ext_no_named_members_in_struct_union)
19372-
<< Record->isUnion();
19368+
// but are accepted by GCC. In C2y, this became implementation-defined
19369+
// (C2y 6.7.3.2p10).
19370+
if (NonBitFields == 0 && !getLangOpts().CPlusPlus && !getLangOpts().C2y) {
19371+
Diag(RecLoc, IsEmpty ? diag::ext_empty_struct_union
19372+
: diag::ext_no_named_members_in_struct_union)
19373+
<< Record->isUnion();
1937319374
}
1937419375
}
1937519376
} else {

clang/test/C/C2y/n3341.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// RUN: %clang_cc1 -verify -std=c2y -Wall -pedantic %s
2+
// RUN: %clang_cc1 -verify=gnu -Wall -pedantic %s
3+
4+
/* WG14 N3341: Yes
5+
* Slay Some Earthly Demons III
6+
*
7+
* Empty structure and union objects are now implementation-defined.
8+
*/
9+
10+
// expected-no-diagnostics
11+
12+
struct R {}; // gnu-warning {{empty struct is a GNU extension}}
13+
struct S { struct { }; }; // gnu-warning {{empty struct is a GNU extension}}
14+
struct T { int : 0; }; // gnu-warning {{struct without named members is a GNU extension}}
15+
union U {}; // gnu-warning {{empty union is a GNU extension}}
16+

0 commit comments

Comments
 (0)