]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/opts.c
PR debug/38757 continued. Handle C11, C++11 and C++14.
[thirdparty/gcc.git] / gcc / opts.c
index 305419620186b62fe6bfd5d8eb1097fc149312fb..3a0ed61e59372414fe32c74634693f117151ddde 100644 (file)
@@ -307,6 +307,14 @@ init_options_struct (struct gcc_options *opts, struct gcc_options *opts_set)
   targetm_common.option_init_struct (opts);
 }
 
+/* Release any allocations owned by OPTS.  */
+
+void
+finalize_options_struct (struct gcc_options *opts)
+{
+  XDELETEVEC (opts->x_param_values);
+}
+
 /* If indicated by the optimization level LEVEL (-Os if SIZE is set,
    -Ofast if FAST is set, -Og if DEBUG is set), apply the option DEFAULT_OPT
    to OPTS and OPTS_SET, diagnostic context DC, location LOC, with language
@@ -500,6 +508,7 @@ static const struct default_options default_options_table[] =
     { OPT_LEVELS_2_PLUS, OPT_fipa_icf, NULL, 1 },
     { OPT_LEVELS_2_PLUS, OPT_fisolate_erroneous_paths_dereference, NULL, 1 },
     { OPT_LEVELS_2_PLUS, OPT_fuse_caller_save, NULL, 1 },
+    { OPT_LEVELS_2_PLUS, OPT_flra_remat, NULL, 1 },
 
     /* -O3 optimizations.  */
     { OPT_LEVELS_3_PLUS, OPT_ftree_loop_distribute_patterns, NULL, 1 },
@@ -877,19 +886,45 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set,
   if (opts->x_dwarf_split_debug_info)
     opts->x_debug_generate_pub_sections = 2;
 
-  /* Userspace and kernel ASan conflict with each other and with TSan.  */
+  /* Userspace and kernel ASan conflict with each other.  */
 
-  if ((flag_sanitize & SANITIZE_USER_ADDRESS)
-      && (flag_sanitize & SANITIZE_KERNEL_ADDRESS))
+  if ((opts->x_flag_sanitize & SANITIZE_USER_ADDRESS)
+      && (opts->x_flag_sanitize & SANITIZE_KERNEL_ADDRESS))
     error_at (loc,
-              "-fsanitize=address is incompatible with "
-              "-fsanitize=kernel-address");
+             "-fsanitize=address is incompatible with "
+             "-fsanitize=kernel-address");
 
-  if ((flag_sanitize & SANITIZE_ADDRESS)
-      && (flag_sanitize & SANITIZE_THREAD))
+  /* And with TSan.  */
+
+  if ((opts->x_flag_sanitize & SANITIZE_ADDRESS)
+      && (opts->x_flag_sanitize & SANITIZE_THREAD))
     error_at (loc,
-              "-fsanitize=address and -fsanitize=kernel-address "
-              "are incompatible with -fsanitize=thread");
+             "-fsanitize=address and -fsanitize=kernel-address "
+             "are incompatible with -fsanitize=thread");
+
+  /* Error recovery is not allowed for ASan and TSan.  */
+
+  if (opts->x_flag_sanitize_recover & SANITIZE_USER_ADDRESS)
+    error_at (loc, "-fsanitize-recover=address is not supported");
+
+  if (opts->x_flag_sanitize_recover & SANITIZE_THREAD)
+    error_at (loc, "-fsanitize-recover=thread is not supported");
+
+  if (opts->x_flag_sanitize_recover & SANITIZE_LEAK)
+    error_at (loc, "-fsanitize-recover=leak is not supported");
+
+  /* When instrumenting the pointers, we don't want to remove
+     the null pointer checks.  */
+  if (opts->x_flag_sanitize & (SANITIZE_NULL | SANITIZE_NONNULL_ATTRIBUTE
+                               | SANITIZE_RETURNS_NONNULL_ATTRIBUTE))
+    opts->x_flag_delete_null_pointer_checks = 0;
+
+  /* Aggressive compiler optimizations may cause false negatives.  */
+  if (opts->x_flag_sanitize)
+    {
+      opts->x_flag_aggressive_loop_optimizations = 0;
+      opts->x_flag_strict_overflow = 0;
+    }
 }
 
 #define LEFT_COLUMN    27
@@ -1280,6 +1315,50 @@ print_specific_help (unsigned int include_flags,
                       opts->x_help_columns, opts, lang_mask);
 }
 
+/* Enable FDO-related flags.  */
+
+static void
+enable_fdo_optimizations (struct gcc_options *opts,
+                         struct gcc_options *opts_set,
+                         int value)
+{
+  if (!opts_set->x_flag_branch_probabilities)
+    opts->x_flag_branch_probabilities = value;
+  if (!opts_set->x_flag_profile_values)
+    opts->x_flag_profile_values = value;
+  if (!opts_set->x_flag_unroll_loops)
+    opts->x_flag_unroll_loops = value;
+  if (!opts_set->x_flag_peel_loops)
+    opts->x_flag_peel_loops = value;
+  if (!opts_set->x_flag_tracer)
+    opts->x_flag_tracer = value;
+  if (!opts_set->x_flag_value_profile_transformations)
+    opts->x_flag_value_profile_transformations = value;
+  if (!opts_set->x_flag_inline_functions)
+    opts->x_flag_inline_functions = value;
+  if (!opts_set->x_flag_ipa_cp)
+    opts->x_flag_ipa_cp = value;
+  if (!opts_set->x_flag_ipa_cp_clone
+      && value && opts->x_flag_ipa_cp)
+    opts->x_flag_ipa_cp_clone = value;
+  if (!opts_set->x_flag_predictive_commoning)
+    opts->x_flag_predictive_commoning = value;
+  if (!opts_set->x_flag_unswitch_loops)
+    opts->x_flag_unswitch_loops = value;
+  if (!opts_set->x_flag_gcse_after_reload)
+    opts->x_flag_gcse_after_reload = value;
+  if (!opts_set->x_flag_tree_loop_vectorize
+      && !opts_set->x_flag_tree_vectorize)
+    opts->x_flag_tree_loop_vectorize = value;
+  if (!opts_set->x_flag_tree_slp_vectorize
+      && !opts_set->x_flag_tree_vectorize)
+    opts->x_flag_tree_slp_vectorize = value;
+  if (!opts_set->x_flag_vect_cost_model)
+    opts->x_flag_vect_cost_model = VECT_COST_MODEL_DYNAMIC;
+  if (!opts_set->x_flag_tree_loop_distribute_patterns)
+    opts->x_flag_tree_loop_distribute_patterns = value;
+}
+
 /* Handle target- and language-independent options.  Return zero to
    generate an "unknown option" message.  Only options that need
    extra handling need to be listed here; if you simply want
@@ -1473,8 +1552,12 @@ common_handle_option (struct gcc_options *opts,
       break;
 
     case OPT_fsanitize_:
+    case OPT_fsanitize_recover_:
       {
        const char *p = arg;
+       unsigned int *flag
+         = code == OPT_fsanitize_ ? &opts->x_flag_sanitize
+         : &opts->x_flag_sanitize_recover;
        while (*p != 0)
          {
            static const struct
@@ -1540,32 +1623,29 @@ common_handle_option (struct gcc_options *opts,
                {
                  /* Handle both -fsanitize and -fno-sanitize cases.  */
                  if (value)
-                   flag_sanitize |= spec[i].flag;
+                   *flag |= spec[i].flag;
                  else
-                   flag_sanitize &= ~spec[i].flag;
+                   *flag &= ~spec[i].flag;
                  found = true;
                  break;
                }
 
            if (! found)
              error_at (loc,
-                       "unrecognized argument to -fsanitize= option: %q.*s",
-                       (int) len, p);
+                       "unrecognized argument to -fsanitize%s= option: %q.*s",
+                       code == OPT_fsanitize_ ? "" : "-recover", (int) len, p);
 
            if (comma == NULL)
              break;
            p = comma + 1;
          }
 
-       /* When instrumenting the pointers, we don't want to remove
-          the null pointer checks.  */
-       if (flag_sanitize & (SANITIZE_NULL | SANITIZE_NONNULL_ATTRIBUTE
-                            | SANITIZE_RETURNS_NONNULL_ATTRIBUTE))
-         opts->x_flag_delete_null_pointer_checks = 0;
+       if (code != OPT_fsanitize_)
+         break;
 
        /* Kernel ASan implies normal ASan but does not yet support
           all features.  */
-       if (flag_sanitize & SANITIZE_KERNEL_ADDRESS)
+       if (opts->x_flag_sanitize & SANITIZE_KERNEL_ADDRESS)
          {
            maybe_set_param_value (PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD, 0,
                                   opts->x_param_values,
@@ -1584,6 +1664,19 @@ common_handle_option (struct gcc_options *opts,
        break;
       }
 
+    case OPT_fasan_shadow_offset_:
+      /* Deferred.  */
+      break;
+
+    case OPT_fsanitize_recover:
+      if (value)
+       opts->x_flag_sanitize_recover
+         |= SANITIZE_UNDEFINED | SANITIZE_NONDEFAULT;
+      else
+       opts->x_flag_sanitize_recover
+         &= ~(SANITIZE_UNDEFINED | SANITIZE_NONDEFAULT);
+      break;
+
     case OPT_O:
     case OPT_Os:
     case OPT_Ofast:
@@ -1729,6 +1822,17 @@ common_handle_option (struct gcc_options *opts,
       /* Deferred.  */
       break;
 
+    case OPT_foffload_:
+      /* Deferred.  */
+      break;
+
+#ifndef ACCEL_COMPILER
+    case OPT_foffload_abi_:
+      error_at (loc, "-foffload-abi option can be specified only for "
+               "offload compiler");
+      break;
+#endif
+
     case OPT_fpack_struct_:
       if (value <= 0 || (value & (value - 1)) || value > 16)
        error_at (loc,
@@ -1749,50 +1853,30 @@ common_handle_option (struct gcc_options *opts,
       value = true;
       /* No break here - do -fprofile-use processing. */
     case OPT_fprofile_use:
-      if (!opts_set->x_flag_branch_probabilities)
-       opts->x_flag_branch_probabilities = value;
-      if (!opts_set->x_flag_profile_values)
-       opts->x_flag_profile_values = value;
-      if (!opts_set->x_flag_unroll_loops)
-       opts->x_flag_unroll_loops = value;
-      if (!opts_set->x_flag_peel_loops)
-       opts->x_flag_peel_loops = value;
-      if (!opts_set->x_flag_tracer)
-       opts->x_flag_tracer = value;
-      if (!opts_set->x_flag_value_profile_transformations)
-       opts->x_flag_value_profile_transformations = value;
-      if (!opts_set->x_flag_inline_functions)
-       opts->x_flag_inline_functions = value;
-      if (!opts_set->x_flag_ipa_cp)
-       opts->x_flag_ipa_cp = value;
-      if (!opts_set->x_flag_ipa_cp_clone
-         && value && opts->x_flag_ipa_cp)
-       opts->x_flag_ipa_cp_clone = value;
-      if (!opts_set->x_flag_predictive_commoning)
-       opts->x_flag_predictive_commoning = value;
-      if (!opts_set->x_flag_unswitch_loops)
-       opts->x_flag_unswitch_loops = value;
-      if (!opts_set->x_flag_gcse_after_reload)
-       opts->x_flag_gcse_after_reload = value;
-      if (!opts_set->x_flag_tree_loop_vectorize
-          && !opts_set->x_flag_tree_vectorize)
-       opts->x_flag_tree_loop_vectorize = value;
-      if (!opts_set->x_flag_tree_slp_vectorize
-          && !opts_set->x_flag_tree_vectorize)
-       opts->x_flag_tree_slp_vectorize = value;
-      if (!opts_set->x_flag_vect_cost_model)
-       opts->x_flag_vect_cost_model = VECT_COST_MODEL_DYNAMIC;
-      if (!opts_set->x_flag_tree_loop_distribute_patterns)
-       opts->x_flag_tree_loop_distribute_patterns = value;
+      enable_fdo_optimizations (opts, opts_set, value);
       if (!opts_set->x_flag_profile_reorder_functions)
-       opts->x_flag_profile_reorder_functions = value;
-      /* Indirect call profiling should do all useful transformations
-        speculative devirtualization does.  */
+         opts->x_flag_profile_reorder_functions = value;
+       /* Indirect call profiling should do all useful transformations
+          speculative devirtualization does.  */
       if (!opts_set->x_flag_devirtualize_speculatively
          && opts->x_flag_value_profile_transformations)
        opts->x_flag_devirtualize_speculatively = false;
       break;
 
+    case OPT_fauto_profile_:
+      opts->x_auto_profile_file = xstrdup (arg);
+      opts->x_flag_auto_profile = true;
+      value = true;
+      /* No break here - do -fauto-profile processing. */
+    case OPT_fauto_profile:
+      enable_fdo_optimizations (opts, opts_set, value);
+      if (!opts_set->x_flag_profile_correction)
+       opts->x_flag_profile_correction = value;
+      maybe_set_param_value (
+       PARAM_EARLY_INLINER_MAX_ITERATIONS, 10,
+       opts->x_param_values, opts_set->x_param_values);
+      break;
+
     case OPT_fprofile_generate_:
       opts->x_profile_data_prefix = xstrdup (arg);
       value = true;
@@ -1866,7 +1950,7 @@ common_handle_option (struct gcc_options *opts,
                             ? STATIC_BUILTIN_STACK_CHECK
                             : GENERIC_STACK_CHECK;
       else
-       warning_at (loc, 0, "unknown stack check parameter \"%s\"", arg);
+       warning_at (loc, 0, "unknown stack check parameter %qs", arg);
       break;
 
     case OPT_fstack_limit:
@@ -1908,7 +1992,7 @@ common_handle_option (struct gcc_options *opts,
       
       /* FALLTHRU */
     case OPT_gdwarf_:
-      if (value < 2 || value > 4)
+      if (value < 2 || value > 5)
        error_at (loc, "dwarf version %d is not supported", value);
       else
        opts->x_dwarf_version = value;
@@ -2142,7 +2226,7 @@ set_debug_level (enum debug_info_type type, int extended, const char *arg,
       if (opts_set->x_write_symbols != NO_DEBUG
          && opts->x_write_symbols != NO_DEBUG
          && type != opts->x_write_symbols)
-       error_at (loc, "debug format \"%s\" conflicts with prior selection",
+       error_at (loc, "debug format %qs conflicts with prior selection",
                  debug_type_names[type]);
       opts->x_write_symbols = type;
       opts_set->x_write_symbols = type;
@@ -2160,9 +2244,9 @@ set_debug_level (enum debug_info_type type, int extended, const char *arg,
     {
       int argval = integral_argument (arg);
       if (argval == -1)
-       error_at (loc, "unrecognised debug output level \"%s\"", arg);
+       error_at (loc, "unrecognised debug output level %qs", arg);
       else if (argval > 3)
-       error_at (loc, "debug output level %s is too high", arg);
+       error_at (loc, "debug output level %qs is too high", arg);
       else
        opts->x_debug_info_level = (enum debug_info_levels) argval;
     }