https://github.com/AaronBallman created https://github.com/llvm/llvm-project/pull/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 >From 753208a20b2a4caf6186fa647c4abfef546e5685 Mon Sep 17 00:00:00 2001 From: Aaron Ballman <aa...@aaronballman.com> Date: Fri, 4 Apr 2025 08:29:55 -0400 Subject: [PATCH] Correctly diagnose incomplete arrays with static storage in C 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 --- clang/docs/ReleaseNotes.rst | 3 +++ clang/include/clang/Basic/DiagnosticSemaKinds.td | 5 +++-- clang/lib/Sema/SemaDecl.cpp | 6 ++++-- clang/test/C/drs/dr0xx.c | 4 +++- clang/test/Sema/incomplete-decl.c | 5 ++--- clang/test/Sema/tentative-decls.c | 4 ++-- 6 files changed, 17 insertions(+), 10 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 3055394dd8b6c..d913221f99a04 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -319,6 +319,9 @@ Improvements to Clang's diagnostics - ``-Wc++98-compat`` no longer diagnoses use of ``__auto_type`` or ``decltype(auto)`` as though it was the extension for ``auto``. (#GH47900) +- Now correctly diagnose use of a tentative definition of an array with static + storage duration in pedantic mode in C. (#GH50661) + Improvements to Clang's time-trace ---------------------------------- diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 52dc477039129..bcb3ea5d04cd1 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -7346,8 +7346,9 @@ def err_typecheck_pointer_arith_void_type : Error< "arithmetic on%select{ a|}0 pointer%select{|s}0 to void">; def err_typecheck_decl_incomplete_type : Error< "variable has incomplete type %0">; -def ext_typecheck_decl_incomplete_type : ExtWarn< - "tentative definition of variable with internal linkage has incomplete non-array type %0">, +def ext_typecheck_decl_incomplete_type : Extension< + "tentative definition of variable with internal linkage has incomplete " + "%select{non-array|array}0 type %1">, InGroup<DiagGroup<"tentative-definition-incomplete-type">>; def err_tentative_def_incomplete_type : Error< "tentative definition has type %0 that is never completed">; diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 9b7b3f856cc55..35de4e8a47e18 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -14246,7 +14246,8 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl) { Var->getLocation(), ArrayT->getElementType(), diag::err_array_incomplete_or_sizeless_type)) Var->setInvalidDecl(); - } else if (Var->getStorageClass() == SC_Static) { + } + if (Var->getStorageClass() == SC_Static) { // C99 6.9.2p3: If the declaration of an identifier for an object is // a tentative definition and has internal linkage (C99 6.2.2p3), the // declared type shall not be an incomplete type. @@ -14258,7 +14259,8 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl) { // NOTE: to avoid multiple warnings, only check the first declaration. if (Var->isFirstDecl()) RequireCompleteType(Var->getLocation(), Type, - diag::ext_typecheck_decl_incomplete_type); + diag::ext_typecheck_decl_incomplete_type, + Type->isArrayType()); } } diff --git a/clang/test/C/drs/dr0xx.c b/clang/test/C/drs/dr0xx.c index 252dc9329c4ca..5fe023deaece9 100644 --- a/clang/test/C/drs/dr0xx.c +++ b/clang/test/C/drs/dr0xx.c @@ -139,7 +139,9 @@ int dr010_c = sizeof(dr010_t); /* expected-error {{invalid application of 'sizeo * Note: DR034 has a question resolved by DR011 and another question where the * result is UB. */ -static int dr011_a[]; /* expected-warning {{tentative array definition assumed to have one element}} */ +static int dr011_a[]; /* expected-warning {{tentative array definition assumed to have one element}} + expected-warning {{tentative definition of variable with internal linkage has incomplete array type 'int[]'}} + */ void dr011(void) { extern int i[]; { diff --git a/clang/test/Sema/incomplete-decl.c b/clang/test/Sema/incomplete-decl.c index bf2890bba9911..f8f234c6b7828 100644 --- a/clang/test/Sema/incomplete-decl.c +++ b/clang/test/Sema/incomplete-decl.c @@ -3,7 +3,7 @@ -struct foo; // c-note 5 {{forward declaration of 'struct foo'}} \ +struct foo; // c-note 4 {{forward declaration of 'struct foo'}} \ cxx-note 3 {{forward declaration of 'foo'}} void b; // expected-error {{variable has incomplete type 'void'}} @@ -11,8 +11,7 @@ struct foo f; // c-error {{tentative definition has type 'struct foo' that is ne cxx-error {{variable has incomplete type 'struct foo'}} static void c; // expected-error {{variable has incomplete type 'void'}} -static struct foo g; // c-warning {{tentative definition of variable with internal linkage has incomplete non-array type 'struct foo'}} \ - c-error {{tentative definition has type 'struct foo' that is never completed}} \ +static struct foo g; // c-error {{tentative definition has type 'struct foo' that is never completed}} \ cxx-error {{variable has incomplete type 'struct foo'}} extern void d; // cxx-error {{variable has incomplete type 'void'}} diff --git a/clang/test/Sema/tentative-decls.c b/clang/test/Sema/tentative-decls.c index 713e65f3d9b35..94d21bdbf94da 100644 --- a/clang/test/Sema/tentative-decls.c +++ b/clang/test/Sema/tentative-decls.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -fsyntax-only -Wprivate-extern -verify +// RUN: %clang_cc1 %s -fsyntax-only -Wprivate-extern -pedantic -verify // PR3310 struct a x1; // expected-note 2{{forward declaration of 'struct a'}} @@ -58,7 +58,7 @@ void func2(void) extern double *p; } -static int a0[]; +static int a0[]; // expected-warning {{tentative definition of variable with internal linkage has incomplete array type 'int[]'}} static int b0; static int a0[] = { 4 }; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits