https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61886
--- Comment #13 from Jan Hubicka <hubicka at ucw dot cz> ---
Hi,
I am testing this variant of the patch.
For gcc-4.9 branch it may make sense to enable the new patch for LTO only.
Index: internal-fn.c
===================================================================
--- internal-fn.c (revision 215958)
+++ internal-fn.c (working copy)
@@ -37,6 +37,8 @@ along with GCC; see the file COPYING3.
#include "stringpool.h"
#include "tree-ssanames.h"
#include "diagnostic-core.h"
+#include "builtins.h"
+#include "pretty-print.h"
/* The names of each internal function, indexed by function number. */
const char *const internal_fn_name_array[] = {
@@ -915,6 +917,26 @@ expand_BUILTIN_EXPECT (gimple stmt)
emit_move_insn (target, val);
}
+static void
+expand_OUTPUT_ERROR (gimple stmt)
+{
+ const char * arg0 = c_getstr (gimple_call_arg (stmt, 0));
+ const char * arg1 = c_getstr (gimple_call_arg (stmt, 1));
+ error_at (gimple_location (stmt),
+ "Call to %qs declared with attribute error: %s",
+ arg0, identifier_to_locale (arg1));
+}
+
+static void
+expand_OUTPUT_WARNING (gimple stmt)
+{
+ const char * arg0 = c_getstr (gimple_call_arg (stmt, 0));
+ const char * arg1 = c_getstr (gimple_call_arg (stmt, 1));
+ warning_at (gimple_location (stmt),
+ 0, "call to %qs declared with attribute warning: %s",
+ arg0, identifier_to_locale (arg1));
+}
+
/* Routines to expand each internal function, indexed by function number.
Each routine has the prototype:
Index: cgraphunit.c
===================================================================
--- cgraphunit.c (revision 215958)
+++ cgraphunit.c (working copy)
@@ -211,6 +211,8 @@ along with GCC; see the file COPYING3.
#include "tree-nested.h"
#include "gimplify.h"
#include "dbgcnt.h"
+#include "expr.h"
+#include "internal-fn.h"
/* Queue of cgraph nodes scheduled to be added into cgraph. This is a
secondary queue used during optimization to accommodate passes that
@@ -976,8 +978,29 @@ analyze_functions (void)
cnode->analyze ();
for (edge = cnode->callees; edge; edge = edge->next_callee)
- if (edge->callee->definition)
- enqueue_node (edge->callee);
+ {
+ tree attr, err_attr = NULL;
+ if (edge->callee->definition)
+ enqueue_node (edge->callee);
+ if ((attr = lookup_attribute ("warning",
+ DECL_ATTRIBUTES (edge->callee->decl))) != NULL
+ || (err_attr = lookup_attribute ("warning",
+ DECL_ATTRIBUTES (edge->callee->decl))))
+ {
+ gimple_stmt_iterator gsi = gsi_for_stmt (edge->call_stmt);
+ const char *arg0 = lang_hooks.decl_printable_name
(edge->callee->decl, 1);
+ const char *arg1= TREE_STRING_POINTER
+ (TREE_VALUE (TREE_VALUE (attr ? attr : err_attr)));
+
+ gimple call = gimple_build_call_internal
+ (attr ? IFN_OUTPUT_WARNING : IFN_OUTPUT_ERROR, 2,
+ build_string_literal (strlen (arg0), arg0),
+ build_string_literal (strlen (arg1), arg1));
+ gsi_insert_before (&gsi, call, GSI_SAME_STMT);
+ gimple_set_location (call, gimple_location (edge->call_stmt));
+ gimple_set_block (call, gimple_block (edge->call_stmt));
+ }
+ }
if (optimize && flag_devirtualize)
{
cgraph_edge *next;
Index: expr.c
===================================================================
--- expr.c (revision 215958)
+++ expr.c (working copy)
@@ -10346,21 +10346,7 @@ expand_expr_real_1 (tree exp, rtx target
if (CALL_EXPR_VA_ARG_PACK (exp))
error ("%Kinvalid use of %<__builtin_va_arg_pack ()%>", exp);
{
- tree fndecl = get_callee_fndecl (exp), attr;
-
- if (fndecl
- && (attr = lookup_attribute ("error",
- DECL_ATTRIBUTES (fndecl))) != NULL)
- error ("%Kcall to %qs declared with attribute error: %s",
- exp, identifier_to_locale (lang_hooks.decl_printable_name (fndecl,
1)),
- TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr))));
- if (fndecl
- && (attr = lookup_attribute ("warning",
- DECL_ATTRIBUTES (fndecl))) != NULL)
- warning_at (tree_nonartificial_location (exp),
- 0, "%Kcall to %qs declared with attribute warning: %s",
- exp, identifier_to_locale (lang_hooks.decl_printable_name
(fndecl, 1)),
- TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr))));
+ tree fndecl = get_callee_fndecl (exp);
/* Check for a built-in function. */
if (fndecl && DECL_BUILT_IN (fndecl))
Index: internal-fn.def
===================================================================
--- internal-fn.def (revision 215958)
+++ internal-fn.def (working copy)
@@ -56,3 +56,5 @@ DEF_INTERNAL_FN (UBSAN_CHECK_MUL, ECF_CO
DEF_INTERNAL_FN (ABNORMAL_DISPATCHER, ECF_NORETURN, NULL)
DEF_INTERNAL_FN (BUILTIN_EXPECT, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL)
DEF_INTERNAL_FN (ASAN_CHECK, ECF_TM_PURE | ECF_LEAF | ECF_NOTHROW, ".W...")
+DEF_INTERNAL_FN (OUTPUT_ERROR, ECF_TM_PURE | ECF_LEAF | ECF_CONST |
ECF_NOTHROW | ECF_LOOPING_CONST_OR_PURE, NULL)
+DEF_INTERNAL_FN (OUTPUT_WARNING, ECF_TM_PURE | ECF_LEAF | ECF_CONST |
ECF_NOTHROW | ECF_LOOPING_CONST_OR_PURE, NULL)