summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
authorserge-sans-paille <sguelton@redhat.com>2019-12-05 17:08:10 +0100
committerserge-sans-paille <sguelton@redhat.com>2020-01-10 09:44:20 +0100
commit921f871ac438175ca8fcfcafdfcfac4d7ddf3905 (patch)
tree7e7d223ab1fb1ec6111231b9151f0c5629acac02 /clang/lib/CodeGen
parent164da673009ba6c100ce45b6fa9a5dfd3b0b8e38 (diff)
downloadbcm5719-llvm-921f871ac438175ca8fcfcafdfcfac4d7ddf3905.tar.gz
bcm5719-llvm-921f871ac438175ca8fcfcafdfcfac4d7ddf3905.zip
Allow system header to provide their own implementation of some builtin
If a system header provides an (inline) implementation of some of their function, clang still matches on the function name and generate the appropriate llvm builtin, e.g. memcpy. This behavior is in line with glibc recommendation « users may not provide their own version of symbols » but doesn't account for the fact that glibc itself can provide inline version of some functions. It is the case for the memcpy function when -D_FORTIFY_SOURCE=1 is on. In that case an inline version of memcpy calls __memcpy_chk, a function that performs extra runtime checks. Clang currently ignores the inline version and thus provides no runtime check. This code fixes the issue by detecting functions whose name is a builtin name but also have an inline implementation. Differential Revision: https://reviews.llvm.org/D71082
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/CGExpr.cpp9
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp5
2 files changed, 13 insertions, 1 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index c1a0d5639d1..1c961f0ce69 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -4622,8 +4622,15 @@ RValue CodeGenFunction::EmitSimpleCallExpr(const CallExpr *E,
}
static CGCallee EmitDirectCallee(CodeGenFunction &CGF, const FunctionDecl *FD) {
+
if (auto builtinID = FD->getBuiltinID()) {
- return CGCallee::forBuiltin(builtinID, FD);
+ // Replaceable builtin provide their own implementation of a builtin. Unless
+ // we are in the builtin implementation itself, don't call the actual
+ // builtin. If we are in the builtin implementation, avoid trivial infinite
+ // recursion.
+ if (!FD->isInlineBuiltinDeclaration() ||
+ CGF.CurFn->getName() == FD->getName())
+ return CGCallee::forBuiltin(builtinID, FD);
}
llvm::Constant *calleePtr = EmitFunctionDeclPointer(CGF.CGM, FD);
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 963cd82210c..5e0f0db90b0 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -1840,6 +1840,11 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD, llvm::Function *F,
else if (const auto *SA = FD->getAttr<SectionAttr>())
F->setSection(SA->getName());
+ if (FD->isInlineBuiltinDeclaration()) {
+ F->addAttribute(llvm::AttributeList::FunctionIndex,
+ llvm::Attribute::NoBuiltin);
+ }
+
if (FD->isReplaceableGlobalAllocationFunction()) {
// A replaceable global allocation function does not act like a builtin by
// default, only if it is invoked by a new-expression or delete-expression.
OpenPOWER on IntegriCloud