https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61886

--- Comment #11 from Jan Hubicka <hubicka at ucw dot cz> ---
Hi,
this patch implements the lowring.  Each call with warn attribute triggers code
in cgraphunit that inserts call to bulitin_warning/error that is output at
expansion time.

Do we have way to define bulitin that is not user accessible?

Also we do not have way to define LOOPING_CONST bulitin, so I am simply forcing
the flag in cgraphunit.c that is somewhat ugly.

One of consequences of this approach is that indirect calls to functions with
warn attributes will not produce warning.  I think it is sort of acceptable
because we also do not warn when the indirect call is produced late by RTL
backend.

Honza

Index: expr.c
===================================================================
--- expr.c    (revision 215901)
+++ 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: builtin-types.def
===================================================================
--- builtin-types.def    (revision 215901)
+++ builtin-types.def    (working copy)
@@ -581,3 +581,5 @@ DEF_FUNCTION_TYPE_2 (BT_FN_VOID_VPTR_LDO
              BT_VOLATILE_PTR, BT_LONGDOUBLE)
 DEF_FUNCTION_TYPE_2 (BT_FN_VOID_VPTR_SIZE, BT_VOID,
              BT_VOLATILE_PTR, BT_SIZE)
+DEF_FUNCTION_TYPE_2 (BT_FN_VOID_CONST_STRING_CONST_STRING,
+             BT_VOID, BT_CONST_STRING, BT_CONST_STRING)
Index: builtins.c
===================================================================
--- builtins.c    (revision 215901)
+++ builtins.c    (working copy)
@@ -59,6 +59,8 @@ along with GCC; see the file COPYING3.
 #include "builtins.h"
 #include "ubsan.h"
 #include "cilk.h"
+#include "pretty-print.h"
+#include "print-tree.h"


 static tree do_mpc_arg1 (tree, tree, int (*)(mpc_ptr, mpc_srcptr, mpc_rnd_t));
@@ -6816,6 +6818,31 @@ expand_builtin (tree exp, rtx target, rt
       expand_builtin_cilk_pop_frame (exp);
       return const0_rtx;

+    case BUILT_IN_WARNING:
+      const char * arg0;
+      const char * arg1;
+      if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
+      || (arg0 = c_getstr (CALL_EXPR_ARG (exp, 0))) == NULL
+      || (arg1 = c_getstr (CALL_EXPR_ARG (exp, 1))) == NULL)
+    warning_at (tree_nonartificial_location (exp), 0,
+            "%K__builtin_warning used without both arguments being string
constants",
+            exp);
+      else
+    warning_at (tree_nonartificial_location (exp),
+            0, "%Kcall to %qs declared with attribute warning: %s",
+            exp, arg0, identifier_to_locale (arg1));
+      return const0_rtx;
+    case BUILT_IN_ERROR:
+      if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
+      || (arg0 = c_getstr (CALL_EXPR_ARG (exp, 0))) == NULL
+      || (arg1 = c_getstr (CALL_EXPR_ARG (exp, 1))) == NULL)
+    error ("%K__builtin_error used without both arguments being string
constants",
+           exp);
+      else
+    error ("%Kcall to %qs declared with attribute warning: %s",
+           exp, arg0, identifier_to_locale (arg1));
+      return const0_rtx;
+
     default:    /* just do library call, if unknown builtin */
       break;
     }
Index: cgraphunit.c
===================================================================
--- cgraphunit.c    (revision 215901)
+++ cgraphunit.c    (working copy)
@@ -211,6 +211,7 @@ along with GCC; see the file COPYING3.
 #include "tree-nested.h"
 #include "gimplify.h"
 #include "dbgcnt.h"
+#include "expr.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 +977,30 @@ 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)));
+              tree dest = builtin_decl_implicit (attr ? BUILT_IN_WARNING :
BUILT_IN_ERROR);
+
+              cgraph_node::get_create (dest)->set_const_flag (true, true);
+              gimple call = gimple_build_call (dest, 2,
+                               build_string_literal (strlen (arg0), arg0),
+                               build_string_literal (strlen (arg1), arg1));
+              gsi_insert_before (&gsi, call, GSI_SAME_STMT);
+              cnode->create_edge (cgraph_node::get_create (dest), call,
+                      edge->count, edge->frequency);
+            }
+        }
           if (optimize && flag_devirtualize)
         {
           cgraph_edge *next;
Index: builtins.def
===================================================================
--- builtins.def    (revision 215901)
+++ builtins.def    (working copy)
@@ -820,6 +820,9 @@ DEF_EXT_LIB_BUILTIN    (BUILT_IN_PRINTF_
 DEF_EXT_LIB_BUILTIN    (BUILT_IN_VFPRINTF_CHK, "__vfprintf_chk",
BT_FN_INT_FILEPTR_INT_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_3_0)
 DEF_EXT_LIB_BUILTIN    (BUILT_IN_VPRINTF_CHK, "__vprintf_chk",
BT_FN_INT_INT_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_2_0)

+DEF_GCC_BUILTIN        (BUILT_IN_ERROR, "error",
BT_FN_VOID_CONST_STRING_CONST_STRING, ATTR_NOTHROW_LEAF_LIST)
+DEF_GCC_BUILTIN        (BUILT_IN_WARNING, "warning",
BT_FN_VOID_CONST_STRING_CONST_STRING, ATTR_NOTHROW_LEAF_LIST)
+
 /* Profiling hooks.  */
 DEF_BUILTIN (BUILT_IN_PROFILE_FUNC_ENTER, "__cyg_profile_func_enter",
BUILT_IN_NORMAL, BT_FN_VOID_PTR_PTR, BT_LAST,
          false, false, false, ATTR_NULL, true, true)

Reply via email to