svenvh created this revision.
svenvh added reviewers: yaxunl, Anastasia.
Herald added a subscriber: cfe-commits.

Stop crashing on placement new/delete in OpenCL C++ mode, and reject
non-placement new/delete with a diagnostic instead of a crash.


Repository:
  rC Clang

https://reviews.llvm.org/D46651

Files:
  lib/Sema/SemaDeclCXX.cpp
  lib/Sema/SemaExprCXX.cpp
  lib/Sema/SemaType.cpp
  test/SemaOpenCLCXX/newdelete.cl

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];
+}
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: 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/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<PointerType>()) {
+      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(),
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D46651: [OpenCL... Sven van Haastregt via Phabricator via cfe-commits

Reply via email to