We give a better diagnostic for non-constant array bounds in
compute_array_index_type_loc, we don't need to diagnose it in the parser.
But to avoid a regression on parse/varmod1.C we need to actually check
non-dependent expressions in a template.

Tested x86_64-pc-linux-gnu, applying to trunk.

gcc/cp/ChangeLog
2020-05-21  Jason Merrill  <ja...@redhat.com>

        * decl.c (compute_array_index_type_loc): Diagnose expressions
        in a template that can't be constant.
        * parser.c (cp_parser_direct_declarator): Don't check
        non-constant array bounds here.
---
 gcc/cp/decl.c                                       | 12 ++++++------
 gcc/cp/parser.c                                     |  2 ++
 gcc/testsuite/c-c++-common/gomp/depend-iterator-2.c |  2 +-
 gcc/testsuite/g++.dg/ext/vla1.C                     |  3 +--
 gcc/testsuite/g++.dg/template/array9.C              |  4 ++--
 gcc/testsuite/g++.dg/template/error41.C             |  2 +-
 6 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 6d1c08e064a..2e1390837e8 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -10328,13 +10328,14 @@ compute_array_index_type_loc (location_t name_loc, 
tree name, tree size,
      dependent type or whose size is specified by a constant expression
      that is value-dependent.  */
   /* We can only call value_dependent_expression_p on integral constant
-     expressions; treat non-constant expressions as dependent, too.  */
+     expressions.  */
   if (processing_template_decl
-      && (!TREE_CONSTANT (size) || value_dependent_expression_p (size)))
+      && potential_constant_expression (size)
+      && value_dependent_expression_p (size))
     {
-      /* We cannot do any checking for a SIZE that isn't known to be
-        constant. Just build the index type and mark that it requires
+      /* Just build the index type and mark that it requires
         structural equality checks.  */
+    in_template:
       itype = build_index_type (build_min (MINUS_EXPR, sizetype,
                                           size, size_one_node));
       TYPE_DEPENDENT_P (itype) = 1;
@@ -10447,8 +10448,7 @@ compute_array_index_type_loc (location_t name_loc, tree 
name, tree size,
     }
 
   if (processing_template_decl && !TREE_CONSTANT (size))
-    /* A variable sized array.  */
-    itype = build_min (MINUS_EXPR, sizetype, size, integer_one_node);
+    goto in_template;
   else
     {
       if (!TREE_CONSTANT (size))
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 6a0ef4d76ee..54ca875ce54 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -21366,6 +21366,8 @@ cp_parser_direct_declarator (cp_parser* parser,
                /* OK */;
              else if (error_operand_p (bounds))
                /* Already gave an error.  */;
+             else if (!cp_parser_uncommitted_to_tentative_parse_p (parser))
+               /* Let compute_array_index_type diagnose this.  */;
              else if (!parser->in_function_body
                       || current_binding_level->kind == sk_function_parms)
                {
diff --git a/gcc/testsuite/c-c++-common/gomp/depend-iterator-2.c 
b/gcc/testsuite/c-c++-common/gomp/depend-iterator-2.c
index 127528271ee..fff32a4761f 100644
--- a/gcc/testsuite/c-c++-common/gomp/depend-iterator-2.c
+++ b/gcc/testsuite/c-c++-common/gomp/depend-iterator-2.c
@@ -41,7 +41,7 @@ f1 (void)
   ;
   #pragma omp task depend (iterator (int i = 0:4, \
                                     struct U { int (*p)[i + 2]; } *p = 0:2) , 
in : a)  /* { dg-error "type of iterator 'p' refers to outer iterator 'i'" "" { 
target c } } */
-  ;                                                                    /* { 
dg-error "types may not be defined in iterator type|not an integer constant" "" 
{ target c++ } .-1 } */
+  ;                                                                    /* { 
dg-error "types may not be defined in iterator type|not an integral constant" 
"" { target c++ } .-1 } */
   #pragma omp task depend (iterator (i = 0:4, j = i:16) , in : a)      /* { 
dg-error "begin expression refers to outer iterator 'i'" } */
   ;
   #pragma omp task depend (iterator (i = 0:4, j = 2:i:1) , in : a)     /* { 
dg-error "end expression refers to outer iterator 'i'" } */
diff --git a/gcc/testsuite/g++.dg/ext/vla1.C b/gcc/testsuite/g++.dg/ext/vla1.C
index c017b6e90ed..cae3f82135a 100644
--- a/gcc/testsuite/g++.dg/ext/vla1.C
+++ b/gcc/testsuite/g++.dg/ext/vla1.C
@@ -19,8 +19,7 @@ class B { B (int); };
 B::B (int i)
 {
   struct S {
-    int ar[1][i];  // { dg-error "15:size of array .ar. is not an integral" "" 
{ target c++11 } }
-// { dg-error "array bound" "" { target c++98_only } .-1 }
+    int ar[1][i];  // { dg-error "15:size of array .ar. is not an integral" }
   } s;
 
   s.ar[0][0] = 0;  // { dg-prune-output "no member" }
diff --git a/gcc/testsuite/g++.dg/template/array9.C 
b/gcc/testsuite/g++.dg/template/array9.C
index f3e8335c943..ce9fb649d3a 100644
--- a/gcc/testsuite/g++.dg/template/array9.C
+++ b/gcc/testsuite/g++.dg/template/array9.C
@@ -7,8 +7,8 @@ struct Tree {
   Tree* R[subtrees]; // { dg-error "" }
   ~Tree()
   {
-    delete [] L[0]; // { dg-error "" }
-    delete [] R[0]; // { dg-error "" }
+    delete [] L[0];
+    delete [] R[0];
   }
 };
 
diff --git a/gcc/testsuite/g++.dg/template/error41.C 
b/gcc/testsuite/g++.dg/template/error41.C
index c92b8497aff..21e8ffbc20e 100644
--- a/gcc/testsuite/g++.dg/template/error41.C
+++ b/gcc/testsuite/g++.dg/template/error41.C
@@ -8,5 +8,5 @@ struct A
 
 template <int> struct B
 {
-  int x[A::i]; // { dg-error "array bound is not an integer constant" }
+  int x[A::i]; // { dg-error "not an integral constant-expression" }
 };

base-commit: 149c8c7c27a17a2941d07e2f76b1e1c823e2fa80
-- 
2.18.1

Reply via email to