The attached patch cleanups the clo processing
of clo which are (or should be) 'enum set'.

* pub_tool_options.h : add new macrox VG_USET_CLO and VG_USETX_CLO to
  parse an 'enum set' command line option (with or without "all" keyword).

* use VG_USET_CLO for existing enum set clo options:
   memcheck --errors-for-leak-kinds, --show-leak-kinds, --leak-check-heuristics
   coregrind --vgdb-stop-at

* change --sim-hints and --kernel-variants to enum set
  (this allows to detect user typos: currently, a typo in a sim-hint
   or kernel variant is silently ignored. Now, an error will be given
   to the user)

* The 2 new sets (--sim-hints and --kernel-variants) should not make
  use of the 'all' keyword => VG_(parse_enum_set) has a new argument
  to enable/disable the use of the "all" keyword.

* The macros defining an 'all enum' set definition was duplicating
  all enum values (so addition of a new enum value could easily
  give a bug). Removing these macros as they are unused
  (to the exception of the leak-kind set).
  For this set, the 'all macro' has been replaced by an 'all function',
  coded using parse_enum_set parsing the "all" keyword.



git-svn-id: svn://svn.valgrind.org/valgrind/trunk@14301 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/m_libcbase.c b/coregrind/m_libcbase.c
index 0159510..b6f293d 100644
--- a/coregrind/m_libcbase.c
+++ b/coregrind/m_libcbase.c
@@ -521,6 +521,7 @@
 }
 
 Bool VG_(parse_enum_set) ( const HChar *tokens,
+                           Bool  allow_all,
                            const HChar *input,
                            UInt *enum_set)
 {
@@ -549,7 +550,7 @@
         input_word;
         input_word = VG_(strtok_r)(NULL, ",", &input_saveptr)) {
       word_nr++;
-      if (0 == VG_(strcmp)(input_word, "all")) {
+      if (allow_all && 0 == VG_(strcmp)(input_word, "all")) {
          seen_all_kw = True;
          known_words++;
       } else if (0 == VG_(strcmp)(input_word, "none")) {
diff --git a/coregrind/m_libcprint.c b/coregrind/m_libcprint.c
index 5aa8340..46b488a 100644
--- a/coregrind/m_libcprint.c
+++ b/coregrind/m_libcprint.c
@@ -422,7 +422,8 @@
       // (useful to run regression tests in an outer/inner setup
       // and avoid the diff failing due to these unexpected '>').
       depth = RUNNING_ON_VALGRIND;
-      if (depth > 0 && !VG_(strstr)(VG_(clo_sim_hints), "no-inner-prefix")) {
+      if (depth > 0 
+          && !SimHintiS(SimHint_no_inner_prefix, VG_(clo_sim_hints))) {
          if (depth > 10)
             depth = 10; // ?!?!
          for (i = 0; i < depth; i++) {
diff --git a/coregrind/m_main.c b/coregrind/m_main.c
index af7a6d9..1a3374c 100644
--- a/coregrind/m_main.c
+++ b/coregrind/m_main.c
@@ -174,11 +174,13 @@
 "    --vgdb-shadow-registers=no|yes   let gdb see the shadow registers [no]\n"
 "    --vgdb-prefix=<prefix>    prefix for vgdb FIFOs [%s]\n"
 "    --run-libc-freeres=no|yes free up glibc memory at exit on Linux? [yes]\n"
-"    --sim-hints=hint1,hint2,...  known hints:\n"
-"                                 lax-ioctls, enable-outer, fuse-compatible [none]\n"
+"    --sim-hints=hint1,hint2,...  activate unusual sim behaviours [none] \n"
+"         where hint is one of no-inner-prefix lax-ioctls enable-outer\n"
+"                 fuse-compatible none\n"
 "    --fair-sched=no|yes|try   schedule threads fairly on multicore systems [no]\n"
-"    --kernel-variant=variant1,variant2,...  known variants: bproc [none]\n"
-"                              handle non-standard kernel variants\n"
+"    --kernel-variant=variant1,variant2,...  handle non-standard kernel"
+                                                               " variants [none]\n"
+"         where variant is one of bproc none\n"
 "    --merge-recursive-frames=<number>  merge frames between identical\n"
 "           program counters in max <number> frames) [0]\n"
 "    --num-transtab-sectors=<number> size of translated code cache [%d]\n"
@@ -376,7 +378,10 @@
       // Set up VG_(clo_sim_hints). This is needed a.o. for an inner
       // running in an outer, to have "no-inner-prefix" enabled
       // as early as possible.
-      else if VG_STR_CLO (str, "--sim-hints",     VG_(clo_sim_hints)) {}
+      else if VG_USETX_CLO (str, "--sim-hints",
+                            "no-inner-prefix,fuse-compatible,"
+                            "lax-ioctls,enable-outer",
+                            VG_(clo_sim_hints)) {}
    }
 }
 
@@ -545,11 +550,9 @@
       }
       else if VG_INT_CLO (arg, "--vgdb-poll",      VG_(clo_vgdb_poll)) {}
       else if VG_INT_CLO (arg, "--vgdb-error",     VG_(clo_vgdb_error)) {}
-      else if VG_STR_CLO (arg, "--vgdb-stop-at", tmp_str) {
-         if (!VG_(parse_enum_set)("startup,exit,valgrindabexit", tmp_str,
-                                  &VG_(clo_vgdb_stop_at)))
-            VG_(fmsg_bad_option)(arg, "");
-      }
+      else if VG_USET_CLO (arg, "--vgdb-stop-at",
+                           "startup,exit,valgrindabexit",
+                           VG_(clo_vgdb_stop_at)) {}
       else if VG_STR_CLO (arg, "--vgdb-prefix",    VG_(clo_vgdb_prefix)) {
          VG_(arg_vgdb_prefix) = arg;
       }
@@ -622,7 +625,8 @@
                                                     VG_(clo_smc_check),
                                                     Vg_SmcAllNonFile);
 
-      else if VG_STR_CLO (arg, "--kernel-variant",  VG_(clo_kernel_variant)) {}
+      else if VG_USETX_CLO (arg, "--kernel-variant", "bproc",
+                            VG_(clo_kernel_variant)) {}
 
       else if VG_BOOL_CLO(arg, "--dsymutil",        VG_(clo_dsymutil)) {}
 
diff --git a/coregrind/m_options.c b/coregrind/m_options.c
index a331f0e..bc399df 100644
--- a/coregrind/m_options.c
+++ b/coregrind/m_options.c
@@ -112,7 +112,7 @@
 Int    VG_(clo_dump_error)     = 0;
 Int    VG_(clo_backtrace_size) = 12;
 Int    VG_(clo_merge_recursive_frames) = 0; // default value: no merge
-const HChar* VG_(clo_sim_hints)      = NULL;
+UInt   VG_(clo_sim_hints)      = 0;
 Bool   VG_(clo_sym_offsets)    = False;
 Bool   VG_(clo_read_inline_info) = False; // Or should be put it to True by default ???
 Bool   VG_(clo_read_var_info)  = False;
@@ -127,7 +127,7 @@
 Word   VG_(clo_main_stacksize) = 0; /* use client's rlimit.stack */
 Bool   VG_(clo_wait_for_gdb)   = False;
 VgSmc  VG_(clo_smc_check)      = Vg_SmcStack;
-const HChar* VG_(clo_kernel_variant) = NULL;
+UInt   VG_(clo_kernel_variant) = 0;
 Bool   VG_(clo_dsymutil)       = False;
 Bool   VG_(clo_sigill_diag)    = True;
 UInt   VG_(clo_unw_stack_scan_thresh) = 0; /* disabled by default */
diff --git a/coregrind/m_syswrap/priv_types_n_macros.h b/coregrind/m_syswrap/priv_types_n_macros.h
index e69bdf3..62ce783 100644
--- a/coregrind/m_syswrap/priv_types_n_macros.h
+++ b/coregrind/m_syswrap/priv_types_n_macros.h
@@ -368,8 +368,8 @@
    if (VG_(clo_trace_syscalls))                      \
       VG_(printf)(format, ## args)
 
-#define FUSE_COMPATIBLE_MAY_BLOCK()                       \
-   if (VG_(strstr)(VG_(clo_sim_hints),"fuse-compatible")) \
+#define FUSE_COMPATIBLE_MAY_BLOCK()                            \
+   if (SimHintiS(SimHint_fuse_compatible, VG_(clo_sim_hints))) \
       *flags |= SfMayBlock
 
 
diff --git a/coregrind/m_syswrap/syswrap-amd64-linux.c b/coregrind/m_syswrap/syswrap-amd64-linux.c
index c4e65d5..92e9d55 100644
--- a/coregrind/m_syswrap/syswrap-amd64-linux.c
+++ b/coregrind/m_syswrap/syswrap-amd64-linux.c
@@ -664,7 +664,7 @@
    /* 184 is used by sys_bproc.  If we're not on a declared bproc
       variant, fail in the usual way, since it is otherwise unused. */
 
-   if (!VG_(strstr)(VG_(clo_kernel_variant), "bproc")) {
+   if (!KernelVariantiS(KernelVariant_bproc, VG_(clo_kernel_variant))) {
       PRINT("non-existent syscall! (syscall 184)");
       PRE_REG_READ0(long, "ni_syscall(184)");
       SET_STATUS_Failure( VKI_ENOSYS );
diff --git a/coregrind/m_syswrap/syswrap-generic.c b/coregrind/m_syswrap/syswrap-generic.c
index 92da509..8c7c551 100644
--- a/coregrind/m_syswrap/syswrap-generic.c
+++ b/coregrind/m_syswrap/syswrap-generic.c
@@ -3434,7 +3434,7 @@
    
    UInt dir  = _VKI_IOC_DIR(request);
    UInt size = _VKI_IOC_SIZE(request);
-   if (VG_(strstr)(VG_(clo_sim_hints), "lax-ioctls") != NULL) {
+   if (SimHintiS(SimHint_lax_ioctls, VG_(clo_sim_hints))) {
       /* 
        * Be very lax about ioctl handling; the only
        * assumption is that the size is correct. Doesn't
@@ -3844,7 +3844,7 @@
       --sim-hints=enable-outer (used for self hosting). */
    ok = ML_(fd_allowed)(ARG1, "write", tid, False);
    if (!ok && ARG1 == 2/*stderr*/ 
-           && VG_(strstr)(VG_(clo_sim_hints),"enable-outer"))
+           && SimHintiS(SimHint_enable_outer, VG_(clo_sim_hints)))
       ok = True;
    if (!ok)
       SET_STATUS_Failure( VKI_EBADF );
diff --git a/coregrind/m_syswrap/syswrap-x86-linux.c b/coregrind/m_syswrap/syswrap-x86-linux.c
index e5b78af..c07c628 100644
--- a/coregrind/m_syswrap/syswrap-x86-linux.c
+++ b/coregrind/m_syswrap/syswrap-x86-linux.c
@@ -1368,7 +1368,7 @@
    /* 223 is used by sys_bproc.  If we're not on a declared bproc
       variant, fail in the usual way. */
 
-   if (!VG_(strstr)(VG_(clo_kernel_variant), "bproc")) {
+   if (!KernelVariantiS(KernelVariant_bproc, VG_(clo_kernel_variant))) {
       PRINT("non-existent syscall! (syscall 223)");
       PRE_REG_READ0(long, "ni_syscall(223)");
       SET_STATUS_Failure( VKI_ENOSYS );
diff --git a/coregrind/pub_core_options.h b/coregrind/pub_core_options.h
index 97aa3f5..1c1d285 100644
--- a/coregrind/pub_core_options.h
+++ b/coregrind/pub_core_options.h
@@ -36,7 +36,6 @@
 // plus some functions and macros for manipulating them.  Almost every
 // other module imports this one, if only for VG_(clo_verbosity).
 //--------------------------------------------------------------------
-
 #include "pub_tool_options.h"
 
 /* The max number of suppression files. */
@@ -82,11 +81,6 @@
 #define VgdbStopAt2S(a) (1 << (a))
 // VgdbStopAt a is member of the Set s ?
 #define VgdbStopAtiS(a,s) ((s) & VgdbStopAt2S(a))
-// A set with all VgdbStopAt:
-#define VgdbStopAtallS \
-     (VgdbStopAt2S(VgdbStopAt_Startup) \
-    | VgdbStopAt2S(VgdbStopAt_Exit)    \
-    | VgdbStopAt2S(VgdbStopAt_ValgrindAbExit)
 extern UInt VG_(clo_vgdb_stop_at); // A set of VgdbStopAt reasons.
 
 /* prefix for the named pipes (FIFOs) used by vgdb/gdb to communicate with valgrind */
@@ -225,8 +219,23 @@
 /* DEBUG: display gory details for the k'th most popular error.
    default: Infinity. */
 extern Int   VG_(clo_dump_error);
+
 /* Engage miscellaneous weird hacks needed for some progs. */
-extern const HChar* VG_(clo_sim_hints);
+typedef
+   enum {
+      SimHint_no_inner_prefix,
+      SimHint_fuse_compatible,
+      SimHint_lax_ioctls,
+      SimHint_enable_outer
+   }
+   SimHint;
+
+// Build mask to check or set SimHint a membership
+#define SimHint2S(a) (1 << (a))
+// SimHint h is member of the Set s ?
+#define SimHintiS(h,s) ((s) & SimHint2S(h))
+extern UInt VG_(clo_sim_hints);
+
 /* Show symbols in the form 'name+offset' ?  Default: NO */
 extern Bool VG_(clo_sym_offsets);
 /* Read DWARF3 inline info ? */
@@ -326,9 +335,17 @@
    auto-detected. */
 extern VgSmc VG_(clo_smc_check);
 
-/* String containing comma-separated names of minor kernel variants,
+/* A set of minor kernel variants,
    so they can be properly handled by m_syswrap. */
-extern const HChar* VG_(clo_kernel_variant);
+typedef enum {
+      KernelVariant_bproc
+   }
+   KernelVariant;
+// Build mask to check or set KernelVariant a membership
+#define KernelVariant2S(v) (1 << (v))
+// KernelVariant v is member of the Set s ?
+#define KernelVariantiS(v,s) ((s) & KernelVariant2S(v))
+extern UInt VG_(clo_kernel_variant);
 
 /* Darwin-specific: automatically run /usr/bin/dsymutil to update
    .dSYM directories as necessary? */
diff --git a/include/pub_tool_libcbase.h b/include/pub_tool_libcbase.h
index 8a3f363..2c35ef2 100644
--- a/include/pub_tool_libcbase.h
+++ b/include/pub_tool_libcbase.h
@@ -118,14 +118,16 @@
    Using in 'tokens' the special token "-" (a minus character) indicates that
    the corresponding bit position cannot be set.
    In addition to the words specified in 'tokens', VG_(parse_enum_set)
-   automatically accept the words "none" and "all" to indicate respectively
-   an empty enum_set (0) or an enum_set with all bits corresponding
-   to the words in tokens set.
+   automatically accept the word "none" to indicate an empty enum_set (0).
+   If allow_all, VG_(parse_enum_set) automatically accept the word "all"
+   to indicate an enum_set with all bits corresponding to the words in tokens
+    set.
    If "none" or "all" is present in 'input', no other word can be given
    in 'input'.
    If parsing is successful, returns True and sets *enum_set.
    If parsing fails, returns False. */
 extern Bool VG_(parse_enum_set) ( const HChar *tokens,
+                                  Bool  allow_all,
                                   const HChar *input,
                                   UInt *enum_set);
 
diff --git a/include/pub_tool_options.h b/include/pub_tool_options.h
index a9c7ada..cb34639 100644
--- a/include/pub_tool_options.h
+++ b/include/pub_tool_options.h
@@ -71,6 +71,31 @@
     }) \
    )
 
+// UInt enum set arg, eg. --foo=fubar,bar,baz or --foo=none
+// or --foo=all  (if qq_all is True)
+#define VG_USETGEN_CLO(qq_arg, qq_option, qq_vals, qq_var, qq_all) \
+   (VG_STREQN(VG_(strlen)(qq_option)+1, qq_arg, qq_option"=") && \
+    ({ \
+      const HChar* val = &(qq_arg)[ VG_(strlen)(qq_option)+1 ]; \
+      if (!VG_(parse_enum_set)(qq_vals, \
+                               qq_all,/*allow_all*/ \
+                               val, \
+                               &(qq_var))) \
+            VG_(fmsg_bad_option)(qq_arg, "%s is an invalid %s set\n", \
+                                 val, qq_option+2); \
+      True; \
+     }) \
+    )
+
+// UInt enum set arg, eg. --foo=fubar,bar,baz or --foo=none or --foo=all
+#define VG_USET_CLO(qq_arg, qq_option, qq_vals, qq_var) \
+   VG_USETGEN_CLO((qq_arg), qq_option, (qq_vals), (qq_var), True)
+
+/* Same as VG_USET_CLO but not allowing --foo=all.
+   To be used when some or all of the enum set are mutually eXclusive. */
+#define VG_USETX_CLO(qq_arg, qq_option, qq_vals, qq_var) \
+   VG_USETGEN_CLO((qq_arg), qq_option, (qq_vals), (qq_var), False)
+
 // Unbounded integer arg, eg. --foo=10
 #define VG_INT_CLO(qq_arg, qq_option, qq_var) \
    (VG_STREQN(VG_(strlen)(qq_option)+1, qq_arg, qq_option"=") && \
diff --git a/memcheck/mc_errors.c b/memcheck/mc_errors.c
index 125a564..698f75b 100644
--- a/memcheck/mc_errors.c
+++ b/memcheck/mc_errors.c
@@ -248,10 +248,23 @@
    return loss;
 }
 
-Bool MC_(parse_leak_kinds) ( const HChar* str0, UInt* lks )
+const HChar* MC_(parse_leak_kinds_tokens) = 
+   "reachable,possible,indirect,definite";
+
+UInt MC_(all_Reachedness)(void)
 {
-   return VG_(parse_enum_set)("reachable,possible,indirect,definite",
-                              str0, lks);
+   static UInt all;
+
+   if (all == 0) {
+      // Compute a set with all values by doing a parsing of the "all" keyword.
+      Bool parseok = VG_(parse_enum_set)(MC_(parse_leak_kinds_tokens),
+                                         True,/*allow_all*/
+                                         "all",
+                                         &all);
+      tl_assert (parseok && all);
+   }
+
+   return all;
 }
 
 static const HChar* pp_Reachedness_for_leak_kinds(Reachedness r)
@@ -1317,7 +1330,7 @@
       // We might have the optional match-leak-kinds line
       MC_LeakSuppExtra* lse;
       lse = VG_(malloc)("mc.resi.2", sizeof(MC_LeakSuppExtra));
-      lse->match_leak_kinds = RallS;
+      lse->match_leak_kinds = MC_(all_Reachedness)();
       lse->blocks_suppressed = 0;
       lse->bytes_suppressed = 0;
       lse->leak_search_gen = 0;
@@ -1328,7 +1341,9 @@
          i = 17;
          while ((*bufpp)[i] && VG_(isspace((*bufpp)[i])))
             i++;
-         if (!MC_(parse_leak_kinds)((*bufpp)+i, &lse->match_leak_kinds)) {
+         if (!VG_(parse_enum_set)(MC_(parse_leak_kinds_tokens),
+                                  True/*allow_all*/,
+                                  (*bufpp)+i, &lse->match_leak_kinds)) {
             return False;
          }
       } else {
diff --git a/memcheck/mc_include.h b/memcheck/mc_include.h
index f53f3db..9a5017b 100644
--- a/memcheck/mc_include.h
+++ b/memcheck/mc_include.h
@@ -279,9 +279,8 @@
 #define R2S(r) (1 << (r))
 // Reachedness r is member of the Set s ?
 #define RiS(r,s) ((s) & R2S(r))
-// A set with all Reachedness:
-#define RallS \
-   (R2S(Reachable) | R2S(Possible) | R2S(IndirectLeak) | R2S(Unreached))
+// Returns a set containing all Reachedness
+UInt MC_(all_Reachedness)(void);
 
 /* For VALGRIND_COUNT_LEAKS client request */
 extern SizeT MC_(bytes_leaked);
@@ -444,11 +443,8 @@
 Bool MC_(record_fishy_value_error)  ( ThreadId tid, const HChar* function,
                                       const HChar *argument_name, SizeT value );
 
-/* Parses a set of leak kinds (separated by ,).
-   and give the resulting set in *lks.
-   If parsing is succesful, returns True and *lks contains the resulting set.
-   else return False. */
-extern Bool MC_(parse_leak_kinds) ( const HChar* str0, UInt* lks );
+/* Leak kinds tokens to call VG_(parse_enum_set). */
+extern const HChar* MC_(parse_leak_kinds_tokens);
 
 /* prints a description of address a */
 void MC_(pp_describe_addr) (Addr a);
@@ -533,12 +529,8 @@
 
 // Build mask to check or set Heuristic h membership
 #define H2S(h) (1 << (h))
-// CppHeuristic h is member of the Set s ?
-#define HiS(h,s) ((s) & R2S(h))
-// A set with all Heuristics:
-#define HallS \
-   (H2S(LchStdString) | H2S(LchLength64) | H2S(LchNewArray) | \
-       H2S(LchMultipleInheritance))
+// Heuristic h is member of the Set s ?
+#define HiS(h,s) ((s) & H2S(h))
 
 /* Heuristics set to use for the leak search.
    Default : no heuristic. */
diff --git a/memcheck/mc_main.c b/memcheck/mc_main.c
index 7a8e9b7..7cf6cd7 100644
--- a/memcheck/mc_main.c
+++ b/memcheck/mc_main.c
@@ -5195,13 +5195,11 @@
 KeepStacktraces MC_(clo_keep_stacktraces)     = KS_alloc_then_free;
 Int           MC_(clo_mc_level)               = 2;
 
-static Bool MC_(parse_leak_heuristics) ( const HChar *str0, UInt *lhs )
-{
-   return 
-      VG_(parse_enum_set) ("-,stdstring,length64,newarray,multipleinheritance",
-                           str0, lhs);
-}
-
+static const HChar * MC_(parse_leak_heuristics_tokens) =
+   "-,stdstring,length64,newarray,multipleinheritance";
+/* The first heuristic value (LchNone) has no keyword, as this is
+   a fake heuristic used to collect the blocks found without any
+   heuristic. */
 
 static Bool mc_process_cmd_line_options(const HChar* arg)
 {
@@ -5247,21 +5245,18 @@
    }
 
         if VG_BOOL_CLO(arg, "--partial-loads-ok", MC_(clo_partial_loads_ok)) {}
-   else if VG_STR_CLO(arg, "--errors-for-leak-kinds" , tmp_str) {
-      if (!MC_(parse_leak_kinds)(tmp_str, &MC_(clo_error_for_leak_kinds)))
-         return False;
-   }
-   else if VG_STR_CLO(arg, "--show-leak-kinds", tmp_str) {
-      if (!MC_(parse_leak_kinds)(tmp_str, &MC_(clo_show_leak_kinds)))
-         return False;
-   }
-   else if VG_STR_CLO(arg, "--leak-check-heuristics", tmp_str) {
-      if (!MC_(parse_leak_heuristics)(tmp_str, &MC_(clo_leak_check_heuristics)))
-         return False;
-   }
+   else if VG_USET_CLO(arg, "--errors-for-leak-kinds",
+                       MC_(parse_leak_kinds_tokens),
+                       MC_(clo_error_for_leak_kinds)) {}
+   else if VG_USET_CLO(arg, "--show-leak-kinds",
+                       MC_(parse_leak_kinds_tokens),
+                       MC_(clo_show_leak_kinds)) {}
+   else if VG_USET_CLO(arg, "--leak-check-heuristics",
+                       MC_(parse_leak_heuristics_tokens),
+                       MC_(clo_leak_check_heuristics)) {}
    else if (VG_BOOL_CLO(arg, "--show-reachable", tmp_show)) {
       if (tmp_show) {
-         MC_(clo_show_leak_kinds) = RallS;
+         MC_(clo_show_leak_kinds) = MC_(all_Reachedness)();
       } else {
          MC_(clo_show_leak_kinds) &= ~R2S(Reachable);
       }
@@ -5615,15 +5610,18 @@
             lcp.mode = LC_Summary; break;
          case  2: { /* kinds */
             wcmd = VG_(strtok_r) (NULL, " ", &ssaveptr);
-            if (wcmd == NULL || !MC_(parse_leak_kinds)(wcmd,
-                                                       &lcp.show_leak_kinds)) {
+            if (wcmd == NULL 
+                || !VG_(parse_enum_set)(MC_(parse_leak_kinds_tokens),
+                                        True/*allow_all*/,
+                                        wcmd,
+                                        &lcp.show_leak_kinds)) {
                VG_(gdb_printf) ("missing or malformed leak kinds set\n");
                err++;
             }
             break;
          }
          case  3: /* reachable */
-            lcp.show_leak_kinds = RallS;
+            lcp.show_leak_kinds = MC_(all_Reachedness)();
             break;
          case  4: /* possibleleak */
             lcp.show_leak_kinds 
@@ -5634,8 +5632,11 @@
             break;
          case  6: { /* heuristics */
             wcmd = VG_(strtok_r) (NULL, " ", &ssaveptr);
-            if (wcmd == NULL || !MC_(parse_leak_heuristics)(wcmd,
-                                                            &lcp.heuristics)) {
+            if (wcmd == NULL 
+                || !VG_(parse_enum_set)(MC_(parse_leak_heuristics_tokens),
+                                        True,/*allow_all*/
+                                        wcmd,
+                                        &lcp.heuristics)) {
                VG_(gdb_printf) ("missing or malformed heuristics set\n");
                err++;
             }
diff --git a/none/tests/cmdline1.stdout.exp b/none/tests/cmdline1.stdout.exp
index e63d716..122d7e5 100644
--- a/none/tests/cmdline1.stdout.exp
+++ b/none/tests/cmdline1.stdout.exp
@@ -87,11 +87,12 @@
     --vgdb-shadow-registers=no|yes   let gdb see the shadow registers [no]
     --vgdb-prefix=<prefix>    prefix for vgdb FIFOs [/tmp/vgdb-pipe]
     --run-libc-freeres=no|yes free up glibc memory at exit on Linux? [yes]
-    --sim-hints=hint1,hint2,...  known hints:
-                                 lax-ioctls, enable-outer, fuse-compatible [none]
+    --sim-hints=hint1,hint2,...  activate unusual sim behaviours [none] 
+         where hint is one of no-inner-prefix lax-ioctls enable-outer
+                 fuse-compatible none
     --fair-sched=no|yes|try   schedule threads fairly on multicore systems [no]
-    --kernel-variant=variant1,variant2,...  known variants: bproc [none]
-                              handle non-standard kernel variants
+    --kernel-variant=variant1,variant2,...  handle non-standard kernel variants [none]
+         where variant is one of bproc none
     --merge-recursive-frames=<number>  merge frames between identical
            program counters in max <number> frames) [0]
     --num-transtab-sectors=<number> size of translated code cache [16]
diff --git a/none/tests/cmdline2.stdout.exp b/none/tests/cmdline2.stdout.exp
index e35b64e..a26abaf 100644
--- a/none/tests/cmdline2.stdout.exp
+++ b/none/tests/cmdline2.stdout.exp
@@ -87,11 +87,12 @@
     --vgdb-shadow-registers=no|yes   let gdb see the shadow registers [no]
     --vgdb-prefix=<prefix>    prefix for vgdb FIFOs [/tmp/vgdb-pipe]
     --run-libc-freeres=no|yes free up glibc memory at exit on Linux? [yes]
-    --sim-hints=hint1,hint2,...  known hints:
-                                 lax-ioctls, enable-outer, fuse-compatible [none]
+    --sim-hints=hint1,hint2,...  activate unusual sim behaviours [none] 
+         where hint is one of no-inner-prefix lax-ioctls enable-outer
+                 fuse-compatible none
     --fair-sched=no|yes|try   schedule threads fairly on multicore systems [no]
-    --kernel-variant=variant1,variant2,...  known variants: bproc [none]
-                              handle non-standard kernel variants
+    --kernel-variant=variant1,variant2,...  handle non-standard kernel variants [none]
+         where variant is one of bproc none
     --merge-recursive-frames=<number>  merge frames between identical
            program counters in max <number> frames) [0]
     --num-transtab-sectors=<number> size of translated code cache [16]