r334700 - [OpenCL] Support new/delete in Sema

Sven van Haastregt via cfe-commits cfe-commits at lists.llvm.org
Thu Jun 14 02:51:54 PDT 2018


Author: svenvh
Date: Thu Jun 14 02:51:54 2018
New Revision: 334700

URL: http://llvm.org/viewvc/llvm-project?rev=334700&view=rev
Log:
[OpenCL] Support new/delete in Sema

Reject uses of the default new/delete operators with a diagnostic
instead of a crash in OpenCL C++ mode and accept user-defined forms.

Differential Revision: https://reviews.llvm.org/D46651

Added:
    cfe/trunk/test/SemaOpenCLCXX/newdelete.cl
Modified:
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/lib/Sema/SemaType.cpp

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=334700&r1=334699&r2=334700&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Jun 14 02:51:54 2018
@@ -13007,6 +13007,13 @@ CheckOperatorNewDeleteDeclarationScope(S
   return false;
 }
 
+static QualType
+RemoveAddressSpaceFromPtr(Sema &SemaRef, const PointerType *PtrTy) {
+  QualType QTy = PtrTy->getPointeeType();
+  QTy = SemaRef.Context.removeAddrSpaceQualType(QTy);
+  return SemaRef.Context.getPointerType(QTy);
+}
+
 static inline bool
 CheckOperatorNewDeleteTypes(Sema &SemaRef, const FunctionDecl *FnDecl,
                             CanQualType ExpectedResultType,
@@ -13022,6 +13029,13 @@ CheckOperatorNewDeleteTypes(Sema &SemaRe
                         diag::err_operator_new_delete_dependent_result_type)
     << FnDecl->getDeclName() << ExpectedResultType;
 
+  // OpenCL C++: the operator is valid on any address space.
+  if (SemaRef.getLangOpts().OpenCLCPlusPlus) {
+    if (auto *PtrTy = ResultType->getAs<PointerType>()) {
+      ResultType = RemoveAddressSpaceFromPtr(SemaRef, PtrTy);
+    }
+  }
+
   // Check that the result type is what we expect.
   if (SemaRef.Context.getCanonicalType(ResultType) != ExpectedResultType)
     return SemaRef.Diag(FnDecl->getLocation(),
@@ -13047,6 +13061,13 @@ CheckOperatorNewDeleteTypes(Sema &SemaRe
       << FnDecl->getDeclName() << ExpectedFirstParamType;
 
   // Check that the first parameter type is what we expect.
+  if (SemaRef.getLangOpts().OpenCLCPlusPlus) {
+    // OpenCL C++: the operator is valid on any address space.
+    if (auto *PtrTy =
+            FnDecl->getParamDecl(0)->getType()->getAs<PointerType>()) {
+      FirstParamType = RemoveAddressSpaceFromPtr(SemaRef, PtrTy);
+    }
+  }
   if (SemaRef.Context.getCanonicalType(FirstParamType).getUnqualifiedType() !=
       ExpectedFirstParamType)
     return SemaRef.Diag(FnDecl->getLocation(), InvalidParamTypeDiag)

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=334700&r1=334699&r2=334700&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Thu Jun 14 02:51:54 2018
@@ -2146,7 +2146,8 @@ bool Sema::CheckAllocatedType(QualType A
   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();
@@ -2362,6 +2363,11 @@ bool Sema::FindAllocationFunctions(Sourc
       LookupQualifiedName(R, Context.getTranslationUnitDecl());
     }
 
+    if (getLangOpts().OpenCLCPlusPlus && R.empty()) {
+      Diag(StartLoc, diag::err_openclcxx_not_supported) << "default new";
+      return true;
+    }
+
     assert(!R.empty() && "implicitly declared allocation functions not found");
     assert(!R.isAmbiguous() && "global allocation functions are ambiguous");
 
@@ -2597,6 +2603,11 @@ void Sema::DeclareGlobalNewDelete() {
   if (GlobalNewDeleteDeclared)
     return;
 
+  // OpenCL C++ 1.0 s2.9: the implicitly declared new and delete operators
+  // are not supported.
+  if (getLangOpts().OpenCLCPlusPlus)
+    return;
+
   // C++ [basic.std.dynamic]p2:
   //   [...] The following allocation and deallocation functions (18.4) are
   //   implicitly declared in global scope in each translation unit of a
@@ -3230,7 +3241,8 @@ Sema::ActOnCXXDelete(SourceLocation Star
     QualType Pointee = Type->getAs<PointerType>()->getPointeeType();
     QualType PointeeElem = Context.getBaseElementType(Pointee);
 
-    if (Pointee.getAddressSpace() != LangAS::Default)
+    if (Pointee.getAddressSpace() != LangAS::Default &&
+        !getLangOpts().OpenCLCPlusPlus)
       return Diag(Ex.get()->getLocStart(),
                   diag::err_address_space_qualified_delete)
                << Pointee.getUnqualifiedType()
@@ -3305,6 +3317,11 @@ Sema::ActOnCXXDelete(SourceLocation Star
     }
 
     if (!OperatorDelete) {
+      if (getLangOpts().OpenCLCPlusPlus) {
+        Diag(StartLoc, diag::err_openclcxx_not_supported) << "default delete";
+        return ExprError();
+      }
+
       bool IsComplete = isCompleteType(StartLoc, Pointee);
       bool CanProvideSize =
           IsComplete && (!ArrayForm || UsualArrayDeleteWantsSize ||

Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=334700&r1=334699&r2=334700&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Thu Jun 14 02:51:54 2018
@@ -7173,8 +7173,9 @@ static void deduceOpenCLImplicitAddrSpac
   // 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:

Added: cfe/trunk/test/SemaOpenCLCXX/newdelete.cl
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaOpenCLCXX/newdelete.cl?rev=334700&view=auto
==============================================================================
--- cfe/trunk/test/SemaOpenCLCXX/newdelete.cl (added)
+++ cfe/trunk/test/SemaOpenCLCXX/newdelete.cl Thu Jun 14 02:51:54 2018
@@ -0,0 +1,55 @@
+// 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;
+
+class B {
+  public:
+  B() : bx(42) {}
+  void *operator new(size_t);
+  void operator delete(void *ptr);
+  int bx;
+};
+
+// There are no global user-defined new operators at this point. Test that clang
+// rejects these gracefully.
+void test_default_new_delete(void *buffer, A **pa) {
+  A *a = new A;         // expected-error {{'default new' is not supported in OpenCL C++}}
+  delete a;             // expected-error {{'default delete' is not supported in OpenCL C++}}
+  *pa = new (buffer) A; // expected-error {{'default new' is not supported in OpenCL C++}}
+}
+
+// expected-note at +1 {{candidate function not viable: requires 2 arguments, but 1 was provided}}
+void *operator new(size_t _s, void *ptr) noexcept {
+  return ptr;
+}
+
+// expected-note at +1 {{candidate function not viable: requires 2 arguments, but 1 was provided}}
+void *operator new[](size_t _s, void *ptr) noexcept {
+  return ptr;
+}
+
+void test_new_delete(void *buffer, A **a, B **b) {
+  *a = new A; // expected-error {{no matching function for call to 'operator new'}}
+  delete a;   // expected-error {{'default delete' is not supported in OpenCL C++}}
+
+  *a = new A[20]; // expected-error {{no matching function for call to 'operator new[]'}}
+  delete[] *a;    // expected-error {{'default delete' is not supported in OpenCL C++}}
+
+  // User-defined placement new is supported.
+  *a = new (buffer) A;
+
+  // User-defined placement new[] is supported.
+  *a = new (buffer) A[30];
+
+  // User-defined new is supported.
+  *b = new B;
+
+  // User-defined delete is supported.
+  delete *b;
+}




More information about the cfe-commits mailing list