Skip to content

Commit b9ec684

Browse files
Correctly diagnose incomplete arrays with static storage in C (#134374)
A file scope declaration without an initializer which is neither extern nor thread_local is a tentative definition. If the declaration of an identifier for an object is a tentative definition and has internal linkage, the declared type shall not be an incomplete type. Clang was previously failing to diagnose this in -pedantic mode. Fixes #50661 --------- Co-authored-by: Mariya Podchishchaeva <[email protected]>
1 parent b9c876d commit b9ec684

File tree

6 files changed

+17
-10
lines changed

6 files changed

+17
-10
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,9 @@ Improvements to Clang's diagnostics
319319
- ``-Wc++98-compat`` no longer diagnoses use of ``__auto_type`` or
320320
``decltype(auto)`` as though it was the extension for ``auto``. (#GH47900)
321321

322+
- Now correctly diagnose a tentative definition of an array with static
323+
storage duration in pedantic mode in C. (#GH50661)
324+
322325
Improvements to Clang's time-trace
323326
----------------------------------
324327

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7350,8 +7350,9 @@ def err_typecheck_pointer_arith_void_type : Error<
73507350
"arithmetic on%select{ a|}0 pointer%select{|s}0 to void">;
73517351
def err_typecheck_decl_incomplete_type : Error<
73527352
"variable has incomplete type %0">;
7353-
def ext_typecheck_decl_incomplete_type : ExtWarn<
7354-
"tentative definition of variable with internal linkage has incomplete non-array type %0">,
7353+
def ext_typecheck_decl_incomplete_type : Extension<
7354+
"tentative definition of variable with internal linkage has incomplete "
7355+
"%select{non-array|array}0 type %1">,
73557356
InGroup<DiagGroup<"tentative-definition-incomplete-type">>;
73567357
def err_tentative_def_incomplete_type : Error<
73577358
"tentative definition has type %0 that is never completed">;

clang/lib/Sema/SemaDecl.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14246,7 +14246,8 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl) {
1424614246
Var->getLocation(), ArrayT->getElementType(),
1424714247
diag::err_array_incomplete_or_sizeless_type))
1424814248
Var->setInvalidDecl();
14249-
} else if (Var->getStorageClass() == SC_Static) {
14249+
}
14250+
if (Var->getStorageClass() == SC_Static) {
1425014251
// C99 6.9.2p3: If the declaration of an identifier for an object is
1425114252
// a tentative definition and has internal linkage (C99 6.2.2p3), the
1425214253
// declared type shall not be an incomplete type.
@@ -14258,7 +14259,8 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl) {
1425814259
// NOTE: to avoid multiple warnings, only check the first declaration.
1425914260
if (Var->isFirstDecl())
1426014261
RequireCompleteType(Var->getLocation(), Type,
14261-
diag::ext_typecheck_decl_incomplete_type);
14262+
diag::ext_typecheck_decl_incomplete_type,
14263+
Type->isArrayType());
1426214264
}
1426314265
}
1426414266

clang/test/C/drs/dr0xx.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,9 @@ int dr010_c = sizeof(dr010_t); /* expected-error {{invalid application of 'sizeo
139139
* Note: DR034 has a question resolved by DR011 and another question where the
140140
* result is UB.
141141
*/
142-
static int dr011_a[]; /* expected-warning {{tentative array definition assumed to have one element}} */
142+
static int dr011_a[]; /* expected-warning {{tentative array definition assumed to have one element}}
143+
expected-warning {{tentative definition of variable with internal linkage has incomplete array type 'int[]'}}
144+
*/
143145
void dr011(void) {
144146
extern int i[];
145147
{

clang/test/Sema/incomplete-decl.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,15 @@
33

44

55

6-
struct foo; // c-note 5 {{forward declaration of 'struct foo'}} \
6+
struct foo; // c-note 4 {{forward declaration of 'struct foo'}} \
77
cxx-note 3 {{forward declaration of 'foo'}}
88

99
void b; // expected-error {{variable has incomplete type 'void'}}
1010
struct foo f; // c-error {{tentative definition has type 'struct foo' that is never completed}} \
1111
cxx-error {{variable has incomplete type 'struct foo'}}
1212

1313
static void c; // expected-error {{variable has incomplete type 'void'}}
14-
static struct foo g; // c-warning {{tentative definition of variable with internal linkage has incomplete non-array type 'struct foo'}} \
15-
c-error {{tentative definition has type 'struct foo' that is never completed}} \
14+
static struct foo g; // c-error {{tentative definition has type 'struct foo' that is never completed}} \
1615
cxx-error {{variable has incomplete type 'struct foo'}}
1716

1817
extern void d; // cxx-error {{variable has incomplete type 'void'}}

clang/test/Sema/tentative-decls.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %clang_cc1 %s -fsyntax-only -Wprivate-extern -verify
1+
// RUN: %clang_cc1 %s -fsyntax-only -Wprivate-extern -pedantic -verify
22

33
// PR3310
44
struct a x1; // expected-note 2{{forward declaration of 'struct a'}}
@@ -58,7 +58,7 @@ void func2(void)
5858
extern double *p;
5959
}
6060

61-
static int a0[];
61+
static int a0[]; // expected-warning {{tentative definition of variable with internal linkage has incomplete array type 'int[]'}}
6262
static int b0;
6363

6464
static int a0[] = { 4 };

0 commit comments

Comments
 (0)