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,46 @@ #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) { return ::operator new(size); } + +inline void operator delete(void *ptr)OPENMP_NOEXCEPT { ::free(ptr); } + +inline void operator delete[](void *ptr) 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 --- a/clang/lib/Headers/openmp_wrappers/new +++ b/clang/lib/Headers/openmp_wrappers/new @@ -9,6 +9,8 @@ #ifndef __CLANG_OPENMP_WRAPPERS_NEW #define __CLANG_OPENMP_WRAPPERS_NEW +// We need the system for the std::nothrow_t. The new/delete operators +// which do not use nothrow_t are provided without the header. #include_next #if defined(__NVPTX__) && defined(_OPENMP) @@ -22,48 +24,24 @@ #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 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