Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -8242,8 +8242,10 @@ 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< Index: lib/Sema/SemaExpr.cpp =================================================================== --- lib/Sema/SemaExpr.cpp +++ lib/Sema/SemaExpr.cpp @@ -4304,14 +4304,13 @@ 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 @@ 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 @@ } 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) Index: test/OpenMP/target_depend_messages.cpp =================================================================== --- test/OpenMP/target_depend_messages.cpp +++ test/OpenMP/target_depend_messages.cpp @@ -66,7 +66,7 @@ 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(); Index: test/OpenMP/target_enter_data_depend_messages.cpp =================================================================== --- test/OpenMP/target_enter_data_depend_messages.cpp +++ test/OpenMP/target_enter_data_depend_messages.cpp @@ -68,7 +68,7 @@ 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 @@ 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(); Index: test/OpenMP/target_exit_data_depend_messages.cpp =================================================================== --- test/OpenMP/target_exit_data_depend_messages.cpp +++ test/OpenMP/target_exit_data_depend_messages.cpp @@ -68,7 +68,7 @@ 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 @@ 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(); Index: test/OpenMP/target_map_messages.cpp =================================================================== --- test/OpenMP/target_map_messages.cpp +++ test/OpenMP/target_map_messages.cpp @@ -51,6 +51,10 @@ {} #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) {} Index: test/OpenMP/target_parallel_depend_messages.cpp =================================================================== --- test/OpenMP/target_parallel_depend_messages.cpp +++ test/OpenMP/target_parallel_depend_messages.cpp @@ -66,7 +66,7 @@ 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(); Index: test/OpenMP/target_parallel_for_depend_messages.cpp =================================================================== --- test/OpenMP/target_parallel_for_depend_messages.cpp +++ test/OpenMP/target_parallel_for_depend_messages.cpp @@ -67,7 +67,7 @@ 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(); Index: test/OpenMP/target_parallel_for_map_messages.cpp =================================================================== --- test/OpenMP/target_parallel_for_map_messages.cpp +++ test/OpenMP/target_parallel_for_map_messages.cpp @@ -80,6 +80,10 @@ 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 @@ 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) Index: test/OpenMP/target_parallel_for_simd_depend_messages.cpp =================================================================== --- test/OpenMP/target_parallel_for_simd_depend_messages.cpp +++ test/OpenMP/target_parallel_for_simd_depend_messages.cpp @@ -67,7 +67,7 @@ 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(); Index: test/OpenMP/target_parallel_for_simd_map_messages.cpp =================================================================== --- test/OpenMP/target_parallel_for_simd_map_messages.cpp +++ test/OpenMP/target_parallel_for_simd_map_messages.cpp @@ -80,6 +80,10 @@ 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 @@ 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) Index: test/OpenMP/target_parallel_map_messages.cpp =================================================================== --- test/OpenMP/target_parallel_map_messages.cpp +++ test/OpenMP/target_parallel_map_messages.cpp @@ -80,6 +80,10 @@ 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 @@ 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) Index: test/OpenMP/target_update_depend_messages.cpp =================================================================== --- test/OpenMP/target_update_depend_messages.cpp +++ test/OpenMP/target_update_depend_messages.cpp @@ -50,7 +50,7 @@ #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 @@ #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}} Index: test/OpenMP/task_depend_messages.cpp =================================================================== --- test/OpenMP/task_depend_messages.cpp +++ test/OpenMP/task_depend_messages.cpp @@ -43,7 +43,7 @@ #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}}