public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Jason Merrill <jason@redhat.com>
To: Richard Biener <richard.guenther@gmail.com>
Cc: Marc Glisse <marc.glisse@inria.fr>,
	"Joseph S. Myers" <joseph@codesourcery.com>,
		Jakub Jelinek <jakub@redhat.com>,
	GCC Patches <gcc-patches@gcc.gnu.org>,
		Ulrich Weigand <uweigand@de.ibm.com>,
	Ilya Enkovich <enkovich.gnu@gmail.com>,
	DJ Delorie <dj@redhat.com>
Subject: Re: [RFTesting] New POINTER_DIFF_EXPR
Date: Fri, 17 Nov 2017 14:06:00 -0000	[thread overview]
Message-ID: <CADzB+2mxsExjLKmFXnd3ZU6Q1QJGf=nzPnHsgz6AUh-yo74SsA@mail.gmail.com> (raw)
In-Reply-To: <CAFiYyc1Tv-fFYXkFKttDzAGz+aiP3hpEPtjHp46PfZm_w1D+nw@mail.gmail.com>

On Fri, Nov 17, 2017 at 7:56 AM, Richard Biener
<richard.guenther@gmail.com> wrote:
> On Sat, Nov 11, 2017 at 12:44 AM, Marc Glisse <marc.glisse@inria.fr> wrote:
>> Adding some random cc: to people who might be affected. Hopefully I am not
>> breaking any of your stuff...
>>
>> Ulrich Weigand (address space)
>> Ilya Enkovich (pointer bound check)
>> DJ Delorie (target with 24-bit partial mode pointer)
>>
>> If you want to give it a try, or just take a quick look to check that you
>> are obviously not affected, that would be nice, but don't feel forced.
>>
>> Here is an updated version of the patch, with just a few more
>> transformations in match.pd, to match some MINUS_EXPR optimizations I missed
>> the first time: -(A-B), X-Z<Y-Z, (X-Z)-(Y-Z), Z-X<Z-Y, (Z-X)-(Z-Y),
>> (A-B)+(C-A)
>>
>> The exact undefined-behavior status should probably be clarified more.
>> First, I'd like to say that POINTER_DIFF_EXPR may only take 2 pointers into
>> the same "object" (like in C/C++), so they differ by at most half the size
>> of the address space, and a-b is not allowed to be the minimum negative
>> value (so I can safely use b-a), and if we compute a-b and b-c, then a and c
>> are in the same object so I can safely compute a-c, etc. Second, we probably
>> need modes without undefined behavior, wrapping with either -fwrapv or a new
>> -fwrapp, or sanitized. For the sanitized version, we could keep using
>> POINTER_DIFF_EXPR and check TYPE_OVERFLOW_SANITIZED on the pointer type as
>> we currently do for integers. For wrapping, either we say that
>> POINTER_DIFF_EXPR has wrapping semantics when that option is in effect, or
>> we do not use POINTER_DIFF_EXPR and instead cast to unsigned before applying
>> a MINUS_EXPR (my preference).
>
> CCing C/C++ FE folks as well.
>
> +      /* It is better if the caller provides the return type.  */
> +      if (code == POINTER_DIFF_EXPR)
> +       {
> +         offset_int res = wi::sub (wi::to_offset (arg1),
> +                                   wi::to_offset (arg2));
> +         return force_fit_type (signed_type_for (TREE_TYPE (arg1)), res, 1,
> +                                TREE_OVERFLOW (arg1) | TREE_OVERFLOW (arg2));
> +       }
> +
>
> there's an overload that provides the type... (we should probably go
> over all callers
> and use that).  There is already a folding that is only done when the type is
> available.  So I'd simply remove the above from the non-type overload handling.
> What breaks then?
>
> With the patch it's of course somewhat ugly in that we need to deal with both
> MINUS_EXPR on pointers and POINTER_DIFF_EXPR - at least that's what
>
> +    case POINTER_DIFF_EXPR:
>      case MINUS_EXPR:
> +      /* Fold &a[i] - &a[j] to i-j.  */
> +      if (TREE_CODE (arg0) == ADDR_EXPR
> +         && TREE_CODE (TREE_OPERAND (arg0, 0)) == ARRAY_REF
> +         && TREE_CODE (arg1) == ADDR_EXPR
> +         && TREE_CODE (TREE_OPERAND (arg1, 0)) == ARRAY_REF)
> +        {
> +         tree tem = fold_addr_of_array_ref_difference (loc, type,
> +                                                       TREE_OPERAND (arg0, 0),
> +                                                       TREE_OPERAND (arg1, 0),
> +                                                       code
> +                                                       == POINTER_DIFF_EXPR);
>
> suggests.  But is that really so?  The FEs today should never build
> a MINUS_EXPR with pointer operands and your patch also doesn't.
> I suppose we only arrive above because STRIP_NOPS strips the
> pointer to integer conversion?
>
> +    case POINTER_DIFF_EXPR:
> +      if (!POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0)))
> +         || !POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 1))))
> +       {
> +         error ("invalid operand to pointer diff, operand is not a pointer");
> +         return t;
> +       }
> +      CHECK_OP (0, "invalid operand to pointer diff");
> +      CHECK_OP (1, "invalid operand to pointer diff");
> +      break;
>
> can you add
>   || TREE_CODE (TREE_TYPE (t)) != INTEGER_TYPE
>   || TYPE_UNSIGNED (TREE_TYPE (t))
>
> ?  Note that if the precision of the pointer type arguments are not equal to the
> precision of the return value then foldings like
>
>    (simplify
> +   (plus:c (pointer_diff @0 @1) (pointer_diff @2 @0))
> +   (if (TYPE_OVERFLOW_UNDEFINED (type)
> +       && !TYPE_OVERFLOW_SANITIZED (TREE_TYPE (@0)))
> +    (pointer_diff @2 @1)))
>
> might not be correct as we drop a possible truncation here.  Shall we
> require (and document) that the result of the pointer difference in
> a POINTER_DIFF_EXPR has to be representable in the type of the
> expression, otherwise
> the behavior is undefined?  Shall we allow an unsigned return type for
> differences known to be representable?  Probably not...  Does the behavior
> depend on TYPE_OVERFLOW_UNDEFINED?  It would be nice to amend
> the generic.texi docs somewhat here.
>
> Ah, the gimple checking adds some more bits here that clarify things:
>
> +    case POINTER_DIFF_EXPR:
> +      {
> +       if (!POINTER_TYPE_P (rhs1_type)
> +           || !POINTER_TYPE_P (rhs2_type)
> +           || !types_compatible_p (rhs1_type, rhs2_type)
> +           || TREE_CODE (lhs_type) != INTEGER_TYPE
> +           || TYPE_UNSIGNED (lhs_type)
> +           || TYPE_PRECISION (lhs_type) != TYPE_PRECISION (rhs1_type))
> +         {
> +           error ("type mismatch in pointer diff expression");
> +           debug_generic_stmt (lhs_type);
> +           debug_generic_stmt (rhs1_type);
> +           debug_generic_stmt (rhs2_type);
> +           return true;
> +         }
>
>
> I think the patch is ok for trunk, the FE bits should get approval
> from their maintainers.
> Joseph may have an idea about the address-space issue.
>
> With this in place we should be able to fix some of the issues Jakub ran into
> with pointer sanitizing?
>
> Also with this in place it would be nice to do the corresponding adjustment to
> POINTER_PLUS_EXPR, that is, require a _signed_ offset type that matches
> the precision of the other argument.
>
> Richard.
>
>>
>>
>> On Sat, 28 Oct 2017, Marc Glisse wrote:
>>
>>> Hello,
>>>
>>> first, if you are doing anything unusual with pointers (address spaces,
>>> pointer/sizetype with weird sizes, instrumentation, etc), it would be great
>>> if you could give this patch a try. It was bootstrapped and regtested on
>>> powerpc64le-unknown-linux-gnu (gcc112), and a slightly older version on
>>> x86_64-pc-linux-gnu (skylake laptop). I also built bare cross-compilers (no
>>> sysroot or anything) for avr, m32c, alpha64-vms, s390-linux, and visium to
>>> check that on trivial examples it behaves as expected (by the way, m32c
>>> seems broken for unrelated reasons at the moment), but I wouldn't count that
>>> as complete testing.
>>>
>>> This was previously discussed in the thread "Fix pointer diff (was:
>>> -fsanitize=pointer-overflow support (PR sanitizer/80998))" (
>>> https://gcc.gnu.org/ml/gcc-patches/2017-10/msg02128.html for the latest
>>> message).
>>>
>>> Front-ends other than C/C++ can be changed later (I took a quick look at
>>> fortran and ada, but they are way too unfamiliar to me), I did not remove
>>> any handling for the other representations.
>>>
>>> 2017-10-28  Marc Glisse  <marc.glisse@inria.fr>
>>>
>>> gcc/cp/
>>>         * constexpr.c (cxx_eval_constant_expression,
>>>         potential_constant_expression_1): Handle POINTER_DIFF_EXPR.
>>>         * cp-gimplify.c (cp_fold): Likewise.
>>>         * error.c (dump_expr): Likewise.
>>>         * typeck.c (cp_build_binary_op): Likewise.

It's not clear to me that cp_build_binary_op needs to handle
POINTER_DIFF_EXPR, it should get MINUS_EXPR and produce
POINTER_DIFF_EXPR.

>>>         * tree.def: New tree code POINTER_DIFF_EXPR.

The comment might mention that the value is the same for all pointer
types, not divided by the size of the pointed-to type.

Jason

  reply	other threads:[~2017-11-17 13:58 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-10-28 14:58 Marc Glisse
2017-11-11  0:11 ` Marc Glisse
2017-11-17 13:13   ` Richard Biener
2017-11-17 14:06     ` Jason Merrill [this message]
2017-11-18  9:54       ` Marc Glisse
2017-11-20  0:12       ` Marc Glisse
2017-11-20 14:13         ` Jason Merrill
2017-11-21 17:06         ` Jeff Law
2017-11-22  8:25         ` Christophe Lyon
2017-11-22  8:29           ` Marc Glisse
2017-11-22  8:44             ` Marc Glisse
2017-11-22  9:05               ` Christophe Lyon
2017-11-26  0:54         ` Gerald Pfeifer
2017-11-27 15:48           ` David Malcolm
2017-11-27 16:08             ` Jakub Jelinek
2017-11-17 17:37     ` Joseph Myers
2017-11-17 17:52       ` Richard Biener
2017-11-17 17:54         ` DJ Delorie
2017-11-17 18:05           ` Joseph Myers
2017-11-18 10:34             ` Marc Glisse
2017-11-18 10:23           ` Marc Glisse
2017-11-17 17:57         ` Joseph Myers
2017-11-18 10:26     ` Marc Glisse
2017-11-18 12:18       ` Richard Biener

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CADzB+2mxsExjLKmFXnd3ZU6Q1QJGf=nzPnHsgz6AUh-yo74SsA@mail.gmail.com' \
    --to=jason@redhat.com \
    --cc=dj@redhat.com \
    --cc=enkovich.gnu@gmail.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=jakub@redhat.com \
    --cc=joseph@codesourcery.com \
    --cc=marc.glisse@inria.fr \
    --cc=richard.guenther@gmail.com \
    --cc=uweigand@de.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).