re PR debug/66691 (ICE on valid code at -O3 with -g enabled in simplify_subreg, at...
[gcc.git] / gcc / ipa-chkp.c
index 3218d42330e14c647413916f705b9987f3d70e9f..acb89bed65f7a3467613bf75ff22fc56d50f7321 100644 (file)
@@ -21,16 +21,9 @@ along with GCC; see the file COPYING3.  If not see
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
-#include "hash-set.h"
-#include "machmode.h"
-#include "vec.h"
-#include "double-int.h"
-#include "input.h"
 #include "alias.h"
 #include "symtab.h"
 #include "options.h"
-#include "wide-int.h"
-#include "inchash.h"
 #include "tree.h"
 #include "fold-const.h"
 #include "stor-layout.h"
@@ -41,12 +34,11 @@ along with GCC; see the file COPYING3.  If not see
 #include "tm.h"
 #include "hard-reg-set.h"
 #include "function.h"
-#include "is-a.h"
+#include "calls.h"
 #include "tree-ssa-alias.h"
 #include "predict.h"
 #include "basic-block.h"
 #include "gimple.h"
-#include "ipa-ref.h"
 #include "lto-streamer.h"
 #include "cgraph.h"
 #include "tree-chkp.h"
@@ -104,7 +96,7 @@ along with GCC; see the file COPYING3.  If not see
 
 /* Return 1 calls to FNDECL should be replaced with
    a call to wrapper function.  */
-static bool
+bool
 chkp_wrap_function (tree fndecl)
 {
   if (!flag_chkp_use_wrappers)
@@ -139,6 +131,51 @@ chkp_wrap_function (tree fndecl)
   return false;
 }
 
+static const char *
+chkp_wrap_function_name (tree fndecl)
+{
+  gcc_assert (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL);
+
+  switch (DECL_FUNCTION_CODE (fndecl))
+    {
+    case BUILT_IN_STRLEN:
+      return CHKP_WRAPPER_SYMBOL_PREFIX "strlen";
+    case BUILT_IN_STRCPY:
+      return CHKP_WRAPPER_SYMBOL_PREFIX "strcpy";
+    case BUILT_IN_STRNCPY:
+      return CHKP_WRAPPER_SYMBOL_PREFIX "strncpy";
+    case BUILT_IN_STPCPY:
+      return CHKP_WRAPPER_SYMBOL_PREFIX "stpcpy";
+    case BUILT_IN_STPNCPY:
+      return CHKP_WRAPPER_SYMBOL_PREFIX "stpncpy";
+    case BUILT_IN_STRCAT:
+      return CHKP_WRAPPER_SYMBOL_PREFIX "strcat";
+    case BUILT_IN_STRNCAT:
+      return CHKP_WRAPPER_SYMBOL_PREFIX "strncat";
+    case BUILT_IN_MEMCPY:
+      return CHKP_WRAPPER_SYMBOL_PREFIX "memcpy";
+    case BUILT_IN_MEMPCPY:
+      return CHKP_WRAPPER_SYMBOL_PREFIX "mempcpy";
+    case BUILT_IN_MEMSET:
+      return CHKP_WRAPPER_SYMBOL_PREFIX "memset";
+    case BUILT_IN_MEMMOVE:
+      return CHKP_WRAPPER_SYMBOL_PREFIX "memmove";
+    case BUILT_IN_BZERO:
+      return CHKP_WRAPPER_SYMBOL_PREFIX "bzero";
+    case BUILT_IN_MALLOC:
+      return CHKP_WRAPPER_SYMBOL_PREFIX "malloc";
+    case BUILT_IN_CALLOC:
+      return CHKP_WRAPPER_SYMBOL_PREFIX "calloc";
+    case BUILT_IN_REALLOC:
+      return CHKP_WRAPPER_SYMBOL_PREFIX "realloc";
+
+    default:
+      gcc_unreachable ();
+    }
+
+  return "";
+}
+
 /* Build a clone of FNDECL with a modified name.  */
 
 static tree
@@ -164,9 +201,8 @@ chkp_build_instrumented_fndecl (tree fndecl)
      instrumented version.  */
   if (chkp_wrap_function(fndecl))
     {
-      s = CHKP_WRAPPER_SYMBOL_PREFIX;
-      s += IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl));
-      new_name = get_identifier (s.c_str ());
+      new_name = get_identifier (chkp_wrap_function_name (fndecl));
+      DECL_VISIBILITY (new_decl) = VISIBILITY_DEFAULT;
     }
   else
     {
@@ -244,7 +280,7 @@ tree
 chkp_copy_function_type_adding_bounds (tree orig_type)
 {
   tree type;
-  tree arg_type, attrs, t;
+  tree arg_type, attrs;
   unsigned len = list_length (TYPE_ARG_TYPES (orig_type));
   unsigned *indexes = XALLOCAVEC (unsigned, len);
   unsigned idx = 0, new_idx = 0;
@@ -264,7 +300,7 @@ chkp_copy_function_type_adding_bounds (tree orig_type)
   if (!arg_type)
     return orig_type;
 
-  type = copy_node (orig_type);
+  type = build_distinct_type_copy (orig_type);
   TYPE_ARG_TYPES (type) = copy_list (TYPE_ARG_TYPES (type));
 
   for (arg_type = TYPE_ARG_TYPES (type);
@@ -327,20 +363,6 @@ chkp_copy_function_type_adding_bounds (tree orig_type)
       TYPE_ATTRIBUTES (type) = attrs;
     }
 
-  t = TYPE_MAIN_VARIANT (orig_type);
-  if (orig_type != t)
-    {
-      TYPE_MAIN_VARIANT (type) = t;
-      TYPE_NEXT_VARIANT (type) = TYPE_NEXT_VARIANT (t);
-      TYPE_NEXT_VARIANT (t) = type;
-    }
-  else
-    {
-      TYPE_MAIN_VARIANT (type) = type;
-      TYPE_NEXT_VARIANT (type) = NULL;
-    }
-
-
   return type;
 }
 
@@ -541,22 +563,10 @@ chkp_maybe_create_clone (tree fndecl)
 
       if (gimple_has_body_p (fndecl))
        {
-         /* If function will not be instrumented, then it's instrumented
-            version is a thunk for the original.  */
-         if (!chkp_instrumentable_p (fndecl))
-           {
-             clone->remove_callees ();
-             clone->remove_all_references ();
-             clone->thunk.thunk_p = true;
-             clone->thunk.add_pointer_bounds_args = true;
-             clone->create_edge (node, NULL, 0, CGRAPH_FREQ_BASE);
-           }
-         else
-           {
-             tree_function_versioning (fndecl, new_decl, NULL, false,
-                                       NULL, false, NULL, NULL);
-             clone->lowered = true;
-           }
+         gcc_assert (chkp_instrumentable_p (fndecl));
+         tree_function_versioning (fndecl, new_decl, NULL, false,
+                                   NULL, false, NULL, NULL);
+         clone->lowered = true;
        }
 
       /* New params are inserted after versioning because it
@@ -583,12 +593,7 @@ chkp_maybe_create_clone (tree fndecl)
 
       /* Clone all aliases.  */
       for (i = 0; node->iterate_direct_aliases (i, ref); i++)
-       {
-         struct cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
-         struct cgraph_node *chkp_alias
-           = chkp_maybe_create_clone (alias->decl);
-         chkp_alias->create_reference (clone, IPA_REF_ALIAS, NULL);
-       }
+       chkp_maybe_create_clone (ref->referring->decl);
 
       /* Clone all thunks.  */
       for (e = node->callers; e; e = e->next_caller)
@@ -612,7 +617,10 @@ chkp_maybe_create_clone (tree fndecl)
 
          ref = node->ref_list.first_reference ();
          if (ref)
-           chkp_maybe_create_clone (ref->referred->decl);
+           {
+             target = chkp_maybe_create_clone (ref->referred->decl);
+             clone->create_reference (target, IPA_REF_ALIAS);
+           }
 
          if (node->alias_target)
            {
@@ -714,6 +722,9 @@ chkp_produce_thunks (bool early)
                             0, CGRAPH_FREQ_BASE);
          node->create_reference (node->instrumented_version,
                               IPA_REF_CHKP, NULL);
+         /* Thunk shouldn't be a cdtor.  */
+         DECL_STATIC_CONSTRUCTOR (node->decl) = 0;
+         DECL_STATIC_DESTRUCTOR (node->decl) = 0;
        }
     }