[clang] [OpenACC] Implement SubArray Parsing/Sema (PR #90796)
https://github.com/erichkeane closed https://github.com/llvm/llvm-project/pull/90796 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [OpenACC] Implement SubArray Parsing/Sema (PR #90796)
https://github.com/erichkeane updated https://github.com/llvm/llvm-project/pull/90796 >From ac69522bf15c7c169c4cdb9d3d1547c5c0962193 Mon Sep 17 00:00:00 2001 From: erichkeane Date: Tue, 30 Apr 2024 11:42:35 -0700 Subject: [PATCH 1/2] [OpenACC} Implement SubArray Parsing/Sema This implementation takes quite a bit from the OMP implementation of array sections, but only has to enforce the rules as applicable to OpenACC. Additionally, it does its best to create an AST node (with the assistance of RecoveryExprs) with as much checking done as soon as possible in the case of instantiations. --- .../clang/Basic/DiagnosticSemaKinds.td| 24 +- clang/lib/Parse/ParseExpr.cpp | 3 +- clang/lib/Sema/SemaOpenACC.cpp| 232 ++- .../ParserOpenACC/parse-cache-construct.c | 3 +- .../ParserOpenACC/parse-cache-construct.cpp | 8 +- clang/test/ParserOpenACC/parse-clauses.c | 2 - clang/test/ParserOpenACC/parse-sub-array.cpp | 89 +++ .../compute-construct-private-clause.c| 26 +- .../compute-construct-private-clause.cpp | 3 +- .../compute-construct-varlist-ast.cpp | 9 + clang/test/SemaOpenACC/sub-array-ast.cpp | 566 ++ clang/test/SemaOpenACC/sub-array.cpp | 208 +++ 12 files changed, 1131 insertions(+), 42 deletions(-) create mode 100644 clang/test/ParserOpenACC/parse-sub-array.cpp create mode 100644 clang/test/SemaOpenACC/sub-array-ast.cpp create mode 100644 clang/test/SemaOpenACC/sub-array.cpp diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 4b074b853bfe65..fbb107679d94ba 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -12291,8 +12291,8 @@ def warn_acc_if_self_conflict "evaluates to true">, InGroup>; def err_acc_int_expr_requires_integer -: Error<"OpenACC %select{clause|directive}0 '%1' requires expression of " -"integer type (%2 invalid)">; +: Error<"OpenACC %select{clause '%1'|directive '%2'|sub-array bound}0 " +"requires expression of integer type (%3 invalid)">; def err_acc_int_expr_incomplete_class_type : Error<"OpenACC integer expression has incomplete class type %0">; def err_acc_int_expr_explicit_conversion @@ -12310,4 +12310,24 @@ def err_acc_num_gangs_num_args def err_acc_not_a_var_ref : Error<"OpenACC variable is not a valid variable name, sub-array, array " "element, or composite variable member">; +def err_acc_typecheck_subarray_value +: Error<"OpenACC sub-array subscripted value is not an array or pointer">; +def err_acc_subarray_function_type +: Error<"OpenACC sub-array cannot be of function type %0">; +def err_acc_subarray_incomplete_type +: Error<"OpenACC sub-array base is of incomplete type %0">; +def err_acc_subarray_no_length +: Error<"OpenACC sub-array length is unspecified and cannot be inferred " +"because the subscripted value is %select{not an array|an array of " +"unknown bound}0">; +def err_acc_subarray_negative +: Error<"OpenACC sub-array %select{lower bound|length}0 evaluated to " +"negative value %1">; +def err_acc_subarray_out_of_range +: Error<"OpenACC sub-array %select{lower bound|length}0 evaluated to a " +"value (%1) that would be out of the range of the subscripted " +"array size of %2">; +def err_acc_subarray_base_plus_length_out_of_range +: Error<"OpenACC sub-array specified range [%0:%1] would be out of the " +"range of the subscripted array size of %2">; } // end of sema component. diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index 7d6febb04a82c4..5f5f9a79c8c408 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -2039,7 +2039,8 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { if (Tok.is(tok::colon)) { // Consume ':' ColonLocFirst = ConsumeToken(); - Length = Actions.CorrectDelayedTyposInExpr(ParseExpression()); + if (Tok.isNot(tok::r_square)) +Length = Actions.CorrectDelayedTyposInExpr(ParseExpression()); } } else if (ArgExprs.size() <= 1 && getLangOpts().OpenMP) { ColonProtectionRAIIObject RAII(*this); diff --git a/clang/lib/Sema/SemaOpenACC.cpp b/clang/lib/Sema/SemaOpenACC.cpp index 3ea81e0497c203..a203ece7ff3130 100644 --- a/clang/lib/Sema/SemaOpenACC.cpp +++ b/clang/lib/Sema/SemaOpenACC.cpp @@ -16,6 +16,7 @@ #include "clang/Basic/DiagnosticSema.h" #include "clang/Basic/OpenACCKinds.h" #include "clang/Sema/Sema.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/Support/Casting.h" using namespace clang; @@ -367,7 +368,9 @@ ExprResult SemaOpenACC::ActOnIntExpr(OpenACCDirectiveKind DK, assert(((DK != OpenACCDirectiveKind::Invalid && CK == OpenACCClaus
[clang] [OpenACC] Implement SubArray Parsing/Sema (PR #90796)
https://github.com/alexey-bataev approved this pull request. LG with a nit https://github.com/llvm/llvm-project/pull/90796 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [OpenACC] Implement SubArray Parsing/Sema (PR #90796)
@@ -503,12 +512,211 @@ ExprResult SemaOpenACC::ActOnArraySectionExpr(Expr *Base, SourceLocation LBLoc, SourceLocation RBLoc) { ASTContext &Context = getASTContext(); - // TODO OpenACC: We likely have to reproduce a lot of the same logic from the - // OMP version of this, but at the moment we don't have a good way to test it, - // so for now we'll just create the node. + // Handle placeholders. + if (Base->hasPlaceholderType() && + !Base->hasPlaceholderType(BuiltinType::ArraySection)) { +ExprResult Result = SemaRef.CheckPlaceholderExpr(Base); +if (Result.isInvalid()) + return ExprError(); +Base = Result.get(); + } + if (LowerBound && LowerBound->getType()->isNonOverloadPlaceholderType()) { +ExprResult Result = SemaRef.CheckPlaceholderExpr(LowerBound); +if (Result.isInvalid()) + return ExprError(); +Result = SemaRef.DefaultLvalueConversion(Result.get()); +if (Result.isInvalid()) + return ExprError(); +LowerBound = Result.get(); + } + if (Length && Length->getType()->isNonOverloadPlaceholderType()) { +ExprResult Result = SemaRef.CheckPlaceholderExpr(Length); +if (Result.isInvalid()) + return ExprError(); +Result = SemaRef.DefaultLvalueConversion(Result.get()); +if (Result.isInvalid()) + return ExprError(); +Length = Result.get(); + } + + // Check the 'base' value, it must be an array or pointer type, and not to/of + // a function type. + QualType OriginalBaseTy = ArraySectionExpr::getBaseOriginalType(Base); + QualType ResultTy; + if (!Base->isTypeDependent()) { +if (OriginalBaseTy->isAnyPointerType()) { + ResultTy = OriginalBaseTy->getPointeeType(); +} else if (OriginalBaseTy->isArrayType()) { + ResultTy = OriginalBaseTy->getAsArrayTypeUnsafe()->getElementType(); +} else { + return ExprError( + Diag(Base->getExprLoc(), diag::err_acc_typecheck_subarray_value) + << Base->getSourceRange()); +} + +if (ResultTy->isFunctionType()) { + Diag(Base->getExprLoc(), diag::err_acc_subarray_function_type) + << ResultTy << Base->getSourceRange(); + return ExprError(); +} + +if (SemaRef.RequireCompleteType(Base->getExprLoc(), ResultTy, +diag::err_acc_subarray_incomplete_type, +Base)) + return ExprError(); + +if (!Base->hasPlaceholderType(BuiltinType::ArraySection)) { + ExprResult Result = SemaRef.DefaultFunctionArrayLvalueConversion(Base); + if (Result.isInvalid()) +return ExprError(); + Base = Result.get(); +} + } + + auto GetRecovery = [&](Expr *E, QualType Ty) { +ExprResult Recovery = +SemaRef.CreateRecoveryExpr(E->getBeginLoc(), E->getEndLoc(), E, Ty); +return Recovery.isUsable() ? Recovery.get() : nullptr; + }; + + // Ensure both of the expressions are int-exprs. + if (LowerBound && !LowerBound->isTypeDependent()) { +ExprResult LBRes = +ActOnIntExpr(OpenACCDirectiveKind::Invalid, OpenACCClauseKind::Invalid, + LowerBound->getExprLoc(), LowerBound); + +if (LBRes.isUsable()) + LBRes = SemaRef.DefaultLvalueConversion(LBRes.get()); +LowerBound = +LBRes.isUsable() ? LBRes.get() : GetRecovery(LowerBound, Context.IntTy); + } + + if (Length && !Length->isTypeDependent()) { +ExprResult LenRes = +ActOnIntExpr(OpenACCDirectiveKind::Invalid, OpenACCClauseKind::Invalid, + Length->getExprLoc(), Length); + +if (LenRes.isUsable()) + LenRes = SemaRef.DefaultLvalueConversion(LenRes.get()); +Length = +LenRes.isUsable() ? LenRes.get() : GetRecovery(Length, Context.IntTy); + } + + // Length is required if the base type is not an array of known bounds. + if (!Length && (OriginalBaseTy.isNull() || + (!OriginalBaseTy->isDependentType() && + !OriginalBaseTy->isConstantArrayType() && + !OriginalBaseTy->isDependentSizedArrayType( { +bool IsArray = !OriginalBaseTy.isNull() && OriginalBaseTy->isArrayType(); +Diag(ColonLoc, diag::err_acc_subarray_no_length) << IsArray; +// Fill in a dummy 'length' so that when we instantiate this we don't +// double-diagnose here. +ExprResult Recovery = SemaRef.CreateRecoveryExpr( +ColonLoc, SourceLocation(), ArrayRef{std::nullopt}, +Context.IntTy); +Length = Recovery.isUsable() ? Recovery.get() : nullptr; + } + + // Check the values of each of the arguments, they cannot be negative(we + // assume), and if the array bound is known, must be within range. As we do + // so, do our best to continue with evaluation, we can set the + // value/expression to nullptr/nullopt if they are invalid, and treat them as + // not present for the rest of evaluation. + + // We don't have to check for dependence, because the dependent size is + // repres
[clang] [OpenACC] Implement SubArray Parsing/Sema (PR #90796)
https://github.com/alexey-bataev edited https://github.com/llvm/llvm-project/pull/90796 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [OpenACC] Implement SubArray Parsing/Sema (PR #90796)
https://github.com/alexey-bataev edited https://github.com/llvm/llvm-project/pull/90796 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [OpenACC} Implement SubArray Parsing/Sema (PR #90796)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Erich Keane (erichkeane) Changes This implementation takes quite a bit from the OMP implementation of array sections, but only has to enforce the rules as applicable to OpenACC. Additionally, it does its best to create an AST node (with the assistance of RecoveryExprs) with as much checking done as soon as possible in the case of instantiations. --- Patch is 60.81 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/90796.diff 12 Files Affected: - (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+22-2) - (modified) clang/lib/Parse/ParseExpr.cpp (+2-1) - (modified) clang/lib/Sema/SemaOpenACC.cpp (+220-12) - (modified) clang/test/ParserOpenACC/parse-cache-construct.c (+1-2) - (modified) clang/test/ParserOpenACC/parse-cache-construct.cpp (+4-4) - (modified) clang/test/ParserOpenACC/parse-clauses.c (-2) - (added) clang/test/ParserOpenACC/parse-sub-array.cpp (+89) - (modified) clang/test/SemaOpenACC/compute-construct-private-clause.c (+9-17) - (modified) clang/test/SemaOpenACC/compute-construct-private-clause.cpp (+1-2) - (modified) clang/test/SemaOpenACC/compute-construct-varlist-ast.cpp (+9) - (added) clang/test/SemaOpenACC/sub-array-ast.cpp (+566) - (added) clang/test/SemaOpenACC/sub-array.cpp (+208) ``diff diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 4b074b853bfe65..fbb107679d94ba 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -12291,8 +12291,8 @@ def warn_acc_if_self_conflict "evaluates to true">, InGroup>; def err_acc_int_expr_requires_integer -: Error<"OpenACC %select{clause|directive}0 '%1' requires expression of " -"integer type (%2 invalid)">; +: Error<"OpenACC %select{clause '%1'|directive '%2'|sub-array bound}0 " +"requires expression of integer type (%3 invalid)">; def err_acc_int_expr_incomplete_class_type : Error<"OpenACC integer expression has incomplete class type %0">; def err_acc_int_expr_explicit_conversion @@ -12310,4 +12310,24 @@ def err_acc_num_gangs_num_args def err_acc_not_a_var_ref : Error<"OpenACC variable is not a valid variable name, sub-array, array " "element, or composite variable member">; +def err_acc_typecheck_subarray_value +: Error<"OpenACC sub-array subscripted value is not an array or pointer">; +def err_acc_subarray_function_type +: Error<"OpenACC sub-array cannot be of function type %0">; +def err_acc_subarray_incomplete_type +: Error<"OpenACC sub-array base is of incomplete type %0">; +def err_acc_subarray_no_length +: Error<"OpenACC sub-array length is unspecified and cannot be inferred " +"because the subscripted value is %select{not an array|an array of " +"unknown bound}0">; +def err_acc_subarray_negative +: Error<"OpenACC sub-array %select{lower bound|length}0 evaluated to " +"negative value %1">; +def err_acc_subarray_out_of_range +: Error<"OpenACC sub-array %select{lower bound|length}0 evaluated to a " +"value (%1) that would be out of the range of the subscripted " +"array size of %2">; +def err_acc_subarray_base_plus_length_out_of_range +: Error<"OpenACC sub-array specified range [%0:%1] would be out of the " +"range of the subscripted array size of %2">; } // end of sema component. diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index 7d6febb04a82c4..5f5f9a79c8c408 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -2039,7 +2039,8 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { if (Tok.is(tok::colon)) { // Consume ':' ColonLocFirst = ConsumeToken(); - Length = Actions.CorrectDelayedTyposInExpr(ParseExpression()); + if (Tok.isNot(tok::r_square)) +Length = Actions.CorrectDelayedTyposInExpr(ParseExpression()); } } else if (ArgExprs.size() <= 1 && getLangOpts().OpenMP) { ColonProtectionRAIIObject RAII(*this); diff --git a/clang/lib/Sema/SemaOpenACC.cpp b/clang/lib/Sema/SemaOpenACC.cpp index 3ea81e0497c203..a203ece7ff3130 100644 --- a/clang/lib/Sema/SemaOpenACC.cpp +++ b/clang/lib/Sema/SemaOpenACC.cpp @@ -16,6 +16,7 @@ #include "clang/Basic/DiagnosticSema.h" #include "clang/Basic/OpenACCKinds.h" #include "clang/Sema/Sema.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/Support/Casting.h" using namespace clang; @@ -367,7 +368,9 @@ ExprResult SemaOpenACC::ActOnIntExpr(OpenACCDirectiveKind DK, assert(((DK != OpenACCDirectiveKind::Invalid && CK == OpenACCClauseKind::Invalid) || (DK == OpenACCDirectiveKind::Invalid && - CK != OpenACCClauseKind::Invalid)) && + CK != OpenACCClauseKind::Invalid) || +
[clang] [OpenACC} Implement SubArray Parsing/Sema (PR #90796)
https://github.com/erichkeane created https://github.com/llvm/llvm-project/pull/90796 This implementation takes quite a bit from the OMP implementation of array sections, but only has to enforce the rules as applicable to OpenACC. Additionally, it does its best to create an AST node (with the assistance of RecoveryExprs) with as much checking done as soon as possible in the case of instantiations. >From ac69522bf15c7c169c4cdb9d3d1547c5c0962193 Mon Sep 17 00:00:00 2001 From: erichkeane Date: Tue, 30 Apr 2024 11:42:35 -0700 Subject: [PATCH] [OpenACC} Implement SubArray Parsing/Sema This implementation takes quite a bit from the OMP implementation of array sections, but only has to enforce the rules as applicable to OpenACC. Additionally, it does its best to create an AST node (with the assistance of RecoveryExprs) with as much checking done as soon as possible in the case of instantiations. --- .../clang/Basic/DiagnosticSemaKinds.td| 24 +- clang/lib/Parse/ParseExpr.cpp | 3 +- clang/lib/Sema/SemaOpenACC.cpp| 232 ++- .../ParserOpenACC/parse-cache-construct.c | 3 +- .../ParserOpenACC/parse-cache-construct.cpp | 8 +- clang/test/ParserOpenACC/parse-clauses.c | 2 - clang/test/ParserOpenACC/parse-sub-array.cpp | 89 +++ .../compute-construct-private-clause.c| 26 +- .../compute-construct-private-clause.cpp | 3 +- .../compute-construct-varlist-ast.cpp | 9 + clang/test/SemaOpenACC/sub-array-ast.cpp | 566 ++ clang/test/SemaOpenACC/sub-array.cpp | 208 +++ 12 files changed, 1131 insertions(+), 42 deletions(-) create mode 100644 clang/test/ParserOpenACC/parse-sub-array.cpp create mode 100644 clang/test/SemaOpenACC/sub-array-ast.cpp create mode 100644 clang/test/SemaOpenACC/sub-array.cpp diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 4b074b853bfe65..fbb107679d94ba 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -12291,8 +12291,8 @@ def warn_acc_if_self_conflict "evaluates to true">, InGroup>; def err_acc_int_expr_requires_integer -: Error<"OpenACC %select{clause|directive}0 '%1' requires expression of " -"integer type (%2 invalid)">; +: Error<"OpenACC %select{clause '%1'|directive '%2'|sub-array bound}0 " +"requires expression of integer type (%3 invalid)">; def err_acc_int_expr_incomplete_class_type : Error<"OpenACC integer expression has incomplete class type %0">; def err_acc_int_expr_explicit_conversion @@ -12310,4 +12310,24 @@ def err_acc_num_gangs_num_args def err_acc_not_a_var_ref : Error<"OpenACC variable is not a valid variable name, sub-array, array " "element, or composite variable member">; +def err_acc_typecheck_subarray_value +: Error<"OpenACC sub-array subscripted value is not an array or pointer">; +def err_acc_subarray_function_type +: Error<"OpenACC sub-array cannot be of function type %0">; +def err_acc_subarray_incomplete_type +: Error<"OpenACC sub-array base is of incomplete type %0">; +def err_acc_subarray_no_length +: Error<"OpenACC sub-array length is unspecified and cannot be inferred " +"because the subscripted value is %select{not an array|an array of " +"unknown bound}0">; +def err_acc_subarray_negative +: Error<"OpenACC sub-array %select{lower bound|length}0 evaluated to " +"negative value %1">; +def err_acc_subarray_out_of_range +: Error<"OpenACC sub-array %select{lower bound|length}0 evaluated to a " +"value (%1) that would be out of the range of the subscripted " +"array size of %2">; +def err_acc_subarray_base_plus_length_out_of_range +: Error<"OpenACC sub-array specified range [%0:%1] would be out of the " +"range of the subscripted array size of %2">; } // end of sema component. diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index 7d6febb04a82c4..5f5f9a79c8c408 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -2039,7 +2039,8 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { if (Tok.is(tok::colon)) { // Consume ':' ColonLocFirst = ConsumeToken(); - Length = Actions.CorrectDelayedTyposInExpr(ParseExpression()); + if (Tok.isNot(tok::r_square)) +Length = Actions.CorrectDelayedTyposInExpr(ParseExpression()); } } else if (ArgExprs.size() <= 1 && getLangOpts().OpenMP) { ColonProtectionRAIIObject RAII(*this); diff --git a/clang/lib/Sema/SemaOpenACC.cpp b/clang/lib/Sema/SemaOpenACC.cpp index 3ea81e0497c203..a203ece7ff3130 100644 --- a/clang/lib/Sema/SemaOpenACC.cpp +++ b/clang/lib/Sema/SemaOpenACC.cpp @@ -16,6 +16,7 @@ #include "clang/Basic/DiagnosticSema.h" #include "cl