joey updated this revision to Diff 78017.
joey added a comment.

Fixed a latent infinite loop bug in 'getImageAccess', it was dereferencing 
Attrs, instead of Next.


Repository:
  rL LLVM

https://reviews.llvm.org/D26668

Files:
  lib/Sema/SemaType.cpp
  test/SemaOpenCL/access-qualifier.cl
  test/SemaOpenCL/invalid-image.cl


Index: test/SemaOpenCL/invalid-image.cl
===================================================================
--- test/SemaOpenCL/invalid-image.cl
+++ test/SemaOpenCL/invalid-image.cl
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -verify %s
+// RUN: %clang_cc1 -verify -D=ATTR_TEST -fms-compatibility %s
 
 void test1(image1d_t *i) {} // expected-error{{pointer to type '__read_only 
image1d_t' is invalid in OpenCL}}
 
@@ -12,3 +13,8 @@
 }
 
 image1d_t test3() {} // expected-error{{declaring function return value of 
type '__read_only image1d_t' is not allowed}}
+
+#ifdef ATTR_TEST
+// Test case for an infinite loop bug.
+kernel void foob(read_only __ptr32  image2d_t i) { } // 
expected-error{{'__ptr32' attribute only applies to pointer arguments}}
+#endif
Index: test/SemaOpenCL/access-qualifier.cl
===================================================================
--- test/SemaOpenCL/access-qualifier.cl
+++ test/SemaOpenCL/access-qualifier.cl
@@ -67,3 +67,10 @@
 #else
 kernel void k13(__read_write image1d_t i){} // expected-error{{access 
qualifier '__read_write' can not be used for '__read_write image1d_t' prior to 
OpenCL version 2.0}}
 #endif
+
+#if __OPENCL_C_VERSION__ >= 200
+void myPipeWrite(write_only pipe int); // expected-note {{passing argument to 
parameter here}}
+kernel void k14(read_only pipe int p) {
+  myPipeWrite(p); // expected-error {{passing 'read_only pipe int' to 
parameter of incompatible type 'write_only pipe int'}}
+}
+#endif
Index: lib/Sema/SemaType.cpp
===================================================================
--- lib/Sema/SemaType.cpp
+++ lib/Sema/SemaType.cpp
@@ -1209,19 +1209,19 @@
   return CreateParsedType(Result, ResultTInfo);
 }
 
-static StringRef getImageAccessAttrStr(AttributeList *attrs) {
-  if (attrs) {
-
-    AttributeList *Next;
+static OpenCLAccessAttr::Spelling getImageAccess(const AttributeList *Attrs) {
+  if (Attrs) {
+    const AttributeList *Next = Attrs;
     do {
-      AttributeList &Attr = *attrs;
+      const AttributeList &Attr = *Next;
       Next = Attr.getNext();
       if (Attr.getKind() == AttributeList::AT_OpenCLAccess) {
-        return Attr.getName()->getName();
+        return static_cast<OpenCLAccessAttr::Spelling>(
+            Attr.getSemanticSpelling());
       }
     } while (Next);
   }
-  return "";
+  return OpenCLAccessAttr::Keyword_read_only;
 }
 
 /// \brief Convert the specified declspec to the appropriate type
@@ -1619,11 +1619,15 @@
 
 #define GENERIC_IMAGE_TYPE(ImgType, Id) \
   case DeclSpec::TST_##ImgType##_t: \
-    Result = llvm::StringSwitch<QualType>( \
-                 getImageAccessAttrStr(DS.getAttributes().getList())) \
-                 .Cases("write_only", "__write_only", Context.Id##WOTy) \
-                 .Cases("read_write", "__read_write", Context.Id##RWTy) \
-                 .Default(Context.Id##ROTy); \
+    switch (getImageAccess(DS.getAttributes().getList())) { \
+    case OpenCLAccessAttr::Keyword_write_only: \
+      Result = Context.Id##WOTy; break; \
+    case OpenCLAccessAttr::Keyword_read_write: \
+      Result = Context.Id##RWTy; break; \
+    case OpenCLAccessAttr::Keyword_read_only: \
+      Result = Context.Id##ROTy; break; \
+    default: assert(0 && "Unknown access attribute!"); \
+    } \
     break;
 #include "clang/Basic/OpenCLImageTypes.def"
 


Index: test/SemaOpenCL/invalid-image.cl
===================================================================
--- test/SemaOpenCL/invalid-image.cl
+++ test/SemaOpenCL/invalid-image.cl
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -verify %s
+// RUN: %clang_cc1 -verify -D=ATTR_TEST -fms-compatibility %s
 
 void test1(image1d_t *i) {} // expected-error{{pointer to type '__read_only image1d_t' is invalid in OpenCL}}
 
@@ -12,3 +13,8 @@
 }
 
 image1d_t test3() {} // expected-error{{declaring function return value of type '__read_only image1d_t' is not allowed}}
+
+#ifdef ATTR_TEST
+// Test case for an infinite loop bug.
+kernel void foob(read_only __ptr32  image2d_t i) { } // expected-error{{'__ptr32' attribute only applies to pointer arguments}}
+#endif
Index: test/SemaOpenCL/access-qualifier.cl
===================================================================
--- test/SemaOpenCL/access-qualifier.cl
+++ test/SemaOpenCL/access-qualifier.cl
@@ -67,3 +67,10 @@
 #else
 kernel void k13(__read_write image1d_t i){} // expected-error{{access qualifier '__read_write' can not be used for '__read_write image1d_t' prior to OpenCL version 2.0}}
 #endif
+
+#if __OPENCL_C_VERSION__ >= 200
+void myPipeWrite(write_only pipe int); // expected-note {{passing argument to parameter here}}
+kernel void k14(read_only pipe int p) {
+  myPipeWrite(p); // expected-error {{passing 'read_only pipe int' to parameter of incompatible type 'write_only pipe int'}}
+}
+#endif
Index: lib/Sema/SemaType.cpp
===================================================================
--- lib/Sema/SemaType.cpp
+++ lib/Sema/SemaType.cpp
@@ -1209,19 +1209,19 @@
   return CreateParsedType(Result, ResultTInfo);
 }
 
-static StringRef getImageAccessAttrStr(AttributeList *attrs) {
-  if (attrs) {
-
-    AttributeList *Next;
+static OpenCLAccessAttr::Spelling getImageAccess(const AttributeList *Attrs) {
+  if (Attrs) {
+    const AttributeList *Next = Attrs;
     do {
-      AttributeList &Attr = *attrs;
+      const AttributeList &Attr = *Next;
       Next = Attr.getNext();
       if (Attr.getKind() == AttributeList::AT_OpenCLAccess) {
-        return Attr.getName()->getName();
+        return static_cast<OpenCLAccessAttr::Spelling>(
+            Attr.getSemanticSpelling());
       }
     } while (Next);
   }
-  return "";
+  return OpenCLAccessAttr::Keyword_read_only;
 }
 
 /// \brief Convert the specified declspec to the appropriate type
@@ -1619,11 +1619,15 @@
 
 #define GENERIC_IMAGE_TYPE(ImgType, Id) \
   case DeclSpec::TST_##ImgType##_t: \
-    Result = llvm::StringSwitch<QualType>( \
-                 getImageAccessAttrStr(DS.getAttributes().getList())) \
-                 .Cases("write_only", "__write_only", Context.Id##WOTy) \
-                 .Cases("read_write", "__read_write", Context.Id##RWTy) \
-                 .Default(Context.Id##ROTy); \
+    switch (getImageAccess(DS.getAttributes().getList())) { \
+    case OpenCLAccessAttr::Keyword_write_only: \
+      Result = Context.Id##WOTy; break; \
+    case OpenCLAccessAttr::Keyword_read_write: \
+      Result = Context.Id##RWTy; break; \
+    case OpenCLAccessAttr::Keyword_read_only: \
+      Result = Context.Id##ROTy; break; \
+    default: assert(0 && "Unknown access attribute!"); \
+    } \
     break;
 #include "clang/Basic/OpenCLImageTypes.def"
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to