Index: lib/Sema/SemaDeclCXX.cpp =================================================================== --- lib/Sema/SemaDeclCXX.cpp +++ lib/Sema/SemaDeclCXX.cpp @@ -12981,6 +12981,18 @@ diag::err_operator_new_delete_dependent_result_type) << FnDecl->getDeclName() << ExpectedResultType; + // OpenCL C++: ignore the address space as the operator is valid on any + // address space. + if (SemaRef.getLangOpts().OpenCLCPlusPlus) { + if (auto *PtrTy = ResultType.getTypePtr()->getAs()) { + QualType PteeTy = PtrTy->getPointeeType(); + Qualifiers Quals = PteeTy.getQualifiers(); + Quals.removeAddressSpace(); + ResultType = SemaRef.Context.getQualifiedType(PteeTy.getUnqualifiedType(), Quals); + ResultType = SemaRef.Context.getPointerType(ResultType); + } + } + // Check that the result type is what we expect. if (SemaRef.Context.getCanonicalType(ResultType) != ExpectedResultType) return SemaRef.Diag(FnDecl->getLocation(), Index: lib/Sema/SemaExprCXX.cpp =================================================================== --- lib/Sema/SemaExprCXX.cpp +++ lib/Sema/SemaExprCXX.cpp @@ -2019,6 +2019,15 @@ if (!AllPlaceArgs.empty()) PlacementArgs = AllPlaceArgs; + else { + // OpenCL C++ 1.0 s2.9: non-placement new and delete operators are + // not supported. + if (getLangOpts().OpenCLCPlusPlus) { + Diag(StartLoc, diag::err_openclcxx_not_supported) + << "non-placement new/delete"; + return ExprError(); + } + } // FIXME: This is wrong: PlacementArgs misses out the first (size) argument. DiagnoseSentinelCalls(OperatorNew, PlacementLParen, PlacementArgs); @@ -2146,7 +2155,8 @@ else if (AllocType->isVariablyModifiedType()) return Diag(Loc, diag::err_variably_modified_new_type) << AllocType; - else if (AllocType.getAddressSpace() != LangAS::Default) + else if (AllocType.getAddressSpace() != LangAS::Default && + !getLangOpts().OpenCLCPlusPlus) return Diag(Loc, diag::err_address_space_qualified_new) << AllocType.getUnqualifiedType() << AllocType.getQualifiers().getAddressSpaceAttributePrintValue(); @@ -3157,6 +3167,11 @@ bool ArrayFormAsWritten = ArrayForm; bool UsualArrayDeleteWantsSize = false; + if (getLangOpts().OpenCLCPlusPlus) { + Diag(StartLoc, diag::err_openclcxx_not_supported) << "delete"; + return ExprError(); + } + if (!Ex.get()->isTypeDependent()) { // Perform lvalue-to-rvalue cast, if needed. Ex = DefaultLvalueConversion(Ex.get()); Index: lib/Sema/SemaType.cpp =================================================================== --- lib/Sema/SemaType.cpp +++ lib/Sema/SemaType.cpp @@ -7137,8 +7137,9 @@ // The default address space name for arguments to a function in a // program, or local variables of a function is __private. All function // arguments shall be in the __private address space. - if (State.getSema().getLangOpts().OpenCLVersion <= 120) { - ImpAddr = LangAS::opencl_private; + if (State.getSema().getLangOpts().OpenCLVersion <= 120 && + !State.getSema().getLangOpts().OpenCLCPlusPlus) { + ImpAddr = LangAS::opencl_private; } else { // If address space is not set, OpenCL 2.0 defines non private default // address spaces for some cases: Index: test/SemaOpenCLCXX/newdelete.cl =================================================================== --- /dev/null +++ test/SemaOpenCLCXX/newdelete.cl @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=c++ -pedantic -verify -fsyntax-only + +class A { + public: + A() : x(21) {} + int x; +}; + +typedef __SIZE_TYPE__ size_t; +void *operator new(size_t _s, void *ptr) noexcept { + return ptr; +} + +void *operator new[](size_t _s, void *ptr) noexcept { + return ptr; +} + +// Test that only placement new and delete are available. +void test_new_delete(void *buffer, A **a) { + *a = new A; // expected-error {{'non-placement new/delete' is not supported in OpenCL C++}} + delete a; // expected-error {{'delete' is not supported in OpenCL C++}} + + a = new A[20]; // expected-error {{'non-placement new/delete' is not supported in OpenCL C++}} + delete[] a; // expected-error {{'delete' is not supported in OpenCL C++}} + + // Placement new is supported. + *a = new (buffer) A; + + // Placement new is supported. + *a = new (buffer) A[30]; +}