[PATCH] D112059: Fix inline builtin handling in case of redefinition
serge via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Tue Oct 19 02:33:42 PDT 2021
serge-sans-paille created this revision.
serge-sans-paille added reviewers: nickdesaulniers, manojgupta.
serge-sans-paille requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
Basically, inline builtin definition are shadowed by externally visible
redefinition. This matches GCC behavior.
Repository:
rG LLVM Github Monorepo
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,42 @@
+// 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) {
+ unsigned long ret;
+ unsigned long p_size = __builtin_object_size(p, 0);
+
+ if (p_size == (unsigned long)-1 ||
+ (__builtin_constant_p(p[p_size - 1]) && p[p_size - 1] == '\0'))
+ return __builtin_strlen(p);
+ ret = strnlen(p, p_size);
+ if (p_size <= ret)
+ fortify_panic(__func__);
+ return ret;
+}
+char *strim(char *s) {
+ unsigned long size;
+ char *end;
+
+ size = strlen(s);
+ if (!size)
+ return s;
+
+ end = s + size - 1;
+ return end;
+}
+unsigned long strlen(const char *s) {
+ const char *sc;
+
+ for (sc = s; *sc != '\0'; ++sc)
+ ;
+ return sc - s;
+}
+extern typeof(strlen) strlen;
Index: clang/lib/CodeGen/CodeGenFunction.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenFunction.cpp
+++ clang/lib/CodeGen/CodeGenFunction.cpp
@@ -1299,18 +1299,35 @@
// 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) {
- 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 (Fn) {
+ if (FD->isInlineBuiltinDeclaration()) {
+ 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);
+ }
+ Fn->setLinkage(llvm::GlobalValue::ExternalLinkage);
+ Fn = Clone;
+ }
+ // If the inline version is shadowed by a non-inline version, pick the
+ // external one. That's GCC behavior too.
+ else {
+ for (auto const *Redecl : FD->redecls()) {
+ if (Redecl->isInlineBuiltinDeclaration()) {
+ std::string FDInlineName = (Fn->getName() + ".inline").str();
+ llvm::Module *M = Fn->getParent();
+ llvm::Function *Clone = M->getFunction(FDInlineName);
+ if (Clone) {
+ 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.380619.patch
Type: text/x-patch
Size: 3547 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20211019/bd91c23c/attachment-0001.bin>
More information about the cfe-commits
mailing list