Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/system override #50

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions .github/workflows/llvm.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: CI

on: [push]

jobs:
build_llvm:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
- ubuntu-latest
- windows-latest
- macOS-latest
cmake_args:
- ""
steps:
- name: Setup Windows
if: startsWith(matrix.os, 'windows')
uses: tstellar/actions/setup-windows@master
with:
arch: amd64
- uses: actions/checkout@v1
with:
fetch-depth: 1
- name: Install Ninja
uses: tstellar/actions/install-ninja@master
with:
os: ${{ runner.os }}
- name: Test LLVM
uses: tstellar/actions/build-test-llvm-project@master
with:
cmake_args: -G Ninja -DCMAKE_BUILD_TYPE=Release ${{ matrix.cmake_args }}
os: ${{ runner.os }}
3 changes: 3 additions & 0 deletions clang/include/clang/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -2272,6 +2272,9 @@ class FunctionDecl : public DeclaratorDecl,
/// true through IsAligned.
bool isReplaceableGlobalAllocationFunction(bool *IsAligned = nullptr) const;

/// Determine if this function provides the implementation of a system Builtin
bool isReplaceableSystemFunction() const;

/// Determine whether this is a destroying operator delete.
bool isDestroyingOperatorDelete() const;

Expand Down
15 changes: 15 additions & 0 deletions clang/lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3003,6 +3003,15 @@ bool FunctionDecl::isReplaceableGlobalAllocationFunction(bool *IsAligned) const
return Params == FPT->getNumParams();
}

bool FunctionDecl::isReplaceableSystemFunction() const {
FunctionDecl const *Definition;
if (hasBody(Definition)) {
const SourceManager &SM = getASTContext().getSourceManager();
return SM.isInSystemHeader(Definition->getLocation());
}
return false;
}

bool FunctionDecl::isDestroyingOperatorDelete() const {
// C++ P0722:
// Within a class C, a single object deallocation function with signature
Expand Down Expand Up @@ -3165,6 +3174,12 @@ unsigned FunctionDecl::getBuiltinID(bool ConsiderWrapperFunctions) const {
// function. Determine whether it actually refers to the C library
// function or whether it just has the same name.

// If a system-level body was provided, use it instead of the intrinsic. Some
// C library do that to implement fortified version.
if (isReplaceableSystemFunction()) {
return 0;
}

// If this is a static function, it's not a builtin.
if (!ConsiderWrapperFunctions && getStorageClass() == SC_Static)
return 0;
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/CodeGen/CodeGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1831,6 +1831,11 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD, llvm::Function *F,
else if (const auto *SA = FD->getAttr<SectionAttr>())
F->setSection(SA->getName());

if (FD->isReplaceableSystemFunction()) {
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.
Expand Down
8 changes: 8 additions & 0 deletions clang/test/CodeGen/memcpy-nobuitin.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// RUN: clang -S -emit-llvm -o- %s -isystem . -DWITH_DECL | FileCheck --check-prefix=CHECK-WITH-DECL %s
// RUN: clang -S -emit-llvm -o- %s -isystem . -UWITH_DECL | FileCheck --check-prefix=CHECK-NO-DECL %s
// CHECK-WITH-DECL-NOT: @llvm.memcpy
// CHECK-NO-DECL: @llvm.memcpy
#include <memcpy-nobuitin.inc>
void test(void* dest, void const* from, size_t n) {
memcpy(dest, from, n);
}
12 changes: 12 additions & 0 deletions clang/test/CodeGen/memcpy-nobuitin.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include <stddef.h>
extern void* memcpy(void* dest, void const* from, size_t n);

#ifdef WITH_DECL
inline void* memcpy(void* dest, void const* from, size_t n) {
char const* ifrom = from;
char * idest = dest;
while(n--)
*idest++ = *ifrom++;
return dest;
}
#endif