OSDN Git Service

* gcc.dg/lto/ipacp_0.c: New test.
[pf3gnuchains/gcc-fork.git] / gcc / opts.c
index 51a0cb9..d5a9fb3 100644 (file)
@@ -1,5 +1,5 @@
 /* Command line option handling.
-   Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+   Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
    Contributed by Neil Booth.
 
@@ -372,13 +372,11 @@ const char **in_fnames;
 unsigned num_in_fnames;
 
 static int common_handle_option (size_t scode, const char *arg, int value,
-                                unsigned int lang_mask);
+                                unsigned int lang_mask, int kind);
 static void handle_param (const char *);
-static unsigned int handle_option (const char **argv, unsigned int lang_mask);
 static char *write_langs (unsigned int lang_mask);
 static void complain_wrong_lang (const char *, const struct cl_option *,
                                 unsigned int lang_mask);
-static void handle_options (unsigned int, const char **, unsigned int);
 static void set_debug_level (enum debug_info_type type, int extended,
                             const char *arg);
 
@@ -436,7 +434,7 @@ complain_wrong_lang (const char *text, const struct cl_option *option,
   /* The LTO front end inherits all the options from the first front
      end that was used.  However, not all the original front end
      options make sense in LTO.
-     
+
      A real solution would be to filter this in collect2, but collect2
      does not have access to all the option attributes to know what to
      filter.  So, in lto1 we silently accept inherited flags and do
@@ -485,10 +483,57 @@ void print_ignored_options (void)
   input_location = saved_loc;
 }
 
+
+/* Handle option OPT_INDEX, and argument ARG, for the language
+   indicated by LANG_MASK.  VALUE is true, unless no- form of an -f or
+   -W option was given.  KIND is the diagnostic_t if this is a
+   diagnostics option, DK_UNSPECIFIED otherwise.  Returns false if the
+   switch was invalid.  */
+bool
+handle_option (int opt_index, int value, const char *arg,
+               unsigned int lang_mask, int kind)
+{
+  const struct cl_option *option = &cl_options[opt_index];
+
+  if (option->flag_var)
+    set_option (opt_index, value, arg, kind);
+  
+  if (option->flags & lang_mask)
+    {
+      if (lang_hooks.handle_option (opt_index, arg, value, kind) == 0)
+       return false;
+#ifdef ENABLE_LTO
+      else
+       lto_register_user_option (opt_index, arg, value, lang_mask);
+ #endif
+    }
+
+  if (option->flags & CL_COMMON)
+    {
+      if (common_handle_option (opt_index, arg, value, lang_mask, kind) == 0)
+       return false;
+#ifdef ENABLE_LTO
+      else
+       lto_register_user_option (opt_index, arg, value, CL_COMMON);
+#endif
+    }
+
+  if (option->flags & CL_TARGET)
+    {
+      if (!targetm.handle_option (opt_index, arg, value))
+       return false;
+#ifdef ENABLE_LTO
+      else
+       lto_register_user_option (opt_index, arg, value, CL_TARGET);
+#endif
+    }
+  return true;
+}
+
 /* Handle the switch beginning at ARGV for the language indicated by
    LANG_MASK.  Returns the number of switches consumed.  */
 static unsigned int
-handle_option (const char **argv, unsigned int lang_mask)
+read_cmdline_option (const char **argv, unsigned int lang_mask)
 {
   size_t opt_index;
   const char *opt, *arg = 0;
@@ -609,32 +654,8 @@ handle_option (const char **argv, unsigned int lang_mask)
        }
     }
 
-  if (option->flag_var)
-    set_option (option, value, arg);
-
-  if (option->flags & lang_mask)
-    {
-      if (lang_hooks.handle_option (opt_index, arg, value) == 0)
-       result = 0;
-      else
-       lto_register_user_option (opt_index, arg, value, lang_mask);
-    }
-
-  if (result && (option->flags & CL_COMMON))
-    {
-      if (common_handle_option (opt_index, arg, value, lang_mask) == 0)
-       result = 0;
-      else
-       lto_register_user_option (opt_index, arg, value, CL_COMMON);
-    }
-
-  if (result && (option->flags & CL_TARGET))
-    {
-      if (!targetm.handle_option (opt_index, arg, value))
-       result = 0;
-      else
-       lto_register_user_option (opt_index, arg, value, CL_TARGET);
-    }
+  if (!handle_option (opt_index, value, arg, lang_mask, DK_UNSPECIFIED))
+    result = 0;
 
  done:
   if (dup)
@@ -735,7 +756,7 @@ flag_instrument_functions_exclude_p (tree fndecl)
    contains has a single bit set representing the current
    language.  */
 static void
-handle_options (unsigned int argc, const char **argv, unsigned int lang_mask)
+read_cmdline_options (unsigned int argc, const char **argv, unsigned int lang_mask)
 {
   unsigned int n, i;
 
@@ -757,7 +778,7 @@ handle_options (unsigned int argc, const char **argv, unsigned int lang_mask)
          continue;
        }
 
-      n = handle_option (argv + i, lang_mask);
+      n = read_cmdline_option (argv + i, lang_mask);
 
       if (!n)
        {
@@ -829,12 +850,14 @@ decode_options (unsigned int argc, const char **argv)
              if (optimize_val != -1)
                {
                  optimize = optimize_val;
+                 if ((unsigned int) optimize > 255)
+                   optimize = 255;
                  optimize_size = 0;
                }
            }
        }
     }
-  
+
   /* Use priority coloring if cover classes is not defined for the
      target.  */
   if (targetm.ira_cover_classes == NULL)
@@ -856,6 +879,7 @@ decode_options (unsigned int argc, const char **argv)
   flag_if_conversion2 = opt1;
   flag_ipa_pure_const = opt1;
   flag_ipa_reference = opt1;
+  flag_ipa_profile = opt1;
   flag_merge_constants = opt1;
   flag_split_wide_types = opt1;
   flag_tree_ccp = opt1;
@@ -884,7 +908,8 @@ decode_options (unsigned int argc, const char **argv)
   flag_caller_saves = opt2;
   flag_peephole2 = opt2;
 #ifdef INSN_SCHEDULING
-  flag_schedule_insns = opt2;
+  /* Only run the pre-regalloc scheduling pass if optimizing for speed.  */
+  flag_schedule_insns = opt2 && ! optimize_size;
   flag_schedule_insns_after_reload = opt2;
 #endif
   flag_regmove = opt2;
@@ -895,7 +920,7 @@ decode_options (unsigned int argc, const char **argv)
   flag_tree_vrp = opt2;
   flag_tree_builtin_call_dce = opt2;
   flag_tree_pre = opt2;
-  flag_tree_switch_conversion = 1;
+  flag_tree_switch_conversion = opt2;
   flag_ipa_cp = opt2;
   flag_ipa_sra = opt2;
 
@@ -942,6 +967,9 @@ decode_options (unsigned int argc, const char **argv)
   else
     set_param_value ("min-crossjump-insns", initial_min_crossjump_insns);
 
+  /* Enable -Werror=coverage-mismatch by default */
+  enable_warning_as_error("coverage-mismatch", 1, lang_mask);
+
   if (first_time_p)
     {
       /* Initialize whether `char' is signed.  */
@@ -958,34 +986,43 @@ decode_options (unsigned int argc, const char **argv)
       flag_unwind_tables = targetm.unwind_tables_default;
     }
 
+#ifdef ENABLE_LTO
   /* Clear any options currently held for LTO.  */
   lto_clear_user_options ();
+#endif
 
 #ifdef OPTIMIZATION_OPTIONS
   /* Allow default optimizations to be specified on a per-machine basis.  */
   OPTIMIZATION_OPTIONS (optimize, optimize_size);
 #endif
 
-  handle_options (argc, argv, lang_mask);
+  read_cmdline_options (argc, argv, lang_mask);
 
-  /* Make DUMP_BASE_NAME relative to the AUX_BASE_NAME directory,
-     typically the directory to contain the object file.  */
-  if (aux_base_name && ! IS_ABSOLUTE_PATH (dump_base_name))
+  if (dump_base_name && ! IS_ABSOLUTE_PATH (dump_base_name))
     {
-      const char *aux_base;
-
-      base_of_path (aux_base_name, &aux_base);
-      if (aux_base_name != aux_base)
+      /* First try to make DUMP_BASE_NAME relative to the DUMP_DIR_NAME
+        directory.  Then try to make DUMP_BASE_NAME relative to the
+        AUX_BASE_NAME directory, typically the directory to contain
+        the object file.  */
+      if (dump_dir_name)
+       dump_base_name = concat (dump_dir_name, dump_base_name, NULL);
+      else if (aux_base_name)
        {
-         int dir_len = aux_base - aux_base_name;
-         char *new_dump_base_name =
-           XNEWVEC (char, strlen(dump_base_name) + dir_len + 1);
-
-         /* Copy directory component from AUX_BASE_NAME.  */
-         memcpy (new_dump_base_name, aux_base_name, dir_len);
-         /* Append existing DUMP_BASE_NAME.  */
-         strcpy (new_dump_base_name + dir_len, dump_base_name);
-         dump_base_name = new_dump_base_name;
+         const char *aux_base;
+
+         base_of_path (aux_base_name, &aux_base);
+         if (aux_base_name != aux_base)
+           {
+             int dir_len = aux_base - aux_base_name;
+             char *new_dump_base_name =
+               XNEWVEC (char, strlen(dump_base_name) + dir_len + 1);
+
+             /* Copy directory component from AUX_BASE_NAME.  */
+             memcpy (new_dump_base_name, aux_base_name, dir_len);
+             /* Append existing DUMP_BASE_NAME.  */
+             strcpy (new_dump_base_name + dir_len, dump_base_name);
+             dump_base_name = new_dump_base_name;
+           }
        }
     }
 
@@ -1024,6 +1061,7 @@ decode_options (unsigned int argc, const char **argv)
        flag_pic = flag_pie;
       if (flag_pic && !flag_pie)
        flag_shlib = 1;
+      first_time_p = false;
     }
 
   if (optimize == 0)
@@ -1047,7 +1085,7 @@ decode_options (unsigned int argc, const char **argv)
 #endif
         ))
     {
-      inform (input_location, 
+      inform (input_location,
              "-freorder-blocks-and-partition does not work with exceptions on this architecture");
       flag_reorder_blocks_and_partition = 0;
       flag_reorder_blocks = 1;
@@ -1102,13 +1140,6 @@ decode_options (unsigned int argc, const char **argv)
       flag_ira_algorithm = IRA_ALGORITHM_PRIORITY;
     }
 
-  /* Save the current optimization options if this is the first call.  */
-  if (first_time_p)
-    {
-      optimization_default_node = build_optimization_node ();
-      optimization_current_node = optimization_default_node;
-      first_time_p = false;
-    }
   if (flag_conserve_stack)
     {
       if (!PARAM_SET_P (PARAM_LARGE_STACK_FRAME))
@@ -1116,7 +1147,31 @@ decode_options (unsigned int argc, const char **argv)
       if (!PARAM_SET_P (PARAM_STACK_FRAME_GROWTH))
         PARAM_VALUE (PARAM_STACK_FRAME_GROWTH) = 40;
     }
+  if (flag_wpa || flag_ltrans)
+    {
+      /* These passes are not WHOPR compatible yet.  */
+      flag_ipa_pta = 0;
+      flag_ipa_struct_reorg = 0;
+    }
+
+  if (flag_lto || flag_whopr)
+    {
+#ifdef ENABLE_LTO
+      flag_generate_lto = 1;
+
+      /* When generating IL, do not operate in whole-program mode.
+        Otherwise, symbols will be privatized too early, causing link
+        errors later.  */
+      flag_whole_program = 0;
+#else
+      error ("LTO support has not been enabled in this configuration");
+#endif
+    }
 
+  /* Reconcile -flto and -fwhopr.  Set additional flags as appropriate and
+     check option consistency.  */
+  if (flag_lto && flag_whopr)
+    error ("-flto and -fwhopr are mutually exclusive");
 }
 
 #define LEFT_COLUMN    27
@@ -1312,7 +1367,7 @@ print_filtered_help (unsigned int include_flags,
              printf (_(" None found.  Use --help=%s to show *all* the options supported by the %s front-end\n"),
                      lang_names[i], lang_names[i]);
        }
-       
+
     }
   else if (! displayed)
     printf (_(" All options with the desired characteristics have already been displayed\n"));
@@ -1432,7 +1487,7 @@ print_specific_help (unsigned int include_flags,
 
 static int
 common_handle_option (size_t scode, const char *arg, int value,
-                     unsigned int lang_mask)
+                     unsigned int lang_mask, int kind ATTRIBUTE_UNUSED)
 {
   static bool verbose = false;
   enum opt_code code = (enum opt_code) scode;
@@ -1617,8 +1672,8 @@ common_handle_option (size_t scode, const char *arg, int value,
       break;
 
     case OPT_Wlarger_than_:
-      /* This form corresponds to -Wlarger-than-.  
-        Kept for backward compatibility. 
+      /* This form corresponds to -Wlarger-than-.
+        Kept for backward compatibility.
         Don't use it as the first argument of warning().  */
 
     case OPT_Wlarger_than_eq:
@@ -1680,6 +1735,10 @@ common_handle_option (size_t scode, const char *arg, int value,
       dump_base_name = arg;
       break;
 
+    case OPT_dumpdir:
+      dump_dir_name = arg;
+      break;
+
     case OPT_falign_functions_:
       align_functions = value;
       break;
@@ -1731,7 +1790,7 @@ common_handle_option (size_t scode, const char *arg, int value,
       break;
 
     case OPT_fdiagnostics_show_option:
-      global_dc->show_option_requested = true;
+      global_dc->show_option_requested = value;
       break;
 
     case OPT_fdump_:
@@ -2094,14 +2153,24 @@ common_handle_option (size_t scode, const char *arg, int value,
     case OPT_fcse_skip_blocks:
     case OPT_floop_optimize:
     case OPT_frerun_loop_opt:
+    case OPT_fsched2_use_traces:
     case OPT_fstrength_reduce:
     case OPT_ftree_store_copy_prop:
     case OPT_fforce_addr:
     case OPT_ftree_salias:
     case OPT_ftree_store_ccp:
+    case OPT_Wunreachable_code:
+    case OPT_fargument_alias:
+    case OPT_fargument_noalias:
+    case OPT_fargument_noalias_anything:
+    case OPT_fargument_noalias_global:
       /* These are no-ops, preserved for backward compatibility.  */
       break;
 
+    case OPT_fuse_linker_plugin:
+      /* No-op. Used by the driver and passed to us because it starts with f.*/
+      break;
+
     default:
       /* If the flag was handled in a standard way, assume the lack of
         processing here is intentional.  */
@@ -2138,7 +2207,7 @@ handle_param (const char *carg)
   free (arg);
 }
 
-/* Used to set the level of strict aliasing warnings, 
+/* Used to set the level of strict aliasing warnings,
    when no level is specified (i.e., when -Wstrict-aliasing, and not
    -Wstrict-aliasing=level was given).
    ONOFF is assumed to take value 1 when -Wstrict-aliasing is specified,
@@ -2171,8 +2240,8 @@ set_fast_math_flags (int set)
     }
 }
 
-/* When -funsafe-math-optimizations is set the following 
-   flags are set as well.  */ 
+/* When -funsafe-math-optimizations is set the following
+   flags are set as well.  */
 void
 set_unsafe_math_optimizations_flags (int set)
 {
@@ -2327,8 +2396,10 @@ get_option_state (int option, struct cl_option_state *state)
 /* Set *OPTION according to VALUE and ARG.  */
 
 void
-set_option (const struct cl_option *option, int value, const char *arg)
+set_option (int opt_index, int value, const char *arg, int kind)
 {
+  const struct cl_option *option = &cl_options[opt_index];
+
   if (!option->flag_var)
     return;
 
@@ -2358,6 +2429,23 @@ set_option (const struct cl_option *option, int value, const char *arg)
        *(const char **) option->flag_var = arg;
        break;
     }
+
+  if ((diagnostic_t)kind != DK_UNSPECIFIED)
+    diagnostic_classify_diagnostic (global_dc, opt_index, (diagnostic_t)kind);
+}
+
+
+/* Callback function, called when -Werror= enables a warning.  */
+
+static void (*warning_as_error_callback) (int) = NULL;
+
+/* Register a callback for enable_warning_as_error calls.  */
+
+void
+register_warning_as_error_callback (void (*callback) (int))
+{
+  gcc_assert (warning_as_error_callback == NULL || callback == NULL);
+  warning_as_error_callback = callback;
 }
 
 /* Enable a warning option as an error.  This is used by -Werror= and
@@ -2379,14 +2467,20 @@ enable_warning_as_error (const char *arg, int value, unsigned int lang_mask)
     }
   else
     {
-      diagnostic_t kind = value ? DK_ERROR : DK_WARNING;
+      const diagnostic_t kind = value ? DK_ERROR : DK_WARNING;
+
       diagnostic_classify_diagnostic (global_dc, option_index, kind);
-      
-      /* -Werror=foo implies -Wfoo.  */
-      if (cl_options[option_index].var_type == CLVC_BOOLEAN
-         && cl_options[option_index].flag_var
-         && kind == DK_ERROR)
-       *(int *) cl_options[option_index].flag_var = 1;
+      if (kind == DK_ERROR)
+       {
+         const struct cl_option * const option = cl_options + option_index;
+
+         /* -Werror=foo implies -Wfoo.  */
+         if (option->var_type == CLVC_BOOLEAN)
+           handle_option (option_index, value, arg, lang_mask, (int)kind);
+
+         if (warning_as_error_callback)
+           warning_as_error_callback (option_index);
+       }
     }
   free (new_option);
 }