[clang] [Clang][CodeGen] Report when an alias points to an incompatible target (PR #192397)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Apr 15 23:05:43 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Igor Kudrin (igorkudrin)
<details>
<summary>Changes</summary>
Add checks to ensure that an alias and its target have compatible types:
- Generate an error if a function alias points to a variable or vice versa.
- Issue a warning for mismatches in function types.
- Ignore type discrepancies for variables.
This behavior aligns with similar diagnostics in GCC.
Resolves: #<!-- -->47301
---
Full diff: https://github.com/llvm/llvm-project/pull/192397.diff
4 Files Affected:
- (modified) clang/include/clang/Basic/DiagnosticFrontendKinds.td (+6)
- (modified) clang/lib/CodeGen/CodeGenModule.cpp (+43)
- (modified) clang/test/CodeGen/alias.c (+1-1)
- (modified) clang/test/Sema/attr-alias-elf.c (+30)
``````````diff
diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
index 62b74574102e4..5d10cb3ce26f2 100644
--- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -354,6 +354,12 @@ def err_non_default_visibility_dllimport : Error<
"non-default visibility cannot be applied to 'dllimport' declaration">;
def err_ifunc_resolver_return : Error<
"ifunc resolver function must return a pointer">;
+def err_alias_between_function_and_variable : Error<
+ "cannot alias a %select{function|variable}0 with a %select{variable|function}0">;
+def note_aliasee_declaration: Note<"aliasee is declared here">;
+def warn_alias_type_mismatch : Warning<
+ "alias and aliasee have different types %0 and %1">,
+ InGroup<DiagGroup<"attribute-alias">>;
def warn_atomic_op_misaligned : Warning<
"misaligned atomic operation may incur "
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 79c98f82a766f..557ae9bad0174 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -804,6 +804,49 @@ void CodeGenModule::checkAliases() {
continue;
}
+ if (!IsIFunc) {
+ // Function declarations can only alias functions (including IFUNCs).
+ // Similarly, variable declarations can only alias variables.
+ if (isa<FunctionDecl>(D) !=
+ (isa<llvm::Function>(GV) || isa<llvm::GlobalIFunc>(GV))) {
+ GlobalDecl AliaseeGD = getMangledNameDecl(GV->getName());
+ assert(AliaseeGD);
+ Diags.Report(Location, diag::err_alias_between_function_and_variable)
+ << isa<FunctionDecl>(D);
+ Diags.Report(AliaseeGD.getDecl()->getLocation(),
+ diag::note_aliasee_declaration);
+ Error = true;
+ continue;
+ }
+
+ auto shouldReportTypeMismatch = [&]() {
+ llvm::Type *AliasTy = Alias->getValueType();
+ llvm::Type *AliaseeTy = GV->getValueType();
+ // Same types, nothing to report.
+ if (AliasTy == AliaseeTy)
+ return false;
+ // Only report functions.
+ // Type mismatches for variables can be intentional.
+ auto *AliasFTy = dyn_cast<llvm::FunctionType>(AliasTy);
+ auto *AliaseeFTy = dyn_cast<llvm::FunctionType>(AliaseeTy);
+ if (!AliasFTy || !AliaseeFTy)
+ return false;
+ // Only report aliases with unspecified parameter lists if the return
+ // types do not match.
+ if (isa<FunctionNoProtoType>(D->getType().getTypePtr()))
+ return AliasFTy->getReturnType() != AliaseeFTy->getReturnType();
+ return true;
+ };
+ if (shouldReportTypeMismatch()) {
+ GlobalDecl AliaseeGD = getMangledNameDecl(GV->getName());
+ assert(AliaseeGD);
+ Diags.Report(Location, diag::warn_alias_type_mismatch)
+ << D->getType() << cast<ValueDecl>(AliaseeGD.getDecl())->getType();
+ Diags.Report(AliaseeGD.getDecl()->getLocation(),
+ diag::note_aliasee_declaration);
+ }
+ }
+
if (getContext().getTargetInfo().getTriple().isOSAIX())
if (const llvm::GlobalVariable *GVar =
dyn_cast<const llvm::GlobalVariable>(GV))
diff --git a/clang/test/CodeGen/alias.c b/clang/test/CodeGen/alias.c
index 9403c55beae0b..f4bc9668e343c 100644
--- a/clang/test/CodeGen/alias.c
+++ b/clang/test/CodeGen/alias.c
@@ -59,7 +59,7 @@ extern void f1(void) __attribute((alias("f0")));
static inline int foo1() { return 0; }
// CHECKBASIC-LABEL: define internal i32 @foo1()
int foo() __attribute__((alias("foo1")));
-int bar() __attribute__((alias("bar1")));
+extern int bar __attribute__((alias("bar1")));
extern int test6();
void test7() { test6(); } // test6 is emitted as extern.
diff --git a/clang/test/Sema/attr-alias-elf.c b/clang/test/Sema/attr-alias-elf.c
index d2674d1db0312..c46de4b3e6ebc 100644
--- a/clang/test/Sema/attr-alias-elf.c
+++ b/clang/test/Sema/attr-alias-elf.c
@@ -71,3 +71,33 @@ void test4_foo() __attribute__((alias("test4_bar")));
int test5_bar = 0;
extern struct incomplete_type test5_foo __attribute__((alias("test5_bar")));
+
+int test6 = 0;
+// expected-note at -1 {{aliasee is declared here}}
+void test6_alias() __attribute__((alias("test6")));
+// expected-error at -1 {{cannot alias a variable with a function}}
+
+extern int test7_alias __attribute__((alias("test7")));
+// expected-error at -1 {{cannot alias a function with a variable}}
+int test7(int x) { return x * 2; }
+// expected-note at -1 {{aliasee is declared here}}
+
+void *test8_ifunc() { return 0; }
+void test8(void) __attribute__((ifunc("test8_ifunc")));
+// expected-note at -1 {{aliasee is declared here}}
+extern int test8_alias __attribute__((alias("test8")));
+// expected-error at -1 {{cannot alias a function with a variable}}
+
+void test9() {}
+// expected-note at -1 {{aliasee is declared here}}
+int test9_alias() __attribute__((alias("test9")));
+// expected-warning at -1 {{alias and aliasee have different types 'int ()' and 'void ()'}}
+
+// No warning for an alias with unspecified parameters if the return types match
+int test10(int x, int y) { return x + y; }
+int test10_alias() __attribute__((alias("test10")));
+
+int test11(int x, int y) { return x + y; }
+// expected-note at -1 {{aliasee is declared here}}
+int test11_alias(int x, ...) __attribute__((alias("test11")));
+// expected-warning at -1 {{alias and aliasee have different types 'int (int, ...)' and 'int (int, int)'}}
``````````
</details>
https://github.com/llvm/llvm-project/pull/192397
More information about the cfe-commits
mailing list