Anastasia updated this revision to Diff 175120.
Anastasia added a comment.

Removed FIXME from the test case that is being fixed.


https://reviews.llvm.org/D54858

Files:
  lib/Sema/SemaDecl.cpp
  lib/Sema/TreeTransform.h
  test/CodeGenOpenCLCXX/template-address-spaces.cl
  test/SemaOpenCLCXX/address-space-templates.cl

Index: test/SemaOpenCLCXX/address-space-templates.cl
===================================================================
--- /dev/null
+++ test/SemaOpenCLCXX/address-space-templates.cl
@@ -0,0 +1,12 @@
+//RUN: %clang_cc1 %s -cl-std=c++ -pedantic -verify -fsyntax-only
+
+template <typename T>
+struct S {
+  T a;        // expected-error{{field may not be qualified with an address space}}
+  T f1();     // expected-error{{function type may not be qualified with an address space}}
+  void f2(T); // expected-error{{parameter may not be qualified with an address space}}
+};
+
+void bar() {
+  S<const __global int> sintgl; // expected-note{{in instantiation of template class 'S<const __global int>' requested here}}
+}
Index: test/CodeGenOpenCLCXX/template-address-spaces.cl
===================================================================
--- test/CodeGenOpenCLCXX/template-address-spaces.cl
+++ test/CodeGenOpenCLCXX/template-address-spaces.cl
@@ -21,8 +21,6 @@
   S<int> sint;
   S<int*> sintptr;
   S<__global int*> sintptrgl;
-  // FIXME: Preserve AS in TreeTransform
-  //S<__global int> sintgl;
 
   sint.foo();
   sintptr.foo();
Index: lib/Sema/TreeTransform.h
===================================================================
--- lib/Sema/TreeTransform.h
+++ lib/Sema/TreeTransform.h
@@ -4231,6 +4231,15 @@
                                                QualifiedTypeLoc T) {
   Qualifiers Quals = T.getType().getLocalQualifiers();
 
+  // Template parameter types used as function parameters are deduced to
+  // private addr space in OpenCL just like regular function parameters.
+  // The instantiated template might be given different addr space,
+  // this is incorrect but we can only diagnose it once the type is created.
+  // Therefore, the addr space is ignored here so that the type creation
+  // succeeds.
+  if (SemaRef.getLangOpts().OpenCL && T.getType()->isTemplateTypeParmType())
+    Quals.removeAddressSpace();
+
   QualType Result = getDerived().TransformType(TLB, T.getUnqualifiedLoc());
   if (Result.isNull())
     return QualType();
@@ -5273,6 +5282,13 @@
     if (ResultType.isNull())
       return QualType();
 
+    // Return type cann't be qualified with an address space.
+    if (ResultType.getAddressSpace() != LangAS::Default) {
+      SemaRef.Diag(TL.getReturnLoc().getBeginLoc(),
+                   diag::err_attribute_address_function_type);
+      return QualType();
+    }
+
     if (getDerived().TransformFunctionTypeParams(
             TL.getBeginLoc(), TL.getParams(),
             TL.getTypePtr()->param_type_begin(),
Index: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -15094,22 +15094,6 @@
     }
   }
 
-  // TR 18037 does not allow fields to be declared with address spaces.
-  if (T.getQualifiers().hasAddressSpace() ||
-      T->isDependentAddressSpaceType() ||
-      T->getBaseElementTypeUnsafe()->isDependentAddressSpaceType()) {
-    Diag(Loc, diag::err_field_with_address_space);
-    D.setInvalidType();
-  }
-
-  // OpenCL v1.2 s6.9b,r & OpenCL v2.0 s6.12.5 - The following types cannot be
-  // used as structure or union field: image, sampler, event or block types.
-  if (LangOpts.OpenCL && (T->isEventT() || T->isImageType() ||
-                          T->isSamplerT() || T->isBlockPointerType())) {
-    Diag(Loc, diag::err_opencl_type_struct_or_union_field) << T;
-    D.setInvalidType();
-  }
-
   DiagnoseFunctionSpecifiers(D.getDeclSpec());
 
   if (D.getDeclSpec().isInlineSpecified())
@@ -15221,12 +15205,30 @@
     }
   }
 
-  // OpenCL v1.2 s6.9.c: bitfields are not supported.
-  if (BitWidth && getLangOpts().OpenCL) {
-    Diag(Loc, diag::err_opencl_bitfields);
+  // TR 18037 does not allow fields to be declared with address space
+  if (T.getQualifiers().hasAddressSpace() || T->isDependentAddressSpaceType() ||
+      T->getBaseElementTypeUnsafe()->isDependentAddressSpaceType()) {
+    Diag(Loc, diag::err_field_with_address_space);
+    Record->setInvalidDecl();
     InvalidDecl = true;
   }
 
+  if (LangOpts.OpenCL) {
+    // OpenCL v1.2 s6.9b,r & OpenCL v2.0 s6.12.5 - The following types cannot be
+    // used as structure or union field: image, sampler, event or block types.
+    if (T->isEventT() || T->isImageType() || T->isSamplerT() ||
+        T->isBlockPointerType()) {
+      Diag(Loc, diag::err_opencl_type_struct_or_union_field) << T;
+      Record->setInvalidDecl();
+      InvalidDecl = true;
+    }
+    // OpenCL v1.2 s6.9.c: bitfields are not supported.
+    if (BitWidth) {
+      Diag(Loc, diag::err_opencl_bitfields);
+      InvalidDecl = true;
+    }
+  }
+
   // Anonymous bit-fields cannot be cv-qualified (CWG 2229).
   if (!InvalidDecl && getLangOpts().CPlusPlus && !II && BitWidth &&
       T.hasQualifiers()) {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to