[PATCH] D112059: Fix inline builtin handling in case of redefinition
serge via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Wed Oct 20 10:18:57 PDT 2021
serge-sans-paille updated this revision to Diff 381011.
serge-sans-paille added a comment.
Reduce the number of time we would walk redecls.
Simplify test case
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D112059/new/
https://reviews.llvm.org/D112059
Files:
clang/lib/CodeGen/CodeGenFunction.cpp
clang/test/CodeGen/strlen-inline-builtin-redecl.c
Index: clang/test/CodeGen/strlen-inline-builtin-redecl.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/strlen-inline-builtin-redecl.c
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -triple x86_64 -S -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s
+//
+// Verifies that clang-generated *.inline are removed when shadowed by an external definition
+
+// CHECK-NOT: strlen.inline
+
+unsigned long strnlen(const char *, unsigned long);
+void fortify_panic(const char *);
+
+extern inline __attribute__((always_inline)) __attribute__((gnu_inline)) unsigned long strlen(const char *p) {
+ return 1;
+}
+unsigned long mystrlen(char const *s) {
+ return strlen(s);
+}
+unsigned long strlen(const char *s) {
+ return 2;
+}
+unsigned long yourstrlen(char const *s) {
+ return strlen(s);
+}
Index: clang/lib/CodeGen/CodeGenFunction.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenFunction.cpp
+++ clang/lib/CodeGen/CodeGenFunction.cpp
@@ -1299,18 +1299,34 @@
// When generating code for a builtin with an inline declaration, use a
// mangled name to hold the actual body, while keeping an external definition
// in case the function pointer is referenced somewhere.
- if (FD->isInlineBuiltinDeclaration() && Fn) {
+ if (Fn) {
std::string FDInlineName = (Fn->getName() + ".inline").str();
llvm::Module *M = Fn->getParent();
llvm::Function *Clone = M->getFunction(FDInlineName);
- if (!Clone) {
- Clone = llvm::Function::Create(Fn->getFunctionType(),
- llvm::GlobalValue::InternalLinkage,
- Fn->getAddressSpace(), FDInlineName, M);
- Clone->addFnAttr(llvm::Attribute::AlwaysInline);
+ if (FD->isInlineBuiltinDeclaration()) {
+ if (!Clone) {
+ Clone = llvm::Function::Create(Fn->getFunctionType(),
+ llvm::GlobalValue::InternalLinkage,
+ Fn->getAddressSpace(), FDInlineName, M);
+ Clone->addFnAttr(llvm::Attribute::AlwaysInline);
+ }
+ Fn->setLinkage(llvm::GlobalValue::ExternalLinkage);
+ Fn = Clone;
+ }
+
+ // detect the unusual situation where an inline version is shadowed by a
+ // non-inline version. In that case we should pick the external one
+ // everywhere. That's GCC behavior too. Unfortunately, I cannot find a way
+ // to detect that situation before we reach codegen, so do some late
+ // replacement.
+ else if (Clone) {
+ for (auto const *Redecl : FD->redecls()) {
+ if (Redecl->isInlineBuiltinDeclaration()) {
+ Clone->replaceAllUsesWith(Fn);
+ Clone->eraseFromParent();
+ }
+ }
}
- Fn->setLinkage(llvm::GlobalValue::ExternalLinkage);
- Fn = Clone;
}
// Check if we should generate debug info for this function.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D112059.381011.patch
Type: text/x-patch
Size: 2937 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20211020/e9a799ec/attachment.bin>
More information about the cfe-commits
mailing list