public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/18411] New: Warning not legitimate
@ 2004-11-09 23:23 manus at eiffel dot com
2004-11-09 23:29 ` [Bug c/18411] " pinskia at gcc dot gnu dot org
` (13 more replies)
0 siblings, 14 replies; 15+ messages in thread
From: manus at eiffel dot com @ 2004-11-09 23:23 UTC (permalink / raw)
To: gcc-bugs
I'm getting the following compilation warning output:
gcc -c a.c -save-temps
a.c: In function `g':
a.c:8: warning: function called through a non-compatible type
a.c:8: note: if this code is reached, the program will abort
while compiling the following code (content of a.i):
# 1 "a.c"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "a.c"
extern void f();
void g(char a) {
void * fnptr = f;
((void (*) (char)) fnptr) (a);
((void (*) (char)) f)(a);
}
It reports a warning when using `f' but not when using `fnptr'. This is rather
strange and not expected.
Why is it so?
gcc --version is:
gcc (GCC) 3.4.2 20041017 (Red Hat 3.4.2-6.fc3)
Copyright (C) 2004 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
and was compiled on a AMD64 machine using Linux Fedora Core 3 for x86_64:
uname -a
Linux madrid.ise 2.6.9-1.667 #1 Tue Nov 2 14:50:10 EST 2004 x86_64 x86_64
x86_64 GNU/Linux
Thanks,
Manu
--
Summary: Warning not legitimate
Product: gcc
Version: 3.4.2
Status: UNCONFIRMED
Severity: normal
Priority: P2
Component: c
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: manus at eiffel dot com
CC: gcc-bugs at gcc dot gnu dot org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18411
^ permalink raw reply [flat|nested] 15+ messages in thread
* [Bug c/18411] Warning not legitimate
2004-11-09 23:23 [Bug c/18411] New: Warning not legitimate manus at eiffel dot com
@ 2004-11-09 23:29 ` pinskia at gcc dot gnu dot org
2004-11-09 23:32 ` manus at eiffel dot com
` (12 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2004-11-09 23:29 UTC (permalink / raw)
To: gcc-bugs
------- Additional Comments From pinskia at gcc dot gnu dot org 2004-11-09 23:29 -------
The warning is correct:
extern void f();
void g(void)
{
((void (*) (char)) f)(a);
}
this is undefined code which means we could anything at runtime (even wipe out your HD).
--
What |Removed |Added
----------------------------------------------------------------------------
Status|UNCONFIRMED |RESOLVED
Resolution| |INVALID
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18411
^ permalink raw reply [flat|nested] 15+ messages in thread
* [Bug c/18411] Warning not legitimate
2004-11-09 23:23 [Bug c/18411] New: Warning not legitimate manus at eiffel dot com
2004-11-09 23:29 ` [Bug c/18411] " pinskia at gcc dot gnu dot org
@ 2004-11-09 23:32 ` manus at eiffel dot com
2004-11-09 23:34 ` manus at eiffel dot com
` (11 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: manus at eiffel dot com @ 2004-11-09 23:32 UTC (permalink / raw)
To: gcc-bugs
------- Additional Comments From manus at eiffel dot com 2004-11-09 23:32 -------
This is not undefined, I know which feature I'm calling. It is `f'. Moreover I
provide the right function cast which matches how `f' is actually declared.
What strikes me the most is that you reject:
((void (*) (char)) f)(a);
but allow:
void * fnptr = f;
((void (*) (char)) fnptr)(a);
This is rather surprising.
Regards,
Manu
--
What |Removed |Added
----------------------------------------------------------------------------
Status|RESOLVED |UNCONFIRMED
Resolution|INVALID |
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18411
^ permalink raw reply [flat|nested] 15+ messages in thread
* [Bug c/18411] Warning not legitimate
2004-11-09 23:23 [Bug c/18411] New: Warning not legitimate manus at eiffel dot com
2004-11-09 23:29 ` [Bug c/18411] " pinskia at gcc dot gnu dot org
2004-11-09 23:32 ` manus at eiffel dot com
@ 2004-11-09 23:34 ` manus at eiffel dot com
2004-11-09 23:48 ` joseph at codesourcery dot com
` (10 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: manus at eiffel dot com @ 2004-11-09 23:34 UTC (permalink / raw)
To: gcc-bugs
------- Additional Comments From manus at eiffel dot com 2004-11-09 23:34 -------
Also one thing I forgot to add. Is that if you replace `char' by `int' then
there is no warning at all:
extern void f();
void g(int a) {
void * fnptr = f;
((void (*) (int)) fnptr) (a); /* Ok. */
((void (*) (int)) f)(a); /* Not Ok. */
}
Why `char' does trigger the warning and not `int'? This looks like a bug to
me.
Thanks,
Manu
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18411
^ permalink raw reply [flat|nested] 15+ messages in thread
* [Bug c/18411] Warning not legitimate
2004-11-09 23:23 [Bug c/18411] New: Warning not legitimate manus at eiffel dot com
` (2 preceding siblings ...)
2004-11-09 23:34 ` manus at eiffel dot com
@ 2004-11-09 23:48 ` joseph at codesourcery dot com
2004-11-09 23:51 ` pinskia at gcc dot gnu dot org
` (9 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: joseph at codesourcery dot com @ 2004-11-09 23:48 UTC (permalink / raw)
To: gcc-bugs
------- Additional Comments From joseph at codesourcery dot com 2004-11-09 23:47 -------
Subject: Re: Warning not legitimate
On Tue, 9 Nov 2004, manus at eiffel dot com wrote:
> extern void f();
>
> void g(int a) {
> void * fnptr = f;
>
> ((void (*) (int)) fnptr) (a); /* Ok. */
If you want diagnostics for conversions between object and function
pointers, use -pedantic.
> ((void (*) (int)) f)(a); /* Not Ok. */
> }
>
> Why `char' does trigger the warning and not `int'? This looks like a bug to
> me.
The function type compatibility rules are defined in C99 6.7.5.3#15. In
particular:
If one type has a parameter type list and the other
type is specified by a function declarator that is not part
of a function definition and that contains an empty
identifier list, the parameter list shall not have an
ellipsis terminator and the type of each parameter shall be
compatible with the type that results from the application
of the default argument promotions.
char promotes to int under the default argument promotions, and char and
int are not compatible, whereas int promotes to itself.
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18411
^ permalink raw reply [flat|nested] 15+ messages in thread
* [Bug c/18411] Warning not legitimate
2004-11-09 23:23 [Bug c/18411] New: Warning not legitimate manus at eiffel dot com
` (3 preceding siblings ...)
2004-11-09 23:48 ` joseph at codesourcery dot com
@ 2004-11-09 23:51 ` pinskia at gcc dot gnu dot org
2004-11-10 0:42 ` manus at eiffel dot com
` (8 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2004-11-09 23:51 UTC (permalink / raw)
To: gcc-bugs
------- Additional Comments From pinskia at gcc dot gnu dot org 2004-11-09 23:51 -------
As said before this is undefined code.
--
What |Removed |Added
----------------------------------------------------------------------------
Status|UNCONFIRMED |RESOLVED
Resolution| |INVALID
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18411
^ permalink raw reply [flat|nested] 15+ messages in thread
* [Bug c/18411] Warning not legitimate
2004-11-09 23:23 [Bug c/18411] New: Warning not legitimate manus at eiffel dot com
` (4 preceding siblings ...)
2004-11-09 23:51 ` pinskia at gcc dot gnu dot org
@ 2004-11-10 0:42 ` manus at eiffel dot com
2004-11-10 0:48 ` pinskia at gcc dot gnu dot org
` (7 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: manus at eiffel dot com @ 2004-11-10 0:42 UTC (permalink / raw)
To: gcc-bugs
------- Additional Comments From manus at eiffel dot com 2004-11-10 00:42 -------
Thanks for your answer. I see that following the ANSI C standard forces you to
do something. But I believe the right thing to do is:
1 - make it a compile time error (better to catch those errors at compile time
rather than at run-time, like I did)
2 - make it a warning and generates the code that gcc generated in the past and
that has been working for as long as I remember.
But definitely don't do:
- produces a warning and generate code that will crash your program at run-time.
I'm definitely in favor of 2 as it would permit the code I have to continue to
work, especially when I know that I provide all the type information to the C
compiler so that it can generate the right code.
Hopefully someone will listen or convince me otherwise
With best regards,
Manu
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18411
^ permalink raw reply [flat|nested] 15+ messages in thread
* [Bug c/18411] Warning not legitimate
2004-11-09 23:23 [Bug c/18411] New: Warning not legitimate manus at eiffel dot com
` (5 preceding siblings ...)
2004-11-10 0:42 ` manus at eiffel dot com
@ 2004-11-10 0:48 ` pinskia at gcc dot gnu dot org
2004-11-10 0:59 ` manus at eiffel dot com
` (6 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2004-11-10 0:48 UTC (permalink / raw)
To: gcc-bugs
------- Additional Comments From pinskia at gcc dot gnu dot org 2004-11-10 00:47 -------
We cannot do 1 as that is not allowed by the C standard (or at least a DR report of it). Also the reason
why this was changed was because the tree inliner was crashing on things like this if the type was float
and the real argument was int. The correct thing to do is do a correct prototype aka
void f(short); in the first place, other wise the code will not work anyways on some targets where int is
passed one way and short are passed another or var args are done one way and normal arguments are
done another way, this does happen which is why this is undefined in the first place in C.
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18411
^ permalink raw reply [flat|nested] 15+ messages in thread
* [Bug c/18411] Warning not legitimate
2004-11-09 23:23 [Bug c/18411] New: Warning not legitimate manus at eiffel dot com
` (6 preceding siblings ...)
2004-11-10 0:48 ` pinskia at gcc dot gnu dot org
@ 2004-11-10 0:59 ` manus at eiffel dot com
2004-11-10 1:15 ` joseph at codesourcery dot com
` (5 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: manus at eiffel dot com @ 2004-11-10 0:59 UTC (permalink / raw)
To: gcc-bugs
------- Additional Comments From manus at eiffel dot com 2004-11-10 00:59 -------
Ok, so why don't you generate the warning only when it makes sense. In my
original case, I was passing a char and tell the C compiler it was a function
pointer expecting a char. In this scenario it should not produce any warning.
If you have incompatible types (such as int where you expect a float/double)
then I'm ok that you generate a warning (although I would prefer an error since
the generated code is incorrect).
Or better, if possible, try to fix the inliner issue.
Thanks,
Manu
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18411
^ permalink raw reply [flat|nested] 15+ messages in thread
* [Bug c/18411] Warning not legitimate
2004-11-09 23:23 [Bug c/18411] New: Warning not legitimate manus at eiffel dot com
` (7 preceding siblings ...)
2004-11-10 0:59 ` manus at eiffel dot com
@ 2004-11-10 1:15 ` joseph at codesourcery dot com
2004-11-10 1:25 ` manus at eiffel dot com
` (4 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: joseph at codesourcery dot com @ 2004-11-10 1:15 UTC (permalink / raw)
To: gcc-bugs
------- Additional Comments From joseph at codesourcery dot com 2004-11-10 01:15 -------
Subject: Re: Warning not legitimate
On Wed, 10 Nov 2004, manus at eiffel dot com wrote:
> Ok, so why don't you generate the warning only when it makes sense. In my
> original case, I was passing a char and tell the C compiler it was a function
> pointer expecting a char. In this scenario it should not produce any warning.
There is a limit to how much we care about code with undefined behavior on
execution. What type you pass in the source code is a red herring; if you
cast to a prototype type then the arguments will be getting converted to
that type, including if you'd passed a float argument. We aim for the
front end to pass down type-consistent code to the rest of the compiler
(which ideally would never need to call back into the earlier parts of the
compiler); where the standard requires type-inconsistent code to be
compiled but gives it execution-time undefined behavior, the only sensible
consistent structure for the rest of the compiler involves an abort in
place of the nonsensical code.
> If you have incompatible types (such as int where you expect a float/double)
> then I'm ok that you generate a warning (although I would prefer an error since
> the generated code is incorrect).
Remember DR#109:
A conforming implementation must not fail to translate a strictly
conforming program simply because *some* possible execution of that
program would result in undefined behavior.
The undefined behavior is only on execution, so the program must be
accepted. Because its execution is nonsensical - has no meaning whatever
- an abort is generated.
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18411
^ permalink raw reply [flat|nested] 15+ messages in thread
* [Bug c/18411] Warning not legitimate
2004-11-09 23:23 [Bug c/18411] New: Warning not legitimate manus at eiffel dot com
` (8 preceding siblings ...)
2004-11-10 1:15 ` joseph at codesourcery dot com
@ 2004-11-10 1:25 ` manus at eiffel dot com
2004-11-10 1:26 ` pinskia at gcc dot gnu dot org
` (3 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: manus at eiffel dot com @ 2004-11-10 1:25 UTC (permalink / raw)
To: gcc-bugs
------- Additional Comments From manus at eiffel dot com 2004-11-10 01:24 -------
I believe we do not have the right definition of unspecified behavior. Going
back to my initial post:
extern void f();
void g(char a) {
((void (*) (char)) f)(a);
}
Knowing that actually `f' has been declared in some other module as:
extern void f(char){...}
Then the above code "((void (*) (char)) f)(a);" make sense. I'm simply calling
`f' with the right type for the argument thanks to the function cast.
Could you point out where the undefined part is?
Thanks,
Manu
PS: sorry to be so picky on this issue but I feel it is important.
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18411
^ permalink raw reply [flat|nested] 15+ messages in thread
* [Bug c/18411] Warning not legitimate
2004-11-09 23:23 [Bug c/18411] New: Warning not legitimate manus at eiffel dot com
` (9 preceding siblings ...)
2004-11-10 1:25 ` manus at eiffel dot com
@ 2004-11-10 1:26 ` pinskia at gcc dot gnu dot org
2004-11-10 1:41 ` joseph at codesourcery dot com
` (2 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2004-11-10 1:26 UTC (permalink / raw)
To: gcc-bugs
------- Additional Comments From pinskia at gcc dot gnu dot org 2004-11-10 01:26 -------
extern void f();
really means
extern void f(...);
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18411
^ permalink raw reply [flat|nested] 15+ messages in thread
* [Bug c/18411] Warning not legitimate
2004-11-09 23:23 [Bug c/18411] New: Warning not legitimate manus at eiffel dot com
` (10 preceding siblings ...)
2004-11-10 1:26 ` pinskia at gcc dot gnu dot org
@ 2004-11-10 1:41 ` joseph at codesourcery dot com
2004-11-11 20:04 ` manus at eiffel dot com
2005-07-04 1:38 ` SebastianR at gmx dot de
13 siblings, 0 replies; 15+ messages in thread
From: joseph at codesourcery dot com @ 2004-11-10 1:41 UTC (permalink / raw)
To: gcc-bugs
------- Additional Comments From joseph at codesourcery dot com 2004-11-10 01:41 -------
Subject: Re: Warning not legitimate
On Wed, 10 Nov 2004, manus at eiffel dot com wrote:
> I believe we do not have the right definition of unspecified behavior. Going
We're talking about undefined behavior (e.g. your computer, or the whole
universe, may blow up) rather than unspecified (bounded variation on what
may happen).
> extern void f();
> Knowing that actually `f' has been declared in some other module as:
> extern void f(char){...}
Those types are incompatible, 6.7.5.3#15, so you have undefined behavior
by 6.2.7#2. In that case - if the compiler can see both the declaration
and definition in different translation units at once - it is compile-time
undefined (a property of the program, rather than of some execution path,
is undefined), so the program can be rejected. But when compiling only
the translation unit with the unprototyped declaration, it's possible that
(a) the call through the cast pointer is never executed, (b) the real
definition is of a compatible type e.g. void f(void) { ... } so there is
only undefined behavior on execution, not compilation. What is true is
that given the first translation unit with call through a cast to an
incompatible type, the behavior on execution of the call is guaranteed to
be undefined if the behavior on translation wasn't already.
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18411
^ permalink raw reply [flat|nested] 15+ messages in thread
* [Bug c/18411] Warning not legitimate
2004-11-09 23:23 [Bug c/18411] New: Warning not legitimate manus at eiffel dot com
` (11 preceding siblings ...)
2004-11-10 1:41 ` joseph at codesourcery dot com
@ 2004-11-11 20:04 ` manus at eiffel dot com
2005-07-04 1:38 ` SebastianR at gmx dot de
13 siblings, 0 replies; 15+ messages in thread
From: manus at eiffel dot com @ 2004-11-11 20:04 UTC (permalink / raw)
To: gcc-bugs
------- Additional Comments From manus at eiffel dot com 2004-11-11 20:04 -------
Sorry to come back and buzz you again. I just realized that because of this
change in behavior of gcc you broke not just my code, but also the code of the
people using our Eiffel compiler. Indeed our compiler generates C code that is
compiled most of the time with `gcc'. If people upgrade their `gcc' compiler to
3.4 then the generated code compiles but does not work anymore since it will
raise an exception.
You said that raising the exception was an acceptable solution for an undefined
behavior per the C99 standard. However what you just did is to break existing
code that relied on previous implementation of `gcc' (I can tell that we have
using this scheme for more than 10 years) and thus this is something for which
it might be good to go back to the previous code generation/behavior.
If the previous behavior made the inliner crash, then you can either fix it, or
consider that a crash is simply a symptom of undefined behavior and therefore
you are still compliant to the standard.
With best regards,
Manu
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18411
^ permalink raw reply [flat|nested] 15+ messages in thread
* [Bug c/18411] Warning not legitimate
2004-11-09 23:23 [Bug c/18411] New: Warning not legitimate manus at eiffel dot com
` (12 preceding siblings ...)
2004-11-11 20:04 ` manus at eiffel dot com
@ 2005-07-04 1:38 ` SebastianR at gmx dot de
13 siblings, 0 replies; 15+ messages in thread
From: SebastianR at gmx dot de @ 2005-07-04 1:38 UTC (permalink / raw)
To: gcc-bugs
------- Additional Comments From SebastianR at gmx dot de 2005-07-04 01:38 -------
I think there might be an actual bug with this new warning:
In the qsort man page, it says you can use strcmp as the last argument to qsort.
So the types must be compatible, and it also works. However, this fails:
((int(*)(const void *, const void *)) strcmp) ("a", "b");
The type conversion is exactly the same, only this time it is called directly.
I think this bug/feature is really annoying, especially (as already said) the
fact that it compiles but crashes at run time.
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18411
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2005-07-04 1:38 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-11-09 23:23 [Bug c/18411] New: Warning not legitimate manus at eiffel dot com
2004-11-09 23:29 ` [Bug c/18411] " pinskia at gcc dot gnu dot org
2004-11-09 23:32 ` manus at eiffel dot com
2004-11-09 23:34 ` manus at eiffel dot com
2004-11-09 23:48 ` joseph at codesourcery dot com
2004-11-09 23:51 ` pinskia at gcc dot gnu dot org
2004-11-10 0:42 ` manus at eiffel dot com
2004-11-10 0:48 ` pinskia at gcc dot gnu dot org
2004-11-10 0:59 ` manus at eiffel dot com
2004-11-10 1:15 ` joseph at codesourcery dot com
2004-11-10 1:25 ` manus at eiffel dot com
2004-11-10 1:26 ` pinskia at gcc dot gnu dot org
2004-11-10 1:41 ` joseph at codesourcery dot com
2004-11-11 20:04 ` manus at eiffel dot com
2005-07-04 1:38 ` SebastianR at gmx dot de
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).