OSDN Git Service

* haifa-sched.c (extend_global): Split to extend_global_data and
[pf3gnuchains/gcc-fork.git] / gcc / builtins.c
index ca55191..953fb7b 100644 (file)
@@ -207,6 +207,7 @@ static rtx expand_builtin_memory_chk (tree, rtx, enum machine_mode,
                                      enum built_in_function);
 static void maybe_emit_chk_warning (tree, enum built_in_function);
 static void maybe_emit_sprintf_chk_warning (tree, enum built_in_function);
+static void maybe_emit_free_warning (tree);
 static tree fold_builtin_object_size (tree, tree);
 static tree fold_builtin_strcat_chk (tree, tree, tree, tree);
 static tree fold_builtin_strncat_chk (tree, tree, tree, tree, tree);
@@ -2910,7 +2911,7 @@ expand_builtin_pow (tree exp, rtx target, rtx subtarget)
   if (real_identical (&c, &cint)
       && ((n >= -1 && n <= 2)
          || (flag_unsafe_math_optimizations
-             && !optimize_size
+             && optimize_insn_for_speed_p ()
              && powi_cost (n) <= POWI_MAX_MULTS)))
     {
       op = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
@@ -2934,7 +2935,7 @@ expand_builtin_pow (tree exp, rtx target, rtx subtarget)
       real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
       if (real_identical (&c2, &cint)
          && ((flag_unsafe_math_optimizations
-              && !optimize_size
+              && optimize_insn_for_speed_p ()
               && powi_cost (n/2) <= POWI_MAX_MULTS)
              || n == 1))
        {
@@ -2979,7 +2980,7 @@ expand_builtin_pow (tree exp, rtx target, rtx subtarget)
       real_arithmetic (&c2, RDIV_EXPR, &cint, &dconst3);
       real_convert (&c2, mode, &c2);
       if (real_identical (&c2, &c)
-         && ((!optimize_size
+         && ((optimize_insn_for_speed_p ()
               && powi_cost (n/3) <= POWI_MAX_MULTS)
              || n == 1))
        {
@@ -3041,7 +3042,7 @@ expand_builtin_powi (tree exp, rtx target, rtx subtarget)
       if ((TREE_INT_CST_HIGH (arg1) == 0
           || TREE_INT_CST_HIGH (arg1) == -1)
          && ((n >= -1 && n <= 2)
-             || (! optimize_size
+             || (optimize_insn_for_speed_p ()
                  && powi_cost (n) <= POWI_MAX_MULTS)))
        {
          op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
@@ -4463,7 +4464,7 @@ expand_builtin_strcat (tree fndecl, tree exp, rtx target, enum machine_mode mode
       if (p && *p == '\0')
        return expand_expr (dst, target, mode, EXPAND_NORMAL);
 
-      if (!optimize_size)
+      if (optimize_insn_for_speed_p ())
        {
          /* See if we can store by pieces into (dst + strlen(dst)).  */
          tree newsrc, newdst,
@@ -6130,7 +6131,8 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
   if (!optimize
       && !called_as_built_in (fndecl)
       && DECL_ASSEMBLER_NAME_SET_P (fndecl)
-      && fcode != BUILT_IN_ALLOCA)
+      && fcode != BUILT_IN_ALLOCA
+      && fcode != BUILT_IN_FREE)
     return expand_call (exp, target, ignore);
 
   /* The built-in function expanders test for target == const0_rtx
@@ -7007,6 +7009,10 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
       maybe_emit_sprintf_chk_warning (exp, fcode);
       break;
 
+    case BUILT_IN_FREE:
+      maybe_emit_free_warning (exp);
+      break;
+
     default:   /* just do library call, if unknown builtin */
       break;
     }
@@ -11981,6 +11987,27 @@ maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
     }
 }
 
+/* Emit warning if a free is called with address of a variable.  */
+
+static void
+maybe_emit_free_warning (tree exp)
+{
+  tree arg = CALL_EXPR_ARG (exp, 0);
+
+  STRIP_NOPS (arg);
+  if (TREE_CODE (arg) != ADDR_EXPR)
+    return;
+
+  arg = get_base_address (TREE_OPERAND (arg, 0));
+  if (arg == NULL || INDIRECT_REF_P (arg))
+    return;
+
+  if (SSA_VAR_P (arg))
+    warning (0, "%Kattempt to free a non-heap object %qD", exp, arg);
+  else
+    warning (0, "%Kattempt to free a non-heap object", exp);
+}
+
 /* Fold a call to __builtin_object_size with arguments PTR and OST,
    if possible.  */