* [PATCH] avoid ICE when pretty-printing a VLA with an error bound (PR 85956) @ 2018-05-30 20:57 Martin Sebor 2018-05-31 8:19 ` Jakub Jelinek 0 siblings, 1 reply; 12+ messages in thread From: Martin Sebor @ 2018-05-30 20:57 UTC (permalink / raw) To: Gcc Patch List [-- Attachment #1: Type: text/plain, Size: 1738 bytes --] The syntactically valid but undefined test case submitted in bug 85956 shows that the pretty-printer ICEs when passed a pointer to variable-length array whose upper bound is an error-mark-node. The ICE is triggered by -Warray-bounds discovering that a negative subscript into the VLA is out-of-bounds and trying to mention the type of the VLA in the diagnostic. The error bound appears to be the result of the omp pass. The attached change avoids the ICE by ignoring error-mark-node as an array bound. It results in -Warray-bounds printing: array subscript -1 is below array bounds of âint[]â for the VLA type. That's not ideal because the printed type is indistinguishable from an array with an unknown bound, but in the absence of a valid bound I can't really think of a solution that's much better (but see below). Without -fopenmp, when it detects an invalid index into a VLA -Warray-bounds might print something like: array subscript -1 is below array bounds of âint[<Uef30> + 1]â The <Uef30> + 1 represents the variable-length upper bound. That doesn't seem particularly informative or helpful but since it's unrelated to the ICE (and might come up in other diagnostics besides -Warray-bounds) I haven't changed it in the attached patch. If we want to print VLAs differently in diagnostics I think it should be done in a separate change. One possibility is to leave the bound out altogether as this patch does. Another is to use the C [*] VLA syntax. That should turn the above into: array subscript -1 is below array bounds of âint[*]â This notation could be used just for valid VLAs or also for the openmp VLAs with an error upper bound if they can't be made valid. Martin [-- Attachment #2: gcc-85956.diff --] [-- Type: text/x-patch, Size: 2241 bytes --] PR middle-end/85956 - ICE in wide_int_to_tree_1:1549 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. gcc/testsuite/ChangeLog: PR middle-end/85956 * gcc.dg/gomp/pr85956.c: New test. Index: gcc/c-family/c-pretty-print.c =================================================================== --- gcc/c-family/c-pretty-print.c (revision 260969) +++ gcc/c-family/c-pretty-print.c (working copy) @@ -570,20 +570,26 @@ c_pretty_printer::direct_abstract_declarator (tree break; case ARRAY_TYPE: - pp_c_left_bracket (this); - if (TYPE_DOMAIN (t) && TYPE_MAX_VALUE (TYPE_DOMAIN (t))) - { - tree maxval = TYPE_MAX_VALUE (TYPE_DOMAIN (t)); - tree type = TREE_TYPE (maxval); + { + pp_c_left_bracket (this); - if (tree_fits_shwi_p (maxval)) - pp_wide_integer (this, tree_to_shwi (maxval) + 1); - else - expression (fold_build2 (PLUS_EXPR, type, maxval, - build_int_cst (type, 1))); - } - pp_c_right_bracket (this); - direct_abstract_declarator (TREE_TYPE (t)); + if (tree dom = TYPE_DOMAIN (t)) + { + tree maxval = TYPE_MAX_VALUE (dom); + if (maxval && maxval != error_mark_node) + { + tree type = TREE_TYPE (maxval); + + if (tree_fits_shwi_p (maxval)) + pp_wide_integer (this, tree_to_shwi (maxval) + 1); + else + expression (fold_build2 (PLUS_EXPR, type, maxval, + build_int_cst (type, 1))); + } + } + pp_c_right_bracket (this); + direct_abstract_declarator (TREE_TYPE (t)); + } break; case IDENTIFIER_NODE: Index: gcc/testsuite/gcc.dg/gomp/pr85956.c =================================================================== --- gcc/testsuite/gcc.dg/gomp/pr85956.c (nonexistent) +++ gcc/testsuite/gcc.dg/gomp/pr85956.c (working copy) @@ -0,0 +1,13 @@ +/* PR middle-end/85956 - ICE in wide_int_to_tree_1, at tree.c:1549 + { dg-do compile } + { dg-options "-O2 -Wall -fopenmp" } */ + +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 "\\\[-Warray-bounds]" } */ +} ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] avoid ICE when pretty-printing a VLA with an error bound (PR 85956) 2018-05-30 20:57 [PATCH] avoid ICE when pretty-printing a VLA with an error bound (PR 85956) Martin Sebor @ 2018-05-31 8:19 ` Jakub Jelinek 2018-05-31 13:25 ` Jason Merrill 0 siblings, 1 reply; 12+ messages in thread From: Jakub Jelinek @ 2018-05-31 8:19 UTC (permalink / raw) To: Richard Biener, Jason Merrill, Martin Sebor; +Cc: Gcc Patch List 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 <jakub@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 ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] avoid ICE when pretty-printing a VLA with an error bound (PR 85956) 2018-05-31 8:19 ` Jakub Jelinek @ 2018-05-31 13:25 ` Jason Merrill 2018-05-31 13:52 ` Jakub Jelinek 0 siblings, 1 reply; 12+ messages in thread From: Jason Merrill @ 2018-05-31 13:25 UTC (permalink / raw) To: Jakub Jelinek; +Cc: Richard Biener, Martin Sebor, Gcc Patch List On Thu, May 31, 2018 at 2:58 AM, Jakub Jelinek <jakub@redhat.com> wrote: > 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? We generally try to avoid embedded error_mark_node within other trees. If the array bound is erroneous, can we replace the whole array type with error_mark_node? Jason ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] avoid ICE when pretty-printing a VLA with an error bound (PR 85956) 2018-05-31 13:25 ` Jason Merrill @ 2018-05-31 13:52 ` Jakub Jelinek 2018-05-31 15:08 ` Martin Sebor 0 siblings, 1 reply; 12+ messages in thread From: Jakub Jelinek @ 2018-05-31 13:52 UTC (permalink / raw) To: Jason Merrill; +Cc: Richard Biener, Martin Sebor, Gcc Patch List On Thu, May 31, 2018 at 09:14:33AM -0400, Jason Merrill wrote: > > 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? > > We generally try to avoid embedded error_mark_node within other trees. > If the array bound is erroneous, can we replace the whole array type > with error_mark_node? The array bound isn't errorneous, just becomes unknown (well, known only in an outer function), we still need to know it is an array type and that it has 0 as the low bound. Instead of replacing it with NULL we in theory could just create another VAR_DECL and never initialize it, it wouldn't be far from what happens with some other VLAs - during optimizations it is possible to array bound var is optimized away. Just it would be much more work to do it that way. Jakub ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] avoid ICE when pretty-printing a VLA with an error bound (PR 85956) 2018-05-31 13:52 ` Jakub Jelinek @ 2018-05-31 15:08 ` Martin Sebor 2018-05-31 15:31 ` Jason Merrill 0 siblings, 1 reply; 12+ messages in thread From: Martin Sebor @ 2018-05-31 15:08 UTC (permalink / raw) To: Jakub Jelinek, Jason Merrill; +Cc: Richard Biener, Gcc Patch List On 05/31/2018 07:30 AM, Jakub Jelinek wrote: > On Thu, May 31, 2018 at 09:14:33AM -0400, Jason Merrill wrote: >>> 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? >> >> We generally try to avoid embedded error_mark_node within other trees. >> If the array bound is erroneous, can we replace the whole array type >> with error_mark_node? > > The array bound isn't errorneous, just becomes unknown (well, known only in > an outer function), we still need to know it is an array type and that it > has 0 as the low bound. > Instead of replacing it with NULL we in theory could just create another > VAR_DECL and never initialize it, it wouldn't be far from what happens with > some other VLAs - during optimizations it is possible to array bound var is > optimized away. Just it would be much more work to do it that way. In my mind the issue boils down to two questions: 1) should the pretty printer handle error-mark-node gracefully or is it appropriate for it to abort? 2) is it appropriate to be embedding/using error_mark_node in valid constructs as a proxy for "unused" or "unknown" or such? I would expect the answer to (1) to be yes. Despite that, I agree with Jason that the answer to (2) should be no. That said, I don't think the fix for this bug needs to depend on solving (2). We can avoid the ICE by changing the pretty printers and adjust the openmp implementation later. Martin ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] avoid ICE when pretty-printing a VLA with an error bound (PR 85956) 2018-05-31 15:08 ` Martin Sebor @ 2018-05-31 15:31 ` Jason Merrill 2018-05-31 15:36 ` Jakub Jelinek 0 siblings, 1 reply; 12+ messages in thread From: Jason Merrill @ 2018-05-31 15:31 UTC (permalink / raw) To: Martin Sebor; +Cc: Jakub Jelinek, Richard Biener, Gcc Patch List On Thu, May 31, 2018 at 11:00 AM, Martin Sebor <msebor@gmail.com> wrote: > On 05/31/2018 07:30 AM, Jakub Jelinek wrote: >> >> On Thu, May 31, 2018 at 09:14:33AM -0400, Jason Merrill wrote: >>>> >>>> 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? >>> >>> >>> We generally try to avoid embedded error_mark_node within other trees. >>> If the array bound is erroneous, can we replace the whole array type >>> with error_mark_node? >> >> >> The array bound isn't errorneous, just becomes unknown (well, known only >> in >> an outer function), we still need to know it is an array type and that it >> has 0 as the low bound. >> Instead of replacing it with NULL we in theory could just create another >> VAR_DECL and never initialize it, it wouldn't be far from what happens >> with >> some other VLAs - during optimizations it is possible to array bound var >> is >> optimized away. Just it would be much more work to do it that way. > > > In my mind the issue boils down to two questions: > > 1) should the pretty printer handle error-mark-node gracefully > or is it appropriate for it to abort? > 2) is it appropriate to be embedding/using error_mark_node in > valid constructs as a proxy for "unused" or "unknown" or > such? > > I would expect the answer to (1) to be yes. Despite that, > I agree with Jason that the answer to (2) should be no. > > That said, I don't think the fix for this bug needs to depend > on solving (2). We can avoid the ICE by changing the pretty > printers and adjust the openmp implementation later. The problem with embedded error_mark_node is that lots of places are going to blow up like this, and we don't want to change everything to expect it. Adjusting the pretty-printer might fix this particular testcase, but other things are likely to get tripped up by the same problem. Where is the error_mark_node coming from in the first place? Jason ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] avoid ICE when pretty-printing a VLA with an error bound (PR 85956) 2018-05-31 15:31 ` Jason Merrill @ 2018-05-31 15:36 ` Jakub Jelinek 2018-05-31 17:43 ` Jason Merrill 0 siblings, 1 reply; 12+ messages in thread From: Jakub Jelinek @ 2018-05-31 15:36 UTC (permalink / raw) To: Jason Merrill; +Cc: Martin Sebor, Richard Biener, Gcc Patch List On Thu, May 31, 2018 at 11:19:08AM -0400, Jason Merrill wrote: > > In my mind the issue boils down to two questions: > > > > 1) should the pretty printer handle error-mark-node gracefully > > or is it appropriate for it to abort? > > 2) is it appropriate to be embedding/using error_mark_node in > > valid constructs as a proxy for "unused" or "unknown" or > > such? > > > > I would expect the answer to (1) to be yes. Despite that, > > I agree with Jason that the answer to (2) should be no. > > > > That said, I don't think the fix for this bug needs to depend > > on solving (2). We can avoid the ICE by changing the pretty > > printers and adjust the openmp implementation later. > > The problem with embedded error_mark_node is that lots of places are > going to blow up like this, and we don't want to change everything to > expect it. Adjusting the pretty-printer might fix this particular > testcase, but other things are likely to get tripped up by the same > problem. > > Where is the error_mark_node coming from in the first place? remap_type invoked during omp-low.c (scan_omp). omp_copy_decl returns error_mark_node for decls that tree-inline.c wants to remap, but they aren't actually remapped for some reason. For normal VLAs gimplify.c makes sure the needed artifical decls are firstprivatized, but in this case (VLA not in some decl's type, but just referenced indirectly through pointers) nothing scans those unless those temporaries are actually used in the code. Jakub ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] avoid ICE when pretty-printing a VLA with an error bound (PR 85956) 2018-05-31 15:36 ` Jakub Jelinek @ 2018-05-31 17:43 ` Jason Merrill 2018-05-31 17:45 ` Jakub Jelinek 2019-01-07 22:42 ` [PATCH] avoid ICE when pretty-printing a VLA with an error bound (PR 85956, take 2) Jakub Jelinek 0 siblings, 2 replies; 12+ messages in thread From: Jason Merrill @ 2018-05-31 17:43 UTC (permalink / raw) To: Jakub Jelinek; +Cc: Martin Sebor, Richard Biener, Gcc Patch List On Thu, May 31, 2018 at 11:31 AM, Jakub Jelinek <jakub@redhat.com> wrote: > On Thu, May 31, 2018 at 11:19:08AM -0400, Jason Merrill wrote: >> > In my mind the issue boils down to two questions: >> > >> > 1) should the pretty printer handle error-mark-node gracefully >> > or is it appropriate for it to abort? >> > 2) is it appropriate to be embedding/using error_mark_node in >> > valid constructs as a proxy for "unused" or "unknown" or >> > such? >> > >> > I would expect the answer to (1) to be yes. Despite that, >> > I agree with Jason that the answer to (2) should be no. >> > >> > That said, I don't think the fix for this bug needs to depend >> > on solving (2). We can avoid the ICE by changing the pretty >> > printers and adjust the openmp implementation later. >> >> The problem with embedded error_mark_node is that lots of places are >> going to blow up like this, and we don't want to change everything to >> expect it. Adjusting the pretty-printer might fix this particular >> testcase, but other things are likely to get tripped up by the same >> problem. >> >> Where is the error_mark_node coming from in the first place? > > remap_type invoked during omp-low.c (scan_omp). > omp_copy_decl returns error_mark_node for decls that tree-inline.c wants > to remap, but they aren't actually remapped for some reason. > For normal VLAs gimplify.c makes sure the needed artifical decls are > firstprivatized, but in this case (VLA not in some decl's type, but just > referenced indirectly through pointers) nothing scans those unless > those temporaries are actually used in the code. Returning error_mark_node from omp_copy_decl and then continuing seems like the problem, then. Would it really be that hard to return an uninitialized variable instead? Jason ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] avoid ICE when pretty-printing a VLA with an error bound (PR 85956) 2018-05-31 17:43 ` Jason Merrill @ 2018-05-31 17:45 ` Jakub Jelinek 2018-06-19 0:07 ` Martin Sebor 2019-01-07 22:42 ` [PATCH] avoid ICE when pretty-printing a VLA with an error bound (PR 85956, take 2) Jakub Jelinek 1 sibling, 1 reply; 12+ messages in thread From: Jakub Jelinek @ 2018-05-31 17:45 UTC (permalink / raw) To: Jason Merrill; +Cc: Martin Sebor, Richard Biener, Gcc Patch List On Thu, May 31, 2018 at 01:34:19PM -0400, Jason Merrill wrote: > >> Where is the error_mark_node coming from in the first place? > > > > remap_type invoked during omp-low.c (scan_omp). > > omp_copy_decl returns error_mark_node for decls that tree-inline.c wants > > to remap, but they aren't actually remapped for some reason. > > For normal VLAs gimplify.c makes sure the needed artifical decls are > > firstprivatized, but in this case (VLA not in some decl's type, but just > > referenced indirectly through pointers) nothing scans those unless > > those temporaries are actually used in the code. > > Returning error_mark_node from omp_copy_decl and then continuing seems > like the problem, then. Would it really be that hard to return an > uninitialized variable instead? The routine doesn't know if it is used in a context of a VLA bound or something else, in the former case it is acceptable to swap it for some other var, but in the latter case it would be just a bug, so using error_mark_node in that case instead is better to catch those. I can try to do that in tree-inline.c, but really not sure how hard would it be. Or handle it in the gimplifier, scan for such vars and add private clauses for those, that will mean nothing will be passed around. Jakub ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] avoid ICE when pretty-printing a VLA with an error bound (PR 85956) 2018-05-31 17:45 ` Jakub Jelinek @ 2018-06-19 0:07 ` Martin Sebor 0 siblings, 0 replies; 12+ messages in thread From: Martin Sebor @ 2018-06-19 0:07 UTC (permalink / raw) To: Jakub Jelinek, Jason Merrill; +Cc: Richard Biener, Gcc Patch List On 05/31/2018 11:43 AM, Jakub Jelinek wrote: > On Thu, May 31, 2018 at 01:34:19PM -0400, Jason Merrill wrote: >>>> Where is the error_mark_node coming from in the first place? >>> >>> remap_type invoked during omp-low.c (scan_omp). >>> omp_copy_decl returns error_mark_node for decls that tree-inline.c wants >>> to remap, but they aren't actually remapped for some reason. >>> For normal VLAs gimplify.c makes sure the needed artifical decls are >>> firstprivatized, but in this case (VLA not in some decl's type, but just >>> referenced indirectly through pointers) nothing scans those unless >>> those temporaries are actually used in the code. >> >> Returning error_mark_node from omp_copy_decl and then continuing seems >> like the problem, then. Would it really be that hard to return an >> uninitialized variable instead? > > The routine doesn't know if it is used in a context of a VLA bound or > something else, in the former case it is acceptable to swap it for some > other var, but in the latter case it would be just a bug, so using > error_mark_node in that case instead is better to catch those. > I can try to do that in tree-inline.c, but really not sure how hard would it > be. > Or handle it in the gimplifier, scan for such vars and add private clauses > for those, that will mean nothing will be passed around. Are you still working on this approach or should I resubmit my simple patch with the corresponding change for the C++ FE? Martin ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH] avoid ICE when pretty-printing a VLA with an error bound (PR 85956, take 2) 2018-05-31 17:43 ` Jason Merrill 2018-05-31 17:45 ` Jakub Jelinek @ 2019-01-07 22:42 ` Jakub Jelinek 2019-01-11 20:50 ` Jeff Law 1 sibling, 1 reply; 12+ messages in thread From: Jakub Jelinek @ 2019-01-07 22:42 UTC (permalink / raw) To: Jason Merrill, Richard Biener; +Cc: Gcc Patch List Hi! On Thu, May 31, 2018 at 01:34:19PM -0400, Jason Merrill wrote: > Returning error_mark_node from omp_copy_decl and then continuing seems > like the problem, then. Would it really be that hard to return an > uninitialized variable instead? The following patch does that, but not from omp_copy_decl, but only in the caller for the array bounds (the rest would be still errors). Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2019-01-07 Jakub Jelinek <jakub@redhat.com> PR middle-end/85956 PR lto/88733 * 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 a dummy "omp dummy var" variable if id->adjust_array_error_bounds. * omp-low.c (new_omp_context): Set cb.adjust_array_error_bounds. fortran/ * trans-openmp.c: Include attribs.h. (gfc_walk_alloc_comps, gfc_omp_clause_linear_ctor): Handle VAR_DECL max bound with "omp dummy var" attribute like NULL or error_mark_node - recompute number of elts independently. testsuite/ * c-c++-common/gomp/pr85956.c: New test. * g++.dg/gomp/pr88733.C: New test. --- gcc/tree-inline.h.jj 2019-01-07 12:37:38.644966905 +0100 +++ gcc/tree-inline.h 2019-01-07 18:03:27.478852009 +0100 @@ -122,6 +122,10 @@ struct copy_body_data /* True if the location information will need to be reset. */ bool reset_location; + /* Replace error_mark_node as upper bound of array types with + an uninitialized VAR_DECL temporary. */ + bool adjust_array_error_bounds; + /* A function to be called when duplicating BLOCK nodes. */ void (*transform_lang_insert_block) (tree); --- gcc/tree-inline.c.jj 2019-01-07 12:37:38.635967053 +0100 +++ gcc/tree-inline.c 2019-01-07 19:09:29.887727827 +0100 @@ -523,11 +523,27 @@ 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 + an uninitialized VAR_DECL temporary. */ + 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) + { + tree v = create_tmp_var (TREE_TYPE (TYPE_DOMAIN (new_tree))); + DECL_ATTRIBUTES (v) + = tree_cons (get_identifier ("omp dummy var"), NULL_TREE, + DECL_ATTRIBUTES (v)); + TYPE_MAX_VALUE (TYPE_DOMAIN (new_tree)) = v; + } + } break; case RECORD_TYPE: --- gcc/omp-low.c.jj 2019-01-07 12:37:38.501969255 +0100 +++ gcc/omp-low.c 2019-01-07 18:03:27.509851500 +0100 @@ -872,6 +872,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/fortran/trans-openmp.c.jj 2019-01-01 12:37:52.699391804 +0100 +++ gcc/fortran/trans-openmp.c 2019-01-07 19:17:00.295377803 +0100 @@ -43,6 +43,7 @@ along with GCC; see the file COPYING3. #include "diagnostic-core.h" #undef GCC_DIAG_STYLE #define GCC_DIAG_STYLE __gcc_gfc__ +#include "attribs.h" int ompws_flags; @@ -297,10 +298,19 @@ gfc_walk_alloc_comps (tree decl, tree de } else { + bool compute_nelts = false; if (!TYPE_DOMAIN (type) || TYPE_MAX_VALUE (TYPE_DOMAIN (type)) == NULL_TREE || TYPE_MIN_VALUE (TYPE_DOMAIN (type)) == error_mark_node || TYPE_MAX_VALUE (TYPE_DOMAIN (type)) == error_mark_node) + compute_nelts = true; + else if (VAR_P (TYPE_MAX_VALUE (TYPE_DOMAIN (type)))) + { + tree a = DECL_ATTRIBUTES (TYPE_MAX_VALUE (TYPE_DOMAIN (type))); + if (lookup_attribute ("omp dummy var", a)) + compute_nelts = true; + } + if (compute_nelts) { tem = fold_build2 (EXACT_DIV_EXPR, sizetype, TYPE_SIZE_UNIT (type), @@ -912,11 +922,20 @@ gfc_omp_clause_linear_ctor (tree clause, && (!GFC_DECL_GET_SCALAR_ALLOCATABLE (OMP_CLAUSE_DECL (clause)) || !POINTER_TYPE_P (type))) { + bool compute_nelts = false; gcc_assert (TREE_CODE (type) == ARRAY_TYPE); if (!TYPE_DOMAIN (type) || TYPE_MAX_VALUE (TYPE_DOMAIN (type)) == NULL_TREE || TYPE_MIN_VALUE (TYPE_DOMAIN (type)) == error_mark_node || TYPE_MAX_VALUE (TYPE_DOMAIN (type)) == error_mark_node) + compute_nelts = true; + else if (VAR_P (TYPE_MAX_VALUE (TYPE_DOMAIN (type)))) + { + tree a = DECL_ATTRIBUTES (TYPE_MAX_VALUE (TYPE_DOMAIN (type))); + if (lookup_attribute ("omp dummy var", a)) + compute_nelts = true; + } + if (compute_nelts) { nelems = fold_build2 (EXACT_DIV_EXPR, sizetype, TYPE_SIZE_UNIT (type), --- gcc/testsuite/c-c++-common/gomp/pr85956.c.jj 2019-01-07 18:03:27.509851500 +0100 +++ gcc/testsuite/c-c++-common/gomp/pr85956.c 2019-01-07 18:03:27.509851500 +0100 @@ -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" } */ +} --- gcc/testsuite/g++.dg/gomp/pr88733.C.jj 2019-01-07 19:42:10.226723145 +0100 +++ gcc/testsuite/g++.dg/gomp/pr88733.C 2019-01-07 19:41:51.200024075 +0100 @@ -0,0 +1,29 @@ +// PR lto/88733 +// { dg-do compile } +// { dg-additional-options "-flto -ffat-lto-objects" { target lto } } + +struct A { int f; } a; + +__attribute__((noipa)) void +bar (A **x, int) +{ + x[0] = &a; +} + +int +foo (int n) +{ + int g; + A *j[n]; + bar (j, n); +#pragma omp parallel +#pragma omp single + g = j[0]->f; + return g; +} + +int +main () +{ + foo (0); +} Jakub ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] avoid ICE when pretty-printing a VLA with an error bound (PR 85956, take 2) 2019-01-07 22:42 ` [PATCH] avoid ICE when pretty-printing a VLA with an error bound (PR 85956, take 2) Jakub Jelinek @ 2019-01-11 20:50 ` Jeff Law 0 siblings, 0 replies; 12+ messages in thread From: Jeff Law @ 2019-01-11 20:50 UTC (permalink / raw) To: Jakub Jelinek, Jason Merrill, Richard Biener; +Cc: Gcc Patch List On 1/7/19 3:42 PM, Jakub Jelinek wrote: > Hi! > > On Thu, May 31, 2018 at 01:34:19PM -0400, Jason Merrill wrote: >> Returning error_mark_node from omp_copy_decl and then continuing seems >> like the problem, then. Would it really be that hard to return an >> uninitialized variable instead? > > The following patch does that, but not from omp_copy_decl, but only in the > caller for the array bounds (the rest would be still errors). > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? > > 2019-01-07 Jakub Jelinek <jakub@redhat.com> > > PR middle-end/85956 > PR lto/88733 > * 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 > a dummy "omp dummy var" variable if id->adjust_array_error_bounds. > * omp-low.c (new_omp_context): Set cb.adjust_array_error_bounds. > fortran/ > * trans-openmp.c: Include attribs.h. > (gfc_walk_alloc_comps, gfc_omp_clause_linear_ctor): Handle > VAR_DECL max bound with "omp dummy var" attribute like NULL or > error_mark_node - recompute number of elts independently. > testsuite/ > * c-c++-common/gomp/pr85956.c: New test. > * g++.dg/gomp/pr88733.C: New test. OK. jeff ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2019-01-11 20:50 UTC | newest] Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2018-05-30 20:57 [PATCH] avoid ICE when pretty-printing a VLA with an error bound (PR 85956) Martin Sebor 2018-05-31 8:19 ` Jakub Jelinek 2018-05-31 13:25 ` Jason Merrill 2018-05-31 13:52 ` Jakub Jelinek 2018-05-31 15:08 ` Martin Sebor 2018-05-31 15:31 ` Jason Merrill 2018-05-31 15:36 ` Jakub Jelinek 2018-05-31 17:43 ` Jason Merrill 2018-05-31 17:45 ` Jakub Jelinek 2018-06-19 0:07 ` Martin Sebor 2019-01-07 22:42 ` [PATCH] avoid ICE when pretty-printing a VLA with an error bound (PR 85956, take 2) Jakub Jelinek 2019-01-11 20:50 ` Jeff Law
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).