On Fri, Mar 23, 2018 at 11:49:00AM +0100, Marek Polacek wrote:
> cxx_pretty_printer::multiplicative_expression didn't handle RDIV_EXPR, so when
> we tried to print a RDIV_EXPR, we printed it as a pm-expression.  That led to
> printing it as a cast-expression.  That led to printing it as a
> primary-expression.  That led to printing it as a multiplicative expression.
> That led to printing it as a pm-expression.  That led to printing it as a
> cast-expression.  That led to printing it as a primary-expression.  That led
> to... a crash.
> 
> Bootstrapped/regtested on x86_64-linux, ok for trunk?
> 
> 2018-03-23  Marek Polacek  <pola...@redhat.com>
> 
>       PR c++/85045
>       * cxx-pretty-print.c (cxx_pretty_printer::multiplicative_expression):
>       Handle RDIV_EXPR.
> 
>       * g++.dg/cpp0x/Wnarrowing5.C: New test.

I think that is not enough.  This is closely related to c-pretty-print.c,
which has:
c_pretty_printer::multiplicative_expression
    case MULT_EXPR:
    case TRUNC_DIV_EXPR:
    case TRUNC_MOD_EXPR:
    case EXACT_DIV_EXPR:
    case RDIV_EXPR:
and is broken:
      else if (code == TRUNC_DIV_EXPR)
        pp_slash (this);
      else
        pp_modulo (this);
That code == TRUNC_DIV_EXPR really should have been code != TRUNC_MOD_EXPR,
because all the above expressions are / except MULT_EXPR handled earlier and
TRUNC_MOD_EXPR.
c_pretty_printer::expression
then has:
    case MULT_EXPR:
    case TRUNC_MOD_EXPR:
    case TRUNC_DIV_EXPR:
    case EXACT_DIV_EXPR:
    case RDIV_EXPR:
      multiplicative_expression (e);
      break;

So, I think you want:
1) in cxx_pretty_printer::multiplicative_expression add
EXACT_DIV_EXPR and (like you did) RDIV_EXPR, and change the pp_slash
condition to code != TRUNC_MOD_EXPR
2) in cxx_pretty_printer::expression above the multiplicative_expression
call add case EXACT_DIV_EXPR: and case RDIV_EXPR
3) in c_pretty_printer::multiplicative_expression change the
code == TRUNC_DIV_EXPR condition to code != TRUNC_MOD_EXPR.
4) see if you can reproduce the c-pretty-print.c bug in some C testcase,
whether you get really % instead of / printed for floating point division.

> 
> diff --git gcc/cp/cxx-pretty-print.c gcc/cp/cxx-pretty-print.c
> index ca99997f5e1..8527a326c57 100644
> --- gcc/cp/cxx-pretty-print.c
> +++ gcc/cp/cxx-pretty-print.c
> @@ -899,11 +899,12 @@ cxx_pretty_printer::multiplicative_expression (tree e)
>      case MULT_EXPR:
>      case TRUNC_DIV_EXPR:
>      case TRUNC_MOD_EXPR:
> +    case RDIV_EXPR:
>        multiplicative_expression (TREE_OPERAND (e, 0));
>        pp_space (this);
>        if (code == MULT_EXPR)
>       pp_star (this);
> -      else if (code == TRUNC_DIV_EXPR)
> +      else if (code == TRUNC_DIV_EXPR || code == RDIV_EXPR)
>       pp_slash (this);
>        else
>       pp_modulo (this);
> diff --git gcc/testsuite/g++.dg/cpp0x/Wnarrowing5.C 
> gcc/testsuite/g++.dg/cpp0x/Wnarrowing5.C
> index e69de29bb2d..9acdc6b0c91 100644
> --- gcc/testsuite/g++.dg/cpp0x/Wnarrowing5.C
> +++ gcc/testsuite/g++.dg/cpp0x/Wnarrowing5.C
> @@ -0,0 +1,11 @@
> +// PR c++/85045
> +// { dg-do compile { target c++11 } }
> +
> +typedef struct tt {
> +  unsigned short h;
> +} tt;
> +
> +void mainScreen(float a)
> +{
> +  tt numlrect = {int(100/a)}; // { dg-error "narrowing conversion" }
> +}

        Jakub

Reply via email to