This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [Patch, Fortran] PR 35983 C_LOC expanded to a NULL_PTR expr if called from a structure constructor
- From: Mikael Morin <mikael dot morin at tele2 dot fr>
- To: Tobias Burnus <burnus at net-b dot de>
- Cc: gcc-patches at gcc dot gnu dot org, fortran at gcc dot gnu dot org
- Date: Tue, 09 Dec 2008 17:05:47 +0100
- Subject: Re: [Patch, Fortran] PR 35983 C_LOC expanded to a NULL_PTR expr if called from a structure constructor
- References: <20081208222408.GA1085@net-b.de>
Tobias Burnus wrote:
> Mikael,
>
> first question: Have you checked whether now backing out
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35150#c8
> is possible?
>
Short version: I think FX's fix is correct
Extended version:
The problem comes from the following code in trans-expr.c, which uses
static constants temporaries for passing constants as actual arguments.
/******************************************************/
3987 /* Create a temporary var to hold the value. */
3988 if (TREE_CONSTANT (se->expr))
3989 {
3990 tree tmp = se->expr;
3991 STRIP_TYPE_NOPS (tmp);
3992 var = build_decl (CONST_DECL, NULL, TREE_TYPE (tmp));
3993 DECL_INITIAL (var) = tmp;
3994 TREE_STATIC (var) = 1;
3995 pushdecl (var);
3996 }
3997 else
3998 {
3999 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
4000 gfc_add_modify (&se->pre, var, se->expr);
4001 }
4002 gfc_add_block_to_block (&se->pre, &se->post);
/******************************************************/
The middle-end has specific code to handle constant addresses (in expr.c):
/*******************************************************/
6770 /* ??? This should be considered a front-end bug. We should not be
6771 generating ADDR_EXPR of something that isn't an LVALUE. The only
6772 exception here is STRING_CST. */
6773 if (CONSTANT_CLASS_P (exp))
6774 return XEXP (expand_expr_constant (exp, 0, modifier), 0);
6775
6776 /* Everything must be something allowed by
is_gimple_addressable. */
6777 switch (TREE_CODE (exp))
6778 {
6779 case INDIRECT_REF:
6780 /* This case will happen via recursion for &a->b. */
6781 return expand_expr (TREE_OPERAND (exp, 0), target, tmode,
modifier);
6782
6783 case CONST_DECL:
6784 /* Recurse and make the output_constant_def clause above
handle this
. */
6785 return expand_expr_addr_expr_1 (DECL_INITIAL (exp), target,
6786 tmode, modifier);
/*********************************************************/
The first call to expand_expr_addr_expr_1, with the constant temporary
holding as expression, is handled at line 6784 which calls recursively
expand_expr_addr_expr_1 with the temporary initial value (c_loc's value)
as expression.
However, the expression is an address expression, not a constant
expression. Thus, it is not matched by CONSTANT_CLASS_P at line 6773 and
fails later.
I tried to change the recursive call into a goto to the
expand_expr_constant call. It fixed the problem and passed the fortran
testsuite. However, I failed to run the c testsuite as well as it was
freezing my computer (Yes, freezing!)
I thought about it more later and came to the conclusion that all the
above was wrong, as c_loc being a function, its result is an expression,
so that a (writable) temporary should be made for it. Thus, I believe
that FX's fix is correct.
There is a comparable code in gfc_trans_intrinsic_loc:
/******************************************************/
4335 /* Create a temporary variable for loc return value. Without this,
4336 we get an error an ICE in gcc/expr.c(expand_expr_addr_expr_1). */
4337 temp_var = gfc_create_var (gfc_get_int_type
(gfc_index_integer_kind), NUL
L);
4338 gfc_add_modify (&se->pre, temp_var, se->expr);
4339 se->expr = temp_var;
4340 }
/******************************************************/
And the same would probably be necessary for c_funloc:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34199#c7
Mikael