From b63bfa45b621745f9d6e401ad84630d6f465bc79 Mon Sep 17 00:00:00 2001 From: Shoaib Meenai Date: Wed, 16 Oct 2024 20:57:49 -0700 Subject: [PATCH] [CIR][CIRGen] Ensure default visibility for local linkage functions LLVM's verifier enforces this, which was previously causing us to fail verification. This is a bit of a band-aid; the overall linkage and visibility setting flow needs some work to match the original. --- clang/lib/CIR/CodeGen/CIRGenModule.cpp | 11 +++++++++-- clang/test/CIR/CodeGen/visibility-attribute.c | 15 +++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp index cb96adf1e257..872e5e9e05c5 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp @@ -2608,8 +2608,15 @@ void CIRGenModule::setFunctionAttributes(GlobalDecl globalDecl, // TODO(cir): Complete the remaining part of the function. assert(!MissingFeatures::setFunctionAttributes()); - auto decl = globalDecl.getDecl(); - func.setGlobalVisibilityAttr(getGlobalVisibilityAttrFromDecl(decl)); + + // TODO(cir): This needs a lot of work to better match CodeGen. That + // ultimately ends up in setGlobalVisibility, which already has the linkage of + // the LLVM GV (corresponding to our FuncOp) computed, so it doesn't have to + // recompute it here. This is a minimal fix for now. + if (!isLocalLinkage(getFunctionLinkage(globalDecl))) { + auto decl = globalDecl.getDecl(); + func.setGlobalVisibilityAttr(getGlobalVisibilityAttrFromDecl(decl)); + } } /// If the specified mangled name is not in the module, diff --git a/clang/test/CIR/CodeGen/visibility-attribute.c b/clang/test/CIR/CodeGen/visibility-attribute.c index fb675fb51751..07834d78910e 100644 --- a/clang/test/CIR/CodeGen/visibility-attribute.c +++ b/clang/test/CIR/CodeGen/visibility-attribute.c @@ -30,9 +30,24 @@ void __attribute__((__visibility__("protected"))) foo_protected(); // CIR: cir.func no_proto private protected @foo_protected(...) // LLVM: declare {{.*}} protected void @foo_protected(...) +static void static_foo_default() {} +// CIR: cir.func no_proto internal private @static_foo_default() +// LLVM: define internal void @static_foo_default() + +static void __attribute__((__visibility__("hidden"))) static_foo_hidden() {} +// CIR: cir.func no_proto internal private @static_foo_hidden() +// LLVM: define internal void @static_foo_hidden() + +static void __attribute__((__visibility__("protected"))) static_foo_protected() {} +// CIR: cir.func no_proto internal private @static_foo_protected() +// LLVM: define internal void @static_foo_protected() + void call_foo() { foo_default(); foo_hidden(); foo_protected(); + static_foo_default(); + static_foo_hidden(); + static_foo_protected(); }