[compiler-rt] r226169 - [sanitizer] Flag parser rewrite.

Alexey Samsonov vonosmas at gmail.com
Fri Jan 16 08:32:22 PST 2015


Thanks for doing this!

On Thu, Jan 15, 2015 at 8:13 PM, Evgeniy Stepanov <eugeni.stepanov at gmail.com
> wrote:

> Author: eugenis
> Date: Thu Jan 15 09:13:43 2015
> New Revision: 226169
>
> URL: http://llvm.org/viewvc/llvm-project?rev=226169&view=rev
> Log:
> [sanitizer] Flag parser rewrite.
>
> The new parser is a lot stricter about syntax, reports unrecognized
> flags, and will make it easier to implemented some of the planned features.
>
>
> Added:
>     compiler-rt/trunk/lib/sanitizer_common/sanitizer_flag_parser.cc
>  (with props)
>     compiler-rt/trunk/lib/sanitizer_common/sanitizer_flag_parser.h   (with
> props)
>     compiler-rt/trunk/test/asan/TestCases/asan_options-help.cc   (with
> props)
>     compiler-rt/trunk/test/asan/TestCases/asan_options-invalid.cc   (with
> props)
> Modified:
>     compiler-rt/trunk/CMakeLists.txt
>     compiler-rt/trunk/lib/asan/asan_activation.cc
>     compiler-rt/trunk/lib/asan/asan_flags.cc
>     compiler-rt/trunk/lib/asan/asan_flags.h
>     compiler-rt/trunk/lib/asan/tests/CMakeLists.txt
>     compiler-rt/trunk/lib/dfsan/CMakeLists.txt
>     compiler-rt/trunk/lib/dfsan/dfsan.cc
>     compiler-rt/trunk/lib/dfsan/dfsan.h
>     compiler-rt/trunk/lib/lsan/lsan_common.cc
>     compiler-rt/trunk/lib/lsan/lsan_common.h
>     compiler-rt/trunk/lib/msan/msan.cc
>     compiler-rt/trunk/lib/msan/msan_flags.h
>     compiler-rt/trunk/lib/sanitizer_common/CMakeLists.txt
>     compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator_internal.h
>     compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc
>     compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.h
>     compiler-rt/trunk/lib/sanitizer_common/sanitizer_libc.cc
>     compiler-rt/trunk/lib/sanitizer_common/sanitizer_libc.h
>     compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_flags_test.cc
>     compiler-rt/trunk/lib/tsan/dd/dd_rtl.cc
>     compiler-rt/trunk/lib/tsan/rtl/tsan_flags.cc
>     compiler-rt/trunk/lib/ubsan/ubsan_flags.cc
>     compiler-rt/trunk/lib/ubsan/ubsan_flags.h
>     compiler-rt/trunk/lib/ubsan/ubsan_init.cc
>     compiler-rt/trunk/test/asan/TestCases/default_options.cc
>     compiler-rt/trunk/test/lsan/TestCases/ignore_object.cc
>     compiler-rt/trunk/test/lsan/TestCases/ignore_object_errors.cc
>     compiler-rt/trunk/test/ubsan/TestCases/TypeCheck/vptr.cpp
>
> Modified: compiler-rt/trunk/CMakeLists.txt
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/CMakeLists.txt?rev=226169&r1=226168&r2=226169&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/CMakeLists.txt (original)
> +++ compiler-rt/trunk/CMakeLists.txt Thu Jan 15 09:13:43 2015
> @@ -234,7 +234,7 @@ append_list_if(COMPILER_RT_HAS_FUNWIND_T
>  append_list_if(COMPILER_RT_HAS_FNO_STACK_PROTECTOR_FLAG
> -fno-stack-protector SANITIZER_COMMON_CFLAGS)
>  append_list_if(COMPILER_RT_HAS_FVISIBILITY_HIDDEN_FLAG
> -fvisibility=hidden SANITIZER_COMMON_CFLAGS)
>  append_list_if(COMPILER_RT_HAS_FNO_FUNCTION_SECTIONS_FLAG
> -fno-function-sections SANITIZER_COMMON_CFLAGS)
> -append_list_if(COMPILER_RT_HAS_FNO_LTO_FLAG -fno-lto
> SANITIZER_COMMON_CFLAGS)
> +# append_list_if(COMPILER_RT_HAS_FNO_LTO_FLAG -fno-lto
> SANITIZER_COMMON_CFLAGS)
>
>  if(MSVC)
>    # Replace the /MD[d] flags with /MT.
>
> Modified: compiler-rt/trunk/lib/asan/asan_activation.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_activation.cc?rev=226169&r1=226168&r2=226169&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/asan/asan_activation.cc (original)
> +++ compiler-rt/trunk/lib/asan/asan_activation.cc Thu Jan 15 09:13:43 2015
> @@ -32,6 +32,9 @@ static struct AsanDeactivatedFlags {
>    void OverrideFromActivationFlags() {
>      Flags f;
>      CommonFlags cf;
> +    FlagParser parser;
> +    RegisterAsanFlags(&parser, &f);
> +    RegisterCommonFlags(&parser, &cf);
>
>      // Copy the current activation flags.
>      allocator_options.CopyTo(&f, &cf);
> @@ -44,15 +47,13 @@ static struct AsanDeactivatedFlags {
>      // FIXME: Add diagnostic to check that activation flags string doesn't
>      // contain any other flags.
>      if (const char *env = GetEnv("ASAN_ACTIVATION_OPTIONS")) {
> -      cf.ParseFromString(env);
> -      f.ParseFromString(env);
> +      parser.ParseString(env);
>      }
>
>      // Override from getprop asan.options.
>      char buf[100];
>      GetExtraActivationFlags(buf, sizeof(buf));
> -    cf.ParseFromString(buf);
> -    f.ParseFromString(buf);
> +    parser.ParseString(buf);
>
>      allocator_options.SetFrom(&f, &cf);
>      malloc_context_size = cf.malloc_context_size;
>
> Modified: compiler-rt/trunk/lib/asan/asan_flags.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_flags.cc?rev=226169&r1=226168&r2=226169&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/asan/asan_flags.cc (original)
> +++ compiler-rt/trunk/lib/asan/asan_flags.cc Thu Jan 15 09:13:43 2015
> @@ -19,6 +19,7 @@
>  #include "lsan/lsan_common.h"
>  #include "sanitizer_common/sanitizer_common.h"
>  #include "sanitizer_common/sanitizer_flags.h"
> +#include "sanitizer_common/sanitizer_flag_parser.h"
>
>  namespace __asan {
>
> @@ -45,14 +46,18 @@ void Flags::SetDefaults() {
>  #undef ASAN_FLAG
>  }
>
> -void Flags::ParseFromString(const char *str) {
> -#define ASAN_FLAG(Type, Name, DefaultValue, Description)
>    \
> -  ParseFlag(str, &Name, #Name, Description);
> +void RegisterAsanFlags(FlagParser *parser, Flags *f) {
> +#define ASAN_FLAG(Type, Name, DefaultValue, Description) \
> +  RegisterFlag(parser, #Name, Description, &f->Name);
>  #include "asan_flags.inc"
>  #undef ASAN_FLAG
>  }
>
>  void InitializeFlags(Flags *f) {
> +  FlagParser parser;
> +  RegisterAsanFlags(&parser, f);
> +  RegisterCommonFlags(&parser);
> +
>    SetCommonFlagsDefaults();
>    {
>      CommonFlags cf;
> @@ -69,20 +74,17 @@ void InitializeFlags(Flags *f) {
>
>    // Override from compile definition.
>    const char *compile_def = MaybeUseAsanDefaultOptionsCompileDefinition();
> -  ParseCommonFlagsFromString(compile_def);
> -  f->ParseFromString(compile_def);
> +  parser.ParseString(compile_def);
>
>    // Override from user-specified string.
>    const char *default_options = MaybeCallAsanDefaultOptions();
> -  ParseCommonFlagsFromString(default_options);
> -  f->ParseFromString(default_options);
> +  parser.ParseString(default_options);
>    VReport(1, "Using the defaults from __asan_default_options: %s\n",
>            MaybeCallAsanDefaultOptions());
>
>    // Override from command line.
>    if (const char *env = GetEnv("ASAN_OPTIONS")) {
> -    ParseCommonFlagsFromString(env);
> -    f->ParseFromString(env);
> +    parser.ParseString(env);
>      VReport(1, "Parsed ASAN_OPTIONS: %s\n", env);
>    }
>
> @@ -91,14 +93,13 @@ void InitializeFlags(Flags *f) {
>    if (!flags()->start_deactivated) {
>      char buf[100];
>      GetExtraActivationFlags(buf, sizeof(buf));
> -    ParseCommonFlagsFromString(buf);
> -    f->ParseFromString(buf);
> +    parser.ParseString(buf);
>      if (buf[0] != '\0')
>        VReport(1, "Parsed activation flags: %s\n", buf);
>    }
>
>    if (common_flags()->help) {
> -    PrintFlagDescriptions();
> +    parser.PrintFlagDescriptions();
>    }
>
>    // Flag validation:
>
> Modified: compiler-rt/trunk/lib/asan/asan_flags.h
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_flags.h?rev=226169&r1=226168&r2=226169&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/asan/asan_flags.h (original)
> +++ compiler-rt/trunk/lib/asan/asan_flags.h Thu Jan 15 09:13:43 2015
> @@ -16,6 +16,7 @@
>  #define ASAN_FLAGS_H
>
>  #include "sanitizer_common/sanitizer_internal_defs.h"
> +#include "sanitizer_common/sanitizer_flag_parser.h"
>
>  // ASan flag values can be defined in four ways:
>  // 1) initialized with default values at startup.
> @@ -34,13 +35,13 @@ struct Flags {
>  #undef ASAN_FLAG
>
>    void SetDefaults();
> -  void ParseFromString(const char *str);
>  };
>
>  extern Flags asan_flags_dont_use_directly;
>  inline Flags *flags() {
>    return &asan_flags_dont_use_directly;
>  }
> +void RegisterAsanFlags(FlagParser *parser, Flags *f);
>  void InitializeFlags(Flags *f);
>
>  }  // namespace __asan
>
> Modified: compiler-rt/trunk/lib/asan/tests/CMakeLists.txt
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/tests/CMakeLists.txt?rev=226169&r1=226168&r2=226169&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/asan/tests/CMakeLists.txt (original)
> +++ compiler-rt/trunk/lib/asan/tests/CMakeLists.txt Thu Jan 15 09:13:43
> 2015
> @@ -30,7 +30,8 @@ set(ASAN_UNITTEST_COMMON_CFLAGS
>    -fno-rtti
>    -O2
>    -Wno-format
> -  -Werror=sign-compare)
> +  -Werror=sign-compare
> +  -Wno-non-virtual-dtor)
>  append_list_if(COMPILER_RT_HAS_WVARIADIC_MACROS_FLAG -Wno-variadic-macros
> ASAN_UNITTEST_COMMON_CFLAGS)
>
>  # -gline-tables-only must be enough for ASan, so use it if possible.
>
> Modified: compiler-rt/trunk/lib/dfsan/CMakeLists.txt
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/dfsan/CMakeLists.txt?rev=226169&r1=226168&r2=226169&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/dfsan/CMakeLists.txt (original)
> +++ compiler-rt/trunk/lib/dfsan/CMakeLists.txt Thu Jan 15 09:13:43 2015
> @@ -5,7 +5,7 @@ set(DFSAN_RTL_SOURCES
>    dfsan.cc
>    dfsan_custom.cc
>    dfsan_interceptors.cc)
> -set(DFSAN_COMMON_CFLAGS ${SANITIZER_COMMON_CFLAGS})
> +set(DFSAN_COMMON_CFLAGS ${SANITIZER_COMMON_CFLAGS} -fno-rtti)
>

append_no_rtti_flag(DFSAN_COMMON_CFLAGS)


>  # Prevent clang from generating libc calls.
>  append_list_if(COMPILER_RT_HAS_FFREESTANDING_FLAG -ffreestanding
> DFSAN_COMMON_CFLAGS)
>
>
> Modified: compiler-rt/trunk/lib/dfsan/dfsan.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/dfsan/dfsan.cc?rev=226169&r1=226168&r2=226169&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/dfsan/dfsan.cc (original)
> +++ compiler-rt/trunk/lib/dfsan/dfsan.cc Thu Jan 15 09:13:43 2015
> @@ -22,6 +22,7 @@
>  #include "sanitizer_common/sanitizer_atomic.h"
>  #include "sanitizer_common/sanitizer_common.h"
>  #include "sanitizer_common/sanitizer_flags.h"
> +#include "sanitizer_common/sanitizer_flag_parser.h"
>  #include "sanitizer_common/sanitizer_libc.h"
>
>  #include "dfsan/dfsan.h"
> @@ -316,16 +317,18 @@ void Flags::SetDefaults() {
>  #undef DFSAN_FLAG
>  }
>
> -void Flags::ParseFromString(const char *str) {
> -#define DFSAN_FLAG(Type, Name, DefaultValue, Description)
>      \
> -  ParseFlag(str, &Name, #Name, Description);
> +void RegisterDfsanFlags(FlagParser *parser, Flags *f) {
> +#define DFSAN_FLAG(Type, Name, DefaultValue, Description) \
> +  RegisterFlag(parser, #Name, Description, &f->Name);
>  #include "dfsan_flags.inc"
>  #undef DFSAN_FLAG
>  }
>
>  static void InitializeFlags(Flags &f, const char *env) {
> +  FlagParser parser;
> +  RegisterDfsanFlags(&parser, &f);
>    f.SetDefaults();
> -  f.ParseFromString(env);
> +  parser.ParseString(env);
>  }
>
>  static void dfsan_fini() {
>
> Modified: compiler-rt/trunk/lib/dfsan/dfsan.h
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/dfsan/dfsan.h?rev=226169&r1=226168&r2=226169&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/dfsan/dfsan.h (original)
> +++ compiler-rt/trunk/lib/dfsan/dfsan.h Thu Jan 15 09:13:43 2015
> @@ -61,7 +61,6 @@ struct Flags {
>  #undef DFSAN_FLAG
>
>    void SetDefaults();
> -  void ParseFromString(const char *str);
>  };
>
>  extern Flags flags_data;
>
> Modified: compiler-rt/trunk/lib/lsan/lsan_common.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/lsan/lsan_common.cc?rev=226169&r1=226168&r2=226169&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/lsan/lsan_common.cc (original)
> +++ compiler-rt/trunk/lib/lsan/lsan_common.cc Thu Jan 15 09:13:43 2015
> @@ -16,6 +16,7 @@
>
>  #include "sanitizer_common/sanitizer_common.h"
>  #include "sanitizer_common/sanitizer_flags.h"
> +#include "sanitizer_common/sanitizer_flag_parser.h"
>  #include "sanitizer_common/sanitizer_placement_new.h"
>  #include "sanitizer_common/sanitizer_procmaps.h"
>  #include "sanitizer_common/sanitizer_stackdepot.h"
> @@ -42,19 +43,20 @@ void Flags::SetDefaults() {
>  #undef LSAN_FLAG
>  }
>
> -void Flags::ParseFromString(const char *str) {
> -#define LSAN_FLAG(Type, Name, DefaultValue, Description)
>      \
> -  ParseFlag(str, &Name, #Name, Description);
> +static void RegisterLsanFlags(FlagParser *parser, Flags *f) {
> +#define LSAN_FLAG(Type, Name, DefaultValue, Description) \
> +  RegisterFlag(parser, #Name, Description, &f->Name);
>  #include "lsan_flags.inc"
>  #undef LSAN_FLAG
>  }
>
>  static void InitializeFlags(bool standalone) {
>    Flags *f = flags();
> -  f->SetDefaults();
> +  FlagParser parser;
> +  RegisterLsanFlags(&parser, f);
> +  RegisterCommonFlags(&parser);
>
> -  const char *options = GetEnv("LSAN_OPTIONS");
> -  f->ParseFromString(options);
> +  f->SetDefaults();
>
>    // Set defaults for common flags (only in standalone mode) and parse
>    // them from LSAN_OPTIONS.
> @@ -67,7 +69,9 @@ static void InitializeFlags(bool standal
>      cf.detect_leaks = true;
>      OverrideCommonFlags(cf);
>    }
> -  ParseCommonFlagsFromString(options);
> +
> +  const char *options = GetEnv("LSAN_OPTIONS");
> +  parser.ParseString(options);
>  }
>
>  #define LOG_POINTERS(...)                           \
>
> Modified: compiler-rt/trunk/lib/lsan/lsan_common.h
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/lsan/lsan_common.h?rev=226169&r1=226168&r2=226169&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/lsan/lsan_common.h (original)
> +++ compiler-rt/trunk/lib/lsan/lsan_common.h Thu Jan 15 09:13:43 2015
> @@ -43,7 +43,6 @@ struct Flags {
>  #undef LSAN_FLAG
>
>    void SetDefaults();
> -  void ParseFromString(const char *str);
>    uptr pointer_alignment() const {
>      return use_unaligned ? 1 : sizeof(uptr);
>    }
>
> Modified: compiler-rt/trunk/lib/msan/msan.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/msan.cc?rev=226169&r1=226168&r2=226169&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/msan/msan.cc (original)
> +++ compiler-rt/trunk/lib/msan/msan.cc Thu Jan 15 09:13:43 2015
> @@ -19,13 +19,13 @@
>  #include "sanitizer_common/sanitizer_atomic.h"
>  #include "sanitizer_common/sanitizer_common.h"
>  #include "sanitizer_common/sanitizer_flags.h"
> +#include "sanitizer_common/sanitizer_flag_parser.h"
>  #include "sanitizer_common/sanitizer_libc.h"
>  #include "sanitizer_common/sanitizer_procmaps.h"
>  #include "sanitizer_common/sanitizer_stacktrace.h"
>  #include "sanitizer_common/sanitizer_symbolizer.h"
>  #include "sanitizer_common/sanitizer_stackdepot.h"
>
> -
>  // ACHTUNG! No system header includes in this file.
>
>  using namespace __sanitizer;
> @@ -102,20 +102,40 @@ void Flags::SetDefaults() {
>  #undef MSAN_FLAG
>  }
>
> -void Flags::ParseFromString(const char *str) {
> -  // keep_going is an old name for halt_on_error,
> -  // and it has inverse meaning.
> -  halt_on_error = !halt_on_error;
> -  ParseFlag(str, &halt_on_error, "keep_going", "");
> -  halt_on_error = !halt_on_error;
> -
> -#define MSAN_FLAG(Type, Name, DefaultValue, Description)
>    \
> -  ParseFlag(str, &Name, #Name, Description);
> +// keep_going is an old name for halt_on_error,
> +// and it has inverse meaning.
> +class FlagHandlerKeepGoing : public FlagHandlerBase {
> +  bool *halt_on_error_;
> +
> + public:
> +  explicit FlagHandlerKeepGoing(bool *halt_on_error)
> +      : halt_on_error_(halt_on_error) {}
> +  bool Parse(const char *value) {
> +    bool tmp;
> +    FlagHandler<bool> h(&tmp);
> +    if (!h.Parse(value)) return false;
> +    *halt_on_error_ = !tmp;
> +    return true;
> +  }
> +};
> +
> +void RegisterMsanFlags(FlagParser *parser, Flags *f) {
> +#define MSAN_FLAG(Type, Name, DefaultValue, Description) \
> +  RegisterFlag(parser, #Name, Description, &f->Name);
>  #include "msan_flags.inc"
>  #undef MSAN_FLAG
> +
> +  FlagHandlerKeepGoing *fh_keep_going =
> +      new (INTERNAL_ALLOC) FlagHandlerKeepGoing(&f->halt_on_error);  //
> NOLINT
> +  parser->RegisterHandler("keep_going", fh_keep_going,
> +                          "deprecated, use halt_on_error");
>  }
>
>  static void InitializeFlags(Flags *f, const char *options) {
> +  FlagParser parser;
> +  RegisterMsanFlags(&parser, f);
> +  RegisterCommonFlags(&parser);
> +
>    SetCommonFlagsDefaults();
>    {
>      CommonFlags cf;
> @@ -132,13 +152,12 @@ static void InitializeFlags(Flags *f, co
>    f->SetDefaults();
>
>    // Override from user-specified string.
> -  if (__msan_default_options) {
> -    f->ParseFromString(__msan_default_options());
> -    ParseCommonFlagsFromString(__msan_default_options());
> -  }
> +  if (__msan_default_options)
> +    parser.ParseString(__msan_default_options());
> +
> +  parser.ParseString(options);
>
> -  f->ParseFromString(options);
> -  ParseCommonFlagsFromString(options);
> +  if (common_flags()->help) parser.PrintFlagDescriptions();
>
>    // Check flag values:
>    if (f->exit_code < 0 || f->exit_code > 127) {
> @@ -328,7 +347,6 @@ void __msan_init() {
>
>    const char *msan_options = GetEnv("MSAN_OPTIONS");
>    InitializeFlags(&msan_flags, msan_options);
> -  if (common_flags()->help) PrintFlagDescriptions();
>    __sanitizer_set_report_path(common_flags()->log_path);
>
>    InitializeInterceptors();
>
> Modified: compiler-rt/trunk/lib/msan/msan_flags.h
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/msan_flags.h?rev=226169&r1=226168&r2=226169&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/msan/msan_flags.h (original)
> +++ compiler-rt/trunk/lib/msan/msan_flags.h Thu Jan 15 09:13:43 2015
> @@ -21,7 +21,6 @@ struct Flags {
>  #undef MSAN_FLAG
>
>    void SetDefaults();
> -  void ParseFromString(const char *str);
>  };
>
>  Flags *flags();
>
> Modified: compiler-rt/trunk/lib/sanitizer_common/CMakeLists.txt
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/CMakeLists.txt?rev=226169&r1=226168&r2=226169&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/sanitizer_common/CMakeLists.txt (original)
> +++ compiler-rt/trunk/lib/sanitizer_common/CMakeLists.txt Thu Jan 15
> 09:13:43 2015
> @@ -7,6 +7,7 @@ set(SANITIZER_SOURCES
>    sanitizer_deadlock_detector1.cc
>    sanitizer_deadlock_detector2.cc
>    sanitizer_flags.cc
> +  sanitizer_flag_parser.cc
>    sanitizer_libc.cc
>    sanitizer_libignore.cc
>    sanitizer_linux.cc
> @@ -63,6 +64,7 @@ set(SANITIZER_HEADERS
>    sanitizer_common_syscalls.inc
>    sanitizer_deadlock_detector.h
>    sanitizer_deadlock_detector_interface.h
> +  sanitizer_flag_parser.h
>    sanitizer_flags.h
>    sanitizer_flags.inc
>    sanitizer_internal_defs.h
>
> Modified:
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator_internal.h
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator_internal.h?rev=226169&r1=226168&r2=226169&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator_internal.h
> (original)
> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator_internal.h
> Thu Jan 15 09:13:43 2015
> @@ -49,6 +49,15 @@ void *InternalAlloc(uptr size, InternalA
>  void InternalFree(void *p, InternalAllocatorCache *cache = 0);
>  InternalAllocator *internal_allocator();
>
> +enum InternalAllocEnum {
> +  INTERNAL_ALLOC
> +};
> +
>  }  // namespace __sanitizer
>
> +inline void *operator new(__sanitizer::operator_new_size_type size,
> +                          InternalAllocEnum) {
> +  return InternalAlloc(size);
> +}
> +
>  #endif  // SANITIZER_ALLOCATOR_INTERNAL_H
>
> Added: compiler-rt/trunk/lib/sanitizer_common/sanitizer_flag_parser.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_flag_parser.cc?rev=226169&view=auto
>
> ==============================================================================
> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_flag_parser.cc (added)
> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_flag_parser.cc Thu
> Jan 15 09:13:43 2015
> @@ -0,0 +1,117 @@
> +//===-- sanitizer_flag_parser.cc
> ------------------------------------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +//
> +// This file is a part of ThreadSanitizer/AddressSanitizer runtime.
> +//
>
> +//===----------------------------------------------------------------------===//
> +
> +#include "sanitizer_flag_parser.h"
> +
> +#include "sanitizer_common.h"
> +#include "sanitizer_libc.h"
> +#include "sanitizer_flags.h"
> +#include "sanitizer_flag_parser.h"
> +#include "sanitizer_allocator_internal.h"
> +
> +namespace __sanitizer {
> +
> +void FlagParser::PrintFlagDescriptions() {
> +  Printf("Available flags for %s:\n", SanitizerToolName);
> +  for (int i = 0; i < n_flags_; ++i)
> +    Printf("\t%s\n\t\t- %s\n", flags_[i].name, flags_[i].desc);
> +}
> +
> +void FlagParser::fatal_error(const char *err) {
> +  Printf("ERROR: %s\n", err);
> +  Die();
> +}
> +
> +bool FlagParser::is_space(char c) {
> +  return c == ' ' || c == ',' || c == ':' || c == '\n' || c == '\t' ||
> +         c == '\r';
> +}
> +
> +void FlagParser::skip_whitespace() {
> +  while (is_space(buf_[pos_])) ++pos_;
> +}
> +
> +void FlagParser::parse_flag() {
> +  uptr name_start = pos_;
> +  while (buf_[pos_] != 0 && buf_[pos_] != '=' && !is_space(buf_[pos_]))
> ++pos_;
> +  if (buf_[pos_] != '=') fatal_error("expected '='");
> +  const char *name = internal_strndup(buf_ + name_start, pos_ -
> name_start);
> +
> +  uptr value_start = ++pos_;
> +  const char *value;
> +  if (buf_[pos_] == '\'' || buf_[pos_] == '"') {
> +    char quote = buf_[pos_++];
> +    while (buf_[pos_] != 0 && buf_[pos_] != quote) ++pos_;
> +    if (buf_[pos_] == 0) fatal_error("unterminated string");
> +    value = internal_strndup(buf_ + value_start + 1, pos_ - value_start -
> 1);
> +    ++pos_; // consume the closing quote
> +  } else {
> +    while (buf_[pos_] != 0 && !is_space(buf_[pos_])) ++pos_;
> +    if (buf_[pos_] != 0 && !is_space(buf_[pos_]))
> +      fatal_error("expected separator or eol");
> +    value = internal_strndup(buf_ + value_start, pos_ - value_start);
> +  }
> +
> +  bool res = run_handler(name, value);
> +  if (!res) {
> +    Printf("Flag parsing failed.");
> +    Die();
>

fatal_error("Flag parsing failed!"); ?


> +  }
> +  InternalFree((void *)name);
> +  InternalFree((void *)value);
> +}
> +
> +void FlagParser::ParseString(const char *s) {
> +  if (!s) return;
> +  buf_ = s;
> +  pos_ = 0;
> +  while (true) {
> +    skip_whitespace();
> +    if (buf_[pos_] == 0) break;
> +    parse_flag();
> +  }
> +
> +  // Do a sanity check for certain flags.
> +  if (common_flags_dont_use.malloc_context_size < 1)
> +    common_flags_dont_use.malloc_context_size = 1;
> +}
> +
> +bool FlagParser::run_handler(const char *name, const char *value) {
> +  for (int i = 0; i < n_flags_; ++i) {
> +    if (internal_strcmp(name, flags_[i].name) == 0)
> +      return flags_[i].handler->Parse(value);
> +  }
> +  Printf("ERROR: Unknown flag: '%s'\n", name);
>

Do you think we should demote it to warning, or optionally disable this
message?
Sometimes our user add values for new runtime flags before they update the
runtime
to the one that supports these flags.


> +  return false;
> +}
> +
> +void FlagParser::RegisterHandler(const char *name, FlagHandlerBase
> *handler,
> +                                 const char *desc) {
> +  CHECK(n_flags_ < kMaxFlags);
>
CHECK_LE?


> +  flags_[n_flags_].name = name;
> +  flags_[n_flags_].desc = desc;
> +  flags_[n_flags_].handler = handler;
> +  ++n_flags_;
> +}
> +
> +FlagParser::FlagParser() : n_flags_(0), buf_(nullptr), pos_(0) {
> +  flags_ = (Flag *)InternalAlloc(sizeof(Flag) * kMaxFlags);
> +}
>

Any reason to not make it a resizable InternalMmapVector? Although, see
below.


> +
> +FlagParser::~FlagParser() {
> +  for (int i = 0; i < n_flags_; ++i)
> +    InternalFree(flags_[i].handler);
>

I'm mildly concerned by the extensive usage of InternalAllocator this early
during initialization
It probably works because we initialize internal allocator lazily, but what
if at some point
internal allocator will itself depend on some flag values? Older version of
this code used
LowLevelAllocator, which doesn't allow you to deallocate memory, but is
more simple and lightweight.
Why did you decide to switch from it?


> +  InternalFree(flags_);
> +}
> +
> +}  // namespace __sanitizer
>
> Propchange: compiler-rt/trunk/lib/sanitizer_common/sanitizer_flag_parser.cc
>
> ------------------------------------------------------------------------------
>     svn:eol-style = LF
>
> Added: compiler-rt/trunk/lib/sanitizer_common/sanitizer_flag_parser.h
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_flag_parser.h?rev=226169&view=auto
>
> ==============================================================================
> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_flag_parser.h (added)
> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_flag_parser.h Thu Jan
> 15 09:13:43 2015
> @@ -0,0 +1,117 @@
> +//===-- sanitizer_flag_parser.h ---------------------------------*- C++
> -*-===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +//
> +// This file is a part of ThreadSanitizer/AddressSanitizer runtime.
> +//
>
> +//===----------------------------------------------------------------------===//
> +
> +#ifndef SANITIZER_FLAG_REGISTRY_H
> +#define SANITIZER_FLAG_REGISTRY_H
> +
> +#include "sanitizer_internal_defs.h"
> +#include "sanitizer_libc.h"
> +#include "sanitizer_common.h"
> +#include "sanitizer_allocator_internal.h"
> +
> +namespace __sanitizer {
> +
> +class FlagHandlerBase {
> + public:
> +  virtual bool Parse(const char *value) { return false; }
> +};
> +
> +template <typename T>
> +class FlagHandler : public FlagHandlerBase {
> +  T *t_;
> +
> + public:
> +  explicit FlagHandler(T *t) : t_(t) {}
> +  bool Parse(const char *value);
> +};
> +
> +template <>
> +inline bool FlagHandler<bool>::Parse(const char *value) {
> +  if (internal_strcmp(value, "0") == 0 ||
> +      internal_strcmp(value, "no") == 0 ||
> +      internal_strcmp(value, "false") == 0) {
> +    *t_ = false;
> +    return true;
> +  }
> +  if (internal_strcmp(value, "1") == 0 ||
> +      internal_strcmp(value, "yes") == 0 ||
> +      internal_strcmp(value, "true") == 0) {
> +    *t_ = true;
> +    return true;
> +  }
> +  Printf("ERROR: Invalid value for bool option: '%s'\n", value);
> +  return false;
> +}
> +
> +template <>
> +inline bool FlagHandler<const char *>::Parse(const char *value) {
> +  *t_ = internal_strdup(value);
> +  return true;
> +}
> +
> +template <>
> +inline bool FlagHandler<int>::Parse(const char *value) {
> +  char *value_end;
> +  *t_ = internal_simple_strtoll(value, &value_end, 10);
> +  bool ok = *value_end == 0;
> +  if (!ok) Printf("ERROR: Invalid value for int option: '%s'\n", value);
> +  return ok;
> +}
> +
> +template <>
> +inline bool FlagHandler<uptr>::Parse(const char *value) {
> +  char *value_end;
> +  *t_ = internal_simple_strtoll(value, &value_end, 10);
> +  bool ok = *value_end == 0;
> +  if (!ok) Printf("ERROR: Invalid value for uptr option: '%s'\n", value);
> +  return ok;
> +}
> +
> +class FlagParser {
> +  static const int kMaxFlags = 200;
> +  struct Flag {
> +    const char *name;
> +    const char *desc;
> +    FlagHandlerBase *handler;
> +  } *flags_;
> +  int n_flags_;
> +
> +  const char *buf_;
> +  uptr pos_;
> +
> + public:
> +  FlagParser();
> +  ~FlagParser();
> +  void RegisterHandler(const char *name, FlagHandlerBase *handler,
> +                       const char *desc);
> +  void ParseString(const char *s);
> +  void PrintFlagDescriptions();
> +
> + private:
> +  void fatal_error(const char *err);
> +  bool is_space(char c);
> +  void skip_whitespace();
> +  void parse_flag();
> +  bool run_handler(const char *name, const char *value);
> +};
> +
> +template <typename T>
> +static void RegisterFlag(FlagParser *parser, const char *name, const char
> *desc,
> +                         T *var) {
> +  FlagHandler<T> *fh = new (INTERNAL_ALLOC) FlagHandler<T>(var);  //
> NOLINT
> +  parser->RegisterHandler(name, fh, desc);
> +}
> +
> +}  // namespace __sanitizer
> +
> +#endif  // SANITIZER_FLAG_REGISTRY_H
>
> Propchange: compiler-rt/trunk/lib/sanitizer_common/sanitizer_flag_parser.h
>
> ------------------------------------------------------------------------------
>     svn:eol-style = LF
>
> Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc?rev=226169&r1=226168&r2=226169&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc (original)
> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc Thu Jan 15
> 09:13:43 2015
> @@ -16,6 +16,7 @@
>  #include "sanitizer_common.h"
>  #include "sanitizer_libc.h"
>  #include "sanitizer_list.h"
> +#include "sanitizer_flag_parser.h"
>
>  namespace __sanitizer {
>
> @@ -40,150 +41,15 @@ void CommonFlags::SetDefaults() {
>  #undef COMMON_FLAG
>  }
>
> -void CommonFlags::ParseFromString(const char *str) {
> -#define COMMON_FLAG(Type, Name, DefaultValue, Description)
>      \
> -  ParseFlag(str, &Name, #Name, Description);
> -#include "sanitizer_flags.inc"
> -#undef COMMON_FLAG
> -  // Do a sanity check for certain flags.
> -  if (malloc_context_size < 1)
> -    malloc_context_size = 1;
> -}
> -
>  void CommonFlags::CopyFrom(const CommonFlags &other) {
>    internal_memcpy(this, &other, sizeof(*this));
>  }
>
> -static bool GetFlagValue(const char *env, const char *name,
> -                         const char **value, int *value_length) {
> -  if (env == 0)
> -    return false;
> -  const char *pos = 0;
> -  for (;;) {
> -    pos = internal_strstr(env, name);
> -    if (pos == 0)
> -      return false;
> -    const char *name_end = pos + internal_strlen(name);
> -    if ((pos != env &&
> -         ((pos[-1] >= 'a' && pos[-1] <= 'z') || pos[-1] == '_')) ||
> -        *name_end != '=') {
> -      // Seems to be middle of another flag name or value.
> -      env = pos + 1;
> -      continue;
> -    }
> -    pos = name_end;
> -    break;
> -  }
> -  const char *end;
> -  if (pos[0] != '=') {
> -    end = pos;
> -  } else {
> -    pos += 1;
> -    if (pos[0] == '"') {
> -      pos += 1;
> -      end = internal_strchr(pos, '"');
> -    } else if (pos[0] == '\'') {
> -      pos += 1;
> -      end = internal_strchr(pos, '\'');
> -    } else {
> -      // Read until the next space or colon.
> -      end = pos + internal_strcspn(pos, " :\r\n\t");
> -    }
> -    if (end == 0)
> -      end = pos + internal_strlen(pos);
> -  }
> -  *value = pos;
> -  *value_length = end - pos;
> -  return true;
> -}
> -
> -static bool StartsWith(const char *flag, int flag_length, const char
> *value) {
> -  if (!flag || !value)
> -    return false;
> -  int value_length = internal_strlen(value);
> -  return (flag_length >= value_length) &&
> -         (0 == internal_strncmp(flag, value, value_length));
> -}
> -
> -static LowLevelAllocator allocator_for_flags;
> -
> -// The linear scan is suboptimal, but the number of flags is relatively
> small.
> -bool FlagInDescriptionList(const char *name) {
> -  IntrusiveList<FlagDescription>::Iterator it(&flag_descriptions);
> -  while (it.hasNext()) {
> -    if (!internal_strcmp(it.next()->name, name)) return true;
> -  }
> -  return false;
> -}
> -
> -void AddFlagDescription(const char *name, const char *description) {
> -  if (FlagInDescriptionList(name)) return;
> -  FlagDescription *new_description = new(allocator_for_flags)
> FlagDescription;
> -  new_description->name = name;
> -  new_description->description = description;
> -  flag_descriptions.push_back(new_description);
> -}
> -
> -// TODO(glider): put the descriptions inside CommonFlags.
> -void PrintFlagDescriptions() {
> -  IntrusiveList<FlagDescription>::Iterator it(&flag_descriptions);
> -  Printf("Available flags for %s:\n", SanitizerToolName);
> -  while (it.hasNext()) {
> -    FlagDescription *descr = it.next();
> -    Printf("\t%s\n\t\t- %s\n", descr->name, descr->description);
> -  }
> -}
> -
> -void ParseFlag(const char *env, bool *flag,
> -               const char *name, const char *descr) {
> -  const char *value;
> -  int value_length;
> -  AddFlagDescription(name, descr);
> -  if (!GetFlagValue(env, name, &value, &value_length))
> -    return;
> -  if (StartsWith(value, value_length, "0") ||
> -      StartsWith(value, value_length, "no") ||
> -      StartsWith(value, value_length, "false"))
> -    *flag = false;
> -  if (StartsWith(value, value_length, "1") ||
> -      StartsWith(value, value_length, "yes") ||
> -      StartsWith(value, value_length, "true"))
> -    *flag = true;
> -}
> -
> -void ParseFlag(const char *env, int *flag,
> -               const char *name, const char *descr) {
> -  const char *value;
> -  int value_length;
> -  AddFlagDescription(name, descr);
> -  if (!GetFlagValue(env, name, &value, &value_length))
> -    return;
> -  *flag = static_cast<int>(internal_atoll(value));
> -}
> -
> -void ParseFlag(const char *env, uptr *flag,
> -               const char *name, const char *descr) {
> -  const char *value;
> -  int value_length;
> -  AddFlagDescription(name, descr);
> -  if (!GetFlagValue(env, name, &value, &value_length))
> -    return;
> -  *flag = static_cast<uptr>(internal_atoll(value));
> -}
> -
> -void ParseFlag(const char *env, const char **flag,
> -               const char *name, const char *descr) {
> -  const char *value;
> -  int value_length;
> -  AddFlagDescription(name, descr);
> -  if (!GetFlagValue(env, name, &value, &value_length))
> -    return;
> -  // Copy the flag value. Don't use locks here, as flags are parsed at
> -  // tool startup.
> -  char *value_copy = (char*)(allocator_for_flags.Allocate(value_length +
> 1));
> -  internal_memcpy(value_copy, value, value_length);
> -  value_copy[value_length] = '\0';
> -  *flag = value_copy;
> +void RegisterCommonFlags(FlagParser *parser, CommonFlags *cf) {
> +#define COMMON_FLAG(Type, Name, DefaultValue, Description) \
> +  RegisterFlag(parser, #Name, Description, &cf->Name);
> +#include "sanitizer_flags.inc"
> +#undef COMMON_FLAG
>  }
>
>  }  // namespace __sanitizer
>
> Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.h
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.h?rev=226169&r1=226168&r2=226169&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.h (original)
> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.h Thu Jan 15
> 09:13:43 2015
> @@ -18,22 +18,12 @@
>
>  namespace __sanitizer {
>
> -void ParseFlag(const char *env, bool *flag,
> -    const char *name, const char *descr);
> -void ParseFlag(const char *env, int *flag,
> -    const char *name, const char *descr);
> -void ParseFlag(const char *env, uptr *flag,
> -    const char *name, const char *descr);
> -void ParseFlag(const char *env, const char **flag,
> -    const char *name, const char *descr);
> -
>  struct CommonFlags {
>  #define COMMON_FLAG(Type, Name, DefaultValue, Description) Type Name;
>  #include "sanitizer_flags.inc"
>  #undef COMMON_FLAG
>
>    void SetDefaults();
> -  void ParseFromString(const char *str);
>    void CopyFrom(const CommonFlags &other);
>  };
>
> @@ -47,10 +37,6 @@ inline void SetCommonFlagsDefaults() {
>    common_flags_dont_use.SetDefaults();
>  }
>
> -inline void ParseCommonFlagsFromString(const char *str) {
> -  common_flags_dont_use.ParseFromString(str);
> -}
> -
>  // This function can only be used to setup tool-specific overrides for
>  // CommonFlags defaults. Generally, it should only be used right after
>  // SetCommonFlagsDefaults(), but before ParseCommonFlagsFromString(), and
> @@ -60,8 +46,9 @@ inline void OverrideCommonFlags(const Co
>    common_flags_dont_use.CopyFrom(cf);
>  }
>
> -void PrintFlagDescriptions();
> -
> +class FlagParser;
> +void RegisterCommonFlags(FlagParser *parser,
> +                         CommonFlags *cf = &common_flags_dont_use);
>  }  // namespace __sanitizer
>
>  #endif  // SANITIZER_FLAGS_H
>
> Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_libc.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_libc.cc?rev=226169&r1=226168&r2=226169&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_libc.cc (original)
> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_libc.cc Thu Jan 15
> 09:13:43 2015
> @@ -101,6 +101,14 @@ char* internal_strdup(const char *s) {
>    return s2;
>  }
>
> +char* internal_strndup(const char *s, uptr n) {
> +  uptr len = internal_strnlen(s, n);
> +  char *s2 = (char*)InternalAlloc(len + 1);
> +  internal_memcpy(s2, s, len);
> +  s2[len] = 0;
> +  return s2;
> +}
> +
>  int internal_strcmp(const char *s1, const char *s2) {
>    while (true) {
>      unsigned c1 = *s1;
>
> Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_libc.h
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_libc.h?rev=226169&r1=226168&r2=226169&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_libc.h (original)
> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_libc.h Thu Jan 15
> 09:13:43 2015
> @@ -38,6 +38,7 @@ char *internal_strchrnul(const char *s,
>  int internal_strcmp(const char *s1, const char *s2);
>  uptr internal_strcspn(const char *s, const char *reject);
>  char *internal_strdup(const char *s);
> +char *internal_strndup(const char *s, uptr n);
>  uptr internal_strlen(const char *s);
>  char *internal_strncat(char *dst, const char *src, uptr n);
>  int internal_strncmp(const char *s1, const char *s2, uptr n);
>
> Modified:
> compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_flags_test.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_flags_test.cc?rev=226169&r1=226168&r2=226169&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_flags_test.cc
> (original)
> +++ compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_flags_test.cc
> Thu Jan 15 09:13:43 2015
> @@ -12,7 +12,9 @@
>
>  //===----------------------------------------------------------------------===//
>  #include "sanitizer_common/sanitizer_common.h"
>  #include "sanitizer_common/sanitizer_flags.h"
> +#include "sanitizer_common/sanitizer_flag_parser.h"
>  #include "sanitizer_common/sanitizer_libc.h"
> +#include "sanitizer_common/sanitizer_allocator_internal.h"
>  #include "gtest/gtest.h"
>
>  #include <string.h>
> @@ -20,58 +22,74 @@
>  namespace __sanitizer {
>
>  static const char kFlagName[] = "flag_name";
> +static const char kFlagDesc[] = "flag description";
>
>  template <typename T>
>  static void TestFlag(T start_value, const char *env, T final_value) {
>    T flag = start_value;
> -  ParseFlag(env, &flag, kFlagName, "flag description");
> +
> +  FlagParser parser;
> +  RegisterFlag(&parser, kFlagName, kFlagDesc, &flag);
> +
> +  parser.ParseString(env);
> +
>    EXPECT_EQ(final_value, flag);
>  }
>
> -static void TestStrFlag(const char *start_value, const char *env,
> -                        const char *final_value) {
> +template <>
> +void TestFlag(const char *start_value, const char *env,
> +                     const char *final_value) {
>    const char *flag = start_value;
> -  ParseFlag(env, &flag, kFlagName, "flag description");
> +
> +  FlagParser parser;
> +  RegisterFlag(&parser, kFlagName, kFlagDesc, &flag);
> +
> +  parser.ParseString(env);
> +
>    EXPECT_EQ(0, internal_strcmp(final_value, flag));
>  }
>
>  TEST(SanitizerCommon, BooleanFlags) {
> -  TestFlag(true, "--flag_name", true);
> -  TestFlag(false, "flag_name", false);
> -  TestFlag(false, "--flag_name=1", true);
> -  TestFlag(true, "asdas flag_name=0 asdas", false);
> -  TestFlag(true, "    --flag_name=0   ", false);
> +  TestFlag(false, "flag_name=1", true);
>    TestFlag(false, "flag_name=yes", true);
>    TestFlag(false, "flag_name=true", true);
> +  TestFlag(true, "flag_name=0", false);
>    TestFlag(true, "flag_name=no", false);
>    TestFlag(true, "flag_name=false", false);
>  }
>
>  TEST(SanitizerCommon, IntFlags) {
>    TestFlag(-11, 0, -11);
> -  TestFlag(-11, "flag_name", -11);
> -  TestFlag(-11, "--flag_name=", 0);
> -  TestFlag(-11, "--flag_name=42", 42);
> -  TestFlag(-11, "--flag_name=-42", -42);
> +  TestFlag(-11, "flag_name=0", 0);
> +  TestFlag(-11, "flag_name=42", 42);
> +  TestFlag(-11, "flag_name=-42", -42);
> +  EXPECT_DEATH(TestFlag(-11, "flag_name", 0), "expected '='");
> +  EXPECT_DEATH(TestFlag(-11, "--flag_name=42", 0),
> +               "Unknown flag: '--flag_name'");
>  }
>
>  TEST(SanitizerCommon, StrFlags) {
> -  TestStrFlag("zzz", 0, "zzz");
> -  TestStrFlag("zzz", "flag_name", "zzz");
> -  TestStrFlag("zzz", "--flag_name=", "");
> -  TestStrFlag("", "--flag_name=abc", "abc");
> -  TestStrFlag("", "--flag_name='abc zxc'", "abc zxc");
> -  TestStrFlag("", "--flag_name='abc zxcc'", "abc zxcc");
> -  TestStrFlag("", "--flag_name=\"abc qwe\" asd", "abc qwe");
> -  TestStrFlag("", "other_flag_name=zzz", "");
> +  TestFlag("zzz", 0, "zzz");
> +  TestFlag("zzz", "flag_name=", "");
> +  TestFlag("zzz", "flag_name=abc", "abc");
> +  TestFlag("", "flag_name=abc", "abc");
> +  TestFlag("", "flag_name='abc zxc'", "abc zxc");
> +  // TestStrFlag("", "flag_name=\"abc qwe\" asd", "abc qwe");
>  }
>
>  static void TestTwoFlags(const char *env, bool expected_flag1,
> -                         const char *expected_flag2) {
> +                         const char *expected_flag2,
> +                         const char *name1 = "flag1",
> +                         const char *name2 = "flag2") {
>    bool flag1 = !expected_flag1;
>    const char *flag2 = "";
> -  ParseFlag(env, &flag1, "flag1", "flag1 description");
> -  ParseFlag(env, &flag2, "flag2", "flag2 description");
> +
> +  FlagParser parser;
> +  RegisterFlag(&parser, name1, kFlagDesc, &flag1);
> +  RegisterFlag(&parser, name2, kFlagDesc, &flag2);
> +
> +  parser.ParseString(env);
> +
>    EXPECT_EQ(expected_flag1, flag1);
>    EXPECT_EQ(0, internal_strcmp(flag2, expected_flag2));
>  }
> @@ -86,8 +104,20 @@ TEST(SanitizerCommon, MultipleFlags) {
>    TestTwoFlags("flag2=qxx\tflag1=yes", true, "qxx");
>  }
>
> +TEST(SanitizerCommon, CommonSuffixFlags) {
> +  TestTwoFlags("flag=1 other_flag='zzz'", true, "zzz", "flag",
> "other_flag");
> +  TestTwoFlags("other_flag='zzz' flag=1", true, "zzz", "flag",
> "other_flag");
> +  TestTwoFlags("other_flag=' flag=0 ' flag=1", true, " flag=0 ", "flag",
> +               "other_flag");
> +  TestTwoFlags("flag=1 other_flag=' flag=0 '", true, " flag=0 ", "flag",
> +               "other_flag");
> +}
> +
>  TEST(SanitizerCommon, CommonFlags) {
>    CommonFlags cf;
> +  FlagParser parser;
> +  RegisterCommonFlags(&parser, &cf);
> +
>    cf.SetDefaults();
>    EXPECT_TRUE(cf.symbolize);
>    EXPECT_STREQ(".", cf.coverage_dir);
> @@ -97,7 +127,7 @@ TEST(SanitizerCommon, CommonFlags) {
>    cf.coverage_direct = true;
>    cf.log_path = "path/one";
>
> -  cf.ParseFromString("symbolize=1:coverage_direct=false
> log_path='path/two'");
> +  parser.ParseString("symbolize=1:coverage_direct=false
> log_path='path/two'");
>    EXPECT_TRUE(cf.symbolize);
>    EXPECT_TRUE(cf.coverage);
>    EXPECT_FALSE(cf.coverage_direct);
>
> Modified: compiler-rt/trunk/lib/tsan/dd/dd_rtl.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/dd/dd_rtl.cc?rev=226169&r1=226168&r2=226169&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/tsan/dd/dd_rtl.cc (original)
> +++ compiler-rt/trunk/lib/tsan/dd/dd_rtl.cc Thu Jan 15 09:13:43 2015
> @@ -11,6 +11,7 @@
>  #include "sanitizer_common/sanitizer_common.h"
>  #include "sanitizer_common/sanitizer_placement_new.h"
>  #include "sanitizer_common/sanitizer_flags.h"
> +#include "sanitizer_common/sanitizer_flag_parser.h"
>  #include "sanitizer_common/sanitizer_stacktrace.h"
>  #include "sanitizer_common/sanitizer_stackdepot.h"
>
> @@ -80,8 +81,10 @@ void InitializeFlags(Flags *f, const cha
>    }
>
>    // Override from command line.
> -  ParseFlag(env, &f->second_deadlock_stack, "second_deadlock_stack", "");
> -  ParseCommonFlagsFromString(env);
> +  FlagParser parser;
> +  RegisterFlag(&parser, "second_deadlock_stack", "",
> &f->second_deadlock_stack);
> +  RegisterCommonFlags(&parser);
> +  parser.ParseString(env);
>  }
>
>  void Initialize() {
>
> Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_flags.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_flags.cc?rev=226169&r1=226168&r2=226169&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/tsan/rtl/tsan_flags.cc (original)
> +++ compiler-rt/trunk/lib/tsan/rtl/tsan_flags.cc Thu Jan 15 09:13:43 2015
> @@ -12,6 +12,7 @@
>
>  //===----------------------------------------------------------------------===//
>
>  #include "sanitizer_common/sanitizer_flags.h"
> +#include "sanitizer_common/sanitizer_flag_parser.h"
>  #include "sanitizer_common/sanitizer_libc.h"
>  #include "tsan_flags.h"
>  #include "tsan_rtl.h"
> @@ -41,16 +42,18 @@ void Flags::SetDefaults() {
>    second_deadlock_stack = false;
>  }
>
> -void Flags::ParseFromString(const char *str) {
> -#define TSAN_FLAG(Type, Name, DefaultValue, Description)
>    \
> -  ParseFlag(str, &Name, #Name, Description);
> +void RegisterTsanFlags(FlagParser *parser, Flags *f) {
> +#define TSAN_FLAG(Type, Name, DefaultValue, Description) \
> +  RegisterFlag(parser, #Name, Description, &f->Name);
>  #include "tsan_flags.inc"
>  #undef TSAN_FLAG
> -  // DDFlags
> -  ParseFlag(str, &second_deadlock_stack, "second_deadlock_stack", "");
>  }
>
>  void InitializeFlags(Flags *f, const char *env) {
> +  FlagParser parser;
> +  RegisterTsanFlags(&parser, f);
> +  RegisterCommonFlags(&parser);
> +
>    f->SetDefaults();
>
>    SetCommonFlagsDefaults();
> @@ -66,11 +69,9 @@ void InitializeFlags(Flags *f, const cha
>    }
>
>    // Let a frontend override.
> -  f->ParseFromString(__tsan_default_options());
> -  ParseCommonFlagsFromString(__tsan_default_options());
> +  parser.ParseString(__tsan_default_options());
>    // Override from command line.
> -  f->ParseFromString(env);
> -  ParseCommonFlagsFromString(env);
> +  parser.ParseString(env);
>
>    // Sanity check.
>    if (!f->report_bugs) {
> @@ -80,7 +81,7 @@ void InitializeFlags(Flags *f, const cha
>    }
>
>    if (common_flags()->help)
> -    PrintFlagDescriptions();
> +    parser.PrintFlagDescriptions();
>
>    if (f->history_size < 0 || f->history_size > 7) {
>      Printf("ThreadSanitizer: incorrect value for history_size"
>
> Modified: compiler-rt/trunk/lib/ubsan/ubsan_flags.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/ubsan/ubsan_flags.cc?rev=226169&r1=226168&r2=226169&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/ubsan/ubsan_flags.cc (original)
> +++ compiler-rt/trunk/lib/ubsan/ubsan_flags.cc Thu Jan 15 09:13:43 2015
> @@ -14,6 +14,7 @@
>  #include "ubsan_flags.h"
>  #include "sanitizer_common/sanitizer_common.h"
>  #include "sanitizer_common/sanitizer_flags.h"
> +#include "sanitizer_common/sanitizer_flag_parser.h"
>
>  namespace __ubsan {
>
> @@ -21,18 +22,6 @@ static const char *MaybeCallUbsanDefault
>    return (&__ubsan_default_options) ? __ubsan_default_options() : "";
>  }
>
> -void InitializeCommonFlags() {
> -  SetCommonFlagsDefaults();
> -  CommonFlags cf;
> -  cf.CopyFrom(*common_flags());
> -  cf.print_summary = false;
> -  OverrideCommonFlags(cf);
> -  // Override from user-specified string.
> -  ParseCommonFlagsFromString(MaybeCallUbsanDefaultOptions());
> -  // Override from environment variable.
> -  ParseCommonFlagsFromString(GetEnv("UBSAN_OPTIONS"));
> -}
> -
>  Flags ubsan_flags;
>
>  void Flags::SetDefaults() {
> @@ -41,20 +30,42 @@ void Flags::SetDefaults() {
>  #undef UBSAN_FLAG
>  }
>
> -void Flags::ParseFromString(const char *str) {
> -#define UBSAN_FLAG(Type, Name, DefaultValue, Description)
>       \
> -  ParseFlag(str, &Name, #Name, Description);
> +void RegisterUbsanFlags(FlagParser *parser, Flags *f) {
> +#define UBSAN_FLAG(Type, Name, DefaultValue, Description) \
> +  RegisterFlag(parser, #Name, Description, &f->Name);
>  #include "ubsan_flags.inc"
>  #undef UBSAN_FLAG
>  }
>
> -void InitializeFlags() {
> +void InitializeFlags(bool standalone) {
>    Flags *f = flags();
> +  FlagParser parser;
> +  RegisterUbsanFlags(&parser, f);
> +
> +  if (standalone) {
> +    RegisterCommonFlags(&parser);
> +
> +    SetCommonFlagsDefaults();
> +    CommonFlags cf;
> +    cf.CopyFrom(*common_flags());
> +    cf.print_summary = false;
> +    OverrideCommonFlags(cf);
> +  } else {
> +    // Ignore common flags if not standalone.
> +    // This is inconsistent with LSan, which allows common flags in
> LSAN_FLAGS.
> +    // This is caused by undefined initialization order between ASan and
> UBsan,
> +    // which makes it impossible to make sure that common flags from
> ASAN_OPTIONS
> +    // have not been used (in __asan_init) before they are overwritten
> with flags
> +    // from UBSAN_OPTIONS.
> +    CommonFlags cf_ignored;
> +    RegisterCommonFlags(&parser, &cf_ignored);
> +  }
> +
>    f->SetDefaults();
>    // Override from user-specified string.
> -  f->ParseFromString(MaybeCallUbsanDefaultOptions());
> +  parser.ParseString(MaybeCallUbsanDefaultOptions());
>    // Override from environment variable.
> -  f->ParseFromString(GetEnv("UBSAN_OPTIONS"));
> +  parser.ParseString(GetEnv("UBSAN_OPTIONS"));
>  }
>
>  }  // namespace __ubsan
>
> Modified: compiler-rt/trunk/lib/ubsan/ubsan_flags.h
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/ubsan/ubsan_flags.h?rev=226169&r1=226168&r2=226169&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/ubsan/ubsan_flags.h (original)
> +++ compiler-rt/trunk/lib/ubsan/ubsan_flags.h Thu Jan 15 09:13:43 2015
> @@ -23,14 +23,12 @@ struct Flags {
>  #undef UBSAN_FLAG
>
>    void SetDefaults();
> -  void ParseFromString(const char *str);
>  };
>
>  extern Flags ubsan_flags;
>  inline Flags *flags() { return &ubsan_flags; }
>
> -void InitializeCommonFlags();
> -void InitializeFlags();
> +void InitializeFlags(bool standalone);
>
>  }  // namespace __ubsan
>
>
> Modified: compiler-rt/trunk/lib/ubsan/ubsan_init.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/ubsan/ubsan_init.cc?rev=226169&r1=226168&r2=226169&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/ubsan/ubsan_init.cc (original)
> +++ compiler-rt/trunk/lib/ubsan/ubsan_init.cc Thu Jan 15 09:13:43 2015
> @@ -31,6 +31,7 @@ void __ubsan::InitIfNecessary() {
>  #endif
>    if (LIKELY(ubsan_inited))
>     return;
> +  bool standalone = false;
>    if (0 == internal_strcmp(SanitizerToolName, "SanitizerTool")) {
>      // WARNING: If this condition holds, then either UBSan runs in a
> standalone
>      // mode, or initializer for another sanitizer hasn't run yet. In a
> latter
> @@ -38,10 +39,10 @@ void __ubsan::InitIfNecessary() {
>      // common flags. It means, that we are not allowed to *use* common
> flags
>      // in this function.
>      SanitizerToolName = "UndefinedBehaviorSanitizer";
> -    InitializeCommonFlags();
> +    standalone = true;
>    }
>    // Initialize UBSan-specific flags.
> -  InitializeFlags();
> +  InitializeFlags(standalone);
>    SuppressionContext::InitIfNecessary();
>    InitializeCoverage(common_flags()->coverage,
> common_flags()->coverage_dir);
>    ubsan_inited = true;
>
> Added: compiler-rt/trunk/test/asan/TestCases/asan_options-help.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/asan_options-help.cc?rev=226169&view=auto
>
> ==============================================================================
> --- compiler-rt/trunk/test/asan/TestCases/asan_options-help.cc (added)
> +++ compiler-rt/trunk/test/asan/TestCases/asan_options-help.cc Thu Jan 15
> 09:13:43 2015
> @@ -0,0 +1,9 @@
> +// RUN: %clangxx_asan -O0 %s -o %t
> +// RUN: ASAN_OPTIONS=help=1 %run %t 2>&1 | FileCheck %s
> +
> +int main() {
> +}
> +
> +// CHECK: Available flags for AddressSanitizer:
> +// CHECK-DAG: handle_segv
> +// CHECK-DAG: check_initialization_order



>
> Propchange: compiler-rt/trunk/test/asan/TestCases/asan_options-help.cc
>
> ------------------------------------------------------------------------------
>     svn:eol-style = LF
>
> Added: compiler-rt/trunk/test/asan/TestCases/asan_options-invalid.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/asan_options-invalid.cc?rev=226169&view=auto
>
> ==============================================================================
> --- compiler-rt/trunk/test/asan/TestCases/asan_options-invalid.cc (added)
> +++ compiler-rt/trunk/test/asan/TestCases/asan_options-invalid.cc Thu Jan
> 15 09:13:43 2015
> @@ -0,0 +1,7 @@
> +// RUN: %clangxx_asan -O0 %s -o %t
> +// RUN: ASAN_OPTIONS=invalid_option_name=10 not %run %t 2>&1 | FileCheck
> %s
> +
> +int main() {
> +}
> +
> +// CHECK: Unknown flag{{.*}}invalid_option_name
>

Shouldn't this (and maybe similar tests) go into tests/sanitizer_common?


>
> Propchange: compiler-rt/trunk/test/asan/TestCases/asan_options-invalid.cc
>
> ------------------------------------------------------------------------------
>     svn:eol-style = LF
>
> Modified: compiler-rt/trunk/test/asan/TestCases/default_options.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/default_options.cc?rev=226169&r1=226168&r2=226169&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/test/asan/TestCases/default_options.cc (original)
> +++ compiler-rt/trunk/test/asan/TestCases/default_options.cc Thu Jan 15
> 09:13:43 2015
> @@ -4,12 +4,12 @@
>  // __asan_default_options() are not supported on Windows.
>  // XFAIL: win32
>
> -const char *kAsanDefaultOptions="verbosity=1 foo=bar";
> +const char *kAsanDefaultOptions="verbosity=1 strip_path_prefix=bar";
>
>  extern "C"
>  __attribute__((no_sanitize_address))
>  const char *__asan_default_options() {
> -  // CHECK: Using the defaults from __asan_default_options: {{.*}} foo=bar
> +  // CHECK: Using the defaults from __asan_default_options: {{.*}}
> strip_path_prefix=bar
>    return kAsanDefaultOptions;
>  }
>
>
> Modified: compiler-rt/trunk/test/lsan/TestCases/ignore_object.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/lsan/TestCases/ignore_object.cc?rev=226169&r1=226168&r2=226169&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/test/lsan/TestCases/ignore_object.cc (original)
> +++ compiler-rt/trunk/test/lsan/TestCases/ignore_object.cc Thu Jan 15
> 09:13:43 2015
> @@ -1,5 +1,5 @@
>  // Test for __lsan_ignore_object().
> -// RUN:
> LSAN_BASE="report_objects=1:use_registers=0:use_stacks=0:use_globals=0:use_tls=0:verbosity=2"
> +// RUN:
> LSAN_BASE="report_objects=1:use_registers=0:use_stacks=0:use_globals=0:use_tls=0"
>  // RUN: %clangxx_lsan %s -o %t
>  // RUN: LSAN_OPTIONS=$LSAN_BASE not %run %t 2>&1 | FileCheck %s
>
> @@ -20,5 +20,4 @@ int main() {
>    return 0;
>  }
>  // CHECK: Test alloc: [[ADDR:.*]].
> -// CHECK: ignoring heap object at [[ADDR]]
>  // CHECK: SUMMARY: {{(Leak|Address)}}Sanitizer: 1337 byte(s) leaked in 1
> allocation(s)
>

Why was this test changed?


>
> Modified: compiler-rt/trunk/test/lsan/TestCases/ignore_object_errors.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/lsan/TestCases/ignore_object_errors.cc?rev=226169&r1=226168&r2=226169&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/test/lsan/TestCases/ignore_object_errors.cc
> (original)
> +++ compiler-rt/trunk/test/lsan/TestCases/ignore_object_errors.cc Thu Jan
> 15 09:13:43 2015
> @@ -1,5 +1,4 @@
>  // Test for incorrect use of __lsan_ignore_object().
> -// RUN: LSAN_BASE="verbosity=2"
>  // RUN: %clangxx_lsan %s -o %t
>  // RUN: LSAN_OPTIONS=$LSAN_BASE %run %t 2>&1 | FileCheck %s
>
> @@ -18,5 +17,4 @@ int main() {
>    return 0;
>  }
>  // CHECK: Test alloc: [[ADDR:.*]].
> -// CHECK: heap object at [[ADDR]] is already being ignored
> -// CHECK: no heap object found at [[ADDR]]
> +// CHECK-NOT: SUMMARY: {{.*}} leaked
>
> Modified: compiler-rt/trunk/test/ubsan/TestCases/TypeCheck/vptr.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/ubsan/TestCases/TypeCheck/vptr.cpp?rev=226169&r1=226168&r2=226169&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/test/ubsan/TestCases/TypeCheck/vptr.cpp (original)
> +++ compiler-rt/trunk/test/ubsan/TestCases/TypeCheck/vptr.cpp Thu Jan 15
> 09:13:43 2015
> @@ -12,16 +12,16 @@
>  // RUN: %run %t m0 2>&1 | FileCheck %s --check-prefix=CHECK-NULL-MEMBER
> --strict-whitespace
>
>  // RUN: (echo "vptr_check:S"; echo "vptr_check:T"; echo "vptr_check:U") >
> %t.supp
> -// RUN: ASAN_OPTIONS="suppressions='%t.supp':halt_on_error=1"
> UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t mS 2>&1
> -// RUN: ASAN_OPTIONS="suppressions='%t.supp':halt_on_error=1"
> UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t fS 2>&1
> -// RUN: ASAN_OPTIONS="suppressions='%t.supp':halt_on_error=1"
> UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t cS 2>&1
> -// RUN: ASAN_OPTIONS="suppressions='%t.supp':halt_on_error=1"
> UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t mV 2>&1
> -// RUN: ASAN_OPTIONS="suppressions='%t.supp':halt_on_error=1"
> UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t fV 2>&1
> -// RUN: ASAN_OPTIONS="suppressions='%t.supp':halt_on_error=1"
> UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t cV 2>&1
> -// RUN: ASAN_OPTIONS="suppressions='%t.supp':halt_on_error=1"
> UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t oU 2>&1
> +// RUN: ASAN_OPTIONS="suppressions='%t.supp'"
> UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t mS 2>&1
> +// RUN: ASAN_OPTIONS="suppressions='%t.supp'"
> UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t fS 2>&1
> +// RUN: ASAN_OPTIONS="suppressions='%t.supp'"
> UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t cS 2>&1
> +// RUN: ASAN_OPTIONS="suppressions='%t.supp'"
> UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t mV 2>&1
> +// RUN: ASAN_OPTIONS="suppressions='%t.supp'"
> UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t fV 2>&1
> +// RUN: ASAN_OPTIONS="suppressions='%t.supp'"
> UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t cV 2>&1
> +// RUN: ASAN_OPTIONS="suppressions='%t.supp'"
> UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t oU 2>&1
>
>  // RUN: echo "vptr_check:S" > %t.loc-supp
> -// RUN: ASAN_OPTIONS="suppressions='%t.loc-supp':halt_on_error=1"
> UBSAN_OPTIONS="suppressions='%t.loc-supp':halt_on_error=1" not %run %t x-
> 2>&1 | FileCheck %s --check-prefix=CHECK-LOC-SUPPRESS
> +// RUN: ASAN_OPTIONS="suppressions='%t.loc-supp'"
> UBSAN_OPTIONS="suppressions='%t.loc-supp':halt_on_error=1" not %run %t x-
> 2>&1 | FileCheck %s --check-prefix=CHECK-LOC-SUPPRESS
>
>  // FIXME: This test produces linker errors on Darwin.
>  // XFAIL: darwin
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>



-- 
Alexey Samsonov
vonosmas at gmail.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150116/9f93ee5d/attachment.html>


More information about the llvm-commits mailing list