diff options
Diffstat (limited to 'clang/lib/Sema/SemaOpenACCClause.cpp')
-rw-r--r-- | clang/lib/Sema/SemaOpenACCClause.cpp | 114 |
1 files changed, 56 insertions, 58 deletions
diff --git a/clang/lib/Sema/SemaOpenACCClause.cpp b/clang/lib/Sema/SemaOpenACCClause.cpp index b086929..881e960 100644 --- a/clang/lib/Sema/SemaOpenACCClause.cpp +++ b/clang/lib/Sema/SemaOpenACCClause.cpp @@ -1915,51 +1915,34 @@ SemaOpenACC::ActOnClause(ArrayRef<const OpenACCClause *> ExistingClauses, return Result; } -/// OpenACC 3.3 section 2.5.15: -/// At a mininmum, the supported data types include ... the numerical data types -/// in C, C++, and Fortran. -/// -/// If the reduction var is a composite variable, each -/// member of the composite variable must be a supported datatype for the -/// reduction operation. -ExprResult SemaOpenACC::CheckReductionVar(OpenACCDirectiveKind DirectiveKind, - OpenACCReductionOperator ReductionOp, - Expr *VarExpr) { - // For now, we only support 'scalar' types, or composites/arrays of scalar - // types. - VarExpr = VarExpr->IgnoreParenCasts(); +bool SemaOpenACC::CheckReductionVarType(Expr *VarExpr) { SourceLocation VarLoc = VarExpr->getBeginLoc(); SmallVector<PartialDiagnosticAt> Notes; - QualType CurType = VarExpr->getType(); - - // For array like things, the expression can either be an array element - // (subscript expr), array section, or array type. Peel those off, and add - // notes in case we find an illegal kind. We'll allow scalar or composite of - // scalars inside of this. - if (auto *ASE = dyn_cast<ArraySectionExpr>(VarExpr)) { - QualType BaseType = ArraySectionExpr::getBaseOriginalType(ASE); + // The standard isn't clear how many levels of 'array element' or 'subarray' + // are permitted, but we can handle as many as we need, so we'll strip them + // off here. This will result in CurType being the actual 'type' of the + // expression, which is what we are looking to check. + QualType CurType = isa<ArraySectionExpr>(VarExpr) + ? ArraySectionExpr::getBaseOriginalType(VarExpr) + : VarExpr->getType(); + + // This can happen when we have a dependent type in an array element that the + // above function has tried to 'unwrap'. Since this can only happen with + // dependence, just let it go. + if (CurType.isNull()) + return false; - PartialDiagnostic PD = PDiag(diag::note_acc_reduction_array) - << diag::OACCReductionArray::Section << BaseType; - Notes.push_back({ASE->getBeginLoc(), PD}); - - CurType = getASTContext().getBaseElementType(BaseType); - } else if (auto *SubExpr = dyn_cast<ArraySubscriptExpr>(VarExpr)) { - // Array subscript already results in the type of the thing as its type, so - // there is no type to change here. - PartialDiagnostic PD = - PDiag(diag::note_acc_reduction_array) - << diag::OACCReductionArray::Subscript - << SubExpr->getBase()->IgnoreParenImpCasts()->getType(); - Notes.push_back({SubExpr->getBeginLoc(), PD}); - } else if (auto *AT = getASTContext().getAsArrayType(CurType)) { + // If we are still an array type, we allow 1 level of 'unpeeling' of the + // array. The standard isn't clear here whether this is allowed, but + // array-of-valid-things makes sense. + if (auto *AT = getASTContext().getAsArrayType(CurType)) { // If we're already the array type, peel off the array and leave the element // type. - CurType = getASTContext().getBaseElementType(AT); PartialDiagnostic PD = PDiag(diag::note_acc_reduction_array) << diag::OACCReductionArray::ArrayTy << CurType; Notes.push_back({VarLoc, PD}); + CurType = AT->getElementType(); } auto IsValidMemberOfComposite = [](QualType Ty) { @@ -1974,31 +1957,26 @@ ExprResult SemaOpenACC::CheckReductionVar(OpenACCDirectiveKind DirectiveKind, for (auto [Loc, PD] : Notes) Diag(Loc, PD); - Diag(VarLoc, diag::note_acc_reduction_type_summary); + return Diag(VarLoc, diag::note_acc_reduction_type_summary); }; // If the type is already scalar, or is dependent, just give up. if (IsValidMemberOfComposite(CurType)) { // Nothing to do here, is valid. } else if (auto *RD = CurType->getAsRecordDecl()) { - if (!RD->isStruct() && !RD->isClass()) { - EmitDiags(VarLoc, PDiag(diag::err_acc_reduction_type) - << RD << diag::OACCReductionTy::NotClassStruct); - return ExprError(); - } + if (!RD->isStruct() && !RD->isClass()) + return EmitDiags(VarLoc, PDiag(diag::err_acc_reduction_type) + << RD + << diag::OACCReductionTy::NotClassStruct); - if (!RD->isCompleteDefinition()) { - EmitDiags(VarLoc, PDiag(diag::err_acc_reduction_type) - << RD << diag::OACCReductionTy::NotComplete); - return ExprError(); - } + if (!RD->isCompleteDefinition()) + return EmitDiags(VarLoc, PDiag(diag::err_acc_reduction_type) + << RD << diag::OACCReductionTy::NotComplete); if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD); - CXXRD && !CXXRD->isAggregate()) { - EmitDiags(VarLoc, PDiag(diag::err_acc_reduction_type) - << CXXRD << diag::OACCReductionTy::NotAgg); - return ExprError(); - } + CXXRD && !CXXRD->isAggregate()) + return EmitDiags(VarLoc, PDiag(diag::err_acc_reduction_type) + << CXXRD << diag::OACCReductionTy::NotAgg); for (FieldDecl *FD : RD->fields()) { if (!IsValidMemberOfComposite(FD->getType())) { @@ -2007,17 +1985,37 @@ ExprResult SemaOpenACC::CheckReductionVar(OpenACCDirectiveKind DirectiveKind, << FD->getName() << RD->getName(); Notes.push_back({FD->getBeginLoc(), PD}); // TODO: member here.note_acc_reduction_member_of_composite - EmitDiags(VarLoc, PDiag(diag::err_acc_reduction_type) - << FD->getType() - << diag::OACCReductionTy::MemberNotScalar); - return ExprError(); + return EmitDiags(VarLoc, PDiag(diag::err_acc_reduction_type) + << FD->getType() + << diag::OACCReductionTy::MemberNotScalar); } } } else { - EmitDiags(VarLoc, PDiag(diag::err_acc_reduction_type) - << CurType << diag::OACCReductionTy::NotScalar); + return EmitDiags(VarLoc, PDiag(diag::err_acc_reduction_type) + << CurType + << diag::OACCReductionTy::NotScalar); } + return false; +} + +/// OpenACC 3.3 section 2.5.15: +/// At a mininmum, the supported data types include ... the numerical data types +/// in C, C++, and Fortran. +/// +/// If the reduction var is a composite variable, each +/// member of the composite variable must be a supported datatype for the +/// reduction operation. +ExprResult SemaOpenACC::CheckReductionVar(OpenACCDirectiveKind DirectiveKind, + OpenACCReductionOperator ReductionOp, + Expr *VarExpr) { + // For now, we only support 'scalar' types, or composites/arrays of scalar + // types. + VarExpr = VarExpr->IgnoreParenCasts(); + + if (CheckReductionVarType(VarExpr)) + return ExprError(); + // OpenACC3.3: 2.9.11: Reduction clauses on nested constructs for the same // reduction 'var' must have the same reduction operator. if (!VarExpr->isInstantiationDependent()) { |