summaryrefslogtreecommitdiffstats
path: root/clang/lib
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 /clang/lib
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
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Sema/SemaDecl.cpp13
-rw-r--r--clang/lib/Sema/SemaExpr.cpp35
-rw-r--r--clang/lib/Sema/SemaType.cpp9
3 files changed, 57 insertions, 0 deletions
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;
}
OpenPOWER on IntegriCloud