From c37b1442fd2d3f9ee47bef69dcf154bd216f0f86 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Thu, 21 May 2020 10:27:11 -0400 Subject: [PATCH] c++: Check constant array bounds later. 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. gcc/cp/ChangeLog: * 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/testsuite/ChangeLog: * c-c++-common/gomp/depend-iterator-2.c: Adjust. * g++.dg/ext/vla1.C: Adjust. * g++.dg/template/array9.C: Adjust. * g++.dg/template/error41.C: Adjust. --- 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 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" } }; -- 2.30.2