]> granicus.if.org Git - clang/commitdiff
[Sema] Allow creating types with multiple of the same addrspace.
authorAlexey Bader <alexey.bader@intel.com>
Wed, 20 Jun 2018 08:31:24 +0000 (08:31 +0000)
committerAlexey Bader <alexey.bader@intel.com>
Wed, 20 Jun 2018 08:31:24 +0000 (08:31 +0000)
Summary:
The comment with the OpenCL clause about this clearly
says: "No type shall be qualified by qualifiers for
two or more different address spaces."

This must mean that two or more qualifiers for the
_same_ address space is allowed. However, it is
likely unintended by the programmer, so emit a
warning.

For dependent address space types, reject them like
before since we cannot know what the address space
will be.

Patch by Bevin Hansson (ebevhan).

Reviewers: Anastasia

Reviewed By: Anastasia

Subscribers: bader, cfe-commits

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

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

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaType.cpp
test/Sema/address_spaces.c
test/SemaOpenCL/address-spaces.cl

index 9c1b549bdb7cb8abaac1a6c9e6d4dd61283d2b24..878443df4a0d0d0040f148733c02c3ceae48e34f 100644 (file)
@@ -2576,6 +2576,9 @@ def err_attribute_address_space_too_high : Error<
   "address space is larger than the maximum supported (%0)">;
 def err_attribute_address_multiple_qualifiers : Error<
   "multiple address spaces specified for type">;
+def warn_attribute_address_multiple_identical_qualifiers : Warning<
+  "multiple identical address spaces specified for type">,
+  InGroup<DuplicateDeclSpecifier>;
 def err_attribute_address_function_type : Error<
   "function type may not be qualified with an address space">;
 def err_as_qualified_auto_decl : Error<
index 9ee947b80a3944f2cd8b4ab53212b71185676323..978c1cc0158d223d2b2dd1c3eefeaa981f462366 100644 (file)
@@ -5758,14 +5758,6 @@ QualType Sema::BuildAddressSpaceAttr(QualType &T, Expr *AddrSpace,
                                      SourceLocation AttrLoc) {
   if (!AddrSpace->isValueDependent()) { 
 
-    // If this type is already address space qualified, reject it.
-    // ISO/IEC TR 18037 S5.3 (amending C99 6.7.3): "No type shall be qualified
-    // by qualifiers for two or more different address spaces."
-    if (T.getAddressSpace() != LangAS::Default) {
-      Diag(AttrLoc, diag::err_attribute_address_multiple_qualifiers);
-      return QualType();
-    }
-
     llvm::APSInt addrSpace(32);
     if (!AddrSpace->isIntegerConstantExpr(addrSpace, Context)) {
       Diag(AttrLoc, diag::err_attribute_argument_type)
@@ -5796,6 +5788,20 @@ QualType Sema::BuildAddressSpaceAttr(QualType &T, Expr *AddrSpace,
     LangAS ASIdx =
         getLangASFromTargetAS(static_cast<unsigned>(addrSpace.getZExtValue()));
 
+    // If this type is already address space qualified with a different
+    // address space, reject it.
+    // ISO/IEC TR 18037 S5.3 (amending C99 6.7.3): "No type shall be qualified
+    // by qualifiers for two or more different address spaces."
+    if (T.getAddressSpace() != LangAS::Default) {
+      if (T.getAddressSpace() != ASIdx) {
+        Diag(AttrLoc, diag::err_attribute_address_multiple_qualifiers);
+        return QualType();
+      } else
+        // Emit a warning if they are identical; it's likely unintended.
+        Diag(AttrLoc,
+             diag::warn_attribute_address_multiple_identical_qualifiers);
+    }
+
     return Context.getAddrSpaceQualType(T, ASIdx);
   }
 
@@ -5817,15 +5823,6 @@ QualType Sema::BuildAddressSpaceAttr(QualType &T, Expr *AddrSpace,
 /// space for the type.
 static void HandleAddressSpaceTypeAttribute(QualType &Type,
                                             const AttributeList &Attr, Sema &S){
-  // If this type is already address space qualified, reject it.
-  // ISO/IEC TR 18037 S5.3 (amending C99 6.7.3): "No type shall be qualified by
-  // qualifiers for two or more different address spaces."
-  if (Type.getAddressSpace() != LangAS::Default) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_address_multiple_qualifiers);
-    Attr.setInvalid();
-    return;
-  }
-
   // ISO/IEC TR 18037 S5.3 (amending C99 6.7.3): "A function type shall not be
   // qualified by an address-space qualifier."
   if (Type->isFunctionType()) {
@@ -5888,6 +5885,21 @@ static void HandleAddressSpaceTypeAttribute(QualType &Type,
       llvm_unreachable("Invalid address space");
     }
 
+    // If this type is already address space qualified with a different
+    // address space, reject it.
+    // ISO/IEC TR 18037 S5.3 (amending C99 6.7.3): "No type shall be qualified by
+    // qualifiers for two or more different address spaces."
+    if (Type.getAddressSpace() != LangAS::Default) {
+      if (Type.getAddressSpace() != ASIdx) {
+        S.Diag(Attr.getLoc(), diag::err_attribute_address_multiple_qualifiers);
+        Attr.setInvalid();
+        return;
+      } else
+        // Emit a warning if they are identical; it's likely unintended.
+        S.Diag(Attr.getLoc(),
+               diag::warn_attribute_address_multiple_identical_qualifiers);
+    }
+
     Type = S.Context.getAddrSpaceQualType(Type, ASIdx);
   }
 }
index 018a8521bfc50a68d32b6d86a66877cc8a6f0668..87707d7deb0de9d8d93fd1cd645c596f964b3c2d 100644 (file)
@@ -14,6 +14,7 @@ void foo(_AS3 float *a,
 
   int _AS1 _AS2 *Y;   // expected-error {{multiple address spaces specified for type}}
   int *_AS1 _AS2 *Z;  // expected-error {{multiple address spaces specified for type}}
+  int *_AS1 _AS1 *M;  // expected-warning {{multiple identical address spaces specified for type}}
 
   _AS1 int local;     // expected-error {{automatic variable qualified with an address space}}
   _AS1 int array[5];  // expected-error {{automatic variable qualified with an address space}}
index 2fec3e8647df3e75d350f32af04558cb9ad6fb66..c5c58a6a30d07b980600a88835f77edae6064076 100644 (file)
@@ -62,4 +62,6 @@ void func_multiple_addr(void) {
   __private __local int *var2;  // expected-error {{multiple address spaces specified for type}}
   __local private_int_t var3;   // expected-error {{multiple address spaces specified for type}}
   __local private_int_t *var4;  // expected-error {{multiple address spaces specified for type}}
+  __private private_int_t var5; // expected-warning {{multiple identical address spaces specified for type}}
+  __private private_int_t *var6;// expected-warning {{multiple identical address spaces specified for type}}
 }