Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
4 changes: 4 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,10 @@ C Language Changes

C2y Feature Support
^^^^^^^^^^^^^^^^^^^
- Implement `WG14 N3409 <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3409.pdf>`_
which removes UB around use of ``void`` expressions. In practice, this means
that ``_Generic`` selection associations may now have ``void`` type, but it
also removes UB with code like ``(void)(void)1;``.
- Implemented `WG14 N3411 <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3411.pdf>`_
which allows a source file to not end with a newline character. This is still
reported as a conforming extension in earlier language modes.
Expand Down
9 changes: 7 additions & 2 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -10425,8 +10425,13 @@ def warn_type_safety_null_pointer_required : Warning<
"specified %0 type tag requires a null pointer">, InGroup<TypeSafety>;

// Generic selections.
def err_assoc_type_incomplete : Error<
"type %0 in generic association incomplete">;
def ext_assoc_type_incomplete : Extension<
"ISO C requires a complete type in a '_Generic' association; %0 is an "
"incomplete type">;
def warn_c2y_compat_assoc_type_incomplete : Warning<
"use of an incomplete type in a '_Generic' association is incompatible with "
"C standards before C2y; %0 is an incomplete type">,
InGroup<CPre2yCompat>, DefaultIgnore;
def err_assoc_type_nonobject : Error<
"type %0 in generic association not an object type">;
def err_assoc_type_variably_modified : Error<
Expand Down
7 changes: 6 additions & 1 deletion clang/lib/Sema/SemaExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1748,9 +1748,14 @@ ExprResult Sema::CreateGenericSelectionExpr(
//
// C11 6.5.1.1p2 "The type name in a generic association shall specify a
// complete object type other than a variably modified type."
// C2y removed the requirement that an expression form must
// use a complete type, though it's still as-if the type has undergone
// lvalue conversion. We support this as an extension in C23 and
// earlier because GCC does so.
unsigned D = 0;
if (ControllingExpr && Types[i]->getType()->isIncompleteType())
D = diag::err_assoc_type_incomplete;
D = LangOpts.C2y ? diag::warn_c2y_compat_assoc_type_incomplete
: diag::ext_assoc_type_incomplete;
else if (ControllingExpr && !Types[i]->getType()->isObjectType())
D = diag::err_assoc_type_nonobject;
else if (Types[i]->getType()->isVariablyModifiedType())
Expand Down
32 changes: 32 additions & 0 deletions clang/test/C/C2y/n3409.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// RUN: %clang_cc1 -verify -std=c2y -pedantic %s
// RUN: %clang_cc1 -verify=pre-c2y -std=c2y -Wpre-c2y-compat %s
// RUN: %clang_cc1 -verify=ext -std=c23 -pedantic %s
// expected-no-diagnostics

/* WG14 N3409: Clang 21
* Slay Some Earthly Demons X
*
* Removes the requirement that an expression with type void cannot be used in
* any way. This was making it UB to use a void expression in a _Generic
* selection expression for no good reason, as well as making it UB to cast a
* void expression to void, etc.
*/

extern void x;
void foo() {
// FIXME: this is technically an extension before C2y and should be diagnosed
// under -pedantic.
(void)(void)1;
// FIXME: same with this.
x;
_Generic(x, void: 1); /* pre-c2y-warning {{use of an incomplete type in a '_Generic' association is incompatible with C standards before C2y; 'void' is an incomplete type}}
ext-warning {{ISO C requires a complete type in a '_Generic' association; 'void' is an incomplete type}}
*/
_Generic(x, typeof(x): 1); /* pre-c2y-warning {{use of an incomplete type in a '_Generic' association is incompatible with C standards before C2y; 'typeof (x)' (aka 'void') is an incomplete type}}
ext-warning {{ISO C requires a complete type in a '_Generic' association; 'typeof (x)' (aka 'void') is an incomplete type}}
*/
(void)_Generic(void, default : 1); /* pre-c2y-warning {{passing a type argument as the first operand to '_Generic' is incompatible with C standards before C2y}}
ext-warning {{passing a type argument as the first operand to '_Generic' is a C2y extension}}
*/
}

Loading