diff mbox

[C++] PR 38980

Message ID 4E8EE01C.7000500@oracle.com
State New
Headers show

Commit Message

Paolo Carlini Oct. 7, 2011, 11:18 a.m. UTC
Hi,
> Instead of adding the parameter, let's have the C++ front end call a 
> different function that doesn't try to pull out the value from 
> aggregate variables, like C has decl_constant_value_for_optimization.
Ok. The below lives entirely inside the C++ front-end (actually I had 
already experimented with something similar)

Note I'm using the name decl_constant_value_safe, thus I'm not 
overloading the name decl_constant_value_for_optimization, because the 
latter is only used by the C front-end but still exported by c-family. I 
could move back that decl_constant_value_for_optimization currently in 
c-common.c to the C front-end, but callers, also C front-end only, would 
remain in c-family. I'd rather not fiddle further with all of that 
(looks like long term people would like to have more shared code in 
c-common.c, seems indeed an excellent idea, but at the moment large 
chunks are actually used by the C front-end only...).

Tested x86_64-linux.

Paolo.

/////////////////////
/cp
2011-10-07  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-07  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/38980
	* g++.dg/warn/format5.C: New.

Comments

Jason Merrill Oct. 9, 2011, 10:18 p.m. UTC | #1
OK.

Jason
diff mbox

Patch

Index: testsuite/g++.dg/warn/format5.C
===================================================================
--- testsuite/g++.dg/warn/format5.C	(revision 0)
+++ testsuite/g++.dg/warn/format5.C	(revision 0)
@@ -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" }
+}
Index: cp/typeck.c
===================================================================
--- cp/typeck.c	(revision 179649)
+++ cp/typeck.c	(working copy)
@@ -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: cp/init.c
===================================================================
--- cp/init.c	(revision 179649)
+++ cp/init.c	(working copy)
@@ -1794,10 +1794,11 @@  build_offset_ref (tree type, tree member, bool add
    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 @@  static tree
       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,19 +1858,29 @@  static tree
 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.  */
 
Index: cp/call.c
===================================================================
--- cp/call.c	(revision 179649)
+++ cp/call.c	(working copy)
@@ -5703,7 +5703,7 @@  convert_like_real (conversion *convs, tree expr, t
 	 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: cp/cp-tree.h
===================================================================
--- cp/cp-tree.h	(revision 179649)
+++ cp/cp-tree.h	(working copy)
@@ -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 */