summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXiuli Pan <xiulipan@outlook.com>2016-02-24 04:29:36 +0000
committerXiuli Pan <xiulipan@outlook.com>2016-02-24 04:29:36 +0000
commit89307aa3e9fce213a55b64c042a001458d3ba41c (patch)
tree63eb885606d521a2e50c19cbc69cfe258e58dd75
parent74a1fc6f8723873bbbdf9ac62cb8a3a2cff7b8d0 (diff)
downloadbcm5719-llvm-89307aa3e9fce213a55b64c042a001458d3ba41c.tar.gz
bcm5719-llvm-89307aa3e9fce213a55b64c042a001458d3ba41c.zip
[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 llvm-svn: 261719
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td8
-rw-r--r--clang/lib/Sema/SemaDecl.cpp13
-rw-r--r--clang/lib/Sema/SemaExpr.cpp35
-rw-r--r--clang/lib/Sema/SemaType.cpp9
-rw-r--r--clang/test/SemaOpenCL/invalid-block.cl20
5 files changed, 85 insertions, 0 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 45d1b4acc13..53c0a31236b 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -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<
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 0f6470bf453..378abe94e87 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -6708,6 +6708,19 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) {
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
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index ee9e646e24c..0ca5555e1da 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -6458,6 +6458,18 @@ OpenCLCheckVectorConditional(Sema &S, ExprResult &Cond,
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(ExprResult &Cond, ExprResult &LHS,
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(ExprResult &OrigOp, SourceLocation OpLoc) {
// 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(Sema &S, Expr *Op, ExprValueKind &VK,
}
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();
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index cabb5bc0e0a..5c3b7ab3349 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -2175,6 +2175,15 @@ QualType Sema::BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM,
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;
}
diff --git a/clang/test/SemaOpenCL/invalid-block.cl b/clang/test/SemaOpenCL/invalid-block.cl
new file mode 100644
index 00000000000..c3989a28c83
--- /dev/null
+++ b/clang/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 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}}
+}
OpenPOWER on IntegriCloud