]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR lto/69254 (ICE in streamer_get_builtin_tree when using -fsanitize=shift on...
authorJakub Jelinek <jakub@redhat.com>
Tue, 26 Jan 2016 13:01:44 +0000 (14:01 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 26 Jan 2016 13:01:44 +0000 (14:01 +0100)
PR lto/69254
* opts.h (parse_sanitizer_options): New prototype.
* opts.c (sanitizer_opts): New array.
(parse_sanitizer_options): New function.
(common_handle_option): Use parse_sanitizer_options.

From-SVN: r232826

gcc/ChangeLog
gcc/opts.c
gcc/opts.h

index 28cb00c745124b025e207fdf8606ce6f8d7064f1..e84acc123acaa6ee62716fdf119b645849cbff75 100644 (file)
@@ -1,3 +1,11 @@
+2016-01-26  Jakub Jelinek  <jakub@redhat.com>
+
+       PR lto/69254
+       * opts.h (parse_sanitizer_options): New prototype.
+       * opts.c (sanitizer_opts): New array.
+       (parse_sanitizer_options): New function.
+       (common_handle_option): Use parse_sanitizer_options.
+
 2016-01-26  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR target/68986
index b4e8144489cde2a86087c9c0fe99ff60a7c23c63..0a18c26d6e1e1d6279f849642e7147d891b97dff 100644 (file)
@@ -1433,6 +1433,104 @@ enable_fdo_optimizations (struct gcc_options *opts,
     opts->x_flag_tree_loop_distribute_patterns = value;
 }
 
+/* -f{,no-}sanitize{,-recover}= suboptions.  */
+static const struct sanitizer_opts_s
+{
+  const char *const name;
+  unsigned int flag;
+  size_t len;
+} sanitizer_opts[] =
+{
+#define SANITIZER_OPT(name, flags) { #name, flags, sizeof #name - 1 }
+  SANITIZER_OPT (address, SANITIZE_ADDRESS | SANITIZE_USER_ADDRESS),
+  SANITIZER_OPT (kernel-address, SANITIZE_ADDRESS | SANITIZE_KERNEL_ADDRESS),
+  SANITIZER_OPT (thread, SANITIZE_THREAD),
+  SANITIZER_OPT (leak, SANITIZE_LEAK),
+  SANITIZER_OPT (shift, SANITIZE_SHIFT),
+  SANITIZER_OPT (integer-divide-by-zero, SANITIZE_DIVIDE),
+  SANITIZER_OPT (undefined, SANITIZE_UNDEFINED),
+  SANITIZER_OPT (unreachable, SANITIZE_UNREACHABLE),
+  SANITIZER_OPT (vla-bound, SANITIZE_VLA),
+  SANITIZER_OPT (return, SANITIZE_RETURN),
+  SANITIZER_OPT (null, SANITIZE_NULL),
+  SANITIZER_OPT (signed-integer-overflow, SANITIZE_SI_OVERFLOW),
+  SANITIZER_OPT (bool, SANITIZE_BOOL),
+  SANITIZER_OPT (enum, SANITIZE_ENUM),
+  SANITIZER_OPT (float-divide-by-zero, SANITIZE_FLOAT_DIVIDE),
+  SANITIZER_OPT (float-cast-overflow, SANITIZE_FLOAT_CAST),
+  SANITIZER_OPT (bounds, SANITIZE_BOUNDS),
+  SANITIZER_OPT (bounds-strict, SANITIZE_BOUNDS | SANITIZE_BOUNDS_STRICT),
+  SANITIZER_OPT (alignment, SANITIZE_ALIGNMENT),
+  SANITIZER_OPT (nonnull-attribute, SANITIZE_NONNULL_ATTRIBUTE),
+  SANITIZER_OPT (returns-nonnull-attribute, SANITIZE_RETURNS_NONNULL_ATTRIBUTE),
+  SANITIZER_OPT (object-size, SANITIZE_OBJECT_SIZE),
+  SANITIZER_OPT (vptr, SANITIZE_VPTR),
+  SANITIZER_OPT (all, ~0),
+#undef SANITIZER_OPT
+  { NULL, 0, 0 }
+};
+
+/* Parse comma separated sanitizer suboptions from P for option SCODE,
+   adjust previous FLAGS and return new ones.  If COMPLAIN is false,
+   don't issue diagnostics.  */
+
+unsigned int
+parse_sanitizer_options (const char *p, location_t loc, int scode,
+                        unsigned int flags, int value, bool complain)
+{
+  enum opt_code code = (enum opt_code) scode;
+  while (*p != 0)
+    {
+      size_t len, i;
+      bool found = false;
+      const char *comma = strchr (p, ',');
+
+      if (comma == NULL)
+       len = strlen (p);
+      else
+       len = comma - p;
+      if (len == 0)
+       {
+         p = comma + 1;
+         continue;
+       }
+
+      /* Check to see if the string matches an option class name.  */
+      for (i = 0; sanitizer_opts[i].name != NULL; ++i)
+       if (len == sanitizer_opts[i].len
+           && memcmp (p, sanitizer_opts[i].name, len) == 0)
+         {
+           /* Handle both -fsanitize and -fno-sanitize cases.  */
+           if (value && sanitizer_opts[i].flag == ~0U)
+             {
+               if (code == OPT_fsanitize_)
+                 {
+                   if (complain)
+                     error_at (loc, "-fsanitize=all option is not valid");
+                 }
+               else
+                 flags |= ~(SANITIZE_USER_ADDRESS | SANITIZE_THREAD
+                            | SANITIZE_LEAK);
+             }
+           else if (value)
+             flags |= sanitizer_opts[i].flag;
+           else
+             flags &= ~sanitizer_opts[i].flag;
+           found = true;
+           break;
+         }
+
+      if (! found && complain)
+       error_at (loc, "unrecognized argument to -fsanitize%s= option: %q.*s",
+                 code == OPT_fsanitize_ ? "" : "-recover", (int) len, p);
+
+      if (comma == NULL)
+       break;
+      p = comma + 1;
+    }
+  return flags;
+}
+
 /* 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
@@ -1626,129 +1724,32 @@ 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
-           {
-             const char *const name;
-             unsigned int flag;
-             size_t len;
-           } spec[] =
-           {
-             { "address", SANITIZE_ADDRESS | SANITIZE_USER_ADDRESS,
-               sizeof "address" - 1 },
-             { "kernel-address", SANITIZE_ADDRESS | SANITIZE_KERNEL_ADDRESS,
-               sizeof "kernel-address" - 1 },
-             { "thread", SANITIZE_THREAD, sizeof "thread" - 1 },
-             { "leak", SANITIZE_LEAK, sizeof "leak" - 1 },
-             { "shift", SANITIZE_SHIFT, sizeof "shift" - 1 },
-             { "integer-divide-by-zero", SANITIZE_DIVIDE,
-               sizeof "integer-divide-by-zero" - 1 },
-             { "undefined", SANITIZE_UNDEFINED, sizeof "undefined" - 1 },
-             { "unreachable", SANITIZE_UNREACHABLE,
-               sizeof "unreachable" - 1 },
-             { "vla-bound", SANITIZE_VLA, sizeof "vla-bound" - 1 },
-             { "return", SANITIZE_RETURN, sizeof "return" - 1 },
-             { "null", SANITIZE_NULL, sizeof "null" - 1 },
-             { "signed-integer-overflow", SANITIZE_SI_OVERFLOW,
-               sizeof "signed-integer-overflow" -1 },
-             { "bool", SANITIZE_BOOL, sizeof "bool" - 1 },
-             { "enum", SANITIZE_ENUM, sizeof "enum" - 1 },
-             { "float-divide-by-zero", SANITIZE_FLOAT_DIVIDE,
-               sizeof "float-divide-by-zero" - 1 },
-             { "float-cast-overflow", SANITIZE_FLOAT_CAST,
-               sizeof "float-cast-overflow" - 1 },
-             { "bounds", SANITIZE_BOUNDS, sizeof "bounds" - 1 },
-             { "bounds-strict", SANITIZE_BOUNDS | SANITIZE_BOUNDS_STRICT,
-               sizeof "bounds-strict" - 1 },
-             { "alignment", SANITIZE_ALIGNMENT, sizeof "alignment" - 1 },
-             { "nonnull-attribute", SANITIZE_NONNULL_ATTRIBUTE,
-               sizeof "nonnull-attribute" - 1 },
-             { "returns-nonnull-attribute",
-               SANITIZE_RETURNS_NONNULL_ATTRIBUTE,
-               sizeof "returns-nonnull-attribute" - 1 },
-             { "object-size", SANITIZE_OBJECT_SIZE,
-               sizeof "object-size" - 1 },
-             { "vptr", SANITIZE_VPTR, sizeof "vptr" - 1 },
-             { "all", ~0, sizeof "all" - 1 },
-             { NULL, 0, 0 }
-           };
-           const char *comma;
-           size_t len, i;
-           bool found = false;
-
-           comma = strchr (p, ',');
-           if (comma == NULL)
-             len = strlen (p);
-           else
-             len = comma - p;
-           if (len == 0)
-             {
-               p = comma + 1;
-               continue;
-             }
-
-           /* Check to see if the string matches an option class name.  */
-           for (i = 0; spec[i].name != NULL; ++i)
-             if (len == spec[i].len
-                 && memcmp (p, spec[i].name, len) == 0)
-               {
-                 /* Handle both -fsanitize and -fno-sanitize cases.  */
-                 if (value && spec[i].flag == ~0U)
-                   {
-                     if (code == OPT_fsanitize_)
-                       error_at (loc, "-fsanitize=all option is not valid");
-                     else
-                       *flag |= ~(SANITIZE_USER_ADDRESS | SANITIZE_THREAD
-                                  | SANITIZE_LEAK);
-                   }
-                 else if (value)
-                   *flag |= spec[i].flag;
-                 else
-                   *flag &= ~spec[i].flag;
-                 found = true;
-                 break;
-               }
+      opts->x_flag_sanitize
+       = parse_sanitizer_options (arg, loc, code,
+                                  opts->x_flag_sanitize, value, true);
 
-           if (! found)
-             error_at (loc,
-                       "unrecognized argument to -fsanitize%s= option: %q.*s",
-                       code == OPT_fsanitize_ ? "" : "-recover", (int) len, p);
-
-           if (comma == NULL)
-             break;
-           p = comma + 1;
-         }
-
-       if (code != OPT_fsanitize_)
-         break;
-
-       /* Kernel ASan implies normal ASan but does not yet support
-          all features.  */
-       if (opts->x_flag_sanitize & SANITIZE_KERNEL_ADDRESS)
-         {
-           maybe_set_param_value (PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD, 0,
-                                  opts->x_param_values,
-                                  opts_set->x_param_values);
-           maybe_set_param_value (PARAM_ASAN_GLOBALS, 0,
-                                  opts->x_param_values,
-                                  opts_set->x_param_values);
-           maybe_set_param_value (PARAM_ASAN_STACK, 0,
-                                  opts->x_param_values,
-                                  opts_set->x_param_values);
-           maybe_set_param_value (PARAM_ASAN_USE_AFTER_RETURN, 0,
-                                  opts->x_param_values,
-                                  opts_set->x_param_values);
-         }
+      /* Kernel ASan implies normal ASan but does not yet support
+        all features.  */
+      if (opts->x_flag_sanitize & SANITIZE_KERNEL_ADDRESS)
+       {
+         maybe_set_param_value (PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD,
+                                0, opts->x_param_values,
+                                opts_set->x_param_values);
+         maybe_set_param_value (PARAM_ASAN_GLOBALS, 0, opts->x_param_values,
+                                opts_set->x_param_values);
+         maybe_set_param_value (PARAM_ASAN_STACK, 0, opts->x_param_values,
+                                opts_set->x_param_values);
+         maybe_set_param_value (PARAM_ASAN_USE_AFTER_RETURN, 0,
+                                opts->x_param_values,
+                                opts_set->x_param_values);
+       }
+      break;
 
-       break;
-      }
+    case OPT_fsanitize_recover_:
+      opts->x_flag_sanitize_recover
+       = parse_sanitizer_options (arg, loc, code,
+                                  opts->x_flag_sanitize_recover, value, true);
+      break;
 
     case OPT_fasan_shadow_offset_:
       /* Deferred.  */
index 7e48dbe8fe2eda9017022902cf37b715110ad057..6e6dbead94693b3902100a97ccd66130bf852626 100644 (file)
@@ -372,6 +372,8 @@ extern void control_warning_option (unsigned int opt_index, int kind,
 extern char *write_langs (unsigned int mask);
 extern void print_ignored_options (void);
 extern void handle_common_deferred_options (void);
+unsigned int parse_sanitizer_options (const char *, location_t, int,
+                                     unsigned int, int, bool);
 extern bool common_handle_option (struct gcc_options *opts,
                                  struct gcc_options *opts_set,
                                  const struct cl_decoded_option *decoded,