[OpenMP] Allow negative lower bound in array sections based on pointers
authorKelvin Li <kkwli0@gmail.com>
Wed, 20 Jul 2016 20:45:29 +0000 (20:45 +0000)
committerKelvin Li <kkwli0@gmail.com>
Wed, 20 Jul 2016 20:45:29 +0000 (20:45 +0000)
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

llvm-svn: 276177

14 files changed:
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/Sema/SemaExpr.cpp
clang/test/OpenMP/target_depend_messages.cpp
clang/test/OpenMP/target_enter_data_depend_messages.cpp
clang/test/OpenMP/target_exit_data_depend_messages.cpp
clang/test/OpenMP/target_map_messages.cpp
clang/test/OpenMP/target_parallel_depend_messages.cpp
clang/test/OpenMP/target_parallel_for_depend_messages.cpp
clang/test/OpenMP/target_parallel_for_map_messages.cpp
clang/test/OpenMP/target_parallel_for_simd_depend_messages.cpp
clang/test/OpenMP/target_parallel_for_simd_map_messages.cpp
clang/test/OpenMP/target_parallel_map_messages.cpp
clang/test/OpenMP/target_update_depend_messages.cpp
clang/test/OpenMP/task_depend_messages.cpp

index 7987cf0..e172afa 100644 (file)
@@ -8260,8 +8260,10 @@ def warn_omp_section_is_char : Warning<"array section %select{lower bound|length
   InGroup<CharSubscript>, 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 d748b3c..ac5da81 100644 (file)
@@ -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)
index c13a3ed..48bd941 100644 (file)
@@ -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();
index 84254b5..4aa1223 100644 (file)
@@ -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();
index 4c59b62..cdefbee 100644 (file)
@@ -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();
index f9bb941..a3b2168 100644 (file)
@@ -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)
     {}
index a9300ca..fde940b 100644 (file)
@@ -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();
index d0e74f9..cf17d7a 100644 (file)
@@ -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();
index 6b5d2e7..f0019f9 100644 (file)
@@ -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)
index 0504cab..a8b4de7 100644 (file)
@@ -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();
index 93f0be8..195b39c 100644 (file)
@@ -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)
index e168016..ca794ce 100644 (file)
@@ -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)
index fe3325d..64383a0 100644 (file)
@@ -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}}
index 39bf484..576738c 100644 (file)
@@ -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}}