r261719 - [OpenCL] Add Sema checks for OpenCL 2.0 block

Xiuli Pan via cfe-commits cfe-commits at lists.llvm.org
Tue Feb 23 20:40:56 PST 2016


Author: pxl
Date: Tue Feb 23 22:29:36 2016
New Revision: 261719

URL: http://llvm.org/viewvc/llvm-project?rev=261719&view=rev
Log:
[OpenCL] Add Sema checks for OpenCL 2.0 block

Summary:
Add Sema checks for opencl 2.0 new features: Block.
This patch is partitioned from http://reviews.llvm.org/D16047

Reviewers: Anastasia

Subscribers: pekka.jaaskelainen, cfe-commits

Differential Revision: http://reviews.llvm.org/D17436

Added:
    cfe/trunk/test/SemaOpenCL/invalid-block.cl
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaType.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=261719&r1=261718&r2=261719&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Feb 23 22:29:36 2016
@@ -7712,6 +7712,14 @@ def err_atomic_init_constant : Error<
   " in the declaration statement in the program scope">;
 def err_opencl_implicit_vector_conversion : Error<
   "implicit conversions between vector types (%0 and %1) are not permitted">;
+def err_opencl_dereferencing : Error<
+  "dereferencing pointer of type %0 is not allowed in OpenCL">;
+def err_opencl_block_proto_variadic : Error<
+  "invalid block prototype, variadic arguments are not allowed in OpenCL">;
+def err_opencl_invalid_type_array : Error<
+  "array of %0 type is invalid in OpenCL">;
+def err_opencl_ternary_with_block : Error<
+  "block type cannot be used as expression in ternary expression in OpenCL">;
 
 // OpenCL v2.0 s6.13.6 -- Builtin Pipe Functions
 def err_opencl_builtin_pipe_first_arg : Error<

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=261719&r1=261718&r2=261719&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Feb 23 22:29:36 2016
@@ -6708,6 +6708,19 @@ void Sema::CheckVariableDeclarationType(
     NewVD->setInvalidDecl();
     return;
   }
+
+  // OpenCL v2.0 s6.12.5 - Blocks with variadic arguments are not supported.
+  if (LangOpts.OpenCL && T->isBlockPointerType()) {
+    const BlockPointerType *BlkTy = T->getAs<BlockPointerType>();
+    const FunctionProtoType *FTy =
+        BlkTy->getPointeeType()->getAs<FunctionProtoType>();
+    if (FTy->isVariadic()) {
+      Diag(NewVD->getLocation(), diag::err_opencl_block_proto_variadic)
+          << T << NewVD->getSourceRange();
+      NewVD->setInvalidDecl();
+      return;
+    }
+  }
 }
 
 /// \brief Perform semantic checking on a newly-created variable

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=261719&r1=261718&r2=261719&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Feb 23 22:29:36 2016
@@ -6458,6 +6458,18 @@ OpenCLCheckVectorConditional(Sema &S, Ex
   return OpenCLConvertScalarsToVectors(S, LHS, RHS, CondTy, QuestionLoc);
 }
 
+/// \brief Return true if the Expr is block type
+static bool checkBlockType(Sema &S, const Expr *E) {
+  if (const CallExpr *CE = dyn_cast<CallExpr>(E)) {
+    QualType Ty = CE->getCallee()->getType();
+    if (Ty->isBlockPointerType()) {
+      S.Diag(E->getExprLoc(), diag::err_opencl_ternary_with_block);
+      return true;
+    }
+  }
+  return false;
+}
+
 /// Note that LHS is not null here, even if this is the gnu "x ?: y" extension.
 /// In that case, LHS = cond.
 /// C99 6.5.15
@@ -6507,6 +6519,13 @@ QualType Sema::CheckConditionalOperands(
   QualType LHSTy = LHS.get()->getType();
   QualType RHSTy = RHS.get()->getType();
 
+  // OpenCL v2.0 s6.12.5 - Blocks cannot be used as expressions of the ternary
+  // selection operator (?:).
+  if (getLangOpts().OpenCL &&
+      (checkBlockType(*this, LHS.get()) | checkBlockType(*this, RHS.get()))) {
+    return QualType();
+  }
+
   // If both operands have arithmetic type, do the usual arithmetic conversions
   // to find a common type: C99 6.5.15p3,5.
   if (LHSTy->isArithmeticType() && RHSTy->isArithmeticType()) {
@@ -10334,6 +10353,14 @@ QualType Sema::CheckAddressOfOperand(Exp
   // If the operand has type "type", the result has type "pointer to type".
   if (op->getType()->isObjCObjectType())
     return Context.getObjCObjectPointerType(op->getType());
+
+  // OpenCL v2.0 s6.12.5 - The unary operators & cannot be used with a block.
+  if (getLangOpts().OpenCL && OrigOp.get()->getType()->isBlockPointerType()) {
+    Diag(OpLoc, diag::err_typecheck_unary_expr) << OrigOp.get()->getType()
+                                                << op->getSourceRange();
+    return QualType();
+  }
+
   return Context.getPointerType(op->getType());
 }
 
@@ -10375,7 +10402,15 @@ static QualType CheckIndirectionOperand(
   }
 
   if (const PointerType *PT = OpTy->getAs<PointerType>())
+  {
     Result = PT->getPointeeType();
+    // OpenCL v2.0 s6.12.5 - The unary operators * cannot be used with a block.
+    if (S.getLangOpts().OpenCLVersion >= 200 && Result->isBlockPointerType()) {
+      S.Diag(OpLoc, diag::err_opencl_dereferencing) << OpTy
+                                                    << Op->getSourceRange();
+      return QualType();
+    }
+  }
   else if (const ObjCObjectPointerType *OPT =
              OpTy->getAs<ObjCObjectPointerType>())
     Result = OPT->getPointeeType();

Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=261719&r1=261718&r2=261719&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Tue Feb 23 22:29:36 2016
@@ -2175,6 +2175,15 @@ QualType Sema::BuildArrayType(QualType T
     Diag(Loc, diag::warn_vla_used);
   }
 
+  // OpenCL v2.0 s6.12.5 - Arrays of blocks are not supported.
+  if (getLangOpts().OpenCL) {
+    const QualType ArrType = Context.getBaseElementType(T);
+    if (ArrType->isBlockPointerType()) {
+      Diag(Loc, diag::err_opencl_invalid_type_array) << ArrType;
+      return QualType();
+    }
+  }
+
   return T;
 }
 

Added: cfe/trunk/test/SemaOpenCL/invalid-block.cl
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaOpenCL/invalid-block.cl?rev=261719&view=auto
==============================================================================
--- cfe/trunk/test/SemaOpenCL/invalid-block.cl (added)
+++ cfe/trunk/test/SemaOpenCL/invalid-block.cl Tue Feb 23 22:29:36 2016
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -verify -fblocks -cl-std=CL2.0 %s
+
+int (^BlkVariadic)(int, ...) = ^int(int I, ...) { // expected-error {{invalid block prototype, variadic arguments are not allowed in OpenCL}}
+  return 0;
+};
+
+typedef int (^BlkInt)(int);
+void f1(int i) {
+  BlkInt B1 = ^int(int I) {return 1;};
+  BlkInt B2 = ^int(int I) {return 2;};
+  BlkInt Arr[] = {B1, B2}; // expected-error {{array of 'BlkInt' (aka 'int (^)(int)') type is invalid in OpenCL}}
+  int tmp = i ? B1(i)      // expected-error {{block type cannot be used as expression in ternary expression in OpenCL}}
+              : B2(i);     // expected-error {{block type cannot be used as expression in ternary expression in OpenCL}}
+}
+
+void f2(BlkInt *BlockPtr) {
+  BlkInt B = ^int(int I) {return 1;};
+  BlkInt *P = &B; // expected-error {{invalid argument type 'BlkInt' (aka 'int (^)(int)') to unary expression}}
+  B = *BlockPtr;  // expected-error {{dereferencing pointer of type '__generic BlkInt *' (aka 'int (^__generic *)(int)') is not allowed in OpenCL}}
+}




More information about the cfe-commits mailing list