Skip to content

[Clang] [Sema] No longer diagnose type definitions in offsetof in C23 mode #84169

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

Merged
merged 3 commits into from
Mar 29, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
3 changes: 3 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,9 @@ Improvements to Clang's diagnostics
- ``-Wmicrosoft``, ``-Wgnu``, or ``-pedantic`` is now required to diagnose C99
flexible array members in a union or alone in a struct. Fixes GH#84565.

- Clang now no longer diagnoses type definitions in ``offsetof`` in C23 mode.
Fixes #GH83658.

Improvements to Clang's time-trace
----------------------------------

Expand Down
4 changes: 2 additions & 2 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -1748,8 +1748,8 @@ def err_type_defined_in_condition : Error<
def err_type_defined_in_enum : Error<
"%0 cannot be defined in an enumeration">;
def ext_type_defined_in_offsetof : Extension<
"defining a type within '%select{__builtin_offsetof|offsetof}0' is a Clang "
"extension">, InGroup<GNUOffsetofExtensions>;
"defining a type within '%select{__builtin_offsetof|offsetof}0' is a C23 "
"extension">, InGroup<C23>;

def note_pure_virtual_function : Note<
"unimplemented pure virtual method %0 in %1">;
Expand Down
4 changes: 3 additions & 1 deletion clang/lib/Sema/SemaDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18170,7 +18170,9 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc,
cast_or_null<RecordDecl>(PrevDecl));
}

if (OOK != OOK_Outside && TUK == TUK_Definition && !getLangOpts().CPlusPlus)
// Only C23 and later allow defining new types in 'offsetof()'.
if (OOK != OOK_Outside && TUK == TUK_Definition && !getLangOpts().CPlusPlus &&
!getLangOpts().C23)
Diag(New->getLocation(), diag::ext_type_defined_in_offsetof)
<< (OOK == OOK_Macro) << New->getSourceRange();

Expand Down
10 changes: 5 additions & 5 deletions clang/test/C/C2x/n2350.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@
// RUN: %clang_cc1 -fsyntax-only -pedantic -Wno-comment -std=c99 -verify %s
// RUN: %clang_cc1 -fsyntax-only -pedantic -Wno-comment -std=c11 -verify %s
// RUN: %clang_cc1 -fsyntax-only -pedantic -Wno-comment -std=c17 -verify %s
// RUN: %clang_cc1 -fsyntax-only -pedantic -Wno-comment -std=c2x -verify %s
// RUN: %clang_cc1 -fsyntax-only -pedantic -Wno-comment -std=c2x -verify=silent %s

// silent-no-diagnostics

// Reject definitions in __builtin_offsetof
// https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2350.htm
int simple(void) {
return __builtin_offsetof(struct A // cpp-error {{'A' cannot be defined in a type specifier}} \
expected-warning {{defining a type within '__builtin_offsetof' is a Clang extension}}
expected-warning {{defining a type within '__builtin_offsetof' is a C23 extension}}
{
int a;
struct B // expected-warning {{defining a type within '__builtin_offsetof' is a Clang extension}}
struct B // expected-warning {{defining a type within '__builtin_offsetof' is a C23 extension}}
{
int c;
int d;
Expand All @@ -26,7 +26,7 @@ int simple(void) {

int anonymous_struct(void) {
return __builtin_offsetof(struct // cpp-error-re {{'(unnamed struct at {{.*}})' cannot be defined in a type specifier}} \
expected-warning {{defining a type within '__builtin_offsetof' is a Clang extension}}
expected-warning {{defining a type within '__builtin_offsetof' is a C23 extension}}
{
int a;
int b;
Expand All @@ -47,7 +47,7 @@ int struct_in_second_param(void) {

int macro(void) {
return offsetof(struct A // cpp-error {{'A' cannot be defined in a type specifier}} \
expected-warning 2 {{defining a type within 'offsetof' is a Clang extension}}
expected-warning 2 {{defining a type within 'offsetof' is a C23 extension}}
{
int a;
struct B // verifier seems to think the error is emitted by the macro
Expand Down
17 changes: 10 additions & 7 deletions clang/test/C/drs/dr4xx.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* RUN: %clang_cc1 -std=c89 -verify=expected,c89only -pedantic -Wno-c11-extensions %s
RUN: %clang_cc1 -std=c99 -verify=expected -pedantic -Wno-c11-extensions %s
RUN: %clang_cc1 -std=c11 -verify=expected -pedantic %s
RUN: %clang_cc1 -std=c17 -verify=expected -pedantic %s
/* RUN: %clang_cc1 -std=c89 -verify=expected,c89only,pre-c23 -pedantic -Wno-c11-extensions %s
RUN: %clang_cc1 -std=c99 -verify=expected,pre-c23 -pedantic -Wno-c11-extensions %s
RUN: %clang_cc1 -std=c11 -verify=expected,pre-c23 -pedantic %s
RUN: %clang_cc1 -std=c17 -verify=expected,pre-c23 -pedantic %s
RUN: %clang_cc1 -std=c2x -verify=expected -pedantic %s
*/

Expand Down Expand Up @@ -343,10 +343,13 @@ void dr496(void) {
*/

/* The DR asked a question about whether defining a new type within offsetof
* is allowed. C2x N2350 made this explicitly undefined behavior, but GCC and
* Clang both support it as an extension.
* is allowed. C23 N2350 had made this explicitly undefined behavior, but this
* was later overturned when C23 DE-137 was accepted, making it well-formed.
*
* Additionally, GCC and Clang both support it as an extension in pre-C23
* mode.
*/
(void)__builtin_offsetof(struct S { int a; }, a); /* expected-warning{{defining a type within '__builtin_offsetof' is a Clang extension}} */
(void)__builtin_offsetof(struct S { int a; }, a); /* pre-c23-warning{{defining a type within '__builtin_offsetof' is a C23 extension}} */
}

/* WG14 DR499: yes
Expand Down