junaire updated this revision to Diff 459394.
junaire added a comment.

Rebase, adjust commit message and release note.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133088/new/

https://reviews.llvm.org/D133088

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDecl.cpp
  clang/test/Parser/cxx1z-decomposition.cpp
  clang/test/Sema/array-init.c
  clang/test/Sema/err-decl-block-extern-no-init.c
  clang/test/Sema/private-extern.c

Index: clang/test/Sema/private-extern.c
===================================================================
--- clang/test/Sema/private-extern.c
+++ clang/test/Sema/private-extern.c
@@ -69,9 +69,9 @@
 struct s0 { int x; };
 
 void f9(void) {
-  extern int g15 = 0; // expected-error{{'extern' variable cannot have an initializer}}
+  extern int g15 = 0; // expected-error{{declaration of block scope identifier with linkage cannot have an initializer}}
   // FIXME: linkage specifier in warning.
-  __private_extern__ int g16 = 0; // expected-error{{'extern' variable cannot have an initializer}}
+  __private_extern__ int g16 = 0; // expected-error{{declaration of block scope identifier with linkage cannot have an initializer}}
 }
 
 extern int g17;
Index: clang/test/Sema/err-decl-block-extern-no-init.c
===================================================================
--- /dev/null
+++ clang/test/Sema/err-decl-block-extern-no-init.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fsyntax-only -verify %s
+static int x;
+
+void foo(void)
+{
+    extern int x = 1; // expected-error {{declaration of block scope identifier with linkage cannot have an initializer}}
+}
+
+int y;
+
+void bar(void)
+{
+    extern int y = 1; // expected-error {{declaration of block scope identifier with linkage cannot have an initializer}}
+
+}
Index: clang/test/Sema/array-init.c
===================================================================
--- clang/test/Sema/array-init.c
+++ clang/test/Sema/array-init.c
@@ -48,7 +48,7 @@
 
   struct threeElements *p = 7; // expected-error{{incompatible integer to pointer conversion initializing 'struct threeElements *' with an expression of type 'int'}}
 
-  extern int blockScopeExtern[3] = { 1, 3, 5 }; // expected-error{{'extern' variable cannot have an initializer}}
+  extern int blockScopeExtern[3] = { 1, 3, 5 }; // expected-error{{declaration of block scope identifier with linkage cannot have an initializer}}
 
   static long x2[3] = { 1.0,
                         "abc", // expected-error{{incompatible pointer to integer conversion initializing 'long' with an expression of type 'char[4]'}}
Index: clang/test/Parser/cxx1z-decomposition.cpp
===================================================================
--- clang/test/Parser/cxx1z-decomposition.cpp
+++ clang/test/Parser/cxx1z-decomposition.cpp
@@ -69,7 +69,7 @@
     // storage-class-specifiers
     static auto &[a] = n; // expected-warning {{declared 'static' is a C++20 extension}}
     thread_local auto &[b] = n; // expected-warning {{declared 'thread_local' is a C++20 extension}}
-    extern auto &[c] = n; // expected-error {{cannot be declared 'extern'}} expected-error {{cannot have an initializer}}
+    extern auto &[c] = n; // expected-error {{cannot be declared 'extern'}} expected-error {{declaration of block scope identifier with linkage cannot have an initializer}}
     struct S {
       mutable auto &[d] = n; // expected-error {{not permitted in this context}}
 
Index: clang/lib/Sema/SemaDecl.cpp
===================================================================
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -12773,8 +12773,11 @@
     return;
   }
 
+  // C99 6.7.8p5. If the declaration of an identifier has block scope, and
+  // the identifier has external or internal linkage, the declaration shall
+  // have no initializer for the identifier.
+  // C++14 [dcl.init]p5 is the same restriction for C++.
   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);
     VDecl->setInvalidDecl();
     return;
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -5901,7 +5901,7 @@
     : Error<"variable %0 cannot be declared both 'extern' and with the "
             "'loader_uninitialized' attribute">;
 def err_block_extern_cant_init : Error<
-  "'extern' variable cannot have an initializer">;
+  "declaration of block scope identifier with linkage cannot have an initializer">;
 def warn_extern_init : Warning<"'extern' variable has an initializer">,
   InGroup<DiagGroup<"extern-initializer">>;
 def err_variable_object_no_init : Error<
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -136,6 +136,10 @@
 - no_sanitize("...") on a global variable for known but not relevant sanitizers
   is now just a warning. It now says that this will be ignored instead of
   incorrectly saying no_sanitize only applies to functions and methods.
+- Clang will now give a more suitale diagnostic for declaration of block
+  scope identifiers that have external/internal linkage that has an initializer.
+  Fixes `Issue 57478: <https://github.com/llvm/llvm-project/issues/57478>`_.
+
 
 Non-comprehensive list of changes in this release
 -------------------------------------------------
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to