This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [gimple] assignments to volatile


On Jun 24, 2010, at 11:50 PM, Nathan Sidwell wrote:
> On 06/24/10 19:38, Mike Stump wrote:
>> On Jun 24, 2010, at 7:32 AM, Mark Mitchell wrote:
>>> Mike Stump wrote:
>>> 
>>>>> x = y = z;
>>>>> 
>>>>> where "y" is volatile?
>>> 
>>>> C++ requires a re-read of y, the patch was going to remove the
>>>> re-read, I objected because the patch then makes the compiler not
>>>> conform to the C++ standard.
>>> 
>>> I think that you have to read rather a lot into the C++ standard to
>>> arrive at that conclusion.
>> 
>> I disagree.  It we meant to create a temporary for a = b = c, when a b and c are all class types, we would have listed 5.17 in 12.2.  Do you know of any C++ compilers that so create a temporary?  g++ certainly doesn't.  Now, compare 6.6.3.  It can create a temporary, and it does list 12.2, and is listed by 12.2.
> 
> We were talking about scalars.

I don't find any limitation in 5.17 to scalars or to objects of class type.  If you examine the wording in 8.5.3 for example, a place that we all know does create temporaries:

    --Otherwise, a temporary of type "cv1 T1" is created and initialized
      from  the  initializer expression using the rules for a non-refer-
      ence copy initialization  (_dcl.init_).   The  reference  is  then
      bound  to  the  temporary.

we can see the usual language the standard uses to create temporaries.  It _must_ do this, so that the results of == on &lval can be defined.  We use 12.2 as a proxy to find places in the standard that create temporaries.  One can also just search the standard for the word temporary, if one wanted to.  Since 5.17 doesn't distinguish between class nor scalars, we are free to use the semantics of class types to better understand the semantics for scalars.  These semantics _must_ be the same, because there is no stated difference.  The standard is not meant to be misread.  It isn't formal enough to withstand people intentionally or otherwise, misreading it.

So, what we are talking about are the semantics of 5.17, and those are not limited to scalars.

> volatile structs are treated differently.

In a = vob = c; stucts are treated the same.  This is the case we were discussing.  We can know that, because it appears on the 6th lines of this email.

>  I think the behaviour of volatile structs in C++ is too ill-specified to meaningfully talk about when accesses to the members occur.

Again, I disagree.  We could embark upon what the standard says, but, let's just agree to not, unless someone wants to learn what it says, or someone wants to change the status quo behavior in a way that deviates from the standard.

> I think the goal should be to make accesses to volatile scalars, as used when poking at hardware, follow simple, composable, consistent rules.

Yeah, the problem with that is implicit in that, is, I want to make the compiler agree to the ruleset I just invented because I like it, and if we do that, the semantics then change day by day, by the whim of the person doing the patch today, and the each implementor gets to choose a different rule, and the users don't benefit.  The other possibility is to make it conform to the language standard, when reasonable.  I think the later is the best option.  No one has argued that they understand what the standard says and want to intentionally deviate from it, nor have they stated a good reason for doing that.

So, could you please restate what you want to do.  Do you want gcc to follow the language standard, or, would you rather ignore the standard and just invent some rules on the fly for gcc to follow?

>  IMHO the current implemented behaviour is none of those.

Concerning:

Sometimes we re-read the assigned-to object, and sometimes we do not.  For instance,
  return vobj = data;
will cause a reread of vobj, IF data is not a constant.

the proper solution is to make it always reread vobj.  Simple and consistent, while matching the standard, no?

This sort of bug happens because people forget the, this optimization isn't valid when TREE_THIS_VOLATILE is set.  The solution is to add the missing check.  We know it is the optimizer, as if you replace the constant with anything but a constant, we get the proper semantics.  That's proof positive that the bug lies no in the semantics of all other cases, but rather the semantics of the constant case.

>> j is re-read.  It is re-read regardless if j=0, or j=k is used in the source.  Now, for the simpler:
>> 
>> volatile int i, j, k;
>> volatile int vi;
>> void foo(int p) {
>>   i ? j=0 : 0;
>> }
>> 
>> neither gcc nor g++ re-reads, and I'm not arguing changing that.  Nor is anyone suggesting changing that, so I don't see the point of asking.  I'm dodging what the standard says, well, unless someone wants to propose we change how they behave currently.
> 
> But gcc does reread when assigning a non-constant value.  As I pointed out, GCC's behaviour is inconsistent.

Ah, I want hoping to avoid that case...  Oh well...  [ pause ]

g++ doesn't reread in that case.  :-)  I think that matches the language standard 5.16:

4 If  the  second and third operands are lvalues and have the same type,
  the result is of that type and is an lvalue.

and no decay, no access.  I don't see that as problematic.  gcc does access, and I think that follows the C standard.  When exploring it, we find only constants screw it up, so the bug again, is in the optimizer, and the code missing is the one that says, don't do this optimization when volatile.  When that bug is fixed, gcc (c language) is then consistent with itself.

As for the inconsistency between C and C++.  I don't feel as strongly on how to resolve this.  I might vote to leave the g++ hack out here, but if people wanted the hack to be all lvalues cast to void are converted to rvalues, I don't feel strongly enough to oppose, though, I wish people would rather hit up the C and C++ people, lock them in a room, and say you can't come out until one of you relents.  I'd also be ok with it being a hard error, as this can be refined later when the standards people agree on a consistent semantic.  Hard error (off with pedantic) or a note might  be my preferred solution.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]