[CodeGen] fix inline builtin-related breakage from D78162

In cases where we have multiple decls of an inline builtin, we may need
to go hunting for the one with a definition when setting function
attributes.

An additional test-case was provided on
https://github.com/ClangBuiltLinux/linux/issues/979
This commit is contained in:
George Burgess IV 2020-04-16 10:56:19 -07:00
parent 1223255c2d
commit 94908088a8
2 changed files with 25 additions and 3 deletions

View File

@ -1909,9 +1909,15 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD, llvm::Function *F,
F->setSection(SA->getName());
// If we plan on emitting this inline builtin, we can't treat it as a builtin.
if (FD->isInlineBuiltinDeclaration() && shouldEmitFunction(FD)) {
F->addAttribute(llvm::AttributeList::FunctionIndex,
llvm::Attribute::NoBuiltin);
if (FD->isInlineBuiltinDeclaration()) {
const FunctionDecl *FDBody;
bool HasBody = FD->hasBody(FDBody);
(void)HasBody;
assert(HasBody && "Inline builtin declarations should always have an "
"available body!");
if (shouldEmitFunction(FDBody))
F->addAttribute(llvm::AttributeList::FunctionIndex,
llvm::Attribute::NoBuiltin);
}
if (FD->isReplaceableGlobalAllocationFunction()) {

View File

@ -0,0 +1,16 @@
// RUN: %clang_cc1 -triple i686-linux-gnu -std=c++11 -S -emit-llvm -o - %s | FileCheck %s
//
// Regression test for the issue reported at
// https://reviews.llvm.org/D78162#1986104
typedef unsigned long size_t;
extern "C" __inline__ __attribute__((__gnu_inline__)) void *memcpy(void *a, const void *b, unsigned c) {
return __builtin_memcpy(a, b, c);
}
void *memcpy(void *, const void *, unsigned);
// CHECK-LABEL: define void @_Z1av
void a() { (void)memcpy; }
// CHECK-NOT: nobuiltin