-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[C2y] Add test coverage and documentation for WG14 N3341 #115478
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
Conversation
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.
@llvm/pr-subscribers-clang Author: Aaron Ballman (AaronBallman) ChangesThis 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. Full diff: https://github.com/llvm/llvm-project/pull/115478.diff 4 Files Affected:
diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst
index f7285352b9deb9..4dea35d74ced07 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -5974,3 +5974,12 @@ Clang guarantees the following behaviors:
padding bits are initialized to zero.
Currently, the above extension only applies to C source code, not C++.
+
+Empty Objects in C
+==================
+The declaration of a structure or union type which has no named members is
+undefined behavior (C23 and earlier) or implementation-defined behavior (C2y).
+Clang allows the declaration of a structure or union type with no named members
+in all C language modes. `sizeof` for such a type returns `0`, which is
+different behavior than in C++ (where the size of such an object is typically
+`1`).
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index d0c43ff11f7bae..e41b9f0fab1035 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -298,6 +298,12 @@ C2y Feature Support
paper adopts Clang's existing practice, so there were no changes to compiler
behavior.
+- Implemented support for `N3341 <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3341.pdf>`_
+ which makes empty structure and union objects implementation-defined in C.
+ ``-Wgnu-empty-struct`` will be emitted in C23 and earlier modes because the
+ behavior is a conforming GNU extension in those modes, but will no longer
+ have an effect in C2y mode.
+
C23 Feature Support
^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 6b0b4840a1eb2c..61c29e320d5c73 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -19365,11 +19365,12 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
}
// Structs without named members are extension in C (C99 6.7.2.1p7),
- // but are accepted by GCC.
- if (NonBitFields == 0 && !getLangOpts().CPlusPlus) {
- Diag(RecLoc, IsEmpty ? diag::ext_empty_struct_union :
- diag::ext_no_named_members_in_struct_union)
- << Record->isUnion();
+ // but are accepted by GCC. In C2y, this became implementation-defined
+ // (C2y 6.7.3.2p10).
+ if (NonBitFields == 0 && !getLangOpts().CPlusPlus && !getLangOpts().C2y) {
+ Diag(RecLoc, IsEmpty ? diag::ext_empty_struct_union
+ : diag::ext_no_named_members_in_struct_union)
+ << Record->isUnion();
}
}
} else {
diff --git a/clang/test/C/C2y/n3341.c b/clang/test/C/C2y/n3341.c
new file mode 100644
index 00000000000000..523c3dd945ac1d
--- /dev/null
+++ b/clang/test/C/C2y/n3341.c
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -verify -std=c2y -Wall -pedantic %s
+// RUN: %clang_cc1 -verify=gnu -Wall -pedantic %s
+
+/* WG14 N3341: Yes
+ * Slay Some Earthly Demons III
+ *
+ * Empty structure and union objects are now implementation-defined.
+ */
+
+// expected-no-diagnostics
+
+struct R {}; // gnu-warning {{empty struct is a GNU extension}}
+struct S { struct { }; }; // gnu-warning {{empty struct is a GNU extension}}
+struct T { int : 0; }; // gnu-warning {{struct without named members is a GNU extension}}
+union U {}; // gnu-warning {{empty union is a GNU extension}}
+
|
@@ -191,7 +191,7 @@ <h2 id="c2y">C2y implementation status</h2> | |||
<tr> | |||
<td>Slay Some Earthly Demons III</td> | |||
<td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3341.pdf">N3341</a></td> | |||
<td class="unknown" align="center">Unknown</td> | |||
<td class="full" align="center">Yes</td> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder why the patch comes with release note, yet the official support is not claimed starting from clang 20?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It went from UB to implementation-defined, but we've always defined (and failed to document) the behavior. So there were no substantive changes in Clang 20, which is why I claimed "Yes" instead of Clang 20. The release note is mostly for user awareness about the change in diagnostic behavior.
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.
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.