[clang] a7f0567 - [Clang] Avoid assertion failure for initialized extern aliases (#223124)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Oct 6 01:24:23 PDT 2026
Author: nudt_yixiao
Date: 2026-10-06T08:24:15Z
New Revision: a7f05671c9037b7bec6ef6608b97485ff6768d2c
URL: https://github.com/llvm/llvm-project/commit/a7f05671c9037b7bec6ef6608b97485ff6768d2c
DIFF: https://github.com/llvm/llvm-project/commit/a7f05671c9037b7bec6ef6608b97485ff6768d2c.diff
LOG: [Clang] Avoid assertion failure for initialized extern aliases (#223124)
Fix an assertion when an alias variable has an initializer, and treat
defining attributes on in-class static data members as definitions so
that later out-of-line definitions are correctly diagnosed.
Add regression tests and a release note.
AI was used to assist with code analysis, debugging, and drafting the PR
description. I personally debugged, reviewed and verified the changes,
tested the code, and fully understand the submitted contribution.
Fixes https://github.com/llvm/llvm-project/issues/204762
Added:
Modified:
clang/docs/ReleaseNotes.md
clang/lib/AST/Decl.cpp
clang/lib/Sema/SemaDecl.cpp
clang/test/Sema/alias-redefinition.c
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 7b878a0abbab3..cb3657952dbe8 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -648,6 +648,11 @@ 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. Static data members declared with
+ `alias` are now correctly diagnosed as definitions when followed by an
+ out-of-line definition. (#GH204762)
+
#### Bug Fixes to C++ Support
- Fixed lambdas with specifiers or attributes after the capture list being
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index b145560508e95..f7a635e35336a 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -2268,7 +2268,7 @@ VarDecl::isThisDeclarationADefinition(ASTContext &C) const {
TSK_ExplicitSpecialization) ||
isa<VarTemplatePartialSpecializationDecl>(this)))
return Definition;
- if (!isOutOfLine() && isInline())
+ if (!isOutOfLine() && (isInline() || hasDefiningAttr()))
return Definition;
return DeclarationOnly;
}
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 094601a58d508..59c0faa67364a 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -7191,7 +7191,7 @@ static void checkAliasAttr(Sema &S, NamedDecl &ND) {
if (VD->hasInit()) {
if (const auto *Attr = VD->getAttr<AliasAttr>()) {
assert(VD->isThisDeclarationADefinition() &&
- !VD->isExternallyVisible() && "Broken AliasAttr handled late!");
+ "Broken AliasAttr handled late!");
S.Diag(Attr->getLocation(), diag::err_alias_is_definition) << VD << 0;
VD->dropAttr<AliasAttr>();
}
diff --git a/clang/test/Sema/alias-redefinition.c b/clang/test/Sema/alias-redefinition.c
index 526b67d9be7f2..7b5a8a0fe5993 100644
--- a/clang/test/Sema/alias-redefinition.c
+++ b/clang/test/Sema/alias-redefinition.c
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -Wno-strict-prototypes -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -Wno-strict-prototypes -fsyntax-only -verify=expected,c %s
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -Wno-strict-prototypes -x c++ -fsyntax-only -verify=expected,cxx %s
void f0() {}
void fun0(void) __attribute((alias("f0")));
@@ -22,11 +23,73 @@ void fun4(void);
void f5() {}
void __attribute((alias("f5"))) fun5(void) {} // expected-error {{definition 'fun5' cannot also be an alias}}
+typedef void (*func_ptr)(void);
+
+static void implementation(void) {}
+
+static func_ptr resolver1(void) {
+ return implementation;
+}
+
+void f6(void) __attribute__((ifunc("resolver1"))); // expected-note {{previous definition is here}}
+void f6(void) __attribute__((alias("implementation"))); // expected-error {{redefinition of 'f6'}}
+
+void f7(void) __attribute__((alias("implementation"))); // expected-note {{previous definition is here}}
+void f7(void) __attribute__((ifunc("resolver1"))); // expected-error {{redefinition of 'f7'}}
+
+void f8(void) __attribute__((ifunc("resolver1"), alias("implementation"))); // expected-error {{definition 'f8' cannot also be an alias}}
+
+void f9(void) __attribute__((alias("implementation"), ifunc("resolver1"))); // expected-error {{definition 'f9' cannot also be an ifunc}}
+
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 at -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 at -1 {{'extern' variable has an initializer}}
+
+int target;
+int loader_then_alias __attribute((loader_uninitialized, alias("target"))); // expected-error {{definition 'loader_then_alias' cannot also be an alias}}
+
+int alias_then_loader __attribute((alias("target"), loader_uninitialized)); // expected-error {{definition 'alias_then_loader' cannot also be an alias}}
+
+int loader_redecl_alias __attribute((loader_uninitialized)); // expected-note {{previous definition is here}}
+extern int loader_redecl_alias __attribute((alias("target"))); // expected-error {{redefinition of 'loader_redecl_alias'}}
+
+extern int loader_redecl_alias1 __attribute((alias("target"))); // c-note {{previous definition is here}} cxx-note 2 {{previous definition is here}}
+int loader_redecl_alias1 __attribute((loader_uninitialized));
+// c-error at -1 {{redeclaration cannot add 'loader_uninitialized' attribute}}
+// cxx-error at -2 {{redefinition of 'loader_redecl_alias1'}}
+// cxx-warning at -3 {{attribute declaration must precede definition}}
extern int var3 __attribute__((alias("C"))); // expected-note{{previous definition is here}}
int var3 = 3; // expected-error{{redefinition of 'var3'}}
-int var4; // expected-note{{previous definition is here}}
-extern int var4 __attribute__((alias("v4"))); // expected-error{{alias definition of 'var4' after tentative definition}}
+int var4; // expected-note {{previous definition is here}}
+extern int var4 __attribute__((alias("v4")));
+// c-error at -1 {{alias definition of 'var4' after tentative definition}}
+// cxx-error at -2 {{redefinition of 'var4'}}
+
+
+#ifdef __cplusplus
+
+int foo;
+struct S {
+ static const int i __attribute__((alias("foo"))) = 12; // expected-error {{definition 'i' cannot also be an alias}}
+};
+
+struct OutOfLineDefinitionWithInitializer {
+ static int i __attribute__((alias("foo"))); // expected-note {{previous definition is here}}
+};
+int OutOfLineDefinitionWithInitializer::i = 12; // expected-error {{redefinition of 'i'}}
+
+struct OutOfLineDefinitionWithoutInitializer {
+ static int i1 __attribute__((alias("foo"))); // expected-note {{previous definition is here}}
+};
+int OutOfLineDefinitionWithoutInitializer::i1; // expected-error {{redefinition of 'i1'}}
+
+struct AliasDefinition {
+ static int i2 __attribute__((alias("foo")));
+};
+
+#endif
More information about the cfe-commits
mailing list