On Wed, May 30, 2018 at 02:39:15PM -0600, Martin Sebor wrote:
> gcc/c-family/ChangeLog:
> 
>       PR middle-end/85956
>       * c-pretty-print.c (c_pretty_printer::direct_abstract_declarator):
>       Handle error-mark-node in array bounds gracefully.

This isn't sufficient, as it still ICEs with C++:
during GIMPLE pass: vrp
In function ‘_Z3fooiPv._omp_fn.0’:
tree check: expected class ‘type’, have ‘exceptional’ (error_mark) in 
build_int_cst, at tree.c:1342
   #pragma omp parallel shared(a) default(none)
           ^~~
0x15ef6b3 tree_class_check_failed(tree_node const*, tree_code_class, char 
const*, int, char const*)
        ../../gcc/tree.c:9385
0x80fb7c tree_class_check(tree_node*, tree_code_class, char const*, int, char 
const*)
        ../../gcc/tree.h:3258
0x15d017c build_int_cst(tree_node*, poly_int<1u, long>)
        ../../gcc/tree.c:1342
0xe2b685 round_up_loc(unsigned int, tree_node*, unsigned int)
        ../../gcc/fold-const.c:14330
0x1233717 finalize_type_size
        ../../gcc/stor-layout.c:1908
0x1238390 layout_type(tree_node*)
        ../../gcc/stor-layout.c:2578
0x15e9d8c build_array_type_1
        ../../gcc/tree.c:7869
0x15ea022 build_array_type(tree_node*, tree_node*, bool)
        ../../gcc/tree.c:7906
0xad28b7 build_cplus_array_type(tree_node*, tree_node*)
        ../../gcc/cp/tree.c:985
0xad46c5 strip_typedefs(tree_node*, bool*)
        ../../gcc/cp/tree.c:1459
0x9312a8 type_to_string
        ../../gcc/cp/error.c:3176
0x93425c cp_printer
        ../../gcc/cp/error.c:4085
0x1f79f1b pp_format(pretty_printer*, text_info*)
        ../../gcc/pretty-print.c:1375

I came up with the following hack instead (or in addition to),
replace those error_mark_node bounds with NULL (i.e. pretend flexible array
members) if during OpenMP/OpenACC outlining we've decided not to pass around
the bounds artificial decl because nothing really use it.

Is this a reasonable hack, or shall we go with Martin's patch + similar
change in C++ pretty printer to handle error_mark_node specially and perhaps
also handle NULL specially too as the patch does, or both those FE changes
and this, something else?

Bootstrapped/regtested on x86_64-linux and i686-linux.

2018-05-31  Jakub Jelinek  <ja...@redhat.com>

        PR middle-end/85956
        * tree-inline.h (struct copy_body_data): Add adjust_array_error_bounds
        field.
        * tree-inline.c (remap_type_1): Formatting fix.  If TYPE_MAX_VALUE of
        ARRAY_TYPE's TYPE_DOMAIN is newly error_mark_node, replace it with
        NULL if id->adjust_array_error_bounds.
        * omp-low.c (new_omp_context): Set cb.adjust_array_error_bounds.
cp/
        * error.c (dump_type_suffix): Don't crash on NULL max.
testsuite/
        * g++.dg/gomp/pr85956.c: New test.

--- gcc/tree-inline.h.jj        2018-01-03 10:19:54.931533922 +0100
+++ gcc/tree-inline.h   2018-05-30 18:59:47.433022338 +0200
@@ -151,6 +151,10 @@ struct copy_body_data
 
   /* Do not create new declarations when within type remapping.  */
   bool prevent_decl_creation_for_types;
+
+  /* Replace error_mark_node as upper bound of array types with
+     NULL.  */
+  bool adjust_array_error_bounds;
 };
 
 /* Weights of constructions for estimate_num_insns.  */
--- gcc/tree-inline.c.jj        2018-05-29 13:57:38.360164318 +0200
+++ gcc/tree-inline.c   2018-05-30 19:06:49.897605141 +0200
@@ -519,11 +519,21 @@ remap_type_1 (tree type, copy_body_data
 
       if (TYPE_MAIN_VARIANT (new_tree) != new_tree)
        {
-         gcc_checking_assert (TYPE_DOMAIN (type) == TYPE_DOMAIN 
(TYPE_MAIN_VARIANT (type)));
+         gcc_checking_assert (TYPE_DOMAIN (type)
+                              == TYPE_DOMAIN (TYPE_MAIN_VARIANT (type)));
          TYPE_DOMAIN (new_tree) = TYPE_DOMAIN (TYPE_MAIN_VARIANT (new_tree));
        }
       else
-       TYPE_DOMAIN (new_tree) = remap_type (TYPE_DOMAIN (new_tree), id);
+        {
+         TYPE_DOMAIN (new_tree) = remap_type (TYPE_DOMAIN (new_tree), id);
+         /* For array bounds where we have decided not to copy over the bounds
+            variable which isn't used in OpenMP/OpenACC region, change them to
+            NULL.  */
+         if (TYPE_MAX_VALUE (TYPE_DOMAIN (new_tree)) == error_mark_node
+             && id->adjust_array_error_bounds
+             && TYPE_MAX_VALUE (TYPE_DOMAIN (type)) != error_mark_node)
+           TYPE_MAX_VALUE (TYPE_DOMAIN (new_tree)) = NULL_TREE;
+        }
       break;
 
     case RECORD_TYPE:
--- gcc/omp-low.c.jj    2018-02-10 00:22:01.337951717 +0100
+++ gcc/omp-low.c       2018-05-30 19:03:13.876307134 +0200
@@ -855,6 +855,7 @@ new_omp_context (gimple *stmt, omp_conte
     }
 
   ctx->cb.decl_map = new hash_map<tree, tree>;
+  ctx->cb.adjust_array_error_bounds = true;
 
   return ctx;
 }
--- gcc/cp/error.c.jj   2018-05-25 14:34:41.958381711 +0200
+++ gcc/cp/error.c      2018-05-30 19:19:26.890594362 +0200
@@ -922,8 +922,10 @@ dump_type_suffix (cxx_pretty_printer *pp
       if (tree dtype = TYPE_DOMAIN (t))
        {
          tree max = TYPE_MAX_VALUE (dtype);
+         if (max == NULL_TREE)
+           ;
          /* Zero-length arrays have an upper bound of SIZE_MAX.  */
-         if (integer_all_onesp (max))
+         else if (integer_all_onesp (max))
            pp_character (pp, '0');
          else if (tree_fits_shwi_p (max))
            pp_wide_integer (pp, tree_to_shwi (max) + 1);
--- gcc/testsuite/g++.dg/gomp/pr85956.c.jj      2018-05-30 19:20:06.236645197 
+0200
+++ gcc/testsuite/g++.dg/gomp/pr85956.c 2018-05-30 19:16:13.313344213 +0200
@@ -0,0 +1,12 @@
+/* PR middle-end/85956 */
+/* { dg-do compile } */
+/* { dg-additional-options "-O2 -Wall" } */
+
+void
+foo (int n, void *p)
+{
+  int (*a)[n] = (int (*)[n]) p;
+  #pragma omp parallel shared(a) default(none)
+  #pragma omp master
+    a[-1][-1] = 42;    /* { dg-warning "array subscript -1 is below array 
bounds" } */
+}


        Jakub

Reply via email to