summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp12
-rw-r--r--clang/test/CodeGen/memcpy-no-nobuiltin-if-not-emitted.cpp16
2 files changed, 25 insertions, 3 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 73c41dc4cf3..a735bdd814e 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -1848,9 +1848,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()) {
diff --git a/clang/test/CodeGen/memcpy-no-nobuiltin-if-not-emitted.cpp b/clang/test/CodeGen/memcpy-no-nobuiltin-if-not-emitted.cpp
new file mode 100644
index 00000000000..d27aa9c5341
--- /dev/null
+++ b/clang/test/CodeGen/memcpy-no-nobuiltin-if-not-emitted.cpp
@@ -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
OpenPOWER on IntegriCloud