The gcc documentation, section "Declaring Attributes of Functions", states about the __attribute__ ((__warning__ ("..."))) of a function: "If this attribute is used on a function declaration and a call to such a function is not eliminated through dead code elimination or other optimizations, a warning which will include MESSAGE will be diagnosed." Here is a case where the warning is diagnosed although the program contains no direct call to the function: =========================== main.cc =========================== extern "C" int close(int); static int (*safe_close) (int fd) = close; extern __typeof__ (close) close __attribute__ ((__warning__ ("The symbol close refers to the system function. Use safe_close instead."))); int fd; int main() { safe_close(fd); } =============================================================== $ g++ -S -O main.cc main.cc: In function 'int main()': main.cc:7:17: warning: call to 'close' declared with attribute warning: The symbol close refers to the system function. Use safe_close instead. The warning is not justified, because its only use is as initializer of the variable 'safe_close', and at that moment, the warning is not yet attached to it. Notes: - The warning occurs only with optimization, not with -O0. - The warning occurs only if the variable 'safe_close' is 'static', not when it is changed to a global variable. - The behaviour of GCC 4.3.4 and GCC 4.4.3 is the same as the one of GCC 4.5.0.
Created attachment 20479 [details] test case
Subject: Re: New: warning attached to a function is emitted even though the function is not being called It is called directly because safe_close's value is replaced in the indirect call. Since safe_close is static and not changed in the code at all, it is marked as read only and the initialized value can be used directly. Sent from my iPhone On Apr 24, 2010, at 3:49 PM, "bruno at clisp dot org" <gcc-bugzilla@gcc.gnu.org > wrote: > The gcc documentation, section "Declaring Attributes of Functions", > states > about the __attribute__ ((__warning__ ("..."))) of a function: > "If this attribute is used on a function declaration and a call to > such a function is not eliminated through dead code elimination or > other optimizations, a warning which will include MESSAGE will be > diagnosed." > > Here is a case where the warning is diagnosed although the program > contains > no direct call to the function: > =========================== main.cc =========================== > extern "C" int close(int); > static int (*safe_close) (int fd) = close; > extern __typeof__ (close) close __attribute__ ((__warning__ ("The > symbol close > refers to the system function. Use safe_close instead."))); > int fd; > int main() > { > safe_close(fd); > } > =============================================================== > $ g++ -S -O main.cc > main.cc: In function 'int main()': > main.cc:7:17: warning: call to 'close' declared with attribute > warning: The > symbol close refers to the system function. Use safe_close instead. > > The warning is not justified, because its only use is as initializer > of the variable 'safe_close', and at that moment, the warning is not > yet > attached to it. > > Notes: > - The warning occurs only with optimization, not with -O0. > - The warning occurs only if the variable 'safe_close' is 'static', > not > when it is changed to a global variable. > - The behaviour of GCC 4.3.4 and GCC 4.4.3 is the same as the one > of GCC > 4.5.0. > > > -- > Summary: warning attached to a function is emitted even > though > the function is not being called > Product: gcc > Version: 4.5.0 > Status: UNCONFIRMED > Severity: normal > Priority: P3 > Component: c++ > AssignedTo: unassigned at gcc dot gnu dot org > ReportedBy: bruno at clisp dot org > 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=43881 >
When the line static int (*safe_close) (int fd) = close; is changed to static int (*safe_close) (int fd) = ((void)0, close); the warning also disappears, but then the generate code is suboptimal: the variable safe_close is not eliminated from the 'data' section. Therefore I cannot use this as a workaround.
(In reply to comment #2) > It is called directly because safe_close's value is replaced in the > indirect call. Since safe_close is static and not changed in the code > at all, it is marked as read only and the initialized value can be > used directly. This is an explanation why gcc behaves like this, but not a justification. 1) GCC should try to make warnings independent of optimization settings. 2) GCC warns about a line of code that calls 'safe_close', which it should not warn about. Only calls of 'close' should be warned about, and there are no such calls in the source program.
(In reply to comment #4) > (In reply to comment #2) > > It is called directly because safe_close's value is replaced in the > > indirect call. Since safe_close is static and not changed in the code > > at all, it is marked as read only and the initialized value can be > > used directly. > > This is an explanation why gcc behaves like this, but not a justification. > > 1) GCC should try to make warnings independent of optimization settings. > 2) GCC warns about a line of code that calls 'safe_close', which it should not > warn about. Only calls of 'close' should be warned about, and there are > no such calls in the source program. I can see that other people will exactly requrest the opposite (that is, current behavior). 1) is always good, but unfortunately not possible (and in fact people request that with more knowledge available from an optimized program they should get improved warnings).
The best way to do this is to use asm instead: extern "C" int close(int); extern __typeof__ (close) close __attribute__ ((__warning__ ("The symbol close refers to the system function. Use safe_close instead."))); extern __typeof__ (close) safe_close asm("close");