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

Jakub Jelinek jakub@gcc.gnu.org
Mon Oct 5 16:42:10 GMT 2020


https://gcc.gnu.org/g:ac1c65ad1a16d83ec63674efa07c00b062562f15

commit r11-3659-gac1c65ad1a16d83ec63674efa07c00b062562f15
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Mon Oct 5 18:33:17 2020 +0200

    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.

Diff:
---
 gcc/c-family/c-pretty-print.c | 59 +++++++++++++++++++++++++++++++++++++++++++
 gcc/cp/error.c                | 58 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 117 insertions(+)

diff --git a/gcc/c-family/c-pretty-print.c b/gcc/c-family/c-pretty-print.c
index acffd7b872c..8953e3b678b 100644
--- a/gcc/c-family/c-pretty-print.c
+++ b/gcc/c-family/c-pretty-print.c
@@ -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:
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index ecb41e82d8c..ad22b00cb0b 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -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:


More information about the Gcc-cvs mailing list