public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Jason Merrill <jason@redhat.com>
To: Jakub Jelinek <jakub@redhat.com>
Cc: Jonathan Wakely <jwakely@redhat.com>, gcc-patches@gcc.gnu.org
Subject: Re: [PATCH] c++: v2: Add __builtin_bit_cast to implement std::bit_cast [PR93121]
Date: Wed, 25 Nov 2020 19:52:44 -0500	[thread overview]
Message-ID: <e2e097db-83da-6af6-28c7-9ef8b7ed6794@redhat.com> (raw)
In-Reply-To: <20201125185057.GK3788@tucnak>

On 11/25/20 1:50 PM, Jakub Jelinek wrote:
> On Wed, Nov 25, 2020 at 12:26:17PM -0500, Jason Merrill wrote:
>>> +		      if (DECL_BIT_FIELD (fld)
>>> +			  && DECL_NAME (fld) == NULL_TREE)
>>> +			continue;
>>
>> I think you want to check DECL_PADDING_P here; the C and C++ front ends set
>> it on unnamed bit-fields, and that's what is_empty_type looks at.
> 
> Ok, changed in my copy.  I'll also post a patch for
> __builtin_clear_padding to use DECL_PADDING_P in there instead of
> DECL_BIT_FIELD/DECL_NAME==NULL.
> 
>>> +      if (TREE_CODE (TREE_TYPE (arg)) == ARRAY_TYPE)
>>> +	{
>>> +	  /* Don't perform array-to-pointer conversion.  */
>>> +	  arg = mark_rvalue_use (arg, loc, true);
>>> +	  if (!complete_type_or_maybe_complain (TREE_TYPE (arg), arg, complain))
>>> +	    return error_mark_node;
>>> +	}
>>> +      else
>>> +	arg = decay_conversion (arg, complain);
>>
>> bit_cast operates on an lvalue argument, so I don't think we want
>> decay_conversion at all here.
>>
>>> +      if (error_operand_p (arg))
>>> +	return error_mark_node;
>>> +
>>> +      arg = convert_from_reference (arg);
>>
>> This shouldn't be necessary; the argument should already be converted from
>> reference.  Generally we call convert_from_reference on the result of some
>> processing, not on an incoming argument.
> 
> Removing these two regresses some tests in the testsuite.
> It is true that std::bit_cast's argument must be a reference, and so when
> one uses std::bit_cast one won't run into these problems, but the builtin's
> argument itself is an rvalue and so we need to deal with people calling it
> directly.
> So, commenting out the decay_conversion and convert_from_reference results
> in:
> extern V v;
> ...
>    __builtin_bit_cast (int, v);
> no longer being reported as invalid use of incomplete type, but
> error: '__builtin_bit_cast' source size '' not equal to destination type size '4'
> (note nothing in between '' for the size because the size is NULL).
> Ditto for:
> extern V *p;
> ...
>    __builtin_bit_cast (int, *p);
> I guess I could add some hand written code to deal with incomplete types
> to cure these.  But e.g. decay_conversion also calls mark_rvalue_use which
> we also need e.g. for -Wunused-but-set*, but don't we also need it e.g. for
> lambdas? The builtin is after all using the argument as an rvalue
> (reads it).

OK, it isn't exactly use as an rvalue, but I guess it's close enough to 
work.

> Another change that commenting out those two parts causes is different
> diagnostics on bit-cast4.C,
> bit-cast4.C:7:30: error: '__builtin_bit_cast' is not a constant expression because 'const int* const' is a pointer type
> bit-cast4.C:7:30: error: '__builtin_bit_cast' is not a constant expression because 'int D::* const' is a pointer to member type
> bit-cast4.C:7:30: error: '__builtin_bit_cast' is not a constant expression because 'int (D::* const)() const' is a pointer to member type
> The tests expect 'const int*', 'int D::*' and 'int (D::*)() const', i.e. the
> toplevel qualifiers stripped from those.
> Commenting out just the arg = convert_from_reference (arg); doesn't regress
> anything though, it is the decay_conversion.

Let's just drop that part, then.

>>> +/* Attempt to interpret aggregate of TYPE from bytes encoded in target
>>> +   byte order at PTR + OFF with LEN bytes.  MASK contains bits set if the value
>>> +   is indeterminate.  */
>>> +
>>> +static tree
>>> +cxx_native_interpret_aggregate (tree type, const unsigned char *ptr, int off,
>>> +				int len, unsigned char *mask,
>>> +				const constexpr_ctx *ctx, bool *non_constant_p,
>>> +				location_t loc)
>>
>> Can this be, say, native_interpret_initializer in fold-const?  It doesn't
>> seem closely tied to the front end other than diagnostics that could move to
>> the caller, like you've already done for the non-aggregate case.
> 
> The middle-end doesn't need it ATM for anything, plus I think the
> ctx/non_constant_p/loc and diagnostics is really C++ FE specific.
> If you really want it in fold-const.c, the only way I can imagine it is
> that it would be
> tree
> native_interpret_aggregate (tree type, const unsigned char *ptr, int off,
> 			    int len, unsigned char *mask = NULL,
> 			    tree (*mask_callback) (void *, int) = NULL,
> 			    void *mask_data = NULL)
> where C++ would call it with the mask argument, as mask_callback a FE function
> that would emit the diagnostics and decide what to return when mask is set
> on something, and mask_data would be a pointer to struct containing
> const constexpr_ctx *ctx; bool *non_constant_p; location_t loc;
> for it.

Instead of a callback, the function could express mask-related failure 
in a way that the caller can detect and diagnose.  Perhaps by clearing 
mask elements that correspond to padding in the output, so you can again 
just scan through the mask to see if there are any elements set?

Jason


  reply	other threads:[~2020-11-26  0:52 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-07-18 18:50 [PATCH] c++: " Jakub Jelinek
2020-07-22 14:03 ` Paul Koning
2020-07-30 14:16 ` Jason Merrill
2020-07-30 14:57   ` Jakub Jelinek
2020-07-30 21:59     ` Jason Merrill
2020-07-31  8:19       ` Jakub Jelinek
2020-07-31  9:54         ` Jonathan Wakely
2020-07-31 10:06           ` Jakub Jelinek
2020-07-31 20:28             ` Jason Merrill
2020-08-27 10:06               ` Jakub Jelinek
2020-08-27 10:19                 ` Richard Biener
2020-09-02 21:52                   ` Jason Merrill
2020-08-27 10:46                 ` Jakub Jelinek
2020-08-27 11:06                   ` Jonathan Wakely
2020-08-27 11:17                     ` Jakub Jelinek
2020-08-27 11:22                       ` Jonathan Wakely
2020-08-27 10:59                 ` Jonathan Wakely
2020-08-27 20:43                 ` Iain Buclaw
2020-11-02 19:21   ` [PATCH] c++: v2: " Jakub Jelinek
2020-11-25  0:31     ` Jeff Law
2020-11-25  9:23       ` Jakub Jelinek
2020-11-25 10:31         ` Jonathan Wakely
2020-11-25 16:24           ` Jakub Jelinek
2020-11-25 16:28             ` Jonathan Wakely
2020-11-25 17:26     ` Jason Merrill
2020-11-25 18:50       ` Jakub Jelinek
2020-11-26  0:52         ` Jason Merrill [this message]
2020-11-26 15:09           ` [PATCH] c++: v3: " Jakub Jelinek
2020-12-03 14:24             ` Jason Merrill

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=e2e097db-83da-6af6-28c7-9ef8b7ed6794@redhat.com \
    --to=jason@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=jakub@redhat.com \
    --cc=jwakely@redhat.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).