[llvm-branch-commits] [clang] 9486367 - Revert "[Clang] Diagnose UB and emit error when identifier has both internal …"

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Wed Apr 22 03:45:58 PDT 2026


Author: Aaron Ballman
Date: 2026-04-22T06:45:54-04:00
New Revision: 9486367e5bc04dedb7a40432bf6c8676963c1822

URL: https://github.com/llvm/llvm-project/commit/9486367e5bc04dedb7a40432bf6c8676963c1822
DIFF: https://github.com/llvm/llvm-project/commit/9486367e5bc04dedb7a40432bf6c8676963c1822.diff

LOG: Revert "[Clang] Diagnose UB and emit error when identifier has both internal …"

This reverts commit 1e2175ec4df79de3c18c504dea0dcbaab4b38306.

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/include/clang/Basic/DiagnosticSemaKinds.td
    clang/lib/Sema/SemaDecl.cpp
    clang/test/C/C2y/n3410.c
    clang/www/c_status.html

Removed: 
    clang/test/Sema/linkage-internal-extern.c
    clang/test/Sema/linkage-internal-extern.cpp


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index b25bc08b033d2..174731ca0a6ff 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -155,12 +155,6 @@ C Language Changes
 C2y Feature Support
 ^^^^^^^^^^^^^^^^^^^
 
-- Clang now diagnoses the use of the same identifier with both internal and
-  external linkage within a translation unit, as made ill-formed by
-  `N3410 <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3410.pdf>`_.
-  This is also diagnosed in older C language modes as the behavior was
-  undefined prior to C2y. (#GH54215)
-
 C23 Feature Support
 ^^^^^^^^^^^^^^^^^^^
 - Clang now allows C23 ``constexpr`` struct member access through the dot operator in constant expressions. (#GH178349)

diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 3ab8dd412a7ad..dc86a0b58d8f9 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -6534,9 +6534,6 @@ def err_inline_declaration_block_scope : Error<
   "inline declaration of %0 not allowed in block scope">;
 def err_static_non_static : Error<
   "static declaration of %0 follows non-static declaration">;
-def err_internal_extern_mismatch : Error<
-  "variable %0 declared with both internal and external linkage "
-  "in the same translation unit%select{; behavior is undefined|}1">;
 def err_
diff erent_language_linkage : Error<
   "declaration of %0 has a 
diff erent language linkage">;
 def ext_retained_language_linkage : Extension<

diff  --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 83f536cef913d..6afdd73328eba 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -4802,25 +4802,6 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
       return New->setInvalidDecl();
     }
   }
-
-  // C2y 6.7.1p7:
-  //   Within a translation unit, the same identifier shall not appear with
-  //   both internal and external linkage.
-  //
-  // In C11 through C23, this was undefined behavior (C11 6.2.2p7).
-  //
-  // This can occur when an extern declaration in block scope finds a file-scope
-  // static declaration, but a no-linkage local variable shadowed the static,
-  // preventing linkage inheritance per C2y 6.2.2p4.
-  if (!getLangOpts().CPlusPlus && New->isLocalVarDecl() &&
-      New->hasExternalStorage() && Old->isFileVarDecl() && Old->hasLinkage() &&
-      Previous.isShadowed() && Old->getFormalLinkage() == Linkage::Internal) {
-    Diag(New->getLocation(), diag::err_internal_extern_mismatch)
-        << New->getDeclName() << getLangOpts().C2y;
-    Diag(OldLocation, PrevDiag);
-    return New->setInvalidDecl();
-  }
-
   // C99 6.2.2p4:
   //   For an identifier declared with the storage-class specifier
   //   extern in a scope in which a prior declaration of that

diff  --git a/clang/test/C/C2y/n3410.c b/clang/test/C/C2y/n3410.c
index 7ce3c2916d300..e1cb41f375b82 100644
--- a/clang/test/C/C2y/n3410.c
+++ b/clang/test/C/C2y/n3410.c
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -verify -std=c2y -Wall -pedantic -Wno-unused %s
 
-/* WG14 N3410: Clang 23
+/* WG14 N3410: No
  * Slay Some Earthly Demons XI
  *
  * It is now ill-formed for the same identifier within a TU to have both
@@ -24,17 +24,19 @@ void func2() {
   extern int b; // Ok
 }
 
-static int c, d; // expected-note 2 {{previous definition is here}}
+static int c, d;
 void func3() {
   int c; // no linkage, 
diff erent object from the one declared above.
   for (int d;;) {
     // This 'c' is the same as the one declared at file scope, but because of
     // the local scope 'c', the file scope 'c' is not visible.
-    extern int c; // expected-error {{declared with both internal and external linkage}}
+    // FIXME: This should be diagnosed under N3410.
+    extern int c;
     // This 'd' is the same as the one declared at file scope as well, but
     // because of the 'd' declared within the for loop, the file scope 'd' is
     // also not visible, same as with 'c'.
-    extern int d; // expected-error {{declared with both internal and external linkage}}
+    // FIXME: This should be diagnosed under N3410.
+    extern int d;
   }
   for (static int e;;) {
     extern int e; // Ok for the same reason as 'b' above.

diff  --git a/clang/test/Sema/linkage-internal-extern.c b/clang/test/Sema/linkage-internal-extern.c
deleted file mode 100644
index 42591c5b21f0b..0000000000000
--- a/clang/test/Sema/linkage-internal-extern.c
+++ /dev/null
@@ -1,36 +0,0 @@
-// RUN: %clang_cc1 -verify -fsyntax-only %s
-
-// C11 6.2.2p7: same identifier with both internal and external linkage is UB.
-
-// Conflicting linkage (UB)
-
-static int x; // expected-note {{previous}}
-void test_basic_shadow(void) {
-    int x;
-    { extern int x; } // expected-error {{declared with both internal and external linkage}}
-}
-
-static int y; // expected-note {{previous}}
-void test_deep_nesting(void) {
-    int y;
-    { int y; { { extern int y; } } } // expected-error {{declared with both internal and external linkage}}
-}
-
-static int p; // expected-note {{previous}}
-void test_param_shadow(int p) {
-    { extern int p; } // expected-error {{declared with both internal and external linkage}}
-}
-
-// Valid cases
-
-static int a;
-void test_no_shadow(void) {
-    extern int a;
-}
-
-void test_no_file_scope(void) {
-    for (static int b = 0;;) {
-        extern int b;
-        break;
-    }
-}

diff  --git a/clang/test/Sema/linkage-internal-extern.cpp b/clang/test/Sema/linkage-internal-extern.cpp
deleted file mode 100644
index ab084767305fd..0000000000000
--- a/clang/test/Sema/linkage-internal-extern.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-// RUN: %clang_cc1 -verify -fsyntax-only -std=c++17 %s
-
-// expected-no-diagnostics
-
-// CWG 426 / [basic.link]p6: the same identifier with both internal and
-// external linkage should be ill-formed in C++, but Clang does not yet
-// diagnose this due to ABI break concerns. This test documents current
-// behavior.
-
-static int x;
-void test_shadow(void) {
-    int x;
-    {
-        // FIXME: Per CWG 426, this should be ill-formed because the
-        // file-scope 'x' has internal linkage but this 'extern' gets
-        // external linkage due to the local shadow.
-        extern int x;
-    }
-}

diff  --git a/clang/www/c_status.html b/clang/www/c_status.html
index 4b3695831de58..5270033471167 100644
--- a/clang/www/c_status.html
+++ b/clang/www/c_status.html
@@ -283,7 +283,7 @@ <h2 id="c2y">C2y implementation status</h2>
     <tr>
       <td>Slay Some Earthly Demons XI</td>
       <td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3410.pdf">N3410</a></td>
-      <td class="unreleased" align="center">Clang 23</td>
+      <td class="none" align="center">No</td>
 	</tr>
     <tr>
       <td>Slay Some Earthly Demons XII</td>


        


More information about the llvm-branch-commits mailing list