Index: include/clang/Basic/LangOptions.h =================================================================== --- include/clang/Basic/LangOptions.h +++ include/clang/Basic/LangOptions.h @@ -26,6 +26,9 @@ struct SanitizerOptions { #define SANITIZER(NAME, ID) unsigned ID : 1; #include "clang/Basic/Sanitizers.def" + /// \brief Controls how agressive is asan field padding (0: none, 1: least + /// aggressive, 2: more aggressive). + unsigned SanitizeAddressFieldPadding : 2; /// \brief Cached set of sanitizer options with all sanitizers disabled. static const SanitizerOptions Disabled; Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -526,6 +526,9 @@ def fno_sanitize_memory_track_origins : Flag<["-"], "fno-sanitize-memory-track-origins">, Group, Flags<[CC1Option]>, HelpText<"Disable origins tracking in MemorySanitizer">; +def fsanitize_address_field_padding : Joined<["-"], "fsanitize-address-field-padding=">, + Group, Flags<[CC1Option]>, + HelpText<"Level of field padding for AddressSanitizer">; def fsanitize_recover : Flag<["-"], "fsanitize-recover">, Group; def fno_sanitize_recover : Flag<["-"], "fno-sanitize-recover">, Index: include/clang/Driver/SanitizerArgs.h =================================================================== --- include/clang/Driver/SanitizerArgs.h +++ include/clang/Driver/SanitizerArgs.h @@ -49,6 +49,7 @@ std::string BlacklistFile; int MsanTrackOrigins; + int AsanFieldPadding; bool AsanZeroBaseShadow; bool UbsanTrapOnError; bool AsanSharedRuntime; Index: lib/Driver/SanitizerArgs.cpp =================================================================== --- lib/Driver/SanitizerArgs.cpp +++ lib/Driver/SanitizerArgs.cpp @@ -26,6 +26,7 @@ BlacklistFile = ""; MsanTrackOrigins = 0; AsanZeroBaseShadow = false; + AsanFieldPadding = 0; UbsanTrapOnError = false; AsanSharedRuntime = false; LinkCXXRuntimes = false; @@ -164,6 +165,15 @@ (TC.getTriple().getEnvironment() == llvm::Triple::Android); AsanZeroBaseShadow = (TC.getTriple().getEnvironment() == llvm::Triple::Android); + if (Arg *A = + Args.getLastArg(options::OPT_fsanitize_address_field_padding)) { + StringRef S = A->getValue(); + // Legal values are 0 and 1, 2, but in future we may add more levels. + if (S.getAsInteger(0, AsanFieldPadding) || AsanFieldPadding < 0 || + AsanFieldPadding > 2) { + D.Diag(diag::err_drv_invalid_value) << A->getAsString(Args) << S; + } + } } // Parse -link-cxx-sanitizer flag. @@ -191,7 +201,9 @@ if (MsanTrackOrigins) CmdArgs.push_back(Args.MakeArgString("-fsanitize-memory-track-origins=" + llvm::utostr(MsanTrackOrigins))); - + if (AsanFieldPadding) + CmdArgs.push_back(Args.MakeArgString("-fsanitize-address-field-padding=" + + llvm::utostr(AsanFieldPadding))); // Workaround for PR16386. if (needsMsanRt()) CmdArgs.push_back(Args.MakeArgString("-fno-assume-sane-operator-new")); Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -1628,6 +1628,9 @@ break; } } + // -fsanitize-address-field-padding=N has to be a LangOpt, parse it here. + Opts.Sanitize.SanitizeAddressFieldPadding = + getLastArgIntValue(Args, OPT_fsanitize_address_field_padding, 0, Diags); } static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args, Index: test/Driver/fsanitize.c =================================================================== --- test/Driver/fsanitize.c +++ test/Driver/fsanitize.c @@ -80,6 +80,17 @@ // RUN: %clang -target x86_64-linux-gnu -fsanitize=memory -fsanitize-memory-track-origins=3 -pie %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TRACK-ORIGINS-3 // CHECK-TRACK-ORIGINS-3: error: invalid value '3' in '-fsanitize-memory-track-origins=3' +// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-address-field-padding=0 %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-FIELD-PADDING-0 +// CHECK-ASAN-FIELD-PADDING-0-NOT: -fsanitize-address-field-padding +// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-address-field-padding=1 %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-FIELD-PADDING-1 +// CHECK-ASAN-FIELD-PADDING-1: -fsanitize-address-field-padding=1 +// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-address-field-padding=2 %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-FIELD-PADDING-2 +// CHECK-ASAN-FIELD-PADDING-2: -fsanitize-address-field-padding=2 +// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-address-field-padding=3 %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-FIELD-PADDING-3 +// CHECK-ASAN-FIELD-PADDING-3: error: invalid value '3' in '-fsanitize-address-field-padding=3' +// RUN: %clang -target x86_64-linux-gnu -fsanitize-address-field-padding=2 %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-FIELD-PADDING-NO-ASAN +// CHECK-ASAN-FIELD-PADDING-NO-ASAN: warning: argument unused during compilation: '-fsanitize-address-field-padding=3' + // RUN: %clang -target x86_64-linux-gnu -fsanitize=vptr -fno-sanitize=vptr -fsanitize=undefined,address %s -### 2>&1 // OK