diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -116,6 +116,9 @@ - Correctly diagnose a future keyword if it exist as a keyword in the higher language version and specifies in which version it will be a keyword. This supports both c and c++ language. +- Clang will now give a new more accurate diagnostic for declaration of block + scope identifiers that have internal linkage that has an initializer. + Fixes `Issue 57478: `_. Non-comprehensive list of changes in this release ------------------------------------------------- diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -5896,6 +5896,9 @@ "'loader_uninitialized' attribute">; def err_block_extern_cant_init : Error< "'extern' variable cannot have an initializer">; +def err_block_internal_linkage_no_init : Error< + "declaration of block scope identifier with internal linkage shall " + "have no initializer">; def warn_extern_init : Warning<"'extern' variable has an initializer">, InGroup>; def err_variable_object_no_init : Error< diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -12771,9 +12771,14 @@ return; } + // C99 6.7.8p5. C++ has no such restriction, but that is a defect. if (VDecl->isLocalVarDecl() && VDecl->hasExternalStorage()) { - // C99 6.7.8p5. C++ has no such restriction, but that is a defect. - Diag(VDecl->getLocation(), diag::err_block_extern_cant_init); + unsigned DiagKind = diag::err_block_extern_cant_init; + // C2x 6.7.10p6. + if (VDecl->getFormalLinkage() == InternalLinkage) + DiagKind = diag::err_block_internal_linkage_no_init; + + Diag(VDecl->getLocation(), DiagKind); VDecl->setInvalidDecl(); return; } diff --git a/clang/test/Sema/error-decl-block-internal-linkage-no-init.c b/clang/test/Sema/error-decl-block-internal-linkage-no-init.c new file mode 100644 --- /dev/null +++ b/clang/test/Sema/error-decl-block-internal-linkage-no-init.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fsyntax-only -verify %s +static int x; + +void f(void) +{ + extern int x = 1; // expected-error {{declaration of block scope identifier with internal linkage shall have no initializer}} +}