[PATCH] D123308: Handle a subtle hole in inline builtin handling
serge via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Fri Apr 8 00:32:21 PDT 2022
This revision was automatically updated to reflect the committed changes.
Closed by commit rG301e0d91354b: [Clang][Fortify] drop inline decls when redeclared (authored by serge-sans-paille).
Changed prior to commit:
https://reviews.llvm.org/D123308?vs=421187&id=421438#toc
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D123308/new/
https://reviews.llvm.org/D123308
Files:
clang/lib/CodeGen/CGExpr.cpp
clang/test/CodeGen/fread-inline-builtin-late-redecl.c
Index: clang/test/CodeGen/fread-inline-builtin-late-redecl.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/fread-inline-builtin-late-redecl.c
@@ -0,0 +1,26 @@
+// 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, even when that definition appears at the end of the
+// file.
+
+// CHECK-NOT: strlen.inline
+
+extern unsigned long strlen(char const *s);
+
+extern __inline __attribute__((__always_inline__)) __attribute__((__gnu_inline__)) unsigned long strlen(char const *s) {
+ return 1;
+}
+
+static unsigned long chesterfield(char const *s) {
+ return strlen(s);
+}
+static unsigned long (*_strlen)(char const *ptr);
+
+unsigned long blutch(char const *s) {
+ return chesterfield(s);
+}
+
+unsigned long strlen(char const *s) {
+ return _strlen(s);
+}
Index: clang/lib/CodeGen/CGExpr.cpp
===================================================================
--- clang/lib/CodeGen/CGExpr.cpp
+++ clang/lib/CodeGen/CGExpr.cpp
@@ -4948,6 +4948,16 @@
return EmitCall(E->getCallee()->getType(), Callee, E, ReturnValue);
}
+// 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.
+static bool OnlyHasInlineBuiltinDeclaration(const FunctionDecl *FD) {
+ for (const FunctionDecl *PD = FD; PD; PD = PD->getPreviousDecl())
+ if (!PD->isInlineBuiltinDeclaration())
+ return false;
+ return true;
+}
+
static CGCallee EmitDirectCallee(CodeGenFunction &CGF, GlobalDecl GD) {
const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl());
@@ -4955,8 +4965,8 @@
std::string FDInlineName = (FD->getName() + ".inline").str();
// When directing calling an inline builtin, call it through it's mangled
// name to make it clear it's not the actual builtin.
- if (FD->isInlineBuiltinDeclaration() &&
- CGF.CurFn->getName() != FDInlineName) {
+ if (CGF.CurFn->getName() != FDInlineName &&
+ OnlyHasInlineBuiltinDeclaration(FD)) {
llvm::Constant *CalleePtr = EmitFunctionDeclPointer(CGF.CGM, GD);
llvm::Function *Fn = llvm::cast<llvm::Function>(CalleePtr);
llvm::Module *M = Fn->getParent();
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D123308.421438.patch
Type: text/x-patch
Size: 2377 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20220408/acdaf948/attachment.bin>
More information about the cfe-commits
mailing list