[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