https://github.com/keepyixiao updated https://github.com/llvm/llvm-project/pull/223124
>From 8e91d4cec9718746258fb632eac5f73b6792d66a Mon Sep 17 00:00:00 2001 From: yixiao <[email protected]> Date: Sat, 12 Sep 2026 13:50:35 +0800 Subject: [PATCH] [Clang] Avoid assertion failure for initialized extern aliases Attributes are processed before the initializer is attached to the VarDecl, so an initialized extern variable appears declaration-only in handleAliasAttr() and can reach a late assertion. Use Declarator::hasInitializer() and VarDecl::hasExternalStorage() to diagnose and drop the alias during attribute processing. Keep the late assertion as an invariant check, and add a regression test and release note. --- clang/docs/ReleaseNotes.md | 4 ++++ clang/lib/Sema/SemaDeclAttr.cpp | 14 ++++++++++++++ clang/test/Sema/alias-redefinition.c | 5 +++++ 3 files changed, 23 insertions(+) diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index 59b5c14c59242..1ba85521baeb3 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -536,6 +536,10 @@ features cannot lower the translation-unit ABI level; written after the declarator-id, where it appertains to the declared entity rather than to a declarator chunk. (#GH196982, #GH111463) +- Fixed an assertion failure when the `alias` attribute was applied to an + `extern` variable with an initializer. Clang now correctly diagnoses that + such a declaration is a definition and cannot also be an alias. + #### Bug Fixes to C++ Support - Fixed false-positive module ODR diagnostics when a type is found through a diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index eb4a8c2ab9ae0..ffa0cddb5de92 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -8907,6 +8907,20 @@ void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) { // Look for API notes that map to attributes. ProcessAPINotes(D); + + // An initializer makes a variable declaration incompatible with an alias + // attribute. Attributes are processed before the initializer is attached to + // the VarDecl, so an extern variable with an initializer still appears to be + // a declaration in handleAliasAttr(). Use the information recorded by the + // parser and do not let the AliasAttr escape attribute processing. + if (auto *VD = dyn_cast<VarDecl>(D)) { + if (PD.hasInitializer() && VD->hasExternalStorage()) { + if (const auto *Attr = VD->getAttr<AliasAttr>()) { + Diag(Attr->getLocation(), diag::err_alias_is_definition) << VD << 0; + VD->dropAttr<AliasAttr>(); + } + } + } } /// Is the given declaration allowed to use a forbidden type? diff --git a/clang/test/Sema/alias-redefinition.c b/clang/test/Sema/alias-redefinition.c index 526b67d9be7f2..6ecfdf957af9a 100644 --- a/clang/test/Sema/alias-redefinition.c +++ b/clang/test/Sema/alias-redefinition.c @@ -24,6 +24,11 @@ void __attribute((alias("f5"))) fun5(void) {} // expected-error {{definition 'fu int var1 __attribute((alias("v1"))); // expected-error {{definition 'var1' cannot also be an alias}} static int var2 __attribute((alias("v2"))) = 2; // expected-error {{definition 'var2' cannot also be an alias}} +extern int var_with_extern_initializer __attribute__((alias(""))) = 42; // expected-error {{definition 'var_with_extern_initializer' cannot also be an alias}} +// expected-warning@-1 {{'extern' variable has an initializer}} +extern int var_with_extern_initializer1 __attribute__((alias("v1"))) = 42; // expected-error {{definition 'var_with_extern_initializer1' cannot also be an alias}} +// expected-warning@-1 {{'extern' variable has an initializer}} + extern int var3 __attribute__((alias("C"))); // expected-note{{previous definition is here}} int var3 = 3; // expected-error{{redefinition of 'var3'}} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
