re PR c++/38980 (missing -Wformat warning on const char format string)
authorPaolo Carlini <paolo@gcc.gnu.org>
Sun, 9 Oct 2011 23:20:39 +0000 (23:20 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Sun, 9 Oct 2011 23:20:39 +0000 (23:20 +0000)
/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

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/cp-tree.h
gcc/cp/init.c
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/warn/format5.C [new file with mode: 0644]

index d520bda..c27d8a6 100644 (file)
@@ -1,3 +1,14 @@
+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>
            Diego Novillo  <dnovillo@google.com>
 
index a52ec29..ee71d9b 100644 (file)
@@ -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
index 7e5aac7..f824f38 100644 (file)
@@ -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 */
index f246286..7897fff 100644 (file)
@@ -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);
 }
 \f
 /* Common subroutines of build_new and build_vec_delete.  */
index d416b42..305f8f5 100644 (file)
@@ -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;
 
index bef6c34..d3be034 100644 (file)
@@ -1,3 +1,8 @@
+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>
 
        PR fortran/45044
@@ -22,7 +27,7 @@
 
 2011-10-08  Nicola Pero  <nicola.pero@meta-innovation.com>
 
-       PR libobjc/50428        
+       PR libobjc/50428
        * objc/execute/initialize-1.m: New test.
 
 2011-10-08  Paul Thomas  <pault@gcc.gnu.org>
diff --git a/gcc/testsuite/g++.dg/warn/format5.C b/gcc/testsuite/g++.dg/warn/format5.C
new file mode 100644 (file)
index 0000000..e219f88
--- /dev/null
@@ -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" }
+}