Hello,
   I encountered similar issue to PR ipa/61462 where location_t locus = 
gimple_location (e->call_stmt) is called for e->call_stmt == NULL (Firefox with 
-flto -fdump-ipa-devirt). So that, I decided to introduce new function that is called 
for all potentially unsafe locations. I am wondering if a newly added function can be 
added in more seamless way (without playing with va_list and ATTRIBUTE_PRINTF stuff)?

Bootstrapped and regtested on x86_64-unknown-linux-gnu.

Thanks,
Martin

    ChangeLog:

    2014-06-26  Martin Liska  <mli...@suse.cz>

        * include/ansidecl.h: New collection of ATTRIBUTE_NULL_PRINTF_X_0
        defined.

    gcc/ChangeLog:

    2014-06-26  Martin Liska  <mli...@suse.cz>

        * dumpfile.h: New function dump_printf_loc_for_stmt.
        * dumpfile.c: Implementation added.
        (dump_vprintf): New function.i
        * cgraphunit.c: dump_printf_loc_for_stmt usage replaces
        dump_printf_loc.
        * gimple-fold.c: Likewise.
        * ipa-devirt.c: Likewise.
        * ipa-prop.c: Likewise.
        * ipa.c: Likewise.
        * tree-ssa-pre.c: Likewise.




diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 76b2fda1..3b01718 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -905,12 +905,9 @@ walk_polymorphic_call_targets (pointer_set_t *reachable_call_targets,
 				 TDF_SLIM);
 	    }
           if (dump_enabled_p ())
-            {
-	      location_t locus = gimple_location (edge->call_stmt);
-	      dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, locus,
-			       "devirtualizing call in %s to %s\n",
-			       edge->caller->name (), target->name ());
-	    }
+	    dump_printf_loc_for_stmt (MSG_OPTIMIZED_LOCATIONS, edge->call_stmt,
+				      "devirtualizing call in %s to %s\n",
+				      edge->caller->name (), target->name ());
 
 	  cgraph_make_edge_direct (edge, target);
 	  cgraph_redirect_edge_call_stmt_to_callee (edge);
diff --git a/gcc/dumpfile.c b/gcc/dumpfile.c
index fd630a6..b7a791c 100644
--- a/gcc/dumpfile.c
+++ b/gcc/dumpfile.c
@@ -23,6 +23,12 @@ along with GCC; see the file COPYING3.  If not see
 #include "diagnostic-core.h"
 #include "dumpfile.h"
 #include "tree.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
+#include "gimple.h"
 #include "gimple-pretty-print.h"
 #include "context.h"
 
@@ -343,52 +349,80 @@ dump_generic_expr_loc (int dump_kind, source_location loc,
     }
 }
 
-/* Output a formatted message using FORMAT on appropriate dump streams.  */
+/* Output a formatted message using FORMAT on appropriate dump streams.
+   Accepts va_list AP as the last argument.  */
 
-void
-dump_printf (int dump_kind, const char *format, ...)
+ATTRIBUTE_NULL_PRINTF_2_0
+static void
+dump_vprintf (int dump_kind, const char *format, va_list ap)
 {
   if (dump_file && (dump_kind & pflags))
-    {
-      va_list ap;
-      va_start (ap, format);
       vfprintf (dump_file, format, ap);
-      va_end (ap);
-    }
 
   if (alt_dump_file && (dump_kind & alt_flags))
-    {
-      va_list ap;
-      va_start (ap, format);
       vfprintf (alt_dump_file, format, ap);
-      va_end (ap);
-    }
 }
 
-/* Similar to dump_printf, except source location is also printed.  */
+/* Output a formatted message using FORMAT on appropriate dump streams.  */
 
 void
-dump_printf_loc (int dump_kind, source_location loc, const char *format, ...)
+dump_printf (int dump_kind, const char *format, ...)
+{
+  va_list ap;
+  va_start (ap, format);
+  dump_vprintf (dump_kind, format, ap);
+  va_end (ap);
+}
+
+/* Similar to dump_printf, except source location is also printed.
+   Accepts va_list AP as the last argument.  */
+
+void
+dump_vprintf_loc (int dump_kind, source_location loc, const char *format,
+		  va_list ap)
 {
   if (dump_file && (dump_kind & pflags))
     {
-      va_list ap;
       dump_loc (dump_kind, dump_file, loc);
-      va_start (ap, format);
       vfprintf (dump_file, format, ap);
-      va_end (ap);
     }
 
   if (alt_dump_file && (dump_kind & alt_flags))
     {
-      va_list ap;
       dump_loc (dump_kind, alt_dump_file, loc);
-      va_start (ap, format);
       vfprintf (alt_dump_file, format, ap);
-      va_end (ap);
     }
 }
 
+/* Similar to dump_printf, except source location is also printed.  */
+
+void
+dump_printf_loc (int dump_kind, source_location loc, const char *format, ...)
+{
+  va_list ap;
+  va_start (ap, format);
+  dump_vprintf_loc (dump_kind, loc, format, ap);
+  va_end (ap);
+}
+
+/* Similar to dump_printf, except source location is also printed if STMT
+   is not null. Otherwise, fallback to dump_fprintf is called.  */
+
+void
+dump_printf_loc_for_stmt (int dump_kind, const_gimple stmt, const char *format,
+			  ...)
+{
+  va_list ap;
+  va_start (ap, format);
+
+  if (stmt)
+    dump_vprintf_loc (dump_kind, gimple_location (stmt), format, ap);
+  else
+    dump_vprintf (dump_kind, format, ap);
+
+  va_end (ap);
+}
+
 /* Start a dump for PHASE. Store user-supplied dump flags in
    *FLAG_PTR.  Return the number of streams opened.  Set globals
    DUMP_FILE, and ALT_DUMP_FILE to point to the opened streams, and
diff --git a/gcc/dumpfile.h b/gcc/dumpfile.h
index 75949b7..5c1a177 100644
--- a/gcc/dumpfile.h
+++ b/gcc/dumpfile.h
@@ -126,8 +126,12 @@ extern void dump_end (int, FILE *);
 extern int opt_info_switch_p (const char *);
 extern const char *dump_flag_name (int);
 extern void dump_printf (int, const char *, ...) ATTRIBUTE_PRINTF_2;
+extern void dump_vprintf_loc (int, source_location, const char *,
+			      va_list ap) ATTRIBUTE_NULL_PRINTF_3_0;
 extern void dump_printf_loc (int, source_location,
                              const char *, ...) ATTRIBUTE_PRINTF_3;
+extern void dump_printf_loc_for_stmt (int, const_gimple,
+				      const char *, ...) ATTRIBUTE_PRINTF_3;
 extern void dump_basic_block (int, basic_block, int);
 extern void dump_generic_expr_loc (int, source_location, int, tree);
 extern void dump_generic_expr (int, int, tree);
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index 403dee7..e831067 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -386,15 +386,13 @@ fold_gimple_assign (gimple_stmt_iterator *si)
 		    else
 		      fndecl = builtin_decl_implicit (BUILT_IN_UNREACHABLE);
 		    if (dump_enabled_p ())
-		      {
-			location_t loc = gimple_location (stmt);
-			dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,
-					 "resolving virtual function address "
-					 "reference to function %s\n",
-					 targets.length () == 1
-					 ? targets[0]->name ()
-					 : "__builtin_unreachable");
-		      }
+		      dump_printf_loc_for_stmt (MSG_OPTIMIZED_LOCATIONS, stmt,
+						"resolving virtual function "
+						"address reference to "
+						"function %s\n",
+						targets.length () == 1
+						? targets[0]->name ()
+						: "__builtin_unreachable");
 		    val = fold_convert (TREE_TYPE (val), fndecl);
 		    STRIP_USELESS_TYPE_CONVERSION (val);
 		    return val;
@@ -1130,14 +1128,12 @@ gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace)
 	    {
 	      tree lhs = gimple_call_lhs (stmt);
 	      if (dump_enabled_p ())
-		{
-		  location_t loc = gimple_location (stmt);
-		  dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,
-				   "folding virtual function call to %s\n",
-		 		   targets.length () == 1
-		  		   ? targets[0]->name ()
-		  		   : "__builtin_unreachable");
-		}
+		dump_printf_loc_for_stmt (MSG_OPTIMIZED_LOCATIONS, stmt,
+					  "folding virtual function call "
+					  "to %s\n",
+					  targets.length () == 1
+					  ? targets[0]->name ()
+					  : "__builtin_unreachable");
 	      if (targets.length () == 1)
 		{
 		  gimple_call_set_fndecl (stmt, targets[0]->decl);
diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c
index 21f4f11..facbf4c 100644
--- a/gcc/ipa-devirt.c
+++ b/gcc/ipa-devirt.c
@@ -2079,14 +2079,12 @@ ipa_devirt (void)
 	    else if (dbg_cnt (devirt))
 	      {
 		if (dump_enabled_p ())
-                  {
-                    location_t locus = gimple_location (e->call_stmt);
-                    dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, locus,
-                                     "speculatively devirtualizing call in %s/%i to %s/%i\n",
-                                     n->name (), n->order,
-                                     likely_target->name (),
-                                     likely_target->order);
-                  }
+		  dump_printf_loc_for_stmt (MSG_OPTIMIZED_LOCATIONS, e->call_stmt,
+					    "speculatively devirtualizing "
+					    "call in %s/%i to %s/%i\n",
+					    n->name (), n->order,
+					    likely_target->name (),
+					    likely_target->order);
 		if (!symtab_can_be_discarded (likely_target))
 		  {
 		    cgraph_node *alias;
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index 5f5bf89..d062de8 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -2677,11 +2677,10 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target)
 				"making it __builtin_unreachable\n";
 
 	      if (ie->call_stmt)
-		{
-		  location_t loc = gimple_location (ie->call_stmt);
-		  dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc, fmt,
-				   ie->caller->name (), ie->caller->order);
-		}
+		dump_printf_loc_for_stmt (MSG_OPTIMIZED_LOCATIONS,
+					  ie->call_stmt, fmt,
+					  ie->caller->name (),
+					  ie->caller->order);
 	      else if (dump_file)
 		fprintf (dump_file, fmt, ie->caller->name (), ie->caller->order);
 	    }
diff --git a/gcc/ipa.c b/gcc/ipa.c
index fce2e36..5c78690 100644
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -197,14 +197,13 @@ walk_polymorphic_call_targets (pointer_set_t *reachable_call_targets,
 		       (builtin_decl_implicit (BUILT_IN_UNREACHABLE));
 
 	  if (dump_enabled_p ())
-            {
-              location_t locus = gimple_location (edge->call_stmt);
-              dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, locus,
-                               "devirtualizing call in %s/%i to %s/%i\n",
-                               edge->caller->name (), edge->caller->order,
-                               target->name (),
-                               target->order);
-	    }
+	    dump_printf_loc_for_stmt (MSG_OPTIMIZED_LOCATIONS, edge->call_stmt,
+				      "devirtualizing call in %s/%i to "
+				      "%s/%i\n",
+				      edge->caller->name (),
+				      edge->caller->order,
+				      target->name (),
+				      target->order);
 	  edge = cgraph_make_edge_direct (edge, target);
 	  if (inline_summary_vec)
 	    inline_update_overall_summary (node);
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index 74238de..e6a764e 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -4366,13 +4366,10 @@ eliminate_dom_walker::before_dom_children (basic_block b)
 	      if (fn && dbg_cnt (devirt))
 		{
 		  if (dump_enabled_p ())
-		    {
-		      location_t loc = gimple_location (stmt);
-		      dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,
-				       "converting indirect call to "
-				       "function %s\n",
-				       cgraph_get_node (fn)->name ());
-		    }
+		    dump_printf_loc_for_stmt (MSG_OPTIMIZED_LOCATIONS, stmt,
+					      "converting indirect call to "
+					      "function %s\n",
+					      cgraph_get_node (fn)->name ());
 		  gimple_call_set_fndecl (stmt, fn);
 		  gimple_set_modified (stmt, true);
 		}
diff --git a/include/ansidecl.h b/include/ansidecl.h
index 0fb23bb..ba137aa 100644
--- a/include/ansidecl.h
+++ b/include/ansidecl.h
@@ -234,6 +234,12 @@ So instead we use the macro below and test it against specific values.  */
 # define ATTRIBUTE_NULL_PRINTF_3 ATTRIBUTE_NULL_PRINTF(3, 4)
 # define ATTRIBUTE_NULL_PRINTF_4 ATTRIBUTE_NULL_PRINTF(4, 5)
 # define ATTRIBUTE_NULL_PRINTF_5 ATTRIBUTE_NULL_PRINTF(5, 6)
+
+# define ATTRIBUTE_NULL_PRINTF_1_0 ATTRIBUTE_NULL_PRINTF(1, 0)
+# define ATTRIBUTE_NULL_PRINTF_2_0 ATTRIBUTE_NULL_PRINTF(2, 0)
+# define ATTRIBUTE_NULL_PRINTF_3_0 ATTRIBUTE_NULL_PRINTF(3, 0)
+# define ATTRIBUTE_NULL_PRINTF_4_0 ATTRIBUTE_NULL_PRINTF(4, 0)
+# define ATTRIBUTE_NULL_PRINTF_5_0 ATTRIBUTE_NULL_PRINTF(5, 0)
 #endif /* ATTRIBUTE_NULL_PRINTF */
 
 /* Attribute `sentinel' was valid as of gcc 3.5.  */

Reply via email to