Skip to content

Commit af34ac4

Browse files
authored
[Clang] [Sema] No longer diagnose type definitions in offsetof in C23 mode (#84169)
This is now allowed in C23; continue to diagnose it in earlier language modes as before, but now as a C23 extension rather than a GNU extension. This fixes #83658.
1 parent 661bb9d commit af34ac4

File tree

5 files changed

+23
-15
lines changed

5 files changed

+23
-15
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,9 @@ Improvements to Clang's diagnostics
307307
- ``-Wmicrosoft``, ``-Wgnu``, or ``-pedantic`` is now required to diagnose C99
308308
flexible array members in a union or alone in a struct. Fixes GH#84565.
309309

310+
- Clang now no longer diagnoses type definitions in ``offsetof`` in C23 mode.
311+
Fixes #GH83658.
312+
310313
Improvements to Clang's time-trace
311314
----------------------------------
312315

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1748,8 +1748,8 @@ def err_type_defined_in_condition : Error<
17481748
def err_type_defined_in_enum : Error<
17491749
"%0 cannot be defined in an enumeration">;
17501750
def ext_type_defined_in_offsetof : Extension<
1751-
"defining a type within '%select{__builtin_offsetof|offsetof}0' is a Clang "
1752-
"extension">, InGroup<GNUOffsetofExtensions>;
1751+
"defining a type within '%select{__builtin_offsetof|offsetof}0' is a C23 "
1752+
"extension">, InGroup<C23>;
17531753

17541754
def note_pure_virtual_function : Note<
17551755
"unimplemented pure virtual method %0 in %1">;

clang/lib/Sema/SemaDecl.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18170,7 +18170,9 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc,
1817018170
cast_or_null<RecordDecl>(PrevDecl));
1817118171
}
1817218172

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

clang/test/C/C2x/n2350.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,18 @@
55
// RUN: %clang_cc1 -fsyntax-only -pedantic -Wno-comment -std=c99 -verify %s
66
// RUN: %clang_cc1 -fsyntax-only -pedantic -Wno-comment -std=c11 -verify %s
77
// RUN: %clang_cc1 -fsyntax-only -pedantic -Wno-comment -std=c17 -verify %s
8-
// RUN: %clang_cc1 -fsyntax-only -pedantic -Wno-comment -std=c2x -verify %s
8+
// RUN: %clang_cc1 -fsyntax-only -pedantic -Wno-comment -std=c2x -verify=silent %s
99

1010
// silent-no-diagnostics
1111

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

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

4848
int macro(void) {
4949
return offsetof(struct A // cpp-error {{'A' cannot be defined in a type specifier}} \
50-
expected-warning 2 {{defining a type within 'offsetof' is a Clang extension}}
50+
expected-warning 2 {{defining a type within 'offsetof' is a C23 extension}}
5151
{
5252
int a;
5353
struct B // verifier seems to think the error is emitted by the macro

clang/test/C/drs/dr4xx.c

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
/* RUN: %clang_cc1 -std=c89 -verify=expected,c89only -pedantic -Wno-c11-extensions %s
2-
RUN: %clang_cc1 -std=c99 -verify=expected -pedantic -Wno-c11-extensions %s
3-
RUN: %clang_cc1 -std=c11 -verify=expected -pedantic %s
4-
RUN: %clang_cc1 -std=c17 -verify=expected -pedantic %s
1+
/* RUN: %clang_cc1 -std=c89 -verify=expected,c89only,pre-c23 -pedantic -Wno-c11-extensions %s
2+
RUN: %clang_cc1 -std=c99 -verify=expected,pre-c23 -pedantic -Wno-c11-extensions %s
3+
RUN: %clang_cc1 -std=c11 -verify=expected,pre-c23 -pedantic %s
4+
RUN: %clang_cc1 -std=c17 -verify=expected,pre-c23 -pedantic %s
55
RUN: %clang_cc1 -std=c2x -verify=expected -pedantic %s
66
*/
77

@@ -343,10 +343,13 @@ void dr496(void) {
343343
*/
344344

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

352355
/* WG14 DR499: yes

0 commit comments

Comments
 (0)