Bug 77739 - [5 Regression] internal compiler error: in create_tmp_var, at gimple-expr.c:524
Summary: [5 Regression] internal compiler error: in create_tmp_var, at gimple-expr.c:524
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 5.4.0
: P2 normal
Target Milestone: 5.5
Assignee: Not yet assigned to anyone
URL:
Keywords: ice-on-valid-code
: 69001 (view as bug list)
Depends on:
Blocks:
 
Reported: 2016-09-26 05:31 UTC by Vaughn Cato
Modified: 2017-05-30 09:18 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work: 7.0
Known to fail: 5.4.0, 6.2.0
Last reconfirmed: 2016-09-26 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Vaughn Cato 2016-09-26 05:31:33 UTC
gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.2) 


Command: g++ -c -std=c++14 ice.cpp

Output:

ice.cpp: In member function ‘auto B::g(Args&& ...) [with Args = {A<char>, const char (&)[1]}]’:
ice.cpp:15:41: internal compiler error: in create_tmp_var, at gimple-expr.c:524
        return [=](){ return f(args...); };
                                         

ice.cpp:

template <typename T>
struct A {
    A() { }
    A(const A &) { }
};


struct B
{
    B();

    template <typename... Args>
    auto g(Args&&... args)
    {
       return [=](){ return f(args...); };
    }

    void f(A<char>,const char*) { }
};


B::B()
{
    g(A<char>(),"");
}
Comment 1 Markus Trippelsdorf 2016-09-26 06:00:25 UTC
Confirmed. All supported gcc versions are affected.

markus@x4 /tmp % cat ice.ii
struct A {
  A();
  A(const A &);
};
struct B {
  B();
  template <typename... Args> auto g(Args &&... p1) {
    return [=] { f(p1...); };
  }
  void f(A, const char *);
};
B::B() { g(A(), ""); }

markus@x4 /tmp % g++ -c ice.ii
ice.ii: In member function ‘auto B::g(Args&& ...) [with Args = {A, const char (&)[1]}]’:
ice.ii:8:28: internal compiler error: in create_tmp_var, at gimple-expr.c:473
     return [=] { f(p1...); };
                            ^
0xafcb20 create_tmp_var(tree_node*, char const*)
        ../../gcc/gcc/gimple-expr.c:473
0xb2f384 create_tmp_from_val
        ../../gcc/gcc/gimplify.c:500
0xb2f384 lookup_tmp_var
        ../../gcc/gcc/gimplify.c:521
0xb2f384 internal_get_tmp_var
        ../../gcc/gcc/gimplify.c:574
0xb26cc1 gimplify_expr(tree_node**, gimple**, gimple**, bool (*)(tree_node*), int)
        ../../gcc/gcc/gimplify.c:11483
0xb2ab27 gimplify_expr(tree_node**, gimple**, gimple**, bool (*)(tree_node*), int)
        ../../gcc/gcc/gimplify.c:10701
0xb301a6 gimplify_compound_lval
        ../../gcc/gcc/gimplify.c:2195
0xb27165 gimplify_expr(tree_node**, gimple**, gimple**, bool (*)(tree_node*), int)
        ../../gcc/gcc/gimplify.c:10495
0xb3a6cf gimplify_modify_expr
        ../../gcc/gcc/gimplify.c:4824
0xb29008 gimplify_expr(tree_node**, gimple**, gimple**, bool (*)(tree_node*), int)
        ../../gcc/gcc/gimplify.c:10543
0xb2c407 gimplify_stmt(tree_node**, gimple**)
        ../../gcc/gcc/gimplify.c:5805
0xb2c5e8 gimplify_and_add(tree_node*, gimple**)
        ../../gcc/gcc/gimplify.c:427
0xb2c5e8 gimplify_init_ctor_eval
        ../../gcc/gcc/gimplify.c:3799
0xb32e9f gimplify_init_constructor
        ../../gcc/gcc/gimplify.c:4171
0xb33d17 gimplify_modify_expr_rhs
        ../../gcc/gcc/gimplify.c:4432
0xb3a4d0 gimplify_modify_expr
        ../../gcc/gcc/gimplify.c:4769
0xb29008 gimplify_expr(tree_node**, gimple**, gimple**, bool (*)(tree_node*), int)
        ../../gcc/gcc/gimplify.c:10543
0xb2c407 gimplify_stmt(tree_node**, gimple**)
        ../../gcc/gcc/gimplify.c:5805
0xb28116 gimplify_and_add(tree_node*, gimple**)
        ../../gcc/gcc/gimplify.c:427
0xb28116 gimplify_return_expr
        ../../gcc/gcc/gimplify.c:1371
Comment 2 Jakub Jelinek 2016-09-26 07:14:43 UTC
Started with r202605.
Comment 3 Jakub Jelinek 2016-11-22 16:48:15 UTC
The problem is that some expressions are genericized twice.
First when genericizing the whole function, RESULT_DECL is determined to be is_invisiref_parm and therefore references to it are turned into INDIRECT_REF around it and the RESULT_DECL becomes REFERENCE_TYPE.
Later on gimplify_body calls unshare_body and unshares the INDIRECT_REF.
Then the INDIRECT_REF is gimplified into a MEM_REF.  And finally:
(cp_gimplify_expr) <case VEC_INIT_EXPR> does:
625		cp_walk_tree (expr_p, cp_fold_r, &pset, NULL);
626		cp_genericize_tree (expr_p);
and sees the is_invisiref_parm RESULT_DECL again (inside of MEM_REF) and turns it again into INDIRECT_REF and that is later gimplified again into MEM_REF.  So we have 2 nested MEM_REFs, so one indirection too many.

I think one possibility would be to be careful about REFERENCE_REF_Ps and corresponding MEM_REFs (I guess would need to double check that the offset is 0 and type is compatible with the type of the reference), if their argument is is_invisiref_parm, ensure it isn't convert_from_reference again.  Will try to implement that now.
Comment 4 Jakub Jelinek 2016-11-22 16:58:51 UTC
Or another option perhaps would be in cp_genericize_data note whether it is cp_genericize_tree called from cp_genericize or from elsewhere, and only replace invisiref parms if called from cp_genericize.
Comment 6 Jakub Jelinek 2016-11-23 15:55:11 UTC
Author: jakub
Date: Wed Nov 23 15:54:39 2016
New Revision: 242766

URL: https://gcc.gnu.org/viewcvs?rev=242766&root=gcc&view=rev
Log:
	PR c++/77739
	* cp-gimplify.c (cp_gimplify_tree) <case VEC_INIT_EXPR>: Pass
	false as handle_invisiref_parm_p to cp_genericize_tree.
	(struct cp_genericize_data): Add handle_invisiref_parm_p field.
	(cp_genericize_r): Don't wrap is_invisiref_parm into references
	if !wtd->handle_invisiref_parm_p.
	(cp_genericize_tree): Add handle_invisiref_parm_p argument,
	set wtd.handle_invisiref_parm_p to it.
	(cp_genericize): Pass true as handle_invisiref_parm_p to
	cp_genericize_tree.  Formatting fix.

	* g++.dg/cpp1y/pr77739.C: New test.

Added:
    trunk/gcc/testsuite/g++.dg/cpp1y/pr77739.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/cp-gimplify.c
    trunk/gcc/testsuite/ChangeLog
Comment 7 Jakub Jelinek 2016-11-23 16:39:39 UTC
Fixed on the trunk so far.
Comment 8 Jakub Jelinek 2016-12-07 22:55:36 UTC
Author: jakub
Date: Wed Dec  7 22:55:04 2016
New Revision: 243407

URL: https://gcc.gnu.org/viewcvs?rev=243407&root=gcc&view=rev
Log:
	Backported from mainline
	2016-11-23  Jakub Jelinek  <jakub@redhat.com>

	PR c++/77739
	* cp-gimplify.c (cp_gimplify_tree) <case VEC_INIT_EXPR>: Pass
	false as handle_invisiref_parm_p to cp_genericize_tree.
	(struct cp_genericize_data): Add handle_invisiref_parm_p field.
	(cp_genericize_r): Don't wrap is_invisiref_parm into references
	if !wtd->handle_invisiref_parm_p.
	(cp_genericize_tree): Add handle_invisiref_parm_p argument,
	set wtd.handle_invisiref_parm_p to it.
	(cp_genericize): Pass true as handle_invisiref_parm_p to
	cp_genericize_tree.  Formatting fix.

	* g++.dg/cpp1y/pr77739.C: New test.

Added:
    branches/gcc-6-branch/gcc/testsuite/g++.dg/cpp1y/pr77739.C
Modified:
    branches/gcc-6-branch/gcc/cp/ChangeLog
    branches/gcc-6-branch/gcc/cp/cp-gimplify.c
    branches/gcc-6-branch/gcc/testsuite/ChangeLog
Comment 9 Jakub Jelinek 2016-12-08 09:41:23 UTC
Fixed for 6.3+ as well.
Comment 10 Jakub Jelinek 2017-01-10 10:31:16 UTC
*** Bug 69001 has been marked as a duplicate of this bug. ***
Comment 11 Jakub Jelinek 2017-05-30 07:44:43 UTC
Author: jakub
Date: Tue May 30 07:44:11 2017
New Revision: 248627

URL: https://gcc.gnu.org/viewcvs?rev=248627&root=gcc&view=rev
Log:
	Backported from mainline
	2016-11-23  Jakub Jelinek  <jakub@redhat.com>

	PR c++/77739
	* cp-gimplify.c (cp_gimplify_tree) <case VEC_INIT_EXPR>: Pass
	false as handle_invisiref_parm_p to cp_genericize_tree.
	(struct cp_genericize_data): Add handle_invisiref_parm_p field.
	(cp_genericize_r): Don't wrap is_invisiref_parm into references
	if !wtd->handle_invisiref_parm_p.
	(cp_genericize_tree): Add handle_invisiref_parm_p argument,
	set wtd.handle_invisiref_parm_p to it.
	(cp_genericize): Pass true as handle_invisiref_parm_p to
	cp_genericize_tree.  Formatting fix.

	* g++.dg/cpp1y/pr77739.C: New test.

Added:
    branches/gcc-5-branch/gcc/testsuite/g++.dg/cpp1y/pr77739.C
Modified:
    branches/gcc-5-branch/gcc/cp/ChangeLog
    branches/gcc-5-branch/gcc/cp/cp-gimplify.c
    branches/gcc-5-branch/gcc/testsuite/ChangeLog
Comment 12 Jakub Jelinek 2017-05-30 09:18:21 UTC
Fixed.