When compiled with gcc 3.4.6 with -m32 on x86_64 Linux the compiler flags lines 7, 10, and 13 as expected. But when compiled with gcc 4.3.1, only line 7 is diagnosed. $ cat -n t.cpp && g++ -dumpversion && g++ -Wformat -m32 -c t.cpp 1 #include <stdio.h> 2 3 void foo (size_t n) 4 { 5 char buf [32]; 6 7 sprintf (buf, "%" "l" "u", n); 8 9 static const char fmt0[] = "%" "l" "u"; 10 sprintf (buf, fmt0, n); 11 12 const char fmt1[] = "%" "l" "u"; 13 sprintf (buf, fmt1, n); 14 15 static char fmt2[] = "%" "l" "u"; 16 sprintf (buf, fmt2, n); 17 18 char fmt3[] = "%" "l" "u"; 19 sprintf (buf, fmt3, n); 20 } 3.4.6 t.cpp: In function `void foo(size_t)': t.cpp:7: warning: long unsigned int format, size_t arg (arg 3) t.cpp:10: warning: long unsigned int format, size_t arg (arg 3) t.cpp:13: warning: long unsigned int format, size_t arg (arg 3) $ $ g++ -dumpversion && g++ -Wformat -m32 -c t.cpp 4.3.1 t.cpp: In function 'void foo(size_t)': t.cpp:7: warning: format '%lu' expects type 'long unsigned int', but argument 3 has type 'size_t' $
Jakub, can you have a look to this?
I think this has been caused by http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21089#c25 The c-format* stuff uses decl_constant_value, for C it will for const array variable with STRING_CST DECL_INITIAL return the DECL_INITIAL, but in C++ I think since the above commit it will not: 105256 mmitchel /* Do not return an aggregate constant (of which 105256 mmitchel string literals are a special case), as we do not 106533 kazu want to make inadvertent copies of such entities, 105256 mmitchel and we must be sure that their addresses are the 105256 mmitchel same everywhere. */ 105256 mmitchel || TREE_CODE (init) == CONSTRUCTOR 105256 mmitchel || TREE_CODE (init) == STRING_CST))) So, either we need a different function or an argument to decl_constant_value to force returning STRING_CST in that case, because in c-format case making inadvertent copies of such entities isn't a problem, c-format only wants to check that literal.
Thanks a lot for the analysis Jakub, seems easy to fix now.
Author: paolo Date: Sun Oct 9 23:20:39 2011 New Revision: 179731 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=179731 Log: /cp 2011-10-09 Paolo Carlini <paolo.carlini@oracle.com> PR c++/38980 * init.c (constant_value_1): Add bool parameter. (decl_constant_value_safe): Add. (integral_constant_value): Adjust. (decl_constant_value): Adjust. * cp-tree.h (decl_constant_value_safe): Declare. * typeck.c (decay_conversion): Use decl_constant_value_safe. * call.c (convert_like_real): Likewise. /testsuite 2011-10-09 Paolo Carlini <paolo.carlini@oracle.com> PR c++/38980 * g++.dg/warn/format5.C: New. Added: trunk/gcc/testsuite/g++.dg/warn/format5.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/call.c trunk/gcc/cp/cp-tree.h trunk/gcc/cp/init.c trunk/gcc/cp/typeck.c trunk/gcc/testsuite/ChangeLog
Fixed for 4.7.0 so far.
Fixed for 4.7.0, wontfix 4.4/4.5/4.6.