]> granicus.if.org Git - clang/commitdiff
[OpenCL] Improve diags for addr spaces in templates
authorAnastasia Stulova <anastasia.stulova@arm.com>
Thu, 29 Nov 2018 14:11:15 +0000 (14:11 +0000)
committerAnastasia Stulova <anastasia.stulova@arm.com>
Thu, 29 Nov 2018 14:11:15 +0000 (14:11 +0000)
Fix ICEs on template instantiations that were leading to
the creation of invalid code patterns with address spaces.

Incorrect cases are now diagnosed properly.

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

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@347865 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaDecl.cpp
lib/Sema/SemaType.cpp
lib/Sema/TreeTransform.h
test/CodeGenOpenCLCXX/template-address-spaces.cl
test/SemaOpenCLCXX/address-space-templates.cl [new file with mode: 0644]

index 5b2d2899f81103fb6aa530352b794803a8a9cefc..becbb1f186d943e37b2b24920a9a199e354c1ea1 100644 (file)
@@ -15148,22 +15148,6 @@ FieldDecl *Sema::HandleField(Scope *S, RecordDecl *Record,
     }
   }
 
-  // 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())
@@ -15275,12 +15259,30 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T,
     }
   }
 
-  // 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()) {
index 99ea2d129ef67d2034db0336c679be51055a16e1..011d0a585f0914bbe8dee747ae88994836c96b56 100644 (file)
@@ -7226,8 +7226,9 @@ static void deduceOpenCLImplicitAddrSpace(TypeProcessingState &State,
     if (IsPointee) {
       ImpAddr = LangAS::opencl_generic;
     } else {
-      if (D.getContext() == DeclaratorContext::TemplateArgContext) {
-        // Do not deduce address space for non-pointee type in template args
+      if (D.getContext() == DeclaratorContext::TemplateArgContext ||
+          T->isDependentType()) {
+        // Do not deduce address space for non-pointee type in templates.
       } else if (D.getContext() == DeclaratorContext::FileContext) {
         ImpAddr = LangAS::opencl_global;
       } else {
index 4011ec251cfa95eb1b1de0861894a7d844d75aa9..58f73ef10181c5b6a6394437ad233e7672dc76e6 100644 (file)
@@ -5284,6 +5284,13 @@ QualType TreeTransform<Derived>::TransformFunctionProtoType(
     if (ResultType.isNull())
       return QualType();
 
+    // Return type can not 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 606ab22f69f5cfcd147ec836c02f2dd5cc183956..eb274ea4560afbae9a9204c7f38356fcec8a7889 100644 (file)
@@ -21,11 +21,8 @@ void bar(){
   S<int> sint;
   S<int*> sintptr;
   S<__global int*> sintptrgl;
-  // FIXME: Preserve AS in TreeTransform
-  //S<__global int> sintgl;
 
   sint.foo();
   sintptr.foo();
   sintptrgl.foo();
-  //sintgl.foo();
 }
diff --git a/test/SemaOpenCLCXX/address-space-templates.cl b/test/SemaOpenCLCXX/address-space-templates.cl
new file mode 100644 (file)
index 0000000..780175b
--- /dev/null
@@ -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}}
+}