Properly parse invariant &MEM addresses in the GIMPLE FE

Currently the frontend rejects those addresses as not lvalues
because the C frontend doens't expect MEM_REF or TARGET_MEM_REF
to appear (but they would be valid lvalues there).  The following
fixes that by amending lvalue_p.

The change also makes the dumping of the source of the testcase
valid for the GIMPLE FE by not eliding the '&' when dumping
string literals.

2021-10-06  Richard Biener  <rguenther@suse.de>

gcc/c/
	* c-typeck.c (lvalue_p): Also allow MEM_REF and TARGET_MEM_REF.

gcc/
	* tree-pretty-print.c (dump_generic_node): Do not elide
	printing '&' when dumping with -gimple.

gcc/testsuite/
	* gcc.dg/gimplefe-47.c: New testcase.
This commit is contained in:
Richard Biener 2021-10-06 11:02:38 +02:00
parent 57c7ec62ee
commit 6496ae5c96
3 changed files with 36 additions and 2 deletions

View file

@ -4968,6 +4968,10 @@ lvalue_p (const_tree ref)
case STRING_CST:
return true;
case MEM_REF:
case TARGET_MEM_REF:
/* MEM_REFs can appear from -fgimple parsing or folding, so allow them
here as well. */
case INDIRECT_REF:
case ARRAY_REF:
case VAR_DECL:

View file

@ -0,0 +1,27 @@
/* { dg-do compile } */
/* { dg-options "-fgimple" } */
char * begfield (int tab, char * ptr, char * lim, int sword, int schar);
int __GIMPLE (ssa)
main ()
{
char * lim;
char * s;
char * _1;
__BB(2):
_1 = begfield (58, ":ab", &__MEM <char[4]> ((void *)&":ab" + _Literal
(void *) 3), 1, 1);
if (_1 != _Literal (char *) &__MEM <char[4]> ((void *)&":ab" + _Literal (void *) 2))
goto __BB3;
else
goto __BB4;
__BB(3):
__builtin_abort ();
__BB(4):
__builtin_exit (0);
}

View file

@ -2888,10 +2888,13 @@ dump_generic_node (pretty_printer *pp, tree node, int spc, dump_flags_t flags,
case PREDECREMENT_EXPR:
case PREINCREMENT_EXPR:
case INDIRECT_REF:
if (TREE_CODE (node) == ADDR_EXPR
if (!(flags & TDF_GIMPLE)
&& TREE_CODE (node) == ADDR_EXPR
&& (TREE_CODE (TREE_OPERAND (node, 0)) == STRING_CST
|| TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL))
; /* Do not output '&' for strings and function pointers. */
/* Do not output '&' for strings and function pointers when not
dumping GIMPLE FE syntax. */
;
else
pp_string (pp, op_symbol (node));