[PATCH] Fix PR34081/C++ ICE in s390_function_value
Andreas Krebbel
Andreas.Krebbel@de.ibm.com
Mon Nov 26 18:04:00 GMT 2007
> I would suggest we change the name of the parameter to ABSTRACT_P, and
> then use PROCESSING_TEMPLATE_DECL in the front end to initialize that.
> As further cleanups (not required as part of the patch) we could attempt
> the "struct function" split for ABSTRACT_P and/or remove the use of
> current_function_returns_struct from the C++ front-end.
Done with the attached patch.
Bootstrapped on s390x and x86_64.
No testsuite regressions.
New testcase is fixed on s390x.
OK for mainline?
2007-11-26 Andreas Krebbel <krebbel1@de.ibm.com>
PR 34081/C++
* c-decl.c (store_parm_decls): Pass 'false' for the new
allocate_struct_function parameter.
* cgraphunit.c (cgraph_build_static_cdtor): Likewise.
* tree-parloops.c (create_loop_fn): Likewise.
* function.c (push_function_context_to, push_struct_function,
init_function_start): Likewise.
(allocate_struct_function): Add boolean parameter.
* tree.h (allocate_struct_function): Add boolean parameter.
2007-11-26 Andreas Krebbel <krebbel1@de.ibm.com>
PR 34081/C++
* decl.c (start_preparsed_function): Pass
processing_template_decl for the new allocate_struct_function
parameter.
2007-11-26 Andreas Krebbel <krebbel1@de.ibm.com>
PR 34081/C++
* g++.dg/template/dependent-expr6.C: New testcase.
2007-11-26 Andreas Krebbel <krebbel1@de.ibm.com>
PR 34081/C++
* trans.c (Subprogram_Body_to_gnu, Compilation_Unit_to_gnu):
Pass 'false' for the new allocate_struct_function parameter.
* utils.c (build_function_stub): Likewise.
... and so on for the ada, java and treelang front ends.
Index: gcc/ada/trans.c
===================================================================
*** gcc/ada/trans.c.orig 2007-11-21 10:48:54.000000000 +0100
--- gcc/ada/trans.c 2007-11-21 14:02:57.000000000 +0100
*************** Subprogram_Body_to_gnu (Node_Id gnat_nod
*** 1776,1782 ****
Sloc_to_locus (Sloc (gnat_node), &DECL_SOURCE_LOCATION (gnu_subprog_decl));
/* Initialize the information structure for the function. */
! allocate_struct_function (gnu_subprog_decl);
DECL_STRUCT_FUNCTION (gnu_subprog_decl)->language
= GGC_CNEW (struct language_function);
--- 1776,1782 ----
Sloc_to_locus (Sloc (gnat_node), &DECL_SOURCE_LOCATION (gnu_subprog_decl));
/* Initialize the information structure for the function. */
! allocate_struct_function (gnu_subprog_decl, false);
DECL_STRUCT_FUNCTION (gnu_subprog_decl)->language
= GGC_CNEW (struct language_function);
*************** Compilation_Unit_to_gnu (Node_Id gnat_no
*** 2914,2920 ****
push_stack (&gnu_elab_proc_stack, NULL_TREE, gnu_elab_proc_decl);
DECL_ELABORATION_PROC_P (gnu_elab_proc_decl) = 1;
! allocate_struct_function (gnu_elab_proc_decl);
Sloc_to_locus (Sloc (gnat_unit_entity), &cfun->function_end_locus);
set_cfun (NULL);
--- 2914,2920 ----
push_stack (&gnu_elab_proc_stack, NULL_TREE, gnu_elab_proc_decl);
DECL_ELABORATION_PROC_P (gnu_elab_proc_decl) = 1;
! allocate_struct_function (gnu_elab_proc_decl, false);
Sloc_to_locus (Sloc (gnat_unit_entity), &cfun->function_end_locus);
set_cfun (NULL);
Index: gcc/ada/utils.c
===================================================================
*** gcc/ada/utils.c.orig 2007-11-21 10:48:54.000000000 +0100
--- gcc/ada/utils.c 2007-11-21 14:02:57.000000000 +0100
*************** build_function_stub (tree gnu_subprog, E
*** 2983,2989 ****
gnat_poplevel ();
! allocate_struct_function (gnu_stub_decl);
end_subprog_body (gnu_body);
}
--- 2983,2989 ----
gnat_poplevel ();
! allocate_struct_function (gnu_stub_decl, false);
end_subprog_body (gnu_body);
}
Index: gcc/c-decl.c
===================================================================
*** gcc/c-decl.c.orig 2007-11-21 10:49:17.000000000 +0100
--- gcc/c-decl.c 2007-11-21 14:02:57.000000000 +0100
*************** store_parm_decls (void)
*** 6632,6638 ****
gen_aux_info_record (fndecl, 1, 0, proto);
/* Initialize the RTL code for the function. */
! allocate_struct_function (fndecl);
/* Begin the statement tree for this function. */
DECL_SAVED_TREE (fndecl) = push_stmt_list ();
--- 6632,6638 ----
gen_aux_info_record (fndecl, 1, 0, proto);
/* Initialize the RTL code for the function. */
! allocate_struct_function (fndecl, false);
/* Begin the statement tree for this function. */
DECL_SAVED_TREE (fndecl) = push_stmt_list ();
Index: gcc/cgraphunit.c
===================================================================
*** gcc/cgraphunit.c.orig 2007-11-21 10:49:17.000000000 +0100
--- gcc/cgraphunit.c 2007-11-21 14:02:57.000000000 +0100
*************** cgraph_build_static_cdtor (char which, t
*** 1481,1487 ****
DECL_ARTIFICIAL (resdecl) = 1;
DECL_RESULT (decl) = resdecl;
! allocate_struct_function (decl);
TREE_STATIC (decl) = 1;
TREE_USED (decl) = 1;
--- 1481,1487 ----
DECL_ARTIFICIAL (resdecl) = 1;
DECL_RESULT (decl) = resdecl;
! allocate_struct_function (decl, false);
TREE_STATIC (decl) = 1;
TREE_USED (decl) = 1;
Index: gcc/cp/decl.c
===================================================================
*** gcc/cp/decl.c.orig 2007-11-21 10:48:52.000000000 +0100
--- gcc/cp/decl.c 2007-11-26 09:48:16.000000000 +0100
*************** start_preparsed_function (tree decl1, tr
*** 11180,11186 ****
CFUN set up, and our per-function variables initialized.
FIXME factor out the non-RTL stuff. */
bl = current_binding_level;
! allocate_struct_function (decl1);
current_binding_level = bl;
/* Even though we're inside a function body, we still don't want to
--- 11180,11186 ----
CFUN set up, and our per-function variables initialized.
FIXME factor out the non-RTL stuff. */
bl = current_binding_level;
! allocate_struct_function (decl1, processing_template_decl);
current_binding_level = bl;
/* Even though we're inside a function body, we still don't want to
Index: gcc/function.c
===================================================================
*** gcc/function.c.orig 2007-11-21 10:49:17.000000000 +0100
--- gcc/function.c 2007-11-26 09:52:20.000000000 +0100
*************** push_function_context_to (tree context A
*** 247,253 ****
struct function *p;
if (cfun == 0)
! allocate_struct_function (NULL);
p = cfun;
p->outer = outer_function_chain;
--- 247,253 ----
struct function *p;
if (cfun == 0)
! allocate_struct_function (NULL, false);
p = cfun;
p->outer = outer_function_chain;
*************** get_next_funcdef_no (void)
*** 3881,3890 ****
directly into cfun and invoke the back end hook explicitly at the
very end, rather than initializing a temporary and calling set_cfun
on it.
! */
void
! allocate_struct_function (tree fndecl)
{
tree result;
tree fntype = fndecl ? TREE_TYPE (fndecl) : NULL_TREE;
--- 3881,3894 ----
directly into cfun and invoke the back end hook explicitly at the
very end, rather than initializing a temporary and calling set_cfun
on it.
!
! ABSTRACT_P is true if this is a function that will never be seen by
! the middle-end. Such functions are front-end concepts (like C++
! function templates) that do not correspond directly to functions
! placed in object files. */
void
! allocate_struct_function (tree fndecl, bool abstract_p)
{
tree result;
tree fntype = fndecl ? TREE_TYPE (fndecl) : NULL_TREE;
*************** allocate_struct_function (tree fndecl)
*** 3910,3916 ****
cfun->decl = fndecl;
result = DECL_RESULT (fndecl);
! if (aggregate_value_p (result, fndecl))
{
#ifdef PCC_STATIC_STRUCT_RETURN
current_function_returns_pcc_struct = 1;
--- 3914,3920 ----
cfun->decl = fndecl;
result = DECL_RESULT (fndecl);
! if (!abstract_p && aggregate_value_p (result, fndecl))
{
#ifdef PCC_STATIC_STRUCT_RETURN
current_function_returns_pcc_struct = 1;
*************** push_struct_function (tree fndecl)
*** 3943,3949 ****
VEC_safe_push (function_p, heap, cfun_stack, cfun);
if (fndecl)
in_system_header = DECL_IN_SYSTEM_HEADER (fndecl);
! allocate_struct_function (fndecl);
}
/* Reset cfun, and other non-struct-function variables to defaults as
--- 3947,3953 ----
VEC_safe_push (function_p, heap, cfun_stack, cfun);
if (fndecl)
in_system_header = DECL_IN_SYSTEM_HEADER (fndecl);
! allocate_struct_function (fndecl, false);
}
/* Reset cfun, and other non-struct-function variables to defaults as
*************** init_function_start (tree subr)
*** 3998,4004 ****
if (subr && DECL_STRUCT_FUNCTION (subr))
set_cfun (DECL_STRUCT_FUNCTION (subr));
else
! allocate_struct_function (subr);
prepare_function_start ();
/* Warn if this value is an aggregate type,
--- 4002,4008 ----
if (subr && DECL_STRUCT_FUNCTION (subr))
set_cfun (DECL_STRUCT_FUNCTION (subr));
else
! allocate_struct_function (subr, false);
prepare_function_start ();
/* Warn if this value is an aggregate type,
Index: gcc/java/decl.c
===================================================================
*** gcc/java/decl.c.orig 2007-11-21 10:47:25.000000000 +0100
--- gcc/java/decl.c 2007-11-21 14:02:57.000000000 +0100
*************** finish_method (tree fndecl)
*** 1850,1856 ****
if (DECL_STRUCT_FUNCTION (fndecl))
set_cfun (DECL_STRUCT_FUNCTION (fndecl));
else
! allocate_struct_function (fndecl);
#ifdef USE_MAPPED_LOCATION
cfun->function_end_locus = DECL_FUNCTION_LAST_LINE (fndecl);
#else
--- 1850,1856 ----
if (DECL_STRUCT_FUNCTION (fndecl))
set_cfun (DECL_STRUCT_FUNCTION (fndecl));
else
! allocate_struct_function (fndecl, false);
#ifdef USE_MAPPED_LOCATION
cfun->function_end_locus = DECL_FUNCTION_LAST_LINE (fndecl);
#else
Index: gcc/tree-parloops.c
===================================================================
*** gcc/tree-parloops.c.orig 2007-11-21 10:49:17.000000000 +0100
--- gcc/tree-parloops.c 2007-11-21 14:02:57.000000000 +0100
*************** create_loop_fn (void)
*** 1248,1254 ****
TREE_USED (t) = 1;
DECL_ARGUMENTS (decl) = t;
! allocate_struct_function (decl);
/* The call to allocate_struct_function clobbers CFUN, so we need to restore
it. */
--- 1248,1254 ----
TREE_USED (t) = 1;
DECL_ARGUMENTS (decl) = t;
! allocate_struct_function (decl, false);
/* The call to allocate_struct_function clobbers CFUN, so we need to restore
it. */
Index: gcc/tree.h
===================================================================
*** gcc/tree.h.orig 2007-11-21 10:49:17.000000000 +0100
--- gcc/tree.h 2007-11-21 14:02:57.000000000 +0100
*************** extern void expand_main_function (void);
*** 4935,4941 ****
extern void init_dummy_function_start (void);
extern void expand_dummy_function_end (void);
extern unsigned int init_function_for_compilation (void);
! extern void allocate_struct_function (tree);
extern void push_struct_function (tree fndecl);
extern void init_function_start (tree);
extern bool use_register_for_decl (const_tree);
--- 4935,4941 ----
extern void init_dummy_function_start (void);
extern void expand_dummy_function_end (void);
extern unsigned int init_function_for_compilation (void);
! extern void allocate_struct_function (tree, bool);
extern void push_struct_function (tree fndecl);
extern void init_function_start (tree);
extern bool use_register_for_decl (const_tree);
Index: gcc/treelang/treetree.c
===================================================================
*** gcc/treelang/treetree.c.orig 2007-11-21 10:47:25.000000000 +0100
--- gcc/treelang/treetree.c 2007-11-21 14:02:57.000000000 +0100
*************** tree_code_create_function_wrapup (locati
*** 457,463 ****
BLOCK_VARS (block),
stmts, block);
! allocate_struct_function (fn_decl);
cfun->function_end_locus = loc;
/* Dump the original tree to a file. */
--- 457,463 ----
BLOCK_VARS (block),
stmts, block);
! allocate_struct_function (fn_decl, false);
cfun->function_end_locus = loc;
/* Dump the original tree to a file. */
Index: gcc/testsuite/g++.dg/template/dependent-expr6.C
===================================================================
*** /dev/null 1970-01-01 00:00:00.000000000 +0000
--- gcc/testsuite/g++.dg/template/dependent-expr6.C 2007-11-21 14:02:57.000000000 +0100
***************
*** 0 ****
--- 1,21 ----
+ // { dg-do compile }
+
+ // Copyright 2007 Free Software Foundation
+ // Contributed by Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
+
+ // PR C++ 34081 ICE
+
+ class Foo;
+
+ template < class Foo > class Bar
+ {
+ enum Status
+ { OK, NO };
+
+ enum Status getStatus ()
+ {
+ return status;
+ }
+
+ Status status;
+ };
More information about the Gcc-patches
mailing list