support TARGET_MEM_REF in C/C++ error pretty-printing [PR97197]

> See my comment above for Martins attempts to improve things.  I don't
> really want to try decide what to do with those late diagnostic IL
> printing but my commit was blamed for showing target-mem-ref unsupported.
>
> I don't have much time to spend to think what to best print and what not,
> but yes, printing only the MEM_REF part is certainly imprecise.

Here is an updated version of the patch that prints TARGET_MEM_REF the way
it should be printed - as C representation of what it actually means.
Of course it would be better to have the original expressions, but with the
late diagnostics we no longer have them.

2020-10-05  Richard Biener  <rguenther@suse.de>
	    Jakub Jelinek  <jakub@redhat.com>

	PR c++/97197
gcc/cp/
	* error.c (dump_expr): Handle TARGET_MEM_REF.
gcc/c-family/
	* c-pretty-print.c: Include langhooks.h.
	(c_pretty_printer::postfix_expression): Handle TARGET_MEM_REF as
	expression.
	(c_pretty_printer::expression): Handle TARGET_MEM_REF as
	unary_expression.
	(c_pretty_printer::unary_expression): Handle TARGET_MEM_REF.
This commit is contained in:
Jakub Jelinek 2020-10-05 18:33:17 +02:00
parent f92a504fdd
commit ac1c65ad1a
2 changed files with 117 additions and 0 deletions

View File

@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see
#include "intl.h"
#include "tree-pretty-print.h"
#include "selftest.h"
#include "langhooks.h"
/* The pretty-printer code is primarily designed to closely follow
(GNU) C and C++ grammars. That is to be contrasted with spaghetti
@ -1693,6 +1694,7 @@ c_pretty_printer::postfix_expression (tree e)
break;
case MEM_REF:
case TARGET_MEM_REF:
expression (e);
break;
@ -1859,6 +1861,62 @@ c_pretty_printer::unary_expression (tree e)
}
break;
case TARGET_MEM_REF:
/* TARGET_MEM_REF can't appear directly from source, but can appear
during late GIMPLE optimizations and through late diagnostic we might
need to support it. Print it as dereferencing of a pointer after
cast to the TARGET_MEM_REF type, with pointer arithmetics on some
pointer to single byte types, so
*(type *)((char *) ptr + step * index + index2) if all the operands
are present and the casts are needed. */
pp_c_star (this);
if (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (TMR_BASE (e)))) == NULL_TREE
|| !integer_onep (TYPE_SIZE_UNIT
(TREE_TYPE (TREE_TYPE (TMR_BASE (e))))))
{
if (TYPE_SIZE_UNIT (TREE_TYPE (e))
&& integer_onep (TYPE_SIZE_UNIT (TREE_TYPE (e))))
{
pp_c_left_paren (this);
pp_c_type_cast (this, build_pointer_type (TREE_TYPE (e)));
}
else
{
pp_c_type_cast (this, build_pointer_type (TREE_TYPE (e)));
pp_c_left_paren (this);
pp_c_type_cast (this, build_pointer_type (char_type_node));
}
}
else if (!lang_hooks.types_compatible_p
(TREE_TYPE (e), TREE_TYPE (TREE_TYPE (TMR_BASE (e)))))
{
pp_c_type_cast (this, build_pointer_type (TREE_TYPE (e)));
pp_c_left_paren (this);
}
else
pp_c_left_paren (this);
pp_c_cast_expression (this, TMR_BASE (e));
if (TMR_STEP (e) && TMR_INDEX (e))
{
pp_plus (this);
pp_c_cast_expression (this, TMR_INDEX (e));
pp_c_star (this);
pp_c_cast_expression (this, TMR_STEP (e));
}
if (TMR_INDEX2 (e))
{
pp_plus (this);
pp_c_cast_expression (this, TMR_INDEX2 (e));
}
if (!integer_zerop (TMR_OFFSET (e)))
{
pp_plus (this);
pp_c_integer_constant (this,
fold_convert (ssizetype, TMR_OFFSET (e)));
}
pp_c_right_paren (this);
break;
case REALPART_EXPR:
case IMAGPART_EXPR:
pp_c_ws_string (this, code == REALPART_EXPR ? "__real__" : "__imag__");
@ -2295,6 +2353,7 @@ c_pretty_printer::expression (tree e)
case ADDR_EXPR:
case INDIRECT_REF:
case MEM_REF:
case TARGET_MEM_REF:
case NEGATE_EXPR:
case BIT_NOT_EXPR:
case TRUTH_NOT_EXPR:

View File

@ -2400,6 +2400,64 @@ dump_expr (cxx_pretty_printer *pp, tree t, int flags)
}
break;
case TARGET_MEM_REF:
/* TARGET_MEM_REF can't appear directly from source, but can appear
during late GIMPLE optimizations and through late diagnostic we might
need to support it. Print it as dereferencing of a pointer after
cast to the TARGET_MEM_REF type, with pointer arithmetics on some
pointer to single byte types, so
*(type *)((char *) ptr + step * index + index2) if all the operands
are present and the casts are needed. */
pp_cxx_star (pp);
pp_cxx_left_paren (pp);
if (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (TMR_BASE (t)))) == NULL_TREE
|| !integer_onep (TYPE_SIZE_UNIT
(TREE_TYPE (TREE_TYPE (TMR_BASE (t))))))
{
if (TYPE_SIZE_UNIT (TREE_TYPE (t))
&& integer_onep (TYPE_SIZE_UNIT (TREE_TYPE (t))))
{
pp_cxx_left_paren (pp);
dump_type (pp, build_pointer_type (TREE_TYPE (t)), flags);
}
else
{
dump_type (pp, build_pointer_type (TREE_TYPE (t)), flags);
pp_cxx_right_paren (pp);
pp_cxx_left_paren (pp);
pp_cxx_left_paren (pp);
dump_type (pp, build_pointer_type (char_type_node), flags);
}
pp_cxx_right_paren (pp);
}
else if (!same_type_p (TREE_TYPE (t),
TREE_TYPE (TREE_TYPE (TMR_BASE (t)))))
{
dump_type (pp, build_pointer_type (TREE_TYPE (t)), flags);
pp_cxx_right_paren (pp);
pp_cxx_left_paren (pp);
}
dump_expr (pp, TMR_BASE (t), flags);
if (TMR_STEP (t) && TMR_INDEX (t))
{
pp_cxx_ws_string (pp, "+");
dump_expr (pp, TMR_INDEX (t), flags);
pp_cxx_ws_string (pp, "*");
dump_expr (pp, TMR_STEP (t), flags);
}
if (TMR_INDEX2 (t))
{
pp_cxx_ws_string (pp, "+");
dump_expr (pp, TMR_INDEX2 (t), flags);
}
if (!integer_zerop (TMR_OFFSET (t)))
{
pp_cxx_ws_string (pp, "+");
dump_expr (pp, fold_convert (ssizetype, TMR_OFFSET (t)), flags);
}
pp_cxx_right_paren (pp);
break;
case NEGATE_EXPR:
case BIT_NOT_EXPR:
case TRUTH_NOT_EXPR: