Re: [std-discussion] Is this union aliasing code well-defined?

2017-10-29 Thread Richard Biener
On October 29, 2017 2:46:42 AM GMT+01:00, Yubin Ruan  
wrote:
>On 10/27/2017 04:54 PM, Richard Biener wrote:
>> On Fri, Oct 27, 2017 at 3:00 PM, Yubin Ruan 
>wrote:
>>> +Cc gcc-list.
>>>
>>> Does any gcc developer have any comments?
>> 
>> See PR82224.  The code is valid.
>> 
>>> On Mon, Sep 25, 2017 at 01:41:55PM -0700, Myriachan wrote:
 This question that "supercat" posted on Stack Overflow ran into an
 interesting problem:


>https://stackoverflow.com/questions/46205744/is-this-use-of-unions-strictly-conforming/

 A copy of the code involved is as follows:

 struct s1 {unsigned short x;};
 struct s2 {unsigned short x;};
 union s1s2 { struct s1 v1; struct s2 v2; };

 static int read_s1x(struct s1 *p) { return p->x; }
 static void write_s2x(struct s2 *p, int v) { p->x=v;}

 int test(union s1s2 *p1, union s1s2 *p2, union s1s2 *p3)
 {
   if (read_s1x(&p1->v1))
   {
 unsigned short temp;
 temp = p3->v1.x;
 p3->v2.x = temp;
 write_s2x(&p2->v2,1234);
 temp = p3->v2.x;
 p3->v1.x = temp;
   }
   return read_s1x(&p1->v1);
 }
 int test2(int x)
 {
   union s1s2 q[2];
   q->v1.x = 4321;
   return test(q,q+x,q+x);
 }
 #include 
 int main(void)
 {
   printf("%d\n",test2(0));
 }


 Both GCC and Clang in -fstrict-aliasing mode with optimizations are
>acting
 as if they ran into undefined behavior, and return 4321 instead of
>the
 expected 1234.  This happens in both C and C++ mode.  Intel C++ and
>Visual
 C++ return the expected 1234.  All four compilers hardwire the
>result as a
 constant parameter to printf rather than call test2 or modify
>memory at
 runtime.

 From my reading of the C++ Standard, particularly [class.union]/5,
 assignment expressions through a union member access changes the
>active
 member of the union (if the union member has a trivial default
>constructor,
 which it does here, being C code).  Taking the address of p2->v2
>and p1->v1
 ought to be legal because those are the active members of the union
>at the
 time their pointers are taken.

 Is this a well-defined program, or is there subtle undefined
>behavior
 happening here?
>
>Thanks.
>
>As put in my stackoverflow answer[1], I believe this behavior is
>specified in
>the GCC-online-doc, in section `-fstrict-alisgin'[2]:
>
>Pay special attention to code like this:
>
>union a_union {
>  int i;
>  double d;
>};
>
>int f() {
>  union a_union t;
>  t.d = 3.0;
>  return t.i;
>}
>
>The practice of reading from a different union member than the one most
>recently written to (called *type-punning*) is common. Even with
>   *-fstrict-aliasing*, type-punning is allowed, provided the memory is
> accessed through the union type. So, the code above works as expected.
>See Structures unions enumerations and bit-fields implementation.
>However, this code might not: 
>
>int f() {
>   union a_union t;
>   int* ip;
>   t.d = 3.0;
>   ip = &t.i;
>   return *ip;
>}

The difference is that in the original example the dynamic type of the memory 
is changed by a store to the union member via the union type. So this doesn't 
apply. 

Richard. 

> Similarly, access by taking the address, casting the resulting pointer
>  and dereferencing the result has undefined behavior, even if the cast
>uses a union type, e.g.: 
>
>int f() {
>  double d = 3.0;
>  return ((union a_union *) &d)->i;
>}
>
>The -fstrict-aliasing option is enabled at levels -O2, -O3, -Os.
>
>I think the second example above is similar to the OP's question
>(although the
>C standard might not say so... so from my perspective if the second
>example
>above is true, the OP's code is invalid.
>
>Do anyone have any comment?
>
>Yubin
>
>[1]:
>https://stackoverflow.com/questions/46205744/is-this-use-of-unions-strictly-conforming/46968235?noredirect=1#comment80930683_46968235
>[2]: https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html



Re: [std-discussion] Is this union aliasing code well-defined?

2017-10-29 Thread Jeffrey Walton
On Fri, Oct 27, 2017 at 9:00 AM, Yubin Ruan  wrote:
> ...
> On Mon, Sep 25, 2017 at 01:41:55PM -0700, Myriachan wrote:
>> This question that "supercat" posted on Stack Overflow ran into an
>> interesting problem:
>>
>> https://stackoverflow.com/questions/46205744/is-this-use-of-unions-strictly-conforming/
>>
>> A copy of the code involved is as follows:
>>
>> struct s1 {unsigned short x;};
>> struct s2 {unsigned short x;};
>> union s1s2 { struct s1 v1; struct s2 v2; };
>>
>> static int read_s1x(struct s1 *p) { return p->x; }
>> static void write_s2x(struct s2 *p, int v) { p->x=v;}
>>
>> int test(union s1s2 *p1, union s1s2 *p2, union s1s2 *p3)
>> {
>>   if (read_s1x(&p1->v1))
>>   {
>> unsigned short temp;
>> temp = p3->v1.x;
>> p3->v2.x = temp;
>> write_s2x(&p2->v2,1234);
>> temp = p3->v2.x;
>> p3->v1.x = temp;
>>   }
>>   return read_s1x(&p1->v1);
>> }
>> int test2(int x)
>> {
>>   union s1s2 q[2];
>>   q->v1.x = 4321;
>>   return test(q,q+x,q+x);
>> }
>> #include 
>> int main(void)
>> {
>>   printf("%d\n",test2(0));
>> }
>>
>>
>> Both GCC and Clang in -fstrict-aliasing mode with optimizations are acting
>> as if they ran into undefined behavior, and return 4321 instead of the
>> expected 1234.  This happens in both C and C++ mode.  Intel C++ and Visual
>> C++ return the expected 1234.  All four compilers hardwire the result as a
>> constant parameter to printf rather than call test2 or modify memory at
>> runtime.

C++ is different than C, and C++ is more strict. Unlike C, you cannot
access the inactive members of a union in C++. It is undefined
behavior.

If you compile with Sun's C++ compiler it actually issues a warning
for doing so. Clang, GCC, ICC and MSVC does not issue a warning.

Also see 
https://stackoverflow.com/questions/11373203/accessing-inactive-union-member-and-undefined-behavior.

Jeff


Re: Problems in IPA passes

2017-10-29 Thread Kugan Vivekanandarajah
Hi Jeff,

On 28 October 2017 at 18:28, Jeff Law  wrote:
>
> Jan,
>
> What's the purpose behind calling vrp_meet and
> extract_range_from_unary_expr from within the IPA passes?

This is used such that when we have an argument to a function and this
for which we know the VR and this intern is passed as a parameter to
another. For example:

void foo (int i)
{
...
  bar (unary_op (i))
...
}

This is mainly to share what is done in tree-vrp.
>
> AFAICT that is not safe to do.  Various paths through those routines
> will access static objects within tree-vrp.c which may not be
> initialized when IPA runs (vrp_equiv_obstack, vr_value).

IPA-VRP does not track equivalence and vr_value is not used.

Thanks,
Kugan

>
> While this seems to be working today, it's a failure waiting to happen.
>
> Is there any way you can avoid using those routines?  I can't believe
> you really need all the complexity of those routines, particularly
> extract_range_from_unary_expr.  Plus it's just downright fugly from a
> modularity standpoint.
>
>
> ?
>
> Jeff


gcc-8-20171029 is now available

2017-10-29 Thread gccadmin
Snapshot gcc-8-20171029 is now available on
  ftp://gcc.gnu.org/pub/gcc/snapshots/8-20171029/
and on various mirrors, see http://gcc.gnu.org/mirrors.html for details.

This snapshot has been generated from the GCC 8 SVN branch
with the following options: svn://gcc.gnu.org/svn/gcc/trunk revision 254205

You'll find:

 gcc-8-20171029.tar.xzComplete GCC

  SHA256=77d7b00d24911bfc7b6f15a19191a8d7341844fd8a0ba1187ce34e4b832a
  SHA1=5b8ca9ff022c97e2a1752fcfbbe7613ae05ff113

Diffs from 8-20171022 are available in the diffs/ subdirectory.

When a particular snapshot is ready for public consumption the LATEST-8
link is updated and a message is sent to the gcc list.  Please do not use
a snapshot before it has been announced that way.


Re: [std-discussion] Is this union aliasing code well-defined?

2017-10-29 Thread Hyman Rosen
In math, once you reach a contradiction, you realize that one of your
premises was false.  In religion, once you reach a contradiction, you
write books of theology to paper over the mess.  I guess we know
what category type-based alias analysis falls under.