[clang] [Clang] Reland "Diagnose UB and emit error when identifier has both internal and external linkage" (PR #193567)
Vlad Serebrennikov via cfe-commits
cfe-commits at lists.llvm.org
Sat Apr 25 11:26:39 PDT 2026
================
@@ -4802,6 +4802,27 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
return New->setInvalidDecl();
}
}
+
+ // C2y 6.7.1p7: an identifier shall not appear with both internal and
+ // external linkage within a translation unit. Before C2y this was UB
+ // (C11 6.2.2p7).
+ //
+ // In C, a local shadow prevents a block-scope extern from inheriting the
+ // file-scope static's internal linkage (C2y 6.2.2p4), so it defaults to
+ // external linkage, creating the conflict.
+ //
+ // In C++, block-scope extern declarations target the enclosing namespace
+ // scope ([dcl.meaning.general]/3.5), bypassing local shadows entirely, so
+ // the extern always inherits internal linkage. No conflict arises.
+ if (!getLangOpts().CPlusPlus && New->isLocalVarDecl() &&
+ New->hasExternalStorage() && Old->isFileVarDecl() && Old->hasLinkage() &&
+ Previous.isShadowed() && Old->getFormalLinkage() == Linkage::Internal) {
----------------
Endilll wrote:
> I am planning to handle this in a follow-up. MergeFunctionDecl doesn't take LookupResult &Previous as a parameter, so isShadowed() isn't available there.
In case you don't, please at least open an issue on our bug tracker, otherwise we'll lose sight of that.
https://github.com/llvm/llvm-project/pull/193567
More information about the cfe-commits
mailing list