On January 9, 2021 10:32:52 AM GMT+01:00, Jakub Jelinek <ja...@redhat.com> 
wrote:
>Hi!
>
>As conversions between signed integers and signed enums with the same
>precision are useless in GIMPLE, it seems strange that we require that
>POINTER_DIFF_EXPR result must be INTEGER_TYPE.
>
>If we really wanted to require that, we'd need to change the gimplifier
>to ensure that, which it isn't the case on the following testcase.
>What is going on during the gimplification is that when we have the
>(enum T) (p - q) cast, it is stripped through
>      /* Strip away as many useless type conversions as possible
>         at the toplevel.  */
>      STRIP_USELESS_TYPE_CONVERSION (*expr_p);
>and when the MODIFY_EXPR is gimplified, the *to_p has enum T type,
>while *from_p has intptr_t type and as there is no conversion in
>between,
>we just create GIMPLE_ASSIGN from that.
>
>Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

Ok also for the branch. 

Thanks, 
Richard. 

>2021-01-08  Jakub Jelinek  <ja...@redhat.com>
>
>       PR c++/98556
>       * tree-cfg.c (verify_gimple_assign_binary): Allow lhs of
>       POINTER_DIFF_EXPR to be any integral type.
>
>       * c-c++-common/pr98556.c: New test.
>
>--- gcc/tree-cfg.c.jj  2021-01-04 10:25:38.914232907 +0100
>+++ gcc/tree-cfg.c     2021-01-08 15:57:41.605738398 +0100
>@@ -3940,7 +3940,7 @@ verify_gimple_assign_binary (gassign *st
>           /* Because we special-case pointers to void we allow difference
>              of arbitrary pointers with the same mode.  */
>           || TYPE_MODE (rhs1_type) != TYPE_MODE (rhs2_type)
>-          || TREE_CODE (lhs_type) != INTEGER_TYPE
>+          || !INTEGRAL_TYPE_P (lhs_type)
>           || TYPE_UNSIGNED (lhs_type)
>           || TYPE_PRECISION (lhs_type) != TYPE_PRECISION (rhs1_type))
>         {
>--- gcc/testsuite/c-c++-common/pr98556.c.jj    2021-01-08
>16:03:22.298900002 +0100
>+++ gcc/testsuite/c-c++-common/pr98556.c       2021-01-08 16:03:07.715064312
>+0100
>@@ -0,0 +1,11 @@
>+/* PR c++/98556 */
>+/* { dg-do compile } */
>+/* { dg-options "-O0" } */
>+
>+enum T { E = -__LONG_MAX__ - 1 };
>+
>+enum T
>+foo (char *p, char *q)
>+{
>+  return (enum T) (p - q);
>+}
>
>       Jakub

Reply via email to