[Bug regression/40665] dereferencing type-punned pointer warnings cannot be disabled

2009-07-07 Thread manu at gcc dot gnu dot org


--- Comment #6 from manu at gcc dot gnu dot org  2009-07-07 10:25 ---
(In reply to comment #5)
 
 Thus code is undefined you have an acess of a char array as a struct.  
 Yes you are only taking the address of an element but it is still  
 considered an acess by the standards.

I see that users repeatedly fall for this. Could we detect what type is
accessed as what and provide an informative note? Something like:

warning: dereferencing type-punned pointer might break strict-aliasing rules
note: accessing 'char *' as 'structure *' is undefined

Andrew, do you think this would be difficult to implement?


-- 

manu at gcc dot gnu dot org changed:

   What|Removed |Added

 CC||manu at gcc dot gnu dot org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40665



[Bug regression/40665] dereferencing type-punned pointer warnings cannot be disabled

2009-07-07 Thread mikulas at artax dot karlin dot mff dot cuni dot cz


--- Comment #7 from mikulas at artax dot karlin dot mff dot cuni dot cz  
2009-07-07 16:31 ---
  extern int c;
  int a(void)
  {
 return *(short *)(void *)c;
  }

 This is a very bad example of a false positive as you are acessing an
 int as a short; that is undefined. I will look at your code later on,
 my laptop for home is currently broken.

Whether it is a false positive or not depends on the context.
For example, if I call function a() from function b():
int b(void)
{
c = 0x12345678;
__asm__ volatile (:::memory);
return a();
}
the code is valid and the function b() must return a fixed value depending on
the endianity of the machine. That __asm__ statement works as a barrier that
prevents the compiler from reordering two accesses to c.

So I am not against the warning. The warning is good. The problem is that there
is no way to shut up the warning.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40665



[Bug regression/40665] dereferencing type-punned pointer warnings cannot be disabled

2009-07-07 Thread pinskia at gcc dot gnu dot org


--- Comment #9 from pinskia at gcc dot gnu dot org  2009-07-07 16:54 ---
So you say that converting the char * pointer to struct * pointer is understood
as accessing the stored value by the standard?

No.
Let's look at the code:
char buffer[512];

(void *)((struct structure *)(void *)buffer)-x

You are accessing a character array via a struct structure and then taking
the address.  This why it is undefined.  Even though it does not look like an
access in the assembly as it is a-b is an addition, it is an access according
to the C/C++ standard.  Also aliasing is not transitive, that is you can access
anything via a character type but you cannot access a character by everything
(only character types themselves).


the code is valid and the function b() must return a fixed value depending on
the endianity of the machine. That __asm__ statement works as a barrier that
prevents the compiler from reordering two accesses to c.

Actually even with the memory barrier is still undefined according to the C/C++
standards, it does not mean we won't do what you expect but it means we don't
have to do what you expect it to do.  This is why we warn about it.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40665



[Bug regression/40665] dereferencing type-punned pointer warnings cannot be disabled

2009-07-07 Thread mikulas at artax dot karlin dot mff dot cuni dot cz


--- Comment #8 from mikulas at artax dot karlin dot mff dot cuni dot cz  
2009-07-07 16:45 ---
 Thus code is undefined you have an acess of a char array as a struct.
 Yes you are only taking the address of an element but it is still
 considered an acess by the standards.

Why is it undefined?

An object shall have its store value accessed only by an lvalue that has one
of the following types ... * a character type

So you say that converting the char * pointer to struct * pointer is understood
as accessing the stored value by the standard?

The only possible problem could be some hypothetical computer that cannot hold
misaligned pointers to structs (common computers allow unaligned pointers and
trap only on dereferencing unaligned pointers, not on generating them). But
once I know that I have a computer that allows unaligned pointers to structs,
there should be a method how to shut the warning up (with (void *) cast).


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40665



[Bug regression/40665] dereferencing type-punned pointer warnings cannot be disabled

2009-07-07 Thread mikulas at artax dot karlin dot mff dot cuni dot cz


--- Comment #10 from mikulas at artax dot karlin dot mff dot cuni dot cz  
2009-07-07 18:07 ---
So you mean that that -x operator is invalid and break the standard?

Anyway the standard means if you write your code according to the standard =
the code will run correctly, but the inverse implication doesn't apply. It is
sometimes required to break the C standard.

For example, you write unsigned char *framebuffer = vga_getgraphmem(); and
now you want to access the framebuffer. According to the standard, you could
only do it by bytes. But that means one bus cycle to the videocard for every
byte transfered. So people understand that common processors allow aligned
accesses to 2, 4 or 8 bytes and that common videocards have their framebuffer
base address aligned on same larger boundary --- and they simply cast the
pointer to u_int32_t or u_int64_t and access the videoram faster. Each time you
watch some video, remember those undefined memory accesses that are hapenning
for you to get faster performance :)

Another example --- the C standard says how it's not allowed to even produce a
pointer that points before the allocated array or more than one entry after the
last entry of the array and how it's not allowed to subtract two pointers from
different arrays. It is perfectly rational --- unless you are writing the
memory allocator itself! Then you inevitably must do some operations that are
considered undefined by the standard.

Regarding that int * to short * cast --- obviously, the code may run on some
computer that has tagged memory and traps if access with invalid type is done.
But common computers don't have tagged memory and the programmer should be
allowed to do such casts if he understands the implications (for example, if
its done only in arch-specific part of an operating system, it is perfectly
legal). So there should be a method to silence the warning.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40665



[Bug regression/40665] dereferencing type-punned pointer warnings cannot be disabled

2009-07-07 Thread pinskia at gcc dot gnu dot org


--- Comment #11 from pinskia at gcc dot gnu dot org  2009-07-07 18:18 
---
(In reply to comment #10)
 For example, you write unsigned char *framebuffer = vga_getgraphmem(); and
 now you want to access the framebuffer. According to the standard, you could
 only do it by bytes. But that means one bus cycle to the videocard for every
 byte transfered. So people understand that common processors allow aligned
 accesses to 2, 4 or 8 bytes and that common videocards have their framebuffer
 base address aligned on same larger boundary --- and they simply cast the
 pointer to u_int32_t or u_int64_t and access the videoram faster. Each time 
 you
 watch some video, remember those undefined memory accesses that are hapenning
 for you to get faster performance :)

Not fully, you missed part of the standard that takes about the effective type. 
Basically if there is no declared type for an object, the effective type is the
type which is used for storing and then only that can be read back with that
type or character type or the other cases the standard mentions.  The effective
type changes when another store happens.

In both of original cases in this bug report, there is a declared type which is
also the effective type.

And it is not about the cast between the pointer types which causes it to be
undefined but rather the accesses.  


-- 

pinskia at gcc dot gnu dot org changed:

   What|Removed |Added

 Status|UNCONFIRMED |RESOLVED
 Resolution||INVALID


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40665



[Bug regression/40665] dereferencing type-punned pointer warnings cannot be disabled

2009-07-07 Thread mikulas at artax dot karlin dot mff dot cuni dot cz


--- Comment #12 from mikulas at artax dot karlin dot mff dot cuni dot cz  
2009-07-07 19:40 ---
So if there was char *buffer = malloc(512) instead of char buffer[512], would
it be correct to cast it to the pointer to structure?

 And it is not about the cast between the pointer types which causes it to be
 undefined but rather the accesses.

What is considered the access in that code? Is it the - operator? 
operator? = operator? Cast operator? Or anything else?


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40665



[Bug regression/40665] dereferencing type-punned pointer warnings cannot be disabled

2009-07-07 Thread pinskia at gcc dot gnu dot org


--- Comment #13 from pinskia at gcc dot gnu dot org  2009-07-07 20:24 
---
(In reply to comment #12)
 So if there was char *buffer = malloc(512) instead of char buffer[512], would
 it be correct to cast it to the pointer to structure?

Yes.

  And it is not about the cast between the pointer types which causes it to be
  undefined but rather the accesses.
 
 What is considered the access in that code? Is it the - operator? 
 operator? = operator? Cast operator? Or anything else?

The following three operators are causes an access to happen even if  is used
afterwards:
-, ., and *

Thanks,
Andrew PInski


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40665



[Bug regression/40665] dereferencing type-punned pointer warnings cannot be disabled

2009-07-06 Thread mikulas at artax dot karlin dot mff dot cuni dot cz


--- Comment #1 from mikulas at artax dot karlin dot mff dot cuni dot cz  
2009-07-07 01:22 ---
Created an attachment (id=18145)
 -- (http://gcc.gnu.org/bugzilla/attachment.cgi?id=18145action=view)
a bug in -Wstrict-aliasing=3

This is an example of a flaw in -Wstrict-aliasing=3 (this mode is very bad,
produces many false positives on my project and I'm wondering why is it
default?)

Gcc man page says that -Wstrict-aliasing=3 produces less false positives than
-Wstrict-aliasing=2. This is counterexample, it produces type-punned warning
in -Wstrict-aliasing=3 mode and doesn't warn in -Wstrict-aliasing=2. I added
(void *) casts everywhere, but they don't quash the warning.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40665



[Bug regression/40665] dereferencing type-punned pointer warnings cannot be disabled

2009-07-06 Thread mikulas at artax dot karlin dot mff dot cuni dot cz


--- Comment #2 from mikulas at artax dot karlin dot mff dot cuni dot cz  
2009-07-07 01:34 ---
Created an attachment (id=18146)
 -- (http://gcc.gnu.org/bugzilla/attachment.cgi?id=18146action=view)
a bug in -Wstrict-aliasing=3

This is an example of a flaw in -Wstrict-aliasing=3 (this mode is very bad,
produces many false positives on my project and I'm wondering why is it
default?)

Gcc man page says that -Wstrict-aliasing=3 produces less false positives than
-Wstrict-aliasing=2. This is counterexample, it produces type-punned warning
in -Wstrict-aliasing=3 mode and doesn't warn in -Wstrict-aliasing=2. I added
(void *) casts everywhere, but they don't quash the warning.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40665



[Bug regression/40665] dereferencing type-punned pointer warnings cannot be disabled

2009-07-06 Thread pinskia at gmail dot com


--- Comment #3 from pinskia at gmail dot com  2009-07-07 03:44 ---
Subject: Re:   New: dereferencing type-punned pointer warnings cannot be
disabled



Sent from my iPhone

On Jul 6, 2009, at 6:12 PM, mikulas at artax dot karlin dot mff dot  
cuni dot cz gcc-bugzi...@gcc.gnu.org wrote:

 Gcc became recently (4.4) very bad regarding false positive type- 
 punned
 warnings. In previous versions, the warnings could be suppressed by  
 casting to
 (void *), in 3.x and 4.1 it worked perfectly, in 4.3 it still worked  
 somehow
 (except in -Wstrict-aliasing=3 mode), in 4.4 there are cases where  
 it doesn't
 work at all.

 I don't want to completely disable the warnings with -Wno-strict- 
 aliasing (this
 could leave bugs unnotified), but I need a method to disable them on
 case-by-case basis once I verified that the code in question is  
 correct.

 Simple example, compile with -O2 -Wall:

 extern int c;
 int a(void)
 {
return *(short *)(void *)c;
 }

This is a very bad example of a false positive as you are acessing an  
int as a short; that is undefined. I will look at your code later on,  
my laptop for home is currently broken.


 In 4.4 the warning can't be disabled at all! The (void *) cast  
 doesn't suppress
 the warning and none of three options to -Wstrict-aliasing helps. In  
 4.3 the
 cast to (void *) suppressed the warning in -Wstrict-aliasing 1,2  
 modes (and
 didn't suppress it in the default mode 3), in 4.4 the warning can't be
 suppressed at all.

 Gcc developers tried to made these warnings more intelligent with  
 less false
 positives, but unfortunatelly they completely broke the method to  
 disable them
 in the specific case. For me, false positives are not a major  
 problem --- when
 I get a false positive, I just read the code, check it and if I  
 conclude that
 it's OK, I disable the warning with (void *).

 But if there's no way to disable false positives, it makes the  
 warnings
 completely useless.


 -- 
   Summary: dereferencing type-punned pointer warnings cannot  
 be
disabled
   Product: gcc
   Version: 4.4.1
Status: UNCONFIRMED
  Severity: major
  Priority: P3
 Component: regression
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: mikulas at artax dot karlin dot mff dot cuni dot cz
 GCC build triplet: i686-pc-linux-gnu
  GCC host triplet: i686-pc-linux-gnu
 GCC target triplet: i686-pc-linux-gnu


 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40665



-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40665



Re: [Bug regression/40665] dereferencing type-punned pointer warnings cannot be disabled

2009-07-06 Thread Andrew Pinski



Sent from my iPhone

On Jul 6, 2009, at 6:34 PM, mikulas at artax dot karlin dot mff dot  
cuni dot cz gcc-bugzi...@gcc.gnu.org wrote:





--- Comment #2 from mikulas at artax dot karlin dot mff dot cuni  
dot cz  2009-07-07 01:34 ---

Created an attachment (id=18146)
-- (http://gcc.gnu.org/bugzilla/attachment.cgi?id=18146action=view)
a bug in -Wstrict-aliasing=3

This is an example of a flaw in -Wstrict-aliasing=3 (this mode is  
very bad,
produces many false positives on my project and I'm wondering why is  
it

default?)

Gcc man page says that -Wstrict-aliasing=3 produces less false  
positives than
-Wstrict-aliasing=2. This is counterexample, it produces type- 
punned warning
in -Wstrict-aliasing=3 mode and doesn't warn in -Wstrict-aliasing=2.  
I added

(void *) casts everywhere, but they don't quash the warning.


--


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40665



[Bug regression/40665] dereferencing type-punned pointer warnings cannot be disabled

2009-07-06 Thread pinskia at gmail dot com


--- Comment #4 from pinskia at gmail dot com  2009-07-07 03:48 ---
Subject: Re:  dereferencing type-punned pointer warnings cannot be disabled



Sent from my iPhone

On Jul 6, 2009, at 6:34 PM, mikulas at artax dot karlin dot mff dot  
cuni dot cz gcc-bugzi...@gcc.gnu.org wrote:



 --- Comment #2 from mikulas at artax dot karlin dot mff dot cuni  
 dot cz  2009-07-07 01:34 ---
 Created an attachment (id=18146)
 -- (http://gcc.gnu.org/bugzilla/attachment.cgi?id=18146action=view)
 -- (http://gcc.gnu.org/bugzilla/attachment.cgi?id=18146action=view)
 a bug in -Wstrict-aliasing=3

 This is an example of a flaw in -Wstrict-aliasing=3 (this mode is  
 very bad,
 produces many false positives on my project and I'm wondering why is  
 it
 default?)

 Gcc man page says that -Wstrict-aliasing=3 produces less false  
 positives than
 -Wstrict-aliasing=2. This is counterexample, it produces type- 
 punned warning
 in -Wstrict-aliasing=3 mode and doesn't warn in -Wstrict-aliasing=2.  
 I added
 (void *) casts everywhere, but they don't quash the warning.


 -- 


 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40665



-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40665



Re: [Bug regression/40665] dereferencing type-punned pointer warnings cannot be disabled

2009-07-06 Thread Andrew Pinski
Thus code is undefined you have an acess of a char array as a struct.  
Yes you are only taking the address of an element but it is still  
considered an acess by the standards.


Sent from my iPhone

On Jul 6, 2009, at 6:34 PM, mikulas at artax dot karlin dot mff dot  
cuni dot cz gcc-bugzi...@gcc.gnu.org wrote:





--- Comment #2 from mikulas at artax dot karlin dot mff dot cuni  
dot cz  2009-07-07 01:34 ---

Created an attachment (id=18146)
-- (http://gcc.gnu.org/bugzilla/attachment.cgi?id=18146action=view)
a bug in -Wstrict-aliasing=3

This is an example of a flaw in -Wstrict-aliasing=3 (this mode is  
very bad,
produces many false positives on my project and I'm wondering why is  
it

default?)

Gcc man page says that -Wstrict-aliasing=3 produces less false  
positives than
-Wstrict-aliasing=2. This is counterexample, it produces type- 
punned warning
in -Wstrict-aliasing=3 mode and doesn't warn in -Wstrict-aliasing=2.  
I added

(void *) casts everywhere, but they don't quash the warning.


--


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40665



[Bug regression/40665] dereferencing type-punned pointer warnings cannot be disabled

2009-07-06 Thread pinskia at gmail dot com


--- Comment #5 from pinskia at gmail dot com  2009-07-07 03:50 ---
Subject: Re:  dereferencing type-punned pointer warnings cannot be disabled

Thus code is undefined you have an acess of a char array as a struct.  
Yes you are only taking the address of an element but it is still  
considered an acess by the standards.

Sent from my iPhone

On Jul 6, 2009, at 6:34 PM, mikulas at artax dot karlin dot mff dot  
cuni dot cz gcc-bugzi...@gcc.gnu.org wrote:



 --- Comment #2 from mikulas at artax dot karlin dot mff dot cuni  
 dot cz  2009-07-07 01:34 ---
 Created an attachment (id=18146)
 -- (http://gcc.gnu.org/bugzilla/attachment.cgi?id=18146action=view)
 -- (http://gcc.gnu.org/bugzilla/attachment.cgi?id=18146action=view)
 a bug in -Wstrict-aliasing=3

 This is an example of a flaw in -Wstrict-aliasing=3 (this mode is  
 very bad,
 produces many false positives on my project and I'm wondering why is  
 it
 default?)

 Gcc man page says that -Wstrict-aliasing=3 produces less false  
 positives than
 -Wstrict-aliasing=2. This is counterexample, it produces type- 
 punned warning
 in -Wstrict-aliasing=3 mode and doesn't warn in -Wstrict-aliasing=2.  
 I added
 (void *) casts everywhere, but they don't quash the warning.


 -- 


 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40665



-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40665