Commit d437fba8 authored by serge-sans-paille's avatar serge-sans-paille
Browse files

Reapply Allow system header to provide their own implementation of some builtin

This reverts commit 3d210ed3.

See https://reviews.llvm.org/D71082 for the patch and discussion that make it
possible to reapply this patch.
parent 6b840834
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -2309,6 +2309,9 @@ public:
  /// true through IsAligned.
  bool isReplaceableGlobalAllocationFunction(bool *IsAligned = nullptr) const;

  /// Determine if this function provides an inline implementation of a builtin.
  bool isInlineBuiltinDeclaration() const;

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

+8 −0
Original line number Diff line number Diff line
@@ -3046,6 +3046,14 @@ bool FunctionDecl::isReplaceableGlobalAllocationFunction(bool *IsAligned) const
  return Params == FPT->getNumParams();
}

bool FunctionDecl::isInlineBuiltinDeclaration() const {
  if (!getBuiltinID())
    return false;

  const FunctionDecl *Definition;
  return hasBody(Definition) && Definition->isInlineSpecified();
}

bool FunctionDecl::isDestroyingOperatorDelete() const {
  // C++ P0722:
  //   Within a class C, a single object deallocation function with signature
+8 −1
Original line number Diff line number Diff line
@@ -4621,7 +4621,14 @@ RValue CodeGenFunction::EmitSimpleCallExpr(const CallExpr *E,
}

static CGCallee EmitDirectCallee(CodeGenFunction &CGF, const FunctionDecl *FD) {

  if (auto builtinID = FD->getBuiltinID()) {
    // 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);
  }

+5 −0
Original line number Diff line number Diff line
@@ -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.
+15 −0
Original line number Diff line number Diff line
// RUN: %clang_cc1 -verify -S -emit-llvm -o- %s -isystem %S -DWITH_DECL | FileCheck --check-prefix=CHECK-WITH-DECL %s
// RUN: %clang_cc1 -verify -S -emit-llvm -o- %s -isystem %S -UWITH_DECL | FileCheck --check-prefix=CHECK-NO-DECL %s
// RUN: %clang_cc1 -verify -S -emit-llvm -o- %s -isystem %S -DWITH_SELF_REFERENCE_DECL | FileCheck --check-prefix=CHECK-SELF-REF-DECL %s
//
// CHECK-WITH-DECL-NOT: @llvm.memcpy
// CHECK-NO-DECL: @llvm.memcpy
// CHECK-SELF-REF-DECL: @llvm.memcpy
//
#include <memcpy-nobuiltin.inc>
void test(void *dest, void const *from, size_t n) {
  memcpy(dest, from, n);

  static char buffer[1];
  memcpy(buffer, from, 2); // expected-warning {{'memcpy' will always overflow; destination buffer has size 1, but size argument is 2}}
}
Loading