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

Evgeniy Stepanov eugeni.stepanov at gmail.com
Mon Jan 19 02:42:14 PST 2015


On Fri, Jan 16, 2015 at 7:32 PM, Alexey Samsonov <vonosmas at gmail.com> wrote:
> 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)

done

>
>>
>>  # 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!"); ?

yep.

>
>>
>> +  }
>> +  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.

I think this is quite valuable as a sanity check, and users don't
generally read warnings (especially run-time warnings!).
OK, Dmitry convinced me that even default warnings are bad. I'll make
this a verbosity=1 warning.

>
>>
>> +  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?

Because it's way easier. With LowLevelAlloc we'll need to be careful
and not use, say, internal_strdup.

I share your concern, this is not entirely sound. I'll switch back to
LowLevelAlloc.

>
>>
>> +  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?

Good point, will do.

>
>>
>>
>> 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?

An intermediate version of this change required that sanitizer_common
flags are only set in the "main sanitizer" flags, i.e. in ASAN_FLAGS
for the asan+lsan configuration. It did not work out because of the
tests like this one that have to run in both lsan and asan+lsan modes.

Note that we have this bad situation where common flags may be
overwritten from LSAN_FLAGS after most of ASan is already initialized.
My commit does not change it.

Anyway, this test was checking "verbosity=2" messages - something that
users never see. The next CHECK: SUMMARY line seems to be doing this
job, right?

>
>>
>>
>> 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



More information about the llvm-commits mailing list