OSDN Git Service

Change attribute((option(...))) to attribute((target(...))); Do not allocate tree...
[pf3gnuchains/gcc-fork.git] / gcc / c-common.c
index 8bac9cb..748ab52 100644 (file)
@@ -571,7 +571,7 @@ static tree handle_warn_unused_result_attribute (tree *, tree, tree, int,
 static tree handle_sentinel_attribute (tree *, tree, tree, int, bool *);
 static tree handle_type_generic_attribute (tree *, tree, tree, int, bool *);
 static tree handle_alloc_size_attribute (tree *, tree, tree, int, bool *);
-static tree handle_option_attribute (tree *, tree, tree, int, bool *);
+static tree handle_target_attribute (tree *, tree, tree, int, bool *);
 static tree handle_optimize_attribute (tree *, tree, tree, int, bool *);
 
 static void check_function_nonnull (tree, int, tree *);
@@ -856,8 +856,8 @@ const struct attribute_spec c_common_attribute_table[] =
                              handle_error_attribute },
   { "error",                 1, 1, true,  false, false,
                              handle_error_attribute },
-  { "option",                 1, -1, true, false, false,
-                             handle_option_attribute },
+  { "target",                 1, -1, true, false, false,
+                             handle_target_attribute },
   { "optimize",               1, -1, true, false, false,
                              handle_optimize_attribute },
   { NULL,                     0, 0, false, false, false, NULL }
@@ -1044,7 +1044,7 @@ fname_decl (unsigned int rid, tree id)
       input_location = saved_location;
     }
   if (!ix && !current_function_decl)
-    pedwarn (0, "%qD is not defined outside of function scope", decl);
+    pedwarn (input_location, 0, "%qD is not defined outside of function scope", decl);
 
   return decl;
 }
@@ -1093,7 +1093,7 @@ fix_string_type (tree value)
           separate the %d from the 'C'.  'ISO' should not be
           translated, but it may be moved after 'C%d' in languages
           where modifiers follow nouns.  */
-       pedwarn (OPT_Woverlength_strings,
+       pedwarn (input_location, OPT_Woverlength_strings,
                 "string length %qd is greater than the length %qd "
                 "ISO C%d compilers are required to support",
                 nchars - 1, nchars_max, relevant_std);
@@ -1141,7 +1141,7 @@ constant_expression_warning (tree value)
          || TREE_CODE (value) == VECTOR_CST
          || TREE_CODE (value) == COMPLEX_CST)
       && TREE_OVERFLOW (value))
-    pedwarn (OPT_Woverflow, "overflow in constant expression");
+    pedwarn (input_location, OPT_Woverflow, "overflow in constant expression");
 }
 
 /* The same as above but print an unconditional error.  */
@@ -1359,7 +1359,7 @@ check_main_parameter_types (tree decl)
        {
        case 1:
          if (TYPE_MAIN_VARIANT (type) != integer_type_node)
-           pedwarn (OPT_Wmain, "first argument of %q+D should be %<int%>", 
+           pedwarn (input_location, OPT_Wmain, "first argument of %q+D should be %<int%>", 
                    decl);
          break;
 
@@ -1368,7 +1368,7 @@ check_main_parameter_types (tree decl)
              || TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE
              || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type)))
                  != char_type_node))
-           pedwarn (OPT_Wmain, "second argument of %q+D should be %<char **%>",
+           pedwarn (input_location, OPT_Wmain, "second argument of %q+D should be %<char **%>",
                    decl);
          break;
 
@@ -1377,7 +1377,7 @@ check_main_parameter_types (tree decl)
              || TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE
              || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type)))
                  != char_type_node))
-          pedwarn (OPT_Wmain, "third argument of %q+D should probably be "
+          pedwarn (input_location, OPT_Wmain, "third argument of %q+D should probably be "
                    "%<char **%>", decl);
          break;
        }
@@ -1387,7 +1387,7 @@ check_main_parameter_types (tree decl)
     argument because it's only mentioned in an appendix of the
     standard.  */
   if (argct > 0 && (argct < 2 || argct > 3))
-    pedwarn (OPT_Wmain, "%q+D takes only zero or two arguments", decl);
+    pedwarn (input_location, OPT_Wmain, "%q+D takes only zero or two arguments", decl);
 }
 
 /* True if pointers to distinct types T1 and T2 can be converted to
@@ -1436,7 +1436,7 @@ vector_types_convertible_p (const_tree t1, const_tree t2, bool emit_lax_note)
   if (emit_lax_note && !emitted_lax_note)
     {
       emitted_lax_note = true;
-      inform ("use -flax-vector-conversions to permit "
+      inform (input_location, "use -flax-vector-conversions to permit "
               "conversions between vectors with differing "
               "element types or numbers of subparts");
     }
@@ -1556,11 +1556,22 @@ conversion_warning (tree type, tree expr)
 {
   bool give_warning = false;
 
+  int i;
+  const int expr_num_operands = TREE_OPERAND_LENGTH (expr);
   tree expr_type = TREE_TYPE (expr);
 
   if (!warn_conversion && !warn_sign_conversion)
     return;
 
+  /* If any operand is artificial, then this expression was generated
+     by the compiler and we do not warn.  */
+  for (i = 0; i < expr_num_operands; i++)
+    {
+      tree op = TREE_OPERAND (expr, i);
+      if (op && DECL_P (op) && DECL_ARTIFICIAL (op))
+       return;
+    }
+
   switch (TREE_CODE (expr))
     {
     case EQ_EXPR:
@@ -1682,13 +1693,16 @@ conversion_warning (tree type, tree expr)
                                             TREE_OPERAND (expr, 1), 
                                             /* bitwise */1);
 
-             /* If one of the operands is a non-negative constant
-                that fits in the target type, then the type of the
-                other operand does not matter. */
              if (TREE_CODE (expr) == BIT_AND_EXPR)
                {
                  tree op0 = TREE_OPERAND (expr, 0);
                  tree op1 = TREE_OPERAND (expr, 1);
+                 bool unsigned0 = TYPE_UNSIGNED (TREE_TYPE (op0));
+                 bool unsigned1 = TYPE_UNSIGNED (TREE_TYPE (op1));
+
+                 /* If one of the operands is a non-negative constant
+                    that fits in the target type, then the type of the
+                    other operand does not matter. */
                  if ((TREE_CODE (op0) == INTEGER_CST
                       && int_fits_type_p (op0, c_common_signed_type (type))
                       && int_fits_type_p (op0, c_common_unsigned_type (type)))
@@ -1697,6 +1711,15 @@ conversion_warning (tree type, tree expr)
                          && int_fits_type_p (op1, 
                                              c_common_unsigned_type (type))))
                    return;
+                 /* If constant is unsigned and fits in the target
+                    type, then the result will also fit.  */
+                 else if ((TREE_CODE (op0) == INTEGER_CST
+                           && unsigned0 
+                           && int_fits_type_p (op0, type))
+                          || (TREE_CODE (op1) == INTEGER_CST
+                              && unsigned1
+                              && int_fits_type_p (op1, type)))
+                   return;
                }
            }
           /* Warn for integer types converted to smaller integer types.  */
@@ -2166,6 +2189,13 @@ verify_tree (tree x, struct tlist **pbefore_sp, struct tlist **pno_sp,
        return;
       }
 
+    case ADDR_EXPR:
+      x = TREE_OPERAND (x, 0);
+      if (DECL_P (x))
+       return;
+      writer = 0;
+      goto restart;
+
     default:
       /* For other expressions, simply recurse on their operands.
         Manual tail recursion for unary expressions.
@@ -3262,19 +3292,19 @@ pointer_int_sum (enum tree_code resultcode, tree ptrop, tree intop)
 
   if (TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE)
     {
-      pedwarn (pedantic ? OPT_pedantic : OPT_Wpointer_arith, 
+      pedwarn (input_location, pedantic ? OPT_pedantic : OPT_Wpointer_arith, 
               "pointer of type %<void *%> used in arithmetic");
       size_exp = integer_one_node;
     }
   else if (TREE_CODE (TREE_TYPE (result_type)) == FUNCTION_TYPE)
     {
-      pedwarn (pedantic ? OPT_pedantic : OPT_Wpointer_arith, 
+      pedwarn (input_location, pedantic ? OPT_pedantic : OPT_Wpointer_arith, 
               "pointer to a function used in arithmetic");
       size_exp = integer_one_node;
     }
   else if (TREE_CODE (TREE_TYPE (result_type)) == METHOD_TYPE)
     {
-      pedwarn (pedantic ? OPT_pedantic : OPT_Wpointer_arith, 
+      pedwarn (input_location, pedantic ? OPT_pedantic : OPT_Wpointer_arith, 
               "pointer to member function used in arithmetic");
       size_exp = integer_one_node;
     }
@@ -3783,7 +3813,7 @@ c_sizeof_or_alignof_type (tree type, bool is_sizeof, int complain)
       if (is_sizeof)
        {
          if (complain && (pedantic || warn_pointer_arith))
-           pedwarn (pedantic ? OPT_pedantic : OPT_Wpointer_arith, 
+           pedwarn (input_location, pedantic ? OPT_pedantic : OPT_Wpointer_arith, 
                     "invalid application of %<sizeof%> to a function type");
           else if (!complain)
             return error_mark_node;
@@ -3796,7 +3826,7 @@ c_sizeof_or_alignof_type (tree type, bool is_sizeof, int complain)
     {
       if (type_code == VOID_TYPE
          && complain && (pedantic || warn_pointer_arith))
-       pedwarn (pedantic ? OPT_pedantic : OPT_Wpointer_arith, 
+       pedwarn (input_location, pedantic ? OPT_pedantic : OPT_Wpointer_arith, 
                 "invalid application of %qs to a void type", op_name);
       else if (!complain)
         return error_mark_node;
@@ -4664,7 +4694,7 @@ c_add_case_label (splay_tree cases, tree cond, tree orig_type,
 
   /* Case ranges are a GNU extension.  */
   if (high_value)
-    pedwarn (OPT_pedantic, 
+    pedwarn (input_location, OPT_pedantic, 
             "range expressions in switch statements are non-standard");
 
   type = TREE_TYPE (cond);
@@ -4905,6 +4935,8 @@ c_do_switch_warnings (splay_tree cases, location_t switch_location,
   for (chain = TYPE_VALUES (type); chain; chain = TREE_CHAIN (chain))
     {
       tree value = TREE_VALUE (chain);
+      if (TREE_CODE (value) == CONST_DECL)
+        value = DECL_INITIAL (value);
       node = splay_tree_lookup (cases, (splay_tree_key) value);
       if (node)
        {
@@ -4978,7 +5010,7 @@ finish_label_address_expr (tree label)
 {
   tree result;
 
-  pedwarn (OPT_pedantic, "taking the address of a label is non-standard");
+  pedwarn (input_location, OPT_pedantic, "taking the address of a label is non-standard");
 
   if (label == error_mark_node)
     return error_mark_node;
@@ -5228,34 +5260,8 @@ handle_hot_attribute (tree *node, tree name, tree ARG_UNUSED (args),
                   name, "cold");
          *no_add_attrs = true;
        }
-      else
-       {
-         tree old_opts = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node);
-
-         /* If we are not at -O3, but are optimizing, turn on -O3
-            optimizations just for this one function.  */
-         if (((optimize > 0 && optimize < 3) || optimize_size)
-             && targetm.target_option.hot_attribute_sets_optimization
-             && (!old_opts || old_opts == optimization_default_node))
-           {
-             /* Create the hot optimization node if needed.  */
-             if (!optimization_hot_node)
-               {
-                 struct cl_optimization current_options;
-                 static const char *os_argv[] = { NULL, "-O3", NULL };
-
-                 cl_optimization_save (&current_options);
-                 decode_options (2, os_argv);
-                 optimization_hot_node = build_optimization_node ();
-                 cl_optimization_restore (&current_options);
-               }
-
-             DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node)
-               = optimization_hot_node;
-           }
-         /* Most of the rest of the hot processing is done later with
-            lookup_attribute.  */
-       }
+      /* Most of the rest of the hot processing is done later with
+        lookup_attribute.  */
     }
   else
     {
@@ -5280,34 +5286,8 @@ handle_cold_attribute (tree *node, tree name, tree ARG_UNUSED (args),
                   name, "hot");
          *no_add_attrs = true;
        }
-      else
-       {
-         tree old_opts = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node);
-
-         /* If we are optimizing, but not optimizing for space, turn on -Os
-            optimizations just for this one function.  */
-         if (optimize && !optimize_size
-             && targetm.target_option.cold_attribute_sets_optimization
-             && (!old_opts || old_opts == optimization_default_node))
-           {
-             /* Create the cold optimization node if needed.  */
-             if (!optimization_cold_node)
-               {
-                 struct cl_optimization current_options;
-                 static const char *os_argv[] = { NULL, "-Os", NULL };
-
-                 cl_optimization_save (&current_options);
-                 decode_options (2, os_argv);
-                 optimization_cold_node = build_optimization_node ();
-                 cl_optimization_restore (&current_options);
-               }
-
-             DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node)
-               = optimization_cold_node;
-           }
-         /* Most of the rest of the cold processing is done later with
-            lookup_attribute.  */
-       }
+      /* Most of the rest of the cold processing is done later with
+        lookup_attribute.  */
     }
   else
     {
@@ -7006,11 +6986,10 @@ handle_type_generic_attribute (tree *node, tree ARG_UNUSED (name),
   return NULL_TREE;
 }
 
-/* For handling "option" attribute. arguments as in
-   struct attribute_spec.handler.  */
+/* Handle a "target" attribute.  */
 
 static tree
-handle_option_attribute (tree *node, tree name, tree args, int flags,
+handle_target_attribute (tree *node, tree name, tree args, int flags,
                         bool *no_add_attrs)
 {
   /* Ensure we have a function type.  */
@@ -7019,14 +6998,6 @@ handle_option_attribute (tree *node, tree name, tree args, int flags,
       warning (OPT_Wattributes, "%qE attribute ignored", name);
       *no_add_attrs = true;
     }
-  else if (targetm.target_option.valid_attribute_p
-          == default_target_option_valid_attribute_p)
-    {
-      warning (OPT_Wattributes,
-              "%qE attribute is not supported on this machine",
-              name);
-      *no_add_attrs = true;
-    }
   else if (! targetm.target_option.valid_attribute_p (*node, name, args,
                                                      flags))
     *no_add_attrs = true;
@@ -7660,6 +7631,7 @@ fold_offsetof_1 (tree expr, tree stop_ref)
       return error_mark_node;
 
     case CALL_EXPR:
+    case TARGET_EXPR:
       error ("cannot apply %<offsetof%> when %<operator[]%> is overloaded");
       return error_mark_node;