[clang] Diagnose redeclaration with different linkage (PR #178900)

via cfe-commits cfe-commits at lists.llvm.org
Fri Jan 30 07:05:15 PST 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Arbaaz Ahmed (Arbaaz123676)

<details>
<summary>Changes</summary>

Hi @<!-- -->llvmbot,
Clang currently accepts a variable redeclaration with conflicting linkage (internal vs external) in the same translation unit without issuing a diagnostic.

According to the C++ standard, redeclaring an entity with a different linkage in the same translation unit is ill-formed and requires a diagnostic.

This patch adds a diagnostic in Sema::CheckVariableDeclaration to detect conflicting linkage during variable redeclaration and marks the declaration invalid. A regression test is added to ensure correct behavior.

Note: Local check-clang reports unrelated failures on macOS; the added test passes.
#<!-- -->178863

---
Full diff: https://github.com/llvm/llvm-project/pull/178900.diff


3 Files Affected:

- (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+2) 
- (modified) clang/lib/Sema/SemaDecl.cpp (+14-2) 
- (added) clang/test/SemaCXX/redecl-linkage.cpp (+5) 


``````````diff
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 807440c107897..3149142e1a86e 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -6291,6 +6291,8 @@ def note_static_for_internal_linkage : Note<
 def err_static_data_member_reinitialization :
   Error<"static data member %0 already has an initializer">;
 def err_redefinition : Error<"redefinition of %0">;
+def err_redefinition_different_linkage :
+  Error<"redeclaration of %0 with different linkage">;
 def err_alias_after_tentative :
   Error<"alias definition of %0 after tentative definition">;
 def err_alias_is_definition :
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 3b2c93b9fe7b5..7a445ab10fe25 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -9210,9 +9210,21 @@ bool Sema::CheckVariableDeclaration(VarDecl *NewVD, LookupResult &Previous) {
     Previous.setShadowed();
 
   if (!Previous.empty()) {
-    MergeVarDecl(NewVD, Previous);
-    return true;
+  if (auto *OldDecl =
+          dyn_cast<VarDecl>(Previous.getFoundDecl())) {
+    if (OldDecl->getFormalLinkage() != NewVD->getFormalLinkage()) {
+      Diag(NewVD->getLocation(),
+           diag::err_redefinition_different_linkage)
+          << NewVD->getName();
+      NewVD->setInvalidDecl();
+      return true;
+    }
   }
+
+  MergeVarDecl(NewVD, Previous);
+  return true;
+}
+
   return false;
 }
 
diff --git a/clang/test/SemaCXX/redecl-linkage.cpp b/clang/test/SemaCXX/redecl-linkage.cpp
new file mode 100644
index 0000000000000..53cc35e878cd0
--- /dev/null
+++ b/clang/test/SemaCXX/redecl-linkage.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -std=c++17 %s -verify
+
+static int k = 3;
+extern int k; // expected-error {{redeclaration of k with different linkage}}
+

``````````

</details>


https://github.com/llvm/llvm-project/pull/178900


More information about the cfe-commits mailing list