diff options
Diffstat (limited to 'clang/lib/Sema/SemaExpr.cpp')
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 35 |
1 files changed, 35 insertions, 0 deletions
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(); |