pxli168 created this revision.
pxli168 added reviewers: Anastasia, pekka.jaaskelainen.
pxli168 added a subscriber: cfe-commits.
Add Sema checks for opencl 2.0 new features: Block.
http://reviews.llvm.org/D17436
Files:
include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaDecl.cpp
lib/Sema/SemaExpr.cpp
lib/Sema/SemaType.cpp
test/SemaOpenCL/invalid-block.cl
Index: test/SemaOpenCL/invalid-block.cl
===================================================================
--- /dev/null
+++ test/SemaOpenCL/invalid-block.cl
@@ -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}}
+ 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 block is invalid in OpenCL}}
+ int tmp = i ? B1(i) // expected-error {{blocks cannot be used as expressions in ternary expressions}}
+ : B2(i); // expected-error {{blocks cannot be used as expressions in ternary expressions}}
+}
+
+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}}
+}
Index: lib/Sema/SemaType.cpp
===================================================================
--- lib/Sema/SemaType.cpp
+++ lib/Sema/SemaType.cpp
@@ -2175,6 +2175,14 @@
Diag(Loc, diag::warn_vla_used);
}
+ // OpenCL v2.0 s6.12.5 - The following Blocks features are currently not
+ // supported in OpenCL C: Arrays of Blocks.
+ if (getLangOpts().OpenCL && getLangOpts().OpenCLVersion >= 200 &&
+ Context.getBaseElementType(T)->isBlockPointerType()) {
+ Diag(Loc, diag::err_opencl_invalid_block_array);
+ return QualType();
+ }
+
return T;
}
Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -6456,6 +6456,18 @@
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
@@ -6505,6 +6517,15 @@
QualType LHSTy = LHS.get()->getType();
QualType RHSTy = RHS.get()->getType();
+ // OpenCL v2.0 s6.12.5 - To support these behaviors, additional
+ // restrictions in addition to the above feature restrictions are: Blocks
+ // cannot be used as expressions of the ternary selection operator (?:).
+ if (getLangOpts().OpenCL && getLangOpts().OpenCLVersion >= 200) {
+ // should output error for both LHS and RHS, use | instead ||
+ if (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()) {
@@ -10332,6 +10353,17 @@
// 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 (* and &) cannot be used with a
+ // Block
+ if (getLangOpts().OpenCL && getLangOpts().OpenCLVersion >= 200) {
+ if (OrigOp.get()->getType()->isBlockPointerType()) {
+ Diag(OpLoc, diag::err_typecheck_unary_expr) << OrigOp.get()->getType()
+ << op->getSourceRange();
+ return QualType();
+ }
+ }
+
return Context.getPointerType(op->getType());
}
@@ -10373,7 +10405,17 @@
}
if (const PointerType *PT = OpTy->getAs<PointerType>())
+ {
Result = PT->getPointeeType();
+ // OpenCL v2.0 s6.12.5 - The unary operators (* and &) cannot be used with a
+ // Block.
+ if (S.getLangOpts().OpenCL && 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();
Index: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -6708,6 +6708,24 @@
NewVD->setInvalidDecl();
return;
}
+
+ // OpenCL v2.0 s6.12.5 - The following Blocks features are currently not
+ // supported in OpenCL C: Blocks with variadic arguments.
+ if (getLangOpts().OpenCL && LangOpts.OpenCLVersion >= 200 &&
+ T->isBlockPointerType()) {
+ const BlockPointerType *BlkTy = T->getAs<BlockPointerType>();
+ assert(BlkTy && "Not a block pointer.");
+
+ 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
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -7713,6 +7713,14 @@
" 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_block_array : Error<
+ "array of block is invalid in OpenCL">;
+def err_opencl_ternary_with_block : Error<
+ "blocks cannot be used as expressions in ternary expressions in opencl">;
// OpenCL v2.0 s6.13.6 -- Builtin Pipe Functions
def err_opencl_builtin_pipe_first_arg : Error<
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits