[Bug c++/86216] g++ ICE on valid code: verify_ssa failed
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86216 Andrew Pinski changed: What|Removed |Added CC||sam at gentoo dot org --- Comment #12 from Andrew Pinski --- *** Bug 102757 has been marked as a duplicate of this bug. ***
[Bug c++/86216] g++ ICE on valid code: verify_ssa failed
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86216 Arseny Solokha changed: What|Removed |Added CC||asolokha at gmx dot com --- Comment #11 from Arseny Solokha --- *** Bug 88970 has been marked as a duplicate of this bug. ***
[Bug c++/86216] g++ ICE on valid code: verify_ssa failed
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86216 Jason Merrill changed: What|Removed |Added Status|ASSIGNED|RESOLVED Resolution|--- |FIXED Target Milestone|--- |10.0 --- Comment #10 from Jason Merrill --- Fixed for GCC 10.
[Bug c++/86216] g++ ICE on valid code: verify_ssa failed
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86216 --- Comment #9 from CVS Commits --- The master branch has been updated by Jason Merrill : https://gcc.gnu.org/g:00a49cd840f60774b0e9e0109fb10559bc9a9194 commit r10-6389-g00a49cd840f60774b0e9e0109fb10559bc9a9194 Author: Jason Merrill Date: Fri Jan 31 17:10:30 2020 -0500 c++: Fix sizeof VLA lambda capture. sizeof a VLA type is not a constant in C or the GNU C++ extension, so we need to capture the VLA even in unevaluated context. For PR60855 we stopped looking through a previous capture, but we also need to capture the first time the variable is mentioned. PR c++/86216 * semantics.c (process_outer_var_ref): Capture VLAs even in unevaluated context.
[Bug c++/86216] g++ ICE on valid code: verify_ssa failed
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86216 --- Comment #8 from Richard Biener --- The C FE does /* Arrange for the SAVE_EXPR on the inside of the MINUS_EXPR, which allows the -1 to get folded with the +1 that happens when building TYPE_SIZE. */ if (size_varies) size = save_expr (size); while the C++ FE relies on variable_size() after building the whole expression. Eliding the above optimization makes the IL more similar but it still doesn't break.
[Bug c++/86216] g++ ICE on valid code: verify_ssa failed
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86216 --- Comment #7 from Richard Biener --- I can't fully reproduce the obfuscation of the C++ FE (the +-1) but the following is close but it also works: typedef int intptr_t; void foo (intptr_t n, unsigned a) { typedef intptr_t ArrTy[(long)a+1]; ArrTy buffer2; ArrTy buffer1[(long)a+1]; void bar () { n = sizeof(buffer1[n]); void baz() { n = sizeof(buffer2); } baz(); } bar(); } and it has similar gimplification (but not broken): foo (intptr_t n, unsigned int a) { ... _1 = (long int) a; D.1910 = _1 + 1; bar () { static void baz (); _1 = (unsigned int) D.1910; _2 = _1 * 4; n = (intptr_t) _2; baz (); } baz () { _1 = (unsigned int) D.1910; _2 = _1 * 4; n = (intptr_t) _2; } without the array size adjustment I get the SAVE_EXPR only wrapping a, so some promotion done by the C++ FE ends up breaking things.
[Bug c++/86216] g++ ICE on valid code: verify_ssa failed
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86216 --- Comment #6 from rguenther at suse dot de --- On Fri, 13 Jul 2018, jakub at gcc dot gnu.org wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86216 > > --- Comment #5 from Jakub Jelinek --- > I guess lambdas really need to have all the needed parameters captured, and > for > VLAs that likely includes not just the VLAs themselves, but their sizes as > well. > That is something that needs to be done in the FE somewhere, because lambdas > are handled only at that point. Wonder if that means also creating another > set > of the VLA types for the lambda with TYPE_SIZE{,_UNIT} that map to an > artificial field and that the capturing code initializes it with the > TYPE_SIZE{,_UNIT} (i.e. the SAVE_EXPR it has). For normal nested functions (C > or Fortran) this is tree-nested.c's job and I think we handle it there already > right, because it is after gimplification and so the needed vars are exposed. Yeah, though the "new" issue is that while previously tree sharing between nested functions and the respective locals that are defined in the wrong function are resolved by unnesting (also the reason we need to gimplify outer-to-inner and only lower nested functions after that) since we are generating SSA temporaries we'll have cross-function SSA names for such tree sharing. That isn't resolved by unnesting and this is what the pasted patch snippet fixes also for non-lambdas. I think that either the tree sharing is a bug or the gimplifier woring in-place (and thus its need to unshare in the first place) is the bug here. The SSA temporaries by gimplification are new since GCC 7 so we somehow didn't run into this before. > Or reject capturing VLAs (with a sorry) until that is done. Possibly, given VLAs are a GNU extension.
[Bug c++/86216] g++ ICE on valid code: verify_ssa failed
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86216 --- Comment #5 from Jakub Jelinek --- I guess lambdas really need to have all the needed parameters captured, and for VLAs that likely includes not just the VLAs themselves, but their sizes as well. That is something that needs to be done in the FE somewhere, because lambdas are handled only at that point. Wonder if that means also creating another set of the VLA types for the lambda with TYPE_SIZE{,_UNIT} that map to an artificial field and that the capturing code initializes it with the TYPE_SIZE{,_UNIT} (i.e. the SAVE_EXPR it has). For normal nested functions (C or Fortran) this is tree-nested.c's job and I think we handle it there already right, because it is after gimplification and so the needed vars are exposed. Or reject capturing VLAs (with a sorry) until that is done.
[Bug c++/86216] g++ ICE on valid code: verify_ssa failed
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86216 Richard Biener changed: What|Removed |Added CC||jason at gcc dot gnu.org --- Comment #4 from Richard Biener --- And the original expansion bug simply says we're not getting function nesting /unnesting correct. The D.2371 local (what the SAVE_EXPR resolves to in the outer function) needs to be pulled from the static chain but I do not see any. In fact the middle-end isn't presented with nested functions at all but it looks like the C++ FE does lambdas in its own way but forgets about cross-"function/lambda" SAVE_EXPRs? I'm out-of-the way for that C++ FE issue. Maybe it doesn't want to share the SAVE_EXPRs in the end. Who knows.
[Bug c++/86216] g++ ICE on valid code: verify_ssa failed
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86216 Richard Biener changed: What|Removed |Added CC||jakub at gcc dot gnu.org --- Comment #3 from Richard Biener --- The interesting thing is that the RHS _1 is from a different function, a SAVE_EXPR expansion actually, which means this is another case of cross-function tree sharing (I remember fixing such thing in the fortran FE). Breakpoint 7, gimplify_save_expr (expr_p=0x76db3b18, pre_p=0x7fffd058, post_p=0x7fffca98) at ../../src/trunk/gcc/gimplify.c:5870 5870 enum gimplify_status ret = GS_ALL_DONE; $38 = $39 = ... Breakpoint 7, gimplify_save_expr (expr_p=0x76da3ab8, pre_p=0x7fffc658, post_p=0x7fffc458) at ../../src/trunk/gcc/gimplify.c:5870 5870 enum gimplify_status ret = GS_ALL_DONE; $42 = $43 = (gdb) p (*expr_p)->base.public_flag $45 = 1 I guess we can track down at least the SAVE_EXPR case with Index: gcc/gimplify.c === --- gcc/gimplify.c (revision 262624) +++ gcc/gimplify.c (working copy) @@ -869,7 +869,11 @@ copy_if_shared_r (tree *tp, int *walk_su /* Otherwise, mark the node as visited and keep looking. */ else -TREE_VISITED (t) = 1; +{ + if (TREE_CODE (t) == SAVE_EXPR) + gcc_assert (!SAVE_EXPR_RESOLVED_P (t)); + TREE_VISITED (t) = 1; +} return NULL_TREE; } It's probably easy that this case of sharing happens for nested functions since most type sizes are wrapped in SAVE_EXPRs and those do not get unshared even when that is explicitely asked for. But it looks like the tree sharing happens outside of a SAVE_EXPR given we have at gimplify_function_tree time { intptr_t & n [value-expr: this->__n]; intptr_t & n [value-expr: this->__n]; { <; } } where _1 + 1 was what a SAVE_EXPR was resolved to but here we should have seen the DECL created for it rather than the in-place gimplified result. The .original dump though has ;; Function b(intptr_t, T) [with T = int; intptr_t = int] (null) ;; enabled by -tree-original { intptr_t & n [value-expr: this->__n]; intptr_t & n [value-expr: this->__n]; { <) + 1) * 4)) >; } } it looks like there's tree sharing for a bigger part of the expression... Indeed, between the above and { intptr_t & n [value-expr: this->__n]; intptr_t & n [value-expr: this->__n]; { { typedef struct __lambda3 __lambda3; <) + 1) * 4)) >;; } } } we have shared arg:0 side-effects arg:0 side-effects arg:0 side-effects arg:0 t.ii:3:22 start: t.ii:3:22 finish: t.ii:3:26>> arg:1 >> which is the (sizetype) (SAVE_EXPR <(ssizetype) arg + -1>) + 1 part. unit-size align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x76c5b7e0 precision:64 min max pointer_to_this > side-effects arg:0 unit-size align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x76c5b000 precision:64 min max > side-effects arg:0 side-effects these nodes are built by c_sizeof_or_alignof_type #4 0x00bde3e2 in c_sizeof_or_alignof_type (loc=283249, type=, is_sizeof=true, min_alignof=false, complain=1) at ../../src/trunk/gcc/c-family/c-common.c:3650 3650 value = fold_convert_loc (loc, size_type_node, value); where TYPE_SIZE_UNIT of type is ((sizetype) (SAVE_EXPR <(ssizetype) arg - 1>) + 1) * 4 which is of course asking for trouble :/ In the end this is layout_type doing 2483if (TYPE_SIZE_UNIT (element)) 2484 TYPE_SIZE_UNIT (type) 2485= size_binop (MULT_EXPR, TYPE_SIZE_UNIT (element), length); on (sizetype) (SAVE_EXPR <(ssizetype) arg - 1>) + 1 The gimplifier is not set up to do unsharing across functions, so this has to be fixed elsewhere. The particular case could be fixed in c_sizeof_or_alignof_type by doing unshare_expr on TYPE_SIZE_UNIT for all types that might be shared between functions (thus where the gimplifier doesn't take care of unsharing). Or we could make layout_type make sure to wrap all non-constant TYPE_* in a SAVE_EXPR. So the following patch restores the ICE we see in earlier releases. I have audited all possibly variable-size processing in c-common.c. Any comments? Index: gcc/c-family/c-common.c === --- gcc/c-family/c-common.c (revision 262624) +++ gcc/c-family/c-common.c (working copy) @@ -3635,7 +3635,8 @@ c_sizeof_or_alignof_type (location_t loc { if (
[Bug c++/86216] g++ ICE on valid code: verify_ssa failed
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86216 Richard Biener changed: What|Removed |Added Keywords||ice-on-valid-code Status|NEW |ASSIGNED Version|unknown |9.0 Assignee|unassigned at gcc dot gnu.org |rguenth at gcc dot gnu.org --- Comment #2 from Richard Biener --- I think GCC 9 has a fix for the issue you see with GCC 8. And earlier GCC ICE differently again... I suspect the GCC 9 issue is mine (gimplifcation into "SSA"). .gimple has: b(intptr_t, T) [with T = int]::operator() (const struct __lambda3 * const this) { intptr_t & n [value-expr: this->__n]; { _1 = _1 + 1; _2 = (unsigned int) _1; _3 = _2 * 4; _4 = this->__n; _5 = (int) _3; *_4 = _5; }
[Bug c++/86216] g++ ICE on valid code: verify_ssa failed
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86216 Marek Polacek changed: What|Removed |Added Status|UNCONFIRMED |NEW Last reconfirmed||2018-06-19 CC||mpolacek at gcc dot gnu.org Ever confirmed|0 |1 --- Comment #1 from Marek Polacek --- Confirmed. Even GCC 5 ICEs.