Commit 90454da1 by Paolo Carlini

re PR c++/38980 (missing -Wformat warning on const char format string)

/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.

From-SVN: r179731
parent 75e649f6
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.
2011-10-09 Jakub Jelinek <jakub@redhat.com> 2011-10-09 Jakub Jelinek <jakub@redhat.com>
Diego Novillo <dnovillo@google.com> Diego Novillo <dnovillo@google.com>
......
...@@ -5703,7 +5703,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, ...@@ -5703,7 +5703,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
leave it as an lvalue. */ leave it as an lvalue. */
if (inner >= 0) 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 (expr == null_node && INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (totype))
/* If __null has been converted to an integer type, we do not /* If __null has been converted to an integer type, we do not
want to warn about uses of EXPR as an integer, rather than want to warn about uses of EXPR as an integer, rather than
......
...@@ -5097,6 +5097,7 @@ extern tree create_temporary_var (tree); ...@@ -5097,6 +5097,7 @@ extern tree create_temporary_var (tree);
extern void initialize_vtbl_ptrs (tree); extern void initialize_vtbl_ptrs (tree);
extern tree build_java_class_ref (tree); extern tree build_java_class_ref (tree);
extern tree integral_constant_value (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); extern int diagnose_uninitialized_cst_or_ref_member (tree, bool, bool);
/* in lex.c */ /* in lex.c */
......
...@@ -1794,10 +1794,11 @@ build_offset_ref (tree type, tree member, bool address_p) ...@@ -1794,10 +1794,11 @@ build_offset_ref (tree type, tree member, bool address_p)
constant initializer, return the initializer (or, its initializers, constant initializer, return the initializer (or, its initializers,
recursively); otherwise, return DECL. If INTEGRAL_P, the recursively); otherwise, return DECL. If INTEGRAL_P, the
initializer is only returned if DECL is an integral 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 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 while (TREE_CODE (decl) == CONST_DECL
|| (integral_p || (integral_p
...@@ -1834,12 +1835,13 @@ constant_value_1 (tree decl, bool integral_p) ...@@ -1834,12 +1835,13 @@ constant_value_1 (tree decl, bool integral_p)
if (!init if (!init
|| !TREE_TYPE (init) || !TREE_TYPE (init)
|| !TREE_CONSTANT (init) || !TREE_CONSTANT (init)
|| (!integral_p || (!integral_p && !return_aggregate_cst_ok_p
/* Do not return an aggregate constant (of which /* Unless RETURN_AGGREGATE_CST_OK_P is true, do not
string literals are a special case), as we do not return an aggregate constant (of which string
want to make inadvertent copies of such entities, literals are a special case), as we do not want
and we must be sure that their addresses are the to make inadvertent copies of such entities, and
same everywhere. */ we must be sure that their addresses are the
same everywhere. */
&& (TREE_CODE (init) == CONSTRUCTOR && (TREE_CODE (init) == CONSTRUCTOR
|| TREE_CODE (init) == STRING_CST))) || TREE_CODE (init) == STRING_CST)))
break; break;
...@@ -1856,18 +1858,28 @@ constant_value_1 (tree decl, bool integral_p) ...@@ -1856,18 +1858,28 @@ constant_value_1 (tree decl, bool integral_p)
tree tree
integral_constant_value (tree decl) 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 /* A more relaxed version of integral_constant_value, used by the
common C/C++ code and by the C++ front end for optimization common C/C++ code. */
purposes. */
tree tree
decl_constant_value (tree decl) decl_constant_value (tree decl)
{ {
return constant_value_1 (decl, return constant_value_1 (decl, /*integral_p=*/processing_template_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. */ /* Common subroutines of build_new and build_vec_delete. */
......
...@@ -1827,7 +1827,7 @@ decay_conversion (tree exp) ...@@ -1827,7 +1827,7 @@ decay_conversion (tree exp)
/* FIXME remove? at least need to remember that this isn't really a /* 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 constant expression if EXP isn't decl_constant_var_p, like with
C_MAYBE_CONST_EXPR. */ C_MAYBE_CONST_EXPR. */
exp = decl_constant_value (exp); exp = decl_constant_value_safe (exp);
if (error_operand_p (exp)) if (error_operand_p (exp))
return error_mark_node; return error_mark_node;
......
2011-10-09 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/38980
* g++.dg/warn/format5.C: New.
2011-10-09 Tobias Burnus <burnus@net-b.de> 2011-10-09 Tobias Burnus <burnus@net-b.de>
PR fortran/45044 PR fortran/45044
...@@ -22,7 +27,7 @@ ...@@ -22,7 +27,7 @@
2011-10-08 Nicola Pero <nicola.pero@meta-innovation.com> 2011-10-08 Nicola Pero <nicola.pero@meta-innovation.com>
PR libobjc/50428 PR libobjc/50428
* objc/execute/initialize-1.m: New test. * objc/execute/initialize-1.m: New test.
2011-10-08 Paul Thomas <pault@gcc.gnu.org> 2011-10-08 Paul Thomas <pault@gcc.gnu.org>
......
// 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" }
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment