From: Kelvin Li Date: Wed, 20 Jul 2016 20:45:29 +0000 (+0000) Subject: [OpenMP] Allow negative lower bound in array sections based on pointers X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7a77c15ec615a2b014b27307f3efb15c2687a0f9;p=clang [OpenMP] Allow negative lower bound in array sections based on pointers OpenMP 4.5 removed the restriction that array section lower bound must be non negative. This change is to allow negative values for array section based on pointers. For array section based on array type there is still a restriction: "The array section must be a subset of the original array." Patch by David S. Differential Revision: https://reviews.llvm.org/D22481 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@276177 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 7987cf0511..e172afa9e0 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -8260,8 +8260,10 @@ def warn_omp_section_is_char : Warning<"array section %select{lower bound|length InGroup, DefaultIgnore; def err_omp_section_incomplete_type : Error< "section of pointer to incomplete type %0">; -def err_omp_section_negative : Error< - "section %select{lower bound|length}0 is evaluated to a negative value %1">; +def err_omp_section_not_subset_of_array : Error< + "array section must be a subset of the original array">; +def err_omp_section_length_negative : Error< + "section length is evaluated to a negative value %0">; def err_omp_section_length_undefined : Error< "section length is unspecified and cannot be inferred because subscripted value is %select{not an array|an array of unknown bound}0">; def err_omp_wrong_linear_modifier : Error< diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index d748b3c18e..ac5da81129 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -4304,14 +4304,13 @@ ExprResult Sema::ActOnOMPArraySectionExpr(Expr *Base, SourceLocation LBLoc, diag::err_omp_section_incomplete_type, Base)) return ExprError(); - if (LowerBound) { + if (LowerBound && !OriginalTy->isAnyPointerType()) { llvm::APSInt LowerBoundValue; if (LowerBound->EvaluateAsInt(LowerBoundValue, Context)) { - // OpenMP 4.0, [2.4 Array Sections] - // The lower-bound and length must evaluate to non-negative integers. + // OpenMP 4.5, [2.4 Array Sections] + // The array section must be a subset of the original array. if (LowerBoundValue.isNegative()) { - Diag(LowerBound->getExprLoc(), diag::err_omp_section_negative) - << 0 << LowerBoundValue.toString(/*Radix=*/10, /*Signed=*/true) + Diag(LowerBound->getExprLoc(), diag::err_omp_section_not_subset_of_array) << LowerBound->getSourceRange(); return ExprError(); } @@ -4321,11 +4320,11 @@ ExprResult Sema::ActOnOMPArraySectionExpr(Expr *Base, SourceLocation LBLoc, if (Length) { llvm::APSInt LengthValue; if (Length->EvaluateAsInt(LengthValue, Context)) { - // OpenMP 4.0, [2.4 Array Sections] - // The lower-bound and length must evaluate to non-negative integers. + // OpenMP 4.5, [2.4 Array Sections] + // The length must evaluate to non-negative integers. if (LengthValue.isNegative()) { - Diag(Length->getExprLoc(), diag::err_omp_section_negative) - << 1 << LengthValue.toString(/*Radix=*/10, /*Signed=*/true) + Diag(Length->getExprLoc(), diag::err_omp_section_length_negative) + << LengthValue.toString(/*Radix=*/10, /*Signed=*/true) << Length->getSourceRange(); return ExprError(); } @@ -4333,7 +4332,7 @@ ExprResult Sema::ActOnOMPArraySectionExpr(Expr *Base, SourceLocation LBLoc, } else if (ColonLoc.isValid() && (OriginalTy.isNull() || (!OriginalTy->isConstantArrayType() && !OriginalTy->isVariableArrayType()))) { - // OpenMP 4.0, [2.4 Array Sections] + // OpenMP 4.5, [2.4 Array Sections] // When the size of the array dimension is not known, the length must be // specified explicitly. Diag(ColonLoc, diag::err_omp_section_length_undefined) diff --git a/test/OpenMP/target_depend_messages.cpp b/test/OpenMP/target_depend_messages.cpp index c13a3edaf6..48bd94180c 100644 --- a/test/OpenMP/target_depend_messages.cpp +++ b/test/OpenMP/target_depend_messages.cpp @@ -66,7 +66,7 @@ int main(int argc, char **argv, char *env[]) { foo(); #pragma omp target depend (in : argv[0:-1]) // expected-error {{section length is evaluated to a negative value -1}} foo(); - #pragma omp target depend (in : argv[-1:0]) // expected-error {{section lower bound is evaluated to a negative value -1}} + #pragma omp target depend (in : argv[-1:0]) foo(); #pragma omp target depend (in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} foo(); diff --git a/test/OpenMP/target_enter_data_depend_messages.cpp b/test/OpenMP/target_enter_data_depend_messages.cpp index 84254b5c31..4aa122355b 100644 --- a/test/OpenMP/target_enter_data_depend_messages.cpp +++ b/test/OpenMP/target_enter_data_depend_messages.cpp @@ -68,7 +68,7 @@ int tmain(T argc, S **argv, R *env[]) { foo(); #pragma omp target enter data map(to: i) depend (in : argv[0:-1]) // expected-error {{section length is evaluated to a negative value -1}} foo(); - #pragma omp target enter data map(to: i) depend (in : argv[-1:0]) // expected-error {{section lower bound is evaluated to a negative value -1}} + #pragma omp target enter data map(to: i) depend (in : argv[-1:0]) foo(); #pragma omp target enter data map(to: i) depend (in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} foo(); @@ -143,7 +143,7 @@ int main(int argc, char **argv, char *env[]) { foo(); #pragma omp target enter data map(to: i) depend (in : argv[0:-1]) // expected-error {{section length is evaluated to a negative value -1}} foo(); - #pragma omp target enter data map(to: i) depend (in : argv[-1:0]) // expected-error {{section lower bound is evaluated to a negative value -1}} + #pragma omp target enter data map(to: i) depend (in : argv[-1:0]) foo(); #pragma omp target enter data map(to: i) depend (in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} foo(); diff --git a/test/OpenMP/target_exit_data_depend_messages.cpp b/test/OpenMP/target_exit_data_depend_messages.cpp index 4c59b6205f..cdefbeed08 100644 --- a/test/OpenMP/target_exit_data_depend_messages.cpp +++ b/test/OpenMP/target_exit_data_depend_messages.cpp @@ -68,7 +68,7 @@ int tmain(T argc, S **argv, R *env[]) { foo(); #pragma omp target exit data map(from: i) depend (in : argv[0:-1]) // expected-error {{section length is evaluated to a negative value -1}} foo(); - #pragma omp target exit data map(from: i) depend (in : argv[-1:0]) // expected-error {{section lower bound is evaluated to a negative value -1}} + #pragma omp target exit data map(from: i) depend (in : argv[-1:0]) foo(); #pragma omp target exit data map(from: i) depend (in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} foo(); @@ -143,7 +143,7 @@ int main(int argc, char **argv, char *env[]) { foo(); #pragma omp target exit data map(from: i) depend (in : argv[0:-1]) // expected-error {{section length is evaluated to a negative value -1}} foo(); - #pragma omp target exit data map(from: i) depend (in : argv[-1:0]) // expected-error {{section lower bound is evaluated to a negative value -1}} + #pragma omp target exit data map(from: i) depend (in : argv[-1:0]) foo(); #pragma omp target exit data map(from: i) depend (in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} foo(); diff --git a/test/OpenMP/target_map_messages.cpp b/test/OpenMP/target_map_messages.cpp index f9bb9410c4..a3b2168fed 100644 --- a/test/OpenMP/target_map_messages.cpp +++ b/test/OpenMP/target_map_messages.cpp @@ -51,6 +51,10 @@ struct SA { {} #pragma omp target map(to:b,e[:]) {} + #pragma omp target map(b[-1:]) // expected-error {{array section must be a subset of the original array}} + {} + #pragma omp target map(b[:-1]) // expected-error {{section length is evaluated to a negative value -1}} + {} #pragma omp target map(always, tofrom: c,f) {} diff --git a/test/OpenMP/target_parallel_depend_messages.cpp b/test/OpenMP/target_parallel_depend_messages.cpp index a9300ca6ad..fde940be1a 100644 --- a/test/OpenMP/target_parallel_depend_messages.cpp +++ b/test/OpenMP/target_parallel_depend_messages.cpp @@ -66,7 +66,7 @@ int main(int argc, char **argv, char *env[]) { foo(); #pragma omp target parallel depend (in : argv[0:-1]) // expected-error {{section length is evaluated to a negative value -1}} foo(); - #pragma omp target parallel depend (in : argv[-1:0]) // expected-error {{section lower bound is evaluated to a negative value -1}} + #pragma omp target parallel depend (in : argv[-1:0]) foo(); #pragma omp target parallel depend (in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} foo(); diff --git a/test/OpenMP/target_parallel_for_depend_messages.cpp b/test/OpenMP/target_parallel_for_depend_messages.cpp index d0e74f9cc6..cf17d7a5de 100644 --- a/test/OpenMP/target_parallel_for_depend_messages.cpp +++ b/test/OpenMP/target_parallel_for_depend_messages.cpp @@ -67,7 +67,7 @@ int main(int argc, char **argv, char *env[]) { for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for depend (in : argv[0:-1]) // expected-error {{section length is evaluated to a negative value -1}} for (i = 0; i < argc; ++i) foo(); - #pragma omp target parallel for depend (in : argv[-1:0]) // expected-error {{section lower bound is evaluated to a negative value -1}} + #pragma omp target parallel for depend (in : argv[-1:0]) for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for depend (in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} for (i = 0; i < argc; ++i) foo(); diff --git a/test/OpenMP/target_parallel_for_map_messages.cpp b/test/OpenMP/target_parallel_for_map_messages.cpp index 6b5d2e7f82..f0019f94f4 100644 --- a/test/OpenMP/target_parallel_for_map_messages.cpp +++ b/test/OpenMP/target_parallel_for_map_messages.cpp @@ -80,6 +80,10 @@ T tmain(T argc) { for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for map(x: y) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(l[-1:]) // expected-error 2 {{array section must be a subset of the original array}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(l[:-1]) // expected-error 2 {{section length is evaluated to a negative value -1}} + for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for map(x) for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for map(tofrom: t[:I]) @@ -196,6 +200,10 @@ int main(int argc, char **argv) { for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for map(x: y) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(l[-1:]) // expected-error {{array section must be a subset of the original array}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(l[:-1]) // expected-error {{section length is evaluated to a negative value -1}} + for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for map(x) for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for map(to: x) diff --git a/test/OpenMP/target_parallel_for_simd_depend_messages.cpp b/test/OpenMP/target_parallel_for_simd_depend_messages.cpp index 0504cabd0f..a8b4de7ff7 100644 --- a/test/OpenMP/target_parallel_for_simd_depend_messages.cpp +++ b/test/OpenMP/target_parallel_for_simd_depend_messages.cpp @@ -67,7 +67,7 @@ int main(int argc, char **argv, char *env[]) { for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for simd depend (in : argv[0:-1]) // expected-error {{section length is evaluated to a negative value -1}} for (i = 0; i < argc; ++i) foo(); - #pragma omp target parallel for simd depend (in : argv[-1:0]) // expected-error {{section lower bound is evaluated to a negative value -1}} + #pragma omp target parallel for simd depend (in : argv[-1:0]) for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for simd depend (in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} for (i = 0; i < argc; ++i) foo(); diff --git a/test/OpenMP/target_parallel_for_simd_map_messages.cpp b/test/OpenMP/target_parallel_for_simd_map_messages.cpp index 93f0be81e3..195b39c595 100644 --- a/test/OpenMP/target_parallel_for_simd_map_messages.cpp +++ b/test/OpenMP/target_parallel_for_simd_map_messages.cpp @@ -80,6 +80,10 @@ T tmain(T argc) { for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for simd map(x: y) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(l[-1:]) // expected-error 2 {{array section must be a subset of the original array}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(l[:-1]) // expected-error 2 {{section length is evaluated to a negative value -1}} + for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for simd map(x) for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for simd map(tofrom: t[:I]) @@ -196,6 +200,10 @@ int main(int argc, char **argv) { for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for simd map(x: y) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel map(l[-1:]) // expected-error {{array section must be a subset of the original array}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel map(l[:-1]) // expected-error {{section length is evaluated to a negative value -1}} + for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for simd map(x) for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for simd map(to: x) diff --git a/test/OpenMP/target_parallel_map_messages.cpp b/test/OpenMP/target_parallel_map_messages.cpp index e168016654..ca794cecf4 100644 --- a/test/OpenMP/target_parallel_map_messages.cpp +++ b/test/OpenMP/target_parallel_map_messages.cpp @@ -80,6 +80,10 @@ T tmain(T argc) { foo(); #pragma omp target parallel map(x: y) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} foo(); +#pragma omp target parallel map(l[-1:]) // expected-error 2 {{array section must be a subset of the original array}} + foo(); +#pragma omp target parallel map(l[:-1]) // expected-error 2 {{section length is evaluated to a negative value -1}} + foo(); #pragma omp target parallel map(x) foo(); #pragma omp target parallel map(tofrom: t[:I]) @@ -195,6 +199,10 @@ int main(int argc, char **argv) { foo(); #pragma omp target parallel map(x: y) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} foo(); +#pragma omp target parallel map(l[-1:]) // expected-error {{array section must be a subset of the original array}} + foo(); +#pragma omp target parallel map(l[:-1]) // expected-error {{section length is evaluated to a negative value -1}} + foo(); #pragma omp target parallel map(x) foo(); #pragma omp target parallel map(to: x) diff --git a/test/OpenMP/target_update_depend_messages.cpp b/test/OpenMP/target_update_depend_messages.cpp index fe3325d80f..64383a0491 100644 --- a/test/OpenMP/target_update_depend_messages.cpp +++ b/test/OpenMP/target_update_depend_messages.cpp @@ -50,7 +50,7 @@ int tmain(T argc, S **argv, R *env[]) { #pragma omp target update to(z) depend(in : argv[argc: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}} #pragma omp target update to(z) depend(in : argv[argc:argc] // expected-error {{expected ')'}} expected-note {{to match this '('}} #pragma omp target update to(z) depend(in : argv[0:-1]) // expected-error {{section length is evaluated to a negative value -1}} - #pragma omp target update to(z) depend(in : argv[-1:0]) // expected-error {{section lower bound is evaluated to a negative value -1}} + #pragma omp target update to(z) depend(in : argv[-1:0]) #pragma omp target update to(z) depend(in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} #pragma omp target update to(z) depend(in : argv[3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} #pragma omp target update to(z) depend(in:a[0:1]) // expected-error {{subscripted value is not an array or pointer}} @@ -98,7 +98,7 @@ int main(int argc, char **argv, char *env[]) { #pragma omp target update to(z) depend(in : argv[argc: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}} #pragma omp target update to(z) depend(in : argv[argc:argc] // expected-error {{expected ')'}} expected-note {{to match this '('}} #pragma omp target update to(z) depend(in : argv[0:-1]) // expected-error {{section length is evaluated to a negative value -1}} - #pragma omp target update to(z) depend(in : argv[-1:0]) // expected-error {{section lower bound is evaluated to a negative value -1}} + #pragma omp target update to(z) depend(in : argv[-1:0]) #pragma omp target update to(z) depend(in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} #pragma omp target update to(z) depend(in : argv[3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} #pragma omp target update to(z) depend(in:a[0:1]) // expected-error {{subscripted value is not an array or pointer}} diff --git a/test/OpenMP/task_depend_messages.cpp b/test/OpenMP/task_depend_messages.cpp index 39bf484789..576738ceac 100644 --- a/test/OpenMP/task_depend_messages.cpp +++ b/test/OpenMP/task_depend_messages.cpp @@ -43,7 +43,7 @@ int main(int argc, char **argv, char *env[]) { #pragma omp task depend (in : argv[argc: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}} #pragma omp task depend (in : argv[argc:argc] // expected-error {{expected ')'}} expected-note {{to match this '('}} #pragma omp task depend (in : argv[0:-1]) // expected-error {{section length is evaluated to a negative value -1}} - #pragma omp task depend (in : argv[-1:0]) // expected-error {{section lower bound is evaluated to a negative value -1}} + #pragma omp task depend (in : argv[-1:0]) #pragma omp task depend (in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} #pragma omp task depend (in : argv[3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} #pragma omp task depend(in:a[0:1]) // expected-error {{subscripted value is not an array or pointer}}