ibookstein updated this revision to Diff 385541.
ibookstein added a comment.
clang-format + fastforward rebase
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D112868/new/
https://reviews.llvm.org/D112868
Files:
clang/lib/CodeGen/CodeGenModule.cpp
clang/test/Sema/attr-ifunc.c
Index: clang/test/Sema/attr-ifunc.c
===================================================================
--- clang/test/Sema/attr-ifunc.c
+++ clang/test/Sema/attr-ifunc.c
@@ -13,8 +13,7 @@
void f1() __attribute__((ifunc("f1_ifunc")));
//expected-error@-1 {{ifunc must point to a defined function}}
-void* f2_a() __attribute__((ifunc("f2_b")));
-//expected-error@-1 {{ifunc definition is part of a cycle}}
+void *f2_a() __attribute__((alias("f2_b")));
void* f2_b() __attribute__((ifunc("f2_a")));
//expected-error@-1 {{ifunc definition is part of a cycle}}
@@ -27,6 +26,15 @@
void f4() __attribute__((ifunc("f4_ifunc")));
//expected-error@-1 {{ifunc resolver function must return a pointer}}
+int f5_resolver_gvar;
+void f5() __attribute__((ifunc("f5_resolver_gvar")));
+// expected-error@-1 {{ifunc must point to a defined function}}
+
+void *f6_resolver_resolver() { return 0; }
+void *f6_resolver() __attribute__((ifunc("f6_resolver_resolver")));
+void f6() __attribute__((ifunc("f6_resolver")));
+// expected-error@-1 {{ifunc must point to a defined function}}
+
#else
void f1a() __asm("f1");
void f1a() {}
Index: clang/lib/CodeGen/CodeGenModule.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -318,21 +318,57 @@
// This is only used in aliases that we created and we know they have a
// linear structure.
static const llvm::GlobalValue *getAliasedGlobal(const llvm::GlobalValue *GV) {
- llvm::SmallPtrSet<const llvm::GlobalValue *, 4> Visited;
- for (;;) {
- if (!GV || !Visited.insert(GV).second)
- return nullptr;
-
- const llvm::Constant *C;
- if (auto *GA = dyn_cast<llvm::GlobalAlias>(GV))
- C = GA->getAliasee();
- else if (auto *GI = dyn_cast<llvm::GlobalIFunc>(GV))
- C = GI->getResolver();
- else
- return GV;
+ const llvm::Constant *C;
+ if (auto *GA = dyn_cast<llvm::GlobalAlias>(GV))
+ C = GA->getAliasee();
+ else if (auto *GI = dyn_cast<llvm::GlobalIFunc>(GV))
+ C = GI->getResolver();
+ else
+ return GV;
+
+ const auto *AliaseeGV = dyn_cast<llvm::GlobalValue>(C->stripPointerCasts());
+ if (!AliaseeGV)
+ return nullptr;
+
+ const llvm::GlobalValue *FinalGV = AliaseeGV->getAliaseeObject();
+ if (FinalGV == GV)
+ return nullptr;
+
+ return FinalGV;
+}
+
+static bool checkAliasedGlobal(DiagnosticsEngine &Diags,
+ SourceLocation Location, bool IsIFunc,
+ const llvm::GlobalValue *Alias,
+ const llvm::GlobalValue *&GV) {
+ GV = getAliasedGlobal(Alias);
+ if (!GV) {
+ Diags.Report(Location, diag::err_cyclic_alias) << IsIFunc;
+ return false;
+ }
+
+ if (GV->isDeclaration()) {
+ Diags.Report(Location, diag::err_alias_to_undefined) << IsIFunc << IsIFunc;
+ return false;
+ }
+
+ if (IsIFunc) {
+ // Check resolver function type.
+ const auto *F = dyn_cast<llvm::Function>(GV);
+ if (!F) {
+ Diags.Report(Location, diag::err_alias_to_undefined)
+ << IsIFunc << IsIFunc;
+ return false;
+ }
- GV = dyn_cast<llvm::GlobalValue>(C->stripPointerCasts());
+ llvm::FunctionType *FTy = F->getFunctionType();
+ if (!FTy->getReturnType()->isPointerTy()) {
+ Diags.Report(Location, diag::err_ifunc_resolver_return);
+ return false;
+ }
}
+
+ return true;
}
void CodeGenModule::checkAliases() {
@@ -349,23 +385,13 @@
Location = A->getLocation();
else
llvm_unreachable("Not an alias or ifunc?");
+
StringRef MangledName = getMangledName(GD);
llvm::GlobalValue *Alias = GetGlobalValue(MangledName);
- const llvm::GlobalValue *GV = getAliasedGlobal(Alias);
- if (!GV) {
- Error = true;
- Diags.Report(Location, diag::err_cyclic_alias) << IsIFunc;
- } else if (GV->isDeclaration()) {
+ const llvm::GlobalValue *GV = nullptr;
+ if (!checkAliasedGlobal(Diags, Location, IsIFunc, Alias, GV)) {
Error = true;
- Diags.Report(Location, diag::err_alias_to_undefined)
- << IsIFunc << IsIFunc;
- } else if (IsIFunc) {
- // Check resolver function type.
- llvm::FunctionType *FTy = dyn_cast<llvm::FunctionType>(
- GV->getType()->getPointerElementType());
- assert(FTy);
- if (!FTy->getReturnType()->isPointerTy())
- Diags.Report(Location, diag::err_ifunc_resolver_return);
+ continue;
}
llvm::Constant *Aliasee =
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits