From ac1c65ad1a16d83ec63674efa07c00b062562f15 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Mon, 5 Oct 2020 18:33:17 +0200 Subject: [PATCH] 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 Jakub Jelinek 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. --- 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: