diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt --- a/clang/lib/Headers/CMakeLists.txt +++ b/clang/lib/Headers/CMakeLists.txt @@ -161,7 +161,6 @@ openmp_wrappers/complex openmp_wrappers/__clang_openmp_device_functions.h openmp_wrappers/complex_cmath.h - openmp_wrappers/new ) set(output_dir ${LLVM_LIBRARY_OUTPUT_INTDIR}/clang/${CLANG_VERSION}/include) diff --git a/clang/lib/Headers/openmp_wrappers/__clang_openmp_device_functions.h b/clang/lib/Headers/openmp_wrappers/__clang_openmp_device_functions.h --- a/clang/lib/Headers/openmp_wrappers/__clang_openmp_device_functions.h +++ b/clang/lib/Headers/openmp_wrappers/__clang_openmp_device_functions.h @@ -39,4 +39,63 @@ #pragma omp end declare variant +// Ensure we make `_ZdlPv`, aka. `operator delete(void*)` available without the +// need to `include ` in C++ mode. +#ifdef __cplusplus + +// We require malloc/free. +#include + +#pragma push_macro("OPENMP_NOEXCEPT") +#if __cplusplus >= 201103L +#define OPENMP_NOEXCEPT noexcept +#else +#define OPENMP_NOEXCEPT +#endif + +// Device overrides for non-placement new and delete. +inline void *operator new(__SIZE_TYPE__ size) { + if (size == 0) + size = 1; + return ::malloc(size); +} +inline void *operator new(__SIZE_TYPE__ size, + const std::nothrow_t &) OPENMP_NOEXCEPT { + return ::operator new(size); +} + +inline void *operator new[](__SIZE_TYPE__ size) { return ::operator new(size); } +inline void *operator new[](__SIZE_TYPE__ size, const std::nothrow_t &) { + return ::operator new(size); +} + +inline void operator delete(void *ptr)OPENMP_NOEXCEPT { + if (ptr) + ::free(ptr); +} +inline void operator delete(void *ptr, const std::nothrow_t &)OPENMP_NOEXCEPT { + ::operator delete(ptr); +} + +inline void operator delete[](void *ptr) OPENMP_NOEXCEPT { + ::operator delete(ptr); +} +inline void operator delete[](void *ptr, + const std::nothrow_t &) OPENMP_NOEXCEPT { + ::operator delete(ptr); +} + +// Sized delete, C++14 only. +#if __cplusplus >= 201402L +inline void operator delete(void *ptr, __SIZE_TYPE__ size)OPENMP_NOEXCEPT { + ::operator delete(ptr); +} +inline void operator delete[](void *ptr, __SIZE_TYPE__ size) OPENMP_NOEXCEPT { + ::operator delete(ptr); +} +#endif + +#pragma pop_macro("OPENMP_NOEXCEPT") +#endif + #endif diff --git a/clang/lib/Headers/openmp_wrappers/new b/clang/lib/Headers/openmp_wrappers/new deleted file mode 100644 --- a/clang/lib/Headers/openmp_wrappers/new +++ /dev/null @@ -1,70 +0,0 @@ -//===--------- new - OPENMP wrapper for ------------------------------=== -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===-----------------------------------------------------------------------=== - -#ifndef __CLANG_OPENMP_WRAPPERS_NEW -#define __CLANG_OPENMP_WRAPPERS_NEW - -#include_next - -#if defined(__NVPTX__) && defined(_OPENMP) - -#include - -#pragma push_macro("OPENMP_NOEXCEPT") -#if __cplusplus >= 201103L -#define OPENMP_NOEXCEPT noexcept -#else -#define OPENMP_NOEXCEPT -#endif - -// Device overrides for non-placement new and delete. -inline void *operator new(__SIZE_TYPE__ size) { - if (size == 0) - size = 1; - return ::malloc(size); -} -inline void *operator new(__SIZE_TYPE__ size, - const std::nothrow_t &) OPENMP_NOEXCEPT { - return ::operator new(size); -} - -inline void *operator new[](__SIZE_TYPE__ size) { return ::operator new(size); } -inline void *operator new[](__SIZE_TYPE__ size, const std::nothrow_t &) { - return ::operator new(size); -} - -inline void operator delete(void *ptr)OPENMP_NOEXCEPT { - if (ptr) - ::free(ptr); -} -inline void operator delete(void *ptr, const std::nothrow_t &)OPENMP_NOEXCEPT { - ::operator delete(ptr); -} - -inline void operator delete[](void *ptr) OPENMP_NOEXCEPT { - ::operator delete(ptr); -} -inline void operator delete[](void *ptr, - const std::nothrow_t &) OPENMP_NOEXCEPT { - ::operator delete(ptr); -} - -// Sized delete, C++14 only. -#if __cplusplus >= 201402L -inline void operator delete(void *ptr, __SIZE_TYPE__ size)OPENMP_NOEXCEPT { - ::operator delete(ptr); -} -inline void operator delete[](void *ptr, __SIZE_TYPE__ size) OPENMP_NOEXCEPT { - ::operator delete(ptr); -} -#endif - -#pragma pop_macro("OPENMP_NOEXCEPT") -#endif - -#endif // include guard diff --git a/clang/test/Headers/Inputs/include/new b/clang/test/Headers/Inputs/include/new new file mode 100644 --- /dev/null +++ b/clang/test/Headers/Inputs/include/new @@ -0,0 +1,7 @@ + +namespace std +{ + +struct nothrow_t { explicit nothrow_t() = default; }; + +} diff --git a/clang/test/Headers/Inputs/include/stdlib.h b/clang/test/Headers/Inputs/include/stdlib.h --- a/clang/test/Headers/Inputs/include/stdlib.h +++ b/clang/test/Headers/Inputs/include/stdlib.h @@ -1,6 +1,9 @@ #pragma once typedef __SIZE_TYPE__ size_t; +void *malloc(size_t); +void free(void*); + #ifndef __cplusplus extern int abs(int __x) __attribute__((__const__)); #endif diff --git a/clang/test/Headers/target_include_new.cpp b/clang/test/Headers/target_include_new.cpp new file mode 100644 --- /dev/null +++ b/clang/test/Headers/target_include_new.cpp @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 -internal-isystem %S/../../lib/Headers/openmp_wrappers -include __clang_openmp_device_functions.h -internal-isystem %S/Inputs/include -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64 -emit-llvm-bc %s -o %t-ppc-host.bc +// RUN: %clang_cc1 -internal-isystem %S/../../lib/Headers/openmp_wrappers -include __clang_openmp_device_functions.h -internal-isystem %S/Inputs/include -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64 -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s +// expected-no-diagnostics + +// Ensure we make `_ZdlPv`, aka. `operator delete(void*)` available without the need to `include `. + +// CHECK: define {{.*}}_ZdlPv + +#ifndef HEADER +#define HEADER + +class Base { + public: + virtual ~Base() = default; +}; + +class Derived : public Base { + public: + #pragma omp declare target + Derived(); + #pragma omp end declare target +}; + +Derived::Derived() { } + +int main(void) { + #pragma omp target + { + } + return 0; +} +#endif