llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clangir
Author: Erich Keane (erichkeane)
<details>
<summary>Changes</summary>
If a function is first used through a no-prototype declaration, then defined
later as an alias, we erased the old declaration and created the new one with
the new type. However the earlier references still used the old type, which
caused a verification error.
This patch just makes sure we replace the uses of it similar to how we do with
a similar problem with normal functions.
Note: there is a bit of inconsistency in how we're setting the type of the
function between OGCG and CIR that I'm not sure of the impact of,
but that is prexisting.
---
Full diff: https://github.com/llvm/llvm-project/pull/212308.diff
2 Files Affected:
- (modified) clang/lib/CIR/CodeGen/CIRGenModule.cpp (+25-14)
- (modified) clang/test/CIR/CodeGen/attr-alias.c (+52-2)
``````````diff
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index 8b9140caa7471..209671ad47be5 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -2036,6 +2036,10 @@ void
CIRGenModule::replaceUsesOfNonProtoTypeWithRealFunction(
// Iterate through all calls of the no-proto function.
std::optional<mlir::SymbolTable::UseRange> symUses =
oldFn.getSymbolUses(oldFn->getParentOp());
+
+ if (!symUses)
+ return;
+
for (const mlir::SymbolTable::SymbolUse &use : symUses.value()) {
mlir::OpBuilder::InsertionGuard guard(builder);
@@ -3768,34 +3772,41 @@ void CIRGenModule::emitAliasDefinition(GlobalDecl gd) {
const auto *vd = cast<VarDecl>(d);
linkage = getCIRLinkageVarDefinition(vd);
}
-
- // Aliases that target weak symbols must themselves be marked weak.
- if (d->hasAttr<WeakAttr>() || d->hasAttr<WeakRefAttr>() ||
- d->isWeakImported())
- linkage = cir::GlobalLinkageKind::WeakAnyLinkage;
+ //
+ // Create the alias op.
+ // TODO(cir): Make GlobalAlias a separate op.
+ cir::CIRGlobalValueInterface alias =
+ isFunction ? mlir::cast<cir::CIRGlobalValueInterface>(
+ createCIRFunction(loc, mangledName,
+ mlir::cast<cir::FuncType>(declTy),
+ cast<FunctionDecl>(d))
+ .getOperation())
+ : mlir::cast<cir::CIRGlobalValueInterface>(
+ createGlobalOp(loc, mangledName,
declTy).getOperation());
// Create the alias op. If there is an existing declaration with the same
// name, erase it: any references to it via flat symbol reference will
// automatically resolve to the new alias.
+ // However, function aliases actually change its type, so we have to replace
+ // uses of it.
if (entry) {
+ if (isFunction)
+ replaceUsesOfNonProtoTypeWithRealFunction(
+ entry, mlir::cast<cir::FuncOp>(alias.getOperation()));
eraseGlobalSymbol(entry);
entry->erase();
}
+ // Aliases that target weak symbols must themselves be marked weak.
+ if (d->hasAttr<WeakAttr>() || d->hasAttr<WeakRefAttr>() ||
+ d->isWeakImported())
+ linkage = cir::GlobalLinkageKind::WeakAnyLinkage;
+
// Aliases are always definitions, so the MLIR visibility should match the
// linkage rather than defaulting to private.
mlir::SymbolTable::Visibility visibility =
getMLIRVisibilityFromCIRLinkage(linkage);
- // TODO(cir): Make GlobalAlias a separate op.
- cir::CIRGlobalValueInterface alias =
- isFunction ? mlir::cast<cir::CIRGlobalValueInterface>(
- createCIRFunction(loc, mangledName,
- mlir::cast<cir::FuncType>(declTy),
- cast<FunctionDecl>(d))
- .getOperation())
- : mlir::cast<cir::CIRGlobalValueInterface>(
- createGlobalOp(loc, mangledName,
declTy).getOperation());
alias.setAliasee(aa->getAliasee());
alias.setLinkage(linkage);
mlir::SymbolTable::setSymbolVisibility(alias, visibility);
diff --git a/clang/test/CIR/CodeGen/attr-alias.c
b/clang/test/CIR/CodeGen/attr-alias.c
index 3acf90d6a4d22..d7bd525d9b974 100644
--- a/clang/test/CIR/CodeGen/attr-alias.c
+++ b/clang/test/CIR/CodeGen/attr-alias.c
@@ -26,6 +26,24 @@ extern void prior_decl_func(void);
void prior_decl_func_target(void) {}
extern void prior_decl_func(void)
__attribute__((alias("prior_decl_func_target")));
+// Use of a no-prototype function, then alias definition sets the type.
+extern int noproto_used();
+int noproto_use_it(void) { return noproto_used(); }
+int noproto_used_target(void) { return 0; }
+int noproto_used() __attribute__((alias("noproto_used_target")));
+
+// Use of a no-prototype function with args, then alias definition sets the
type.
+extern int noproto_args();
+int noproto_args_use(void) { return noproto_args(1, 2, 3); }
+int noproto_args_target(void) { return 0; }
+int noproto_args() __attribute__((alias("noproto_args_target")));
+
+// Use of a no-prototype function with args, alias adds args.
+extern int noproto_args2();
+int noproto_args_use2(void) { return noproto_args2(1, 2, 3); }
+int noproto_args_target2(void) { return 0; }
+int noproto_args2(int, int, int)
__attribute__((alias("noproto_args_target2")));
+
// Weak variable alias - exercises the WeakAttr linkage override branch.
int weak_var_target = 9;
extern int weak_var_alias __attribute__((weak, alias("weak_var_target")));
@@ -49,6 +67,18 @@ extern void weak_func_alias(void) __attribute__((weak,
alias("weak_func_target")
// CIR-DAG: cir.func weak @weak_func_alias() alias(@weak_func_target)
// CIR-DAG: cir.func dso_local @test13_alias(!u32i) alias(@test13)
+// CIR-DAG: cir.get_global @noproto_used : !cir.ptr<!cir.func<() -> !s32i>>
+// CIR-DAG: cir.func no_proto dso_local @noproto_used() -> !s32i
alias(@noproto_used_target)
+// CIR-DAG: cir.call {{.*}}() : (!cir.ptr<!cir.func<() -> !s32i>>) -> !s32i
+
+// CIR-DAG: cir.get_global @noproto_args : !cir.ptr<!cir.func<() -> !s32i>>
+// CIR-DAG: cir.call {{%.*}}({{.*}}) : (!cir.ptr<!cir.func<(!s32i, !s32i,
!s32i) -> !s32i>>{{.*}}) -> !s32i
+// CIR-DAG: cir.func no_proto dso_local @noproto_args() -> !s32i
alias(@noproto_args_target)
+
+// CIR-DAG: cir.get_global @noproto_args2 : !cir.ptr<!cir.func<(!s32i, !s32i,
!s32i) -> !s32i>>
+// CIR-DAG: cir.call {{%.*}}({{.*}}) : (!cir.ptr<!cir.func<(!s32i, !s32i,
!s32i) -> !s32i>>{{.*}}) -> !s32i
+// CIR-DAG: cir.func no_proto dso_local @noproto_args2(!s32i, !s32i, !s32i) ->
!s32i alias(@noproto_args_target2)
+
// LLVM-DAG: @alias_target = global i32 42
// LLVM-DAG: @prior_decl_var_target = global i32 7
// LLVM-DAG: @weak_var_target = global i32 9
@@ -59,7 +89,17 @@ extern void weak_func_alias(void) __attribute__((weak,
alias("weak_func_target")
// LLVM-DAG: @prior_decl_func = alias void (), ptr @prior_decl_func_target
// LLVM-DAG: @weak_func_alias = weak alias void (), ptr @weak_func_target
// LLVM-DAG: @test13_alias = alias void (i32), ptr @test13
-// LLVM: define {{.*}}void @alias_func_target()
+
+// LLVM-DAG: @noproto_used = alias i32 (), ptr @noproto_used_target
+// LLVM-DAG: call i32 @noproto_used()
+//
+// LLVM-DAG: @noproto_args = alias i32 (), ptr @noproto_args_target
+// LLVM-DAG: call i32 @noproto_args(i32 noundef 1, i32 noundef 2, i32 noundef
3)
+//
+// LLVM-DAG: call i32 @noproto_args2(i32 noundef 1, i32 noundef 2, i32 noundef
3)
+// LLVM-DAG: @noproto_args2 = alias i32 (i32, i32, i32), ptr
@noproto_args_target2
+
+// LLVM-DAG: define {{.*}}void @alias_func_target()
// OGCG-DAG: @alias_target = {{.*}}global i32 42
// OGCG-DAG: @prior_decl_var_target = {{.*}}global i32 7
@@ -71,7 +111,17 @@ extern void weak_func_alias(void) __attribute__((weak,
alias("weak_func_target")
// OGCG-DAG: @prior_decl_func = {{.*}}alias void (), ptr
@prior_decl_func_target
// OGCG-DAG: @weak_func_alias = {{.*}}weak alias void (), ptr @weak_func_target
// OGCG-DAG: @test13_alias = alias {}, ptr @test13
-// OGCG: define {{.*}}void @alias_func_target()
+//
+// OGCG-DAG: @noproto_used = alias i32 (...), ptr @noproto_used_target
+// OGCG-DAG: call i32 (...) @noproto_used()
+//
+// OGCG-DAG: @noproto_args = alias i32 (...), ptr @noproto_args_target
+// OGCG-DAG: call i32 (i32, i32, i32, ...) @noproto_args(i32 noundef 1, i32
noundef 2, i32 noundef 3)
+//
+// OGCG-DAG: call i32 (i32, i32, i32, ...) @noproto_args2(i32 noundef 1, i32
noundef 2, i32 noundef 3)
+// OGCG-DAG: @noproto_args2 = alias i32 (i32, i32, i32), ptr
@noproto_args_target2
+//
+// OGCG-DAG: define {{.*}}void @alias_func_target()
// Test that a non visible (-Wvisibility) type doesn't assert.
enum a_type { test13_a };
``````````
</details>
https://github.com/llvm/llvm-project/pull/212308
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits