From 90454da1c0d74ee14a72a2c157f751de926a6ded Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Sun, 9 Oct 2011 23:20:39 +0000 Subject: re PR c++/38980 (missing -Wformat warning on const char format string) /cp 2011-10-09 Paolo Carlini 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 PR c++/38980 * g++.dg/warn/format5.C: New. From-SVN: r179731 --- gcc/cp/ChangeLog | 11 +++++++++++ gcc/cp/call.c | 2 +- gcc/cp/cp-tree.h | 1 + gcc/cp/init.c | 38 ++++++++++++++++++++++++------------- gcc/cp/typeck.c | 2 +- gcc/testsuite/ChangeLog | 7 ++++++- gcc/testsuite/g++.dg/warn/format5.C | 12 ++++++++++++ 7 files changed, 57 insertions(+), 16 deletions(-) create mode 100644 gcc/testsuite/g++.dg/warn/format5.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d520bda..c27d8a6 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,14 @@ +2011-10-09 Paolo Carlini + + 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. + 2011-10-09 Jakub Jelinek Diego Novillo diff --git a/gcc/cp/call.c b/gcc/cp/call.c index a52ec29..ee71d9b 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -5703,7 +5703,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, leave it as an lvalue. */ if (inner >= 0) { - expr = decl_constant_value (expr); + expr = decl_constant_value_safe (expr); if (expr == null_node && INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (totype)) /* If __null has been converted to an integer type, we do not want to warn about uses of EXPR as an integer, rather than diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 7e5aac7..f824f38 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5097,6 +5097,7 @@ extern tree create_temporary_var (tree); extern void initialize_vtbl_ptrs (tree); extern tree build_java_class_ref (tree); extern tree integral_constant_value (tree); +extern tree decl_constant_value_safe (tree); extern int diagnose_uninitialized_cst_or_ref_member (tree, bool, bool); /* in lex.c */ diff --git a/gcc/cp/init.c b/gcc/cp/init.c index f246286..7897fff 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -1794,10 +1794,11 @@ build_offset_ref (tree type, tree member, bool address_p) constant initializer, return the initializer (or, its initializers, recursively); otherwise, return DECL. If INTEGRAL_P, the initializer is only returned if DECL is an integral - constant-expression. */ + constant-expression. If RETURN_AGGREGATE_CST_OK_P, it is ok to + return an aggregate constant. */ static tree -constant_value_1 (tree decl, bool integral_p) +constant_value_1 (tree decl, bool integral_p, bool return_aggregate_cst_ok_p) { while (TREE_CODE (decl) == CONST_DECL || (integral_p @@ -1834,12 +1835,13 @@ constant_value_1 (tree decl, bool integral_p) if (!init || !TREE_TYPE (init) || !TREE_CONSTANT (init) - || (!integral_p - /* Do not return an aggregate constant (of which - string literals are a special case), as we do not - want to make inadvertent copies of such entities, - and we must be sure that their addresses are the - same everywhere. */ + || (!integral_p && !return_aggregate_cst_ok_p + /* Unless RETURN_AGGREGATE_CST_OK_P is true, do not + return an aggregate constant (of which string + literals are a special case), as we do not want + to make inadvertent copies of such entities, and + we must be sure that their addresses are the + same everywhere. */ && (TREE_CODE (init) == CONSTRUCTOR || TREE_CODE (init) == STRING_CST))) break; @@ -1856,18 +1858,28 @@ constant_value_1 (tree decl, bool integral_p) tree integral_constant_value (tree decl) { - return constant_value_1 (decl, /*integral_p=*/true); + return constant_value_1 (decl, /*integral_p=*/true, + /*return_aggregate_cst_ok_p=*/false); } /* A more relaxed version of integral_constant_value, used by the - common C/C++ code and by the C++ front end for optimization - purposes. */ + common C/C++ code. */ tree decl_constant_value (tree decl) { - return constant_value_1 (decl, - /*integral_p=*/processing_template_decl); + return constant_value_1 (decl, /*integral_p=*/processing_template_decl, + /*return_aggregate_cst_ok_p=*/true); +} + +/* A version of integral_constant_value used by the C++ front end for + optimization purposes. */ + +tree +decl_constant_value_safe (tree decl) +{ + return constant_value_1 (decl, /*integral_p=*/processing_template_decl, + /*return_aggregate_cst_ok_p=*/false); } /* Common subroutines of build_new and build_vec_delete. */ diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index d416b42..305f8f5 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -1827,7 +1827,7 @@ decay_conversion (tree exp) /* FIXME remove? at least need to remember that this isn't really a constant expression if EXP isn't decl_constant_var_p, like with C_MAYBE_CONST_EXPR. */ - exp = decl_constant_value (exp); + exp = decl_constant_value_safe (exp); if (error_operand_p (exp)) return error_mark_node; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index bef6c34..d3be034 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-10-09 Paolo Carlini + + PR c++/38980 + * g++.dg/warn/format5.C: New. + 2011-10-09 Tobias Burnus PR fortran/45044 @@ -22,7 +27,7 @@ 2011-10-08 Nicola Pero - PR libobjc/50428 + PR libobjc/50428 * objc/execute/initialize-1.m: New test. 2011-10-08 Paul Thomas diff --git a/gcc/testsuite/g++.dg/warn/format5.C b/gcc/testsuite/g++.dg/warn/format5.C new file mode 100644 index 0000000..e219f88 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/format5.C @@ -0,0 +1,12 @@ +// PR c++/38980 +// { dg-options "-Wformat" } + +extern "C" +int printf(const char *format, ...) __attribute__((format(printf, 1, 2) )); + +const char fmt1[] = "Hello, %s"; + +void f() +{ + printf(fmt1, 3); // { dg-warning "expects argument" } +} -- cgit v1.1