https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77754
Bug ID: 77754 Summary: internal compiler error : tree code 'call_expr' is not supported in LTO streams Product: gcc Version: 5.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: lto Assignee: unassigned at gcc dot gnu.org Reporter: laurent.alfonsi at st dot com Target Milestone: --- Created attachment 39695 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=39695&action=edit testcase Hi, I am obtaining a ICE in LTO phase, when passing the enclosed example using a nested function with a variable length array parameter : --------- <<reduce.c>> int fn3(); void fn1() { void fn2(int[][fn3()]); } --------- I have been able to reproduce with a x86_64 native gcc : $ gcc -c -flto reduce.c reduce.c:5:1: internal compiler error: tree code 'call_expr' is not supported in LTO streams } My gcc configuration is very simple : $ gcc -v Configured with: ../configure --prefix=<prefix> --with-gnu-as --with-gnu-ld --enable-shared --enable-languages=c,c++ --disable-libgcj --disable-nls --with-gmp=<prefix> --with-mpfr=<prefix> --with-mpc=<prefix> --with-isl=<prefix> --with-cloog=<prefix> --disable-bootstrap --enable-lto --with-local-prefix=<prefix> Thread model: posix gcc version 5.3.0 (GCC) It well passes with gcc 4.9.0 to 4.9.4. Regards, |
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77754
Markus Trippelsdorf <trippels at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |NEW Last reconfirmed| |2016-09-27 CC| |trippels at gcc dot gnu.org Ever confirmed|0 |1 Known to fail| |5.4.0, 6.2.0, 7.0 |
In reply to this post by abensonca at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77754
Martin Liška <marxin at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |ice-on-valid-code CC| |marxin at gcc dot gnu.org Known to work| |4.9.0 Assignee|unassigned at gcc dot gnu.org |marxin at gcc dot gnu.org --- Comment #1 from Martin Liška <marxin at gcc dot gnu.org> --- I can confirm that GCC ICEs for all revisions I have expect 4.9.x. I'm going to take a look how is the CALL_EXPR optimized out. |
In reply to this post by abensonca at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77754
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Component|lto |c Target Milestone|--- |5.5 --- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> --- The issue is we fail to gimplify type sizes properly: fn1 () { extern void fn2 (int[0:(sizetype) ((long int) SAVE_EXPR <fn3 ()> + -1)] *); } happens when we try to output the function type of fn2. Bug in the frontend, a DECL_EXPR is missing here. |
In reply to this post by abensonca at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77754
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |lto CC| |jsm28 at gcc dot gnu.org --- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> --- Note this isn't a nested function but a function declaration. Doesn't ICE with a nested function: int fn3(); void fn1() { void fn2(int a[][fn3()]) { } int x[1][fn3()]; fn2(x); } but still has the bogus non-gimplified type: fn1 () { ... static void fn2 (int[0:(sizetype) ((long int) SAVE_EXPR <fn3 ()> + -1)] *); and odd place of evaluating fn3(): fn2 (int[0:D.1798] * a) { int D.1797; sizetype D.1798; bitsizetype D.1799; sizetype D.1800; D.1797 = fn3 (); _1 = (long int) D.1797; ... I wonder what the standards say about side-effects in those "declarations". |
In reply to this post by abensonca at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77754
--- Comment #4 from Christophe Monat <christophe.monat at st dot com> --- (In reply to Richard Biener from comment #3) > I wonder what the standards say about side-effects in those "declarations". From my instance of ISO+IEC+9899-2011.pdf 6.7.6.2 Array declarators Constraints ... Semantics (5) If the size is an expression that is not an integer constant expression: if it occurs in a declaration at function prototype scope, it is treated as if it were replaced by *; otherwise, each time it is evaluated it shall have a value greater than zero. The size of each instance of a variable length array type does not change during its lifetime. Where a size expression is part of the operand of a sizeof operator and changing the value of the size expression would not affect the result of the operator, it is unspecified whether or not the size expression is evaluated. And 6.7.6.3 Function declarators (including prototypes) (12) If the function declarator is not part of a definition of that function, parameters may have incomplete type and may use the [*] notation in their sequences of declarator specifiers to specify variable length array types. So to me it looks, like the compiler could consider the original declaration as if it where: void fn2(int[][*]); |
In reply to this post by abensonca at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77754
--- Comment #5 from joseph at codesourcery dot com <joseph at codesourcery dot com> --- VLA side effects in function declarations that are not definitions should be discarded. VLA side effects in function declarations that are definitions should occur on entry to the function (this applies both to side effects from sizes of array parameters, which do not affect the function type because those parameters get adjusted to pointers, and to side effects from sizes in parameters involving pointers to VLAs, which do affect the type). See C11 6.9.1#10: "On entry to the function, the size expressions of each variably modified parameter are evaluated ...". The general principle is that where expressions that might have side effects are involved in types, the C front end arranges the trees it generates so that those expressions are explicitly evaluated first at a point chosen by the front end - for example, by inserting a statement to evaluate them before the declaration. Thus, if language-independent gimplifier code recurses into a type and finds a SAVE_EXPR there, it should always find that the SAVE_EXPR in question has already been evaluated as a result of the separate code explicitly inserted by the front end. Now, maybe that isn't possible for this case of expressions involved in function arguments. There, the relevant front-end code is in store_parm_decls processing arg_info->pending_sizes. The pending_sizes expression should include all relevant expressions (modulo bug 77767 which I just found and reported while looking at the present issue), not just those for parameters declared as VLAs. But I don't know whether the code this inserts occurs before or after the language-indpendent code dealing with VLAs involved in function arguments. Thus: for VLAs involved in function arguments in declarations (or type names, etc.) that are not definitions, the front end is expecting the language-independent compiler to treat them as [*], not to insert code to evaluate them (and the front end has no code that uses pending_sizes in such a case, so implicitly discards them). If the language-independent compiler does not have such semantics, that implies a lowering step is needed for any declaration or type name involving such a function type at any level of indirection. For VLAs involved in function arguments in definitions, if language-independent code ever inserts evaluations outside the function in question, including in the case of nested functions, that's definitely wrong, and ideally for the front end it would be able to provide the pending_sizes information in some way so that the language-independent code does not insert its own evaluations of sizes, just verifies that the SAVE_EXPRs in question were already evaluated. |
In reply to this post by abensonca at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77754
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Priority|P3 |P2 |
In reply to this post by abensonca at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77754
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jakub at gcc dot gnu.org --- Comment #6 from Jakub Jelinek <jakub at gcc dot gnu.org> --- int fn3 (void); void fn4 (int[][fn3 ()]); void fn1 (void) { int a[10][fn3 ()]; fn4 (a); } also ICEs. |
In reply to this post by abensonca at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77754
--- Comment #7 from Jakub Jelinek <jakub at gcc dot gnu.org> --- So, where would be the best place to remove the VLA bounds from parameters of fn declarations? Some function called from c_write_global_declarations_1 and from walking BLOCK tree vars e.g. right before calling c_genericize in finish_function? |
In reply to this post by abensonca at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77754
--- Comment #8 from joseph at codesourcery dot com <joseph at codesourcery dot com> --- On Tue, 20 Dec 2016, jakub at gcc dot gnu.org wrote: > So, where would be the best place to remove the VLA bounds from parameters of > fn declarations? Some function called from c_write_global_declarations_1 and > from walking BLOCK tree vars e.g. right before calling c_genericize in > finish_function? That would seem reasonable. |
In reply to this post by abensonca at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77754
--- Comment #9 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Though, it seems they can be hiding pretty much everywhere: int fn3(); void (**fn5) (int[][fn3 ()]); void fn1 () { int a[10][fn3 ()]; (**fn5) (a); } ICEs with -O2 -flto, so does: int fn3(); typedef void (*fn6) (int[][fn3 ()]); fn6 **fn7; void fn1 () { int a[10][fn3 ()]; (**fn7) (a); } and so does: int fn3(); typedef void (*fn6) (int[][fn3 ()]); struct S { fn6 **fn7; fn6 *fn8; fn6 fn9; } s; void fn1 () { int a[10][fn3 ()]; (**s.fn7) (a); (*s.fn8) (a); s.fn9 (a); } So I'd think trying to fix it up late is just too late, we want to change it immediately after finishing a declaration that is not a function definition. |
In reply to this post by abensonca at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77754
--- Comment #10 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Perhaps doing it in grokdeclarator where build_function_type is called, if initialized == false? But it is unclear to me where all the side-effects can hide. E.g. int fn3(); void fn4(int (*)[fn3 ()][fn3 () + 1][fn3 () + 2], struct S { int a[fn3 ()]; } *); void fn1() { int a[10][fn3 ()][fn3 () + 1][fn3 () + 2]; fn4 (a, 0); } is accepted, so it can be even inside of non-array aggregate types. |
In reply to this post by abensonca at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77754
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Target Milestone|5.5 |6.5 --- Comment #11 from Jakub Jelinek <jakub at gcc dot gnu.org> --- GCC 5 branch is being closed |
In reply to this post by abensonca at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77754
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Target Milestone|6.5 |7.4 --- Comment #12 from Jakub Jelinek <jakub at gcc dot gnu.org> --- GCC 6 branch is being closed |
In reply to this post by abensonca at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77754
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Target Milestone|7.4 |7.5 |
In reply to this post by abensonca at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77754
--- Comment #13 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Created attachment 45817 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=45817&action=edit gcc9-pr77754.patch Seems all the ICEs went away with r266271 aka PR87229 fix. I'll test these tests for the testsuite. |
In reply to this post by abensonca at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77754
--- Comment #14 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Author: jakub Date: Mon Feb 25 22:58:45 2019 New Revision: 269197 URL: https://gcc.gnu.org/viewcvs?rev=269197&root=gcc&view=rev Log: PR c/77754 * gcc.c-torture/compile/pr77754-1.c: New test. * gcc.c-torture/compile/pr77754-2.c: New test. * gcc.c-torture/compile/pr77754-3.c: New test. * gcc.c-torture/compile/pr77754-4.c: New test. * gcc.c-torture/compile/pr77754-5.c: New test. * gcc.c-torture/compile/pr77754-6.c: New test. Added: trunk/gcc/testsuite/gcc.c-torture/compile/pr77754-1.c trunk/gcc/testsuite/gcc.c-torture/compile/pr77754-2.c trunk/gcc/testsuite/gcc.c-torture/compile/pr77754-3.c trunk/gcc/testsuite/gcc.c-torture/compile/pr77754-4.c trunk/gcc/testsuite/gcc.c-torture/compile/pr77754-5.c trunk/gcc/testsuite/gcc.c-torture/compile/pr77754-6.c Modified: trunk/gcc/testsuite/ChangeLog |
In reply to this post by abensonca at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77754
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |RESOLVED Known to work| |8.3.0 Resolution|--- |FIXED Target Milestone|7.5 |8.3 Known to fail| |7.5.0, 8.2.0 --- Comment #15 from Richard Biener <rguenth at gcc dot gnu.org> --- Fixed in GCC 8.3. |
Free forum by Nabble | Edit this page |