diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-05-30 17:37:44 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-05-30 17:37:44 +0000 |
commit | 550ae89a710bf458d47e5b1d183f5e7039c2b384 (patch) | |
tree | 4eab680d9198cddf87acb23a14c836472b21ae89 /lib/Sema | |
parent | b5aee35cc5d62f11d98539f62e4fe63f0ac9edc6 (diff) |
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 3 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 28 | ||||
-rw-r--r-- | lib/Sema/SemaOpenMP.cpp | 43 |
3 files changed, 43 insertions, 31 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 96fd952c81c77..a9adbec4f8429 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -12509,6 +12509,9 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc, unsigned diag_id; if (II.getName().startswith("__builtin_")) diag_id = diag::warn_builtin_unknown; + // OpenCL v2.0 s6.9.u - Implicit function declaration is not supported. + else if (getLangOpts().OpenCL) + diag_id = diag::err_opencl_implicit_function_decl; else if (getLangOpts().C99) diag_id = diag::ext_implicit_function_decl; else diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 759c82eeaa077..b1a07ffb7206f 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -8074,28 +8074,38 @@ QualType Sema::InvalidLogicalVectorOperands(SourceLocation Loc, ExprResult &LHS, /// rank; for C, Obj-C, and C++ we allow any real scalar conversion except /// for float->int. /// +/// OpenCL V2.0 6.2.6.p2: +/// An error shall occur if any scalar operand type has greater rank +/// than the type of the vector element. +/// /// \param scalar - if non-null, actually perform the conversions /// \return true if the operation fails (but without diagnosing the failure) static bool tryVectorConvertAndSplat(Sema &S, ExprResult *scalar, QualType scalarTy, QualType vectorEltTy, - QualType vectorTy) { + QualType vectorTy, + unsigned &DiagID) { // The conversion to apply to the scalar before splatting it, // if necessary. CastKind scalarCast = CK_Invalid; if (vectorEltTy->isIntegralType(S.Context)) { - if (!scalarTy->isIntegralType(S.Context)) + if (S.getLangOpts().OpenCL && (scalarTy->isRealFloatingType() || + (scalarTy->isIntegerType() && + S.Context.getIntegerTypeOrder(vectorEltTy, scalarTy) < 0))) { + DiagID = diag::err_opencl_scalar_type_rank_greater_than_vector_type; return true; - if (S.getLangOpts().OpenCL && - S.Context.getIntegerTypeOrder(vectorEltTy, scalarTy) < 0) + } + if (!scalarTy->isIntegralType(S.Context)) return true; scalarCast = CK_IntegralCast; } else if (vectorEltTy->isRealFloatingType()) { if (scalarTy->isRealFloatingType()) { if (S.getLangOpts().OpenCL && - S.Context.getFloatingTypeOrder(vectorEltTy, scalarTy) < 0) + S.Context.getFloatingTypeOrder(vectorEltTy, scalarTy) < 0) { + DiagID = diag::err_opencl_scalar_type_rank_greater_than_vector_type; return true; + } scalarCast = CK_FloatingCast; } else if (scalarTy->isIntegralType(S.Context)) @@ -8341,10 +8351,12 @@ QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS, // If there's a vector type and a scalar, try to convert the scalar to // the vector element type and splat. + unsigned DiagID = diag::err_typecheck_vector_not_convertable; if (!RHSVecType) { if (isa<ExtVectorType>(LHSVecType)) { if (!tryVectorConvertAndSplat(*this, &RHS, RHSType, - LHSVecType->getElementType(), LHSType)) + LHSVecType->getElementType(), LHSType, + DiagID)) return LHSType; } else { if (!tryGCCVectorConvertAndSplat(*this, &RHS, &LHS)) @@ -8355,7 +8367,7 @@ QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS, if (isa<ExtVectorType>(RHSVecType)) { if (!tryVectorConvertAndSplat(*this, (IsCompAssign ? nullptr : &LHS), LHSType, RHSVecType->getElementType(), - RHSType)) + RHSType, DiagID)) return RHSType; } else { if (LHS.get()->getValueKind() == VK_LValue || @@ -8431,7 +8443,7 @@ QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS, } // Otherwise, use the generic diagnostic. - Diag(Loc, diag::err_typecheck_vector_not_convertable) + Diag(Loc, DiagID) << LHSType << RHSType << LHS.get()->getSourceRange() << RHS.get()->getSourceRange(); return QualType(); diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index 43fd055bbc565..2b7733d2adbd2 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -5929,16 +5929,17 @@ StmtResult Sema::ActOnOpenMPTargetParallelForDirective( B, DSAStack->isCancelRegion()); } -/// \brief Check for existence of a map clause in the list of clauses. -static bool HasMapClause(ArrayRef<OMPClause *> Clauses) { - for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end(); - I != E; ++I) { - if (*I != nullptr && (*I)->getClauseKind() == OMPC_map) { - return true; - } - } +/// Check for existence of a map clause in the list of clauses. +static bool hasClauses(ArrayRef<OMPClause *> Clauses, + const OpenMPClauseKind K) { + return llvm::any_of( + Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); +} - return false; +template <typename... Params> +static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, + const Params... ClauseTypes) { + return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); } StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, @@ -5952,8 +5953,9 @@ StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, // OpenMP [2.10.1, Restrictions, p. 97] // At least one map clause must appear on the directive. - if (!HasMapClause(Clauses)) { - Diag(StartLoc, diag::err_omp_no_map_for_directive) + if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { + Diag(StartLoc, diag::err_omp_no_clause_for_directive) + << "'map' or 'use_device_ptr'" << getOpenMPDirectiveName(OMPD_target_data); return StmtError(); } @@ -5970,9 +5972,9 @@ Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, SourceLocation EndLoc) { // OpenMP [2.10.2, Restrictions, p. 99] // At least one map clause must appear on the directive. - if (!HasMapClause(Clauses)) { - Diag(StartLoc, diag::err_omp_no_map_for_directive) - << getOpenMPDirectiveName(OMPD_target_enter_data); + if (!hasClauses(Clauses, OMPC_map)) { + Diag(StartLoc, diag::err_omp_no_clause_for_directive) + << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); return StmtError(); } @@ -5986,9 +5988,9 @@ Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, SourceLocation EndLoc) { // OpenMP [2.10.3, Restrictions, p. 102] // At least one map clause must appear on the directive. - if (!HasMapClause(Clauses)) { - Diag(StartLoc, diag::err_omp_no_map_for_directive) - << getOpenMPDirectiveName(OMPD_target_exit_data); + if (!hasClauses(Clauses, OMPC_map)) { + Diag(StartLoc, diag::err_omp_no_clause_for_directive) + << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); return StmtError(); } @@ -5998,12 +6000,7 @@ Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, SourceLocation StartLoc, SourceLocation EndLoc) { - bool seenMotionClause = false; - for (auto *C : Clauses) { - if (C->getClauseKind() == OMPC_to || C->getClauseKind() == OMPC_from) - seenMotionClause = true; - } - if (!seenMotionClause) { + if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); return StmtError(); } |