| author | |
| committer | |
| log | b3537d0f4adeff824348a4918b495976ae230731 |
| tree | 4635a2febd416352452e5b909afad138db43b601 |
| parent | 23440fbb99a501fac9cfb6af85c6303732cf0b06 |
* Accept -fsanitize-c=trap|full in addition to the existing form.
* Accept -f(no-)sanitize-trap=undefined in zig cc.
* Change type of std.Build.Module.sanitize_c to std.zig.SanitizeC.
* Add some missing Compilation.Config fields to the cache.
Closes #23216.15 files changed, 176 insertions(+), 57 deletions(-)
lib/std/Build/Module.zig+8-3| ... | @@ -22,7 +22,7 @@ unwind_tables: ?std.builtin.UnwindTables, | ... | @@ -22,7 +22,7 @@ unwind_tables: ?std.builtin.UnwindTables, |
| 22 | single_threaded: ?bool, | 22 | single_threaded: ?bool, |
| 23 | stack_protector: ?bool, | 23 | stack_protector: ?bool, |
| 24 | stack_check: ?bool, | 24 | stack_check: ?bool, |
| 25 | sanitize_c: ?bool, | 25 | sanitize_c: ?std.zig.SanitizeC, |
| 26 | sanitize_thread: ?bool, | 26 | sanitize_thread: ?bool, |
| 27 | fuzz: ?bool, | 27 | fuzz: ?bool, |
| 28 | code_model: std.builtin.CodeModel, | 28 | code_model: std.builtin.CodeModel, |
| ... | @@ -256,7 +256,7 @@ pub const CreateOptions = struct { | ... | @@ -256,7 +256,7 @@ pub const CreateOptions = struct { |
| 256 | code_model: std.builtin.CodeModel = .default, | 256 | code_model: std.builtin.CodeModel = .default, |
| 257 | stack_protector: ?bool = null, | 257 | stack_protector: ?bool = null, |
| 258 | stack_check: ?bool = null, | 258 | stack_check: ?bool = null, |
| 259 | sanitize_c: ?bool = null, | 259 | sanitize_c: ?std.zig.SanitizeC = null, |
| 260 | sanitize_thread: ?bool = null, | 260 | sanitize_thread: ?bool = null, |
| 261 | fuzz: ?bool = null, | 261 | fuzz: ?bool = null, |
| 262 | /// Whether to emit machine code that integrates with Valgrind. | 262 | /// Whether to emit machine code that integrates with Valgrind. |
| ... | @@ -559,13 +559,18 @@ pub fn appendZigProcessFlags( | ... | @@ -559,13 +559,18 @@ pub fn appendZigProcessFlags( |
| 559 | try addFlag(zig_args, m.stack_protector, "-fstack-protector", "-fno-stack-protector"); | 559 | try addFlag(zig_args, m.stack_protector, "-fstack-protector", "-fno-stack-protector"); |
| 560 | try addFlag(zig_args, m.omit_frame_pointer, "-fomit-frame-pointer", "-fno-omit-frame-pointer"); | 560 | try addFlag(zig_args, m.omit_frame_pointer, "-fomit-frame-pointer", "-fno-omit-frame-pointer"); |
| 561 | try addFlag(zig_args, m.error_tracing, "-ferror-tracing", "-fno-error-tracing"); | 561 | try addFlag(zig_args, m.error_tracing, "-ferror-tracing", "-fno-error-tracing"); |
| 562 | try addFlag(zig_args, m.sanitize_c, "-fsanitize-c", "-fno-sanitize-c"); | ||
| 563 | try addFlag(zig_args, m.sanitize_thread, "-fsanitize-thread", "-fno-sanitize-thread"); | 562 | try addFlag(zig_args, m.sanitize_thread, "-fsanitize-thread", "-fno-sanitize-thread"); |
| 564 | try addFlag(zig_args, m.fuzz, "-ffuzz", "-fno-fuzz"); | 563 | try addFlag(zig_args, m.fuzz, "-ffuzz", "-fno-fuzz"); |
| 565 | try addFlag(zig_args, m.valgrind, "-fvalgrind", "-fno-valgrind"); | 564 | try addFlag(zig_args, m.valgrind, "-fvalgrind", "-fno-valgrind"); |
| 566 | try addFlag(zig_args, m.pic, "-fPIC", "-fno-PIC"); | 565 | try addFlag(zig_args, m.pic, "-fPIC", "-fno-PIC"); |
| 567 | try addFlag(zig_args, m.red_zone, "-mred-zone", "-mno-red-zone"); | 566 | try addFlag(zig_args, m.red_zone, "-mred-zone", "-mno-red-zone"); |
| 568 | 567 | ||
| 568 | if (m.sanitize_c) |sc| switch (sc) { | ||
| 569 | .off => try zig_args.append("-fno-sanitize-c"), | ||
| 570 | .trap => try zig_args.append("-fsanitize-c=trap"), | ||
| 571 | .full => try zig_args.append("-fsanitize-c=full"), | ||
| 572 | }; | ||
| 573 | |||
| 569 | if (m.dwarf_format) |dwarf_format| { | 574 | if (m.dwarf_format) |dwarf_format| { |
| 570 | try zig_args.append(switch (dwarf_format) { | 575 | try zig_args.append(switch (dwarf_format) { |
| 571 | .@"32" => "-gdwarf32", | 576 | .@"32" => "-gdwarf32", |
lib/std/zig.zig+6| ... | @@ -236,6 +236,12 @@ pub fn binNameAlloc(allocator: Allocator, options: BinNameOptions) error{OutOfMe | ... | @@ -236,6 +236,12 @@ pub fn binNameAlloc(allocator: Allocator, options: BinNameOptions) error{OutOfMe |
| 236 | } | 236 | } |
| 237 | } | 237 | } |
| 238 | 238 | ||
| 239 | pub const SanitizeC = enum { | ||
| 240 | off, | ||
| 241 | trap, | ||
| 242 | full, | ||
| 243 | }; | ||
| 244 | |||
| 239 | pub const BuildId = union(enum) { | 245 | pub const BuildId = union(enum) { |
| 240 | none, | 246 | none, |
| 241 | fast, | 247 | fast, |
src/Compilation.zig+35-28| ... | @@ -1287,7 +1287,14 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil | ... | @@ -1287,7 +1287,14 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil |
| 1287 | const any_unwind_tables = options.config.any_unwind_tables or options.root_mod.unwind_tables != .none; | 1287 | const any_unwind_tables = options.config.any_unwind_tables or options.root_mod.unwind_tables != .none; |
| 1288 | const any_non_single_threaded = options.config.any_non_single_threaded or !options.root_mod.single_threaded; | 1288 | const any_non_single_threaded = options.config.any_non_single_threaded or !options.root_mod.single_threaded; |
| 1289 | const any_sanitize_thread = options.config.any_sanitize_thread or options.root_mod.sanitize_thread; | 1289 | const any_sanitize_thread = options.config.any_sanitize_thread or options.root_mod.sanitize_thread; |
| 1290 | const any_sanitize_c = options.config.any_sanitize_c or options.root_mod.sanitize_c; | 1290 | const any_sanitize_c: std.zig.SanitizeC = switch (options.config.any_sanitize_c) { |
| 1291 | .off => options.root_mod.sanitize_c, | ||
| 1292 | .trap => if (options.root_mod.sanitize_c == .full) | ||
| 1293 | .full | ||
| 1294 | else | ||
| 1295 | .trap, | ||
| 1296 | .full => .full, | ||
| 1297 | }; | ||
| 1291 | const any_fuzz = options.config.any_fuzz or options.root_mod.fuzz; | 1298 | const any_fuzz = options.config.any_fuzz or options.root_mod.fuzz; |
| 1292 | 1299 | ||
| 1293 | const link_eh_frame_hdr = options.link_eh_frame_hdr or any_unwind_tables; | 1300 | const link_eh_frame_hdr = options.link_eh_frame_hdr or any_unwind_tables; |
| ... | @@ -1346,7 +1353,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil | ... | @@ -1346,7 +1353,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil |
| 1346 | // and this reduces unnecessary bloat. | 1353 | // and this reduces unnecessary bloat. |
| 1347 | const ubsan_rt_strat: RtStrat = s: { | 1354 | const ubsan_rt_strat: RtStrat = s: { |
| 1348 | const is_spirv = options.root_mod.resolved_target.result.cpu.arch.isSpirV(); | 1355 | const is_spirv = options.root_mod.resolved_target.result.cpu.arch.isSpirV(); |
| 1349 | const want_ubsan_rt = options.want_ubsan_rt orelse (!is_spirv and any_sanitize_c and is_exe_or_dyn_lib); | 1356 | const want_ubsan_rt = options.want_ubsan_rt orelse (!is_spirv and any_sanitize_c == .full and is_exe_or_dyn_lib); |
| 1350 | if (!want_ubsan_rt) break :s .none; | 1357 | if (!want_ubsan_rt) break :s .none; |
| 1351 | if (options.skip_linker_dependencies) break :s .none; | 1358 | if (options.skip_linker_dependencies) break :s .none; |
| 1352 | if (have_zcu) break :s .zcu; | 1359 | if (have_zcu) break :s .zcu; |
| ... | @@ -1418,6 +1425,10 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil | ... | @@ -1418,6 +1425,10 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil |
| 1418 | cache.hash.add(options.config.lto); | 1425 | cache.hash.add(options.config.lto); |
| 1419 | cache.hash.add(options.config.link_mode); | 1426 | cache.hash.add(options.config.link_mode); |
| 1420 | cache.hash.add(options.config.any_unwind_tables); | 1427 | cache.hash.add(options.config.any_unwind_tables); |
| 1428 | cache.hash.add(options.config.any_non_single_threaded); | ||
| 1429 | cache.hash.add(options.config.any_sanitize_thread); | ||
| 1430 | cache.hash.add(options.config.any_sanitize_c); | ||
| 1431 | cache.hash.add(options.config.any_fuzz); | ||
| 1421 | cache.hash.add(options.function_sections); | 1432 | cache.hash.add(options.function_sections); |
| 1422 | cache.hash.add(options.data_sections); | 1433 | cache.hash.add(options.data_sections); |
| 1423 | cache.hash.add(link_libc); | 1434 | cache.hash.add(link_libc); |
| ... | @@ -6048,7 +6059,7 @@ pub fn addCCArgs( | ... | @@ -6048,7 +6059,7 @@ pub fn addCCArgs( |
| 6048 | { | 6059 | { |
| 6049 | var san_arg: std.ArrayListUnmanaged(u8) = .empty; | 6060 | var san_arg: std.ArrayListUnmanaged(u8) = .empty; |
| 6050 | const prefix = "-fsanitize="; | 6061 | const prefix = "-fsanitize="; |
| 6051 | if (mod.sanitize_c) { | 6062 | if (mod.sanitize_c != .off) { |
| 6052 | if (san_arg.items.len == 0) try san_arg.appendSlice(arena, prefix); | 6063 | if (san_arg.items.len == 0) try san_arg.appendSlice(arena, prefix); |
| 6053 | try san_arg.appendSlice(arena, "undefined,"); | 6064 | try san_arg.appendSlice(arena, "undefined,"); |
| 6054 | } | 6065 | } |
| ... | @@ -6064,37 +6075,33 @@ pub fn addCCArgs( | ... | @@ -6064,37 +6075,33 @@ pub fn addCCArgs( |
| 6064 | if (san_arg.pop()) |_| { | 6075 | if (san_arg.pop()) |_| { |
| 6065 | try argv.append(san_arg.items); | 6076 | try argv.append(san_arg.items); |
| 6066 | 6077 | ||
| 6067 | // These args have to be added after the `-fsanitize` arg or | 6078 | switch (mod.sanitize_c) { |
| 6068 | // they won't take effect. | 6079 | .off => {}, |
| 6069 | if (mod.sanitize_c) { | 6080 | .trap => { |
| 6070 | // This check requires implementing the Itanium C++ ABI. | ||
| 6071 | // We would make it `-fsanitize-trap=vptr`, however this check requires | ||
| 6072 | // a full runtime due to the type hashing involved. | ||
| 6073 | try argv.append("-fno-sanitize=vptr"); | ||
| 6074 | |||
| 6075 | // It is very common, and well-defined, for a pointer on one side of a C ABI | ||
| 6076 | // to have a different but compatible element type. Examples include: | ||
| 6077 | // `char*` vs `uint8_t*` on a system with 8-bit bytes | ||
| 6078 | // `const char*` vs `char*` | ||
| 6079 | // `char*` vs `unsigned char*` | ||
| 6080 | // Without this flag, Clang would invoke UBSAN when such an extern | ||
| 6081 | // function was called. | ||
| 6082 | try argv.append("-fno-sanitize=function"); | ||
| 6083 | |||
| 6084 | if (mod.optimize_mode == .ReleaseSafe) { | ||
| 6085 | // It's recommended to use the minimal runtime in production | ||
| 6086 | // environments due to the security implications of the full runtime. | ||
| 6087 | // The minimal runtime doesn't provide much benefit over simply | ||
| 6088 | // trapping, however, so we do that instead. | ||
| 6089 | try argv.append("-fsanitize-trap=undefined"); | 6081 | try argv.append("-fsanitize-trap=undefined"); |
| 6090 | } else { | 6082 | }, |
| 6083 | .full => { | ||
| 6084 | // This check requires implementing the Itanium C++ ABI. | ||
| 6085 | // We would make it `-fsanitize-trap=vptr`, however this check requires | ||
| 6086 | // a full runtime due to the type hashing involved. | ||
| 6087 | try argv.append("-fno-sanitize=vptr"); | ||
| 6088 | |||
| 6089 | // It is very common, and well-defined, for a pointer on one side of a C ABI | ||
| 6090 | // to have a different but compatible element type. Examples include: | ||
| 6091 | // `char*` vs `uint8_t*` on a system with 8-bit bytes | ||
| 6092 | // `const char*` vs `char*` | ||
| 6093 | // `char*` vs `unsigned char*` | ||
| 6094 | // Without this flag, Clang would invoke UBSAN when such an extern | ||
| 6095 | // function was called. | ||
| 6096 | try argv.append("-fno-sanitize=function"); | ||
| 6097 | |||
| 6091 | // This is necessary because, by default, Clang instructs LLVM to embed | 6098 | // This is necessary because, by default, Clang instructs LLVM to embed |
| 6092 | // a COFF link dependency on `libclang_rt.ubsan_standalone.a` when the | 6099 | // a COFF link dependency on `libclang_rt.ubsan_standalone.a` when the |
| 6093 | // UBSan runtime is used. | 6100 | // UBSan runtime is used. |
| 6094 | if (target.os.tag == .windows) { | 6101 | if (target.os.tag == .windows) { |
| 6095 | try argv.append("-fno-rtlib-defaultlib"); | 6102 | try argv.append("-fno-rtlib-defaultlib"); |
| 6096 | } | 6103 | } |
| 6097 | } | 6104 | }, |
| 6098 | } | 6105 | } |
| 6099 | } | 6106 | } |
| 6100 | 6107 | ||
| ... | @@ -6797,7 +6804,7 @@ pub fn build_crt_file( | ... | @@ -6797,7 +6804,7 @@ pub fn build_crt_file( |
| 6797 | .strip = comp.compilerRtStrip(), | 6804 | .strip = comp.compilerRtStrip(), |
| 6798 | .stack_check = false, | 6805 | .stack_check = false, |
| 6799 | .stack_protector = 0, | 6806 | .stack_protector = 0, |
| 6800 | .sanitize_c = false, | 6807 | .sanitize_c = .off, |
| 6801 | .sanitize_thread = false, | 6808 | .sanitize_thread = false, |
| 6802 | .red_zone = comp.root_mod.red_zone, | 6809 | .red_zone = comp.root_mod.red_zone, |
| 6803 | // Some libcs (e.g. musl) are opinionated about -fomit-frame-pointer. | 6810 | // Some libcs (e.g. musl) are opinionated about -fomit-frame-pointer. |
src/Compilation/Config.zig+2-2| ... | @@ -32,7 +32,7 @@ any_non_single_threaded: bool, | ... | @@ -32,7 +32,7 @@ any_non_single_threaded: bool, |
| 32 | /// per-Module setting. | 32 | /// per-Module setting. |
| 33 | any_error_tracing: bool, | 33 | any_error_tracing: bool, |
| 34 | any_sanitize_thread: bool, | 34 | any_sanitize_thread: bool, |
| 35 | any_sanitize_c: bool, | 35 | any_sanitize_c: std.zig.SanitizeC, |
| 36 | any_fuzz: bool, | 36 | any_fuzz: bool, |
| 37 | pie: bool, | 37 | pie: bool, |
| 38 | /// If this is true then linker code is responsible for making an LLVM IR | 38 | /// If this is true then linker code is responsible for making an LLVM IR |
| ... | @@ -86,7 +86,7 @@ pub const Options = struct { | ... | @@ -86,7 +86,7 @@ pub const Options = struct { |
| 86 | ensure_libcpp_on_non_freestanding: bool = false, | 86 | ensure_libcpp_on_non_freestanding: bool = false, |
| 87 | any_non_single_threaded: bool = false, | 87 | any_non_single_threaded: bool = false, |
| 88 | any_sanitize_thread: bool = false, | 88 | any_sanitize_thread: bool = false, |
| 89 | any_sanitize_c: bool = false, | 89 | any_sanitize_c: std.zig.SanitizeC = .off, |
| 90 | any_fuzz: bool = false, | 90 | any_fuzz: bool = false, |
| 91 | any_unwind_tables: bool = false, | 91 | any_unwind_tables: bool = false, |
| 92 | any_dyn_libs: bool = false, | 92 | any_dyn_libs: bool = false, |
src/Package/Module.zig+13-4| ... | @@ -24,7 +24,7 @@ omit_frame_pointer: bool, | ... | @@ -24,7 +24,7 @@ omit_frame_pointer: bool, |
| 24 | stack_check: bool, | 24 | stack_check: bool, |
| 25 | stack_protector: u32, | 25 | stack_protector: u32, |
| 26 | red_zone: bool, | 26 | red_zone: bool, |
| 27 | sanitize_c: bool, | 27 | sanitize_c: std.zig.SanitizeC, |
| 28 | sanitize_thread: bool, | 28 | sanitize_thread: bool, |
| 29 | fuzz: bool, | 29 | fuzz: bool, |
| 30 | unwind_tables: std.builtin.UnwindTables, | 30 | unwind_tables: std.builtin.UnwindTables, |
| ... | @@ -92,7 +92,7 @@ pub const CreateOptions = struct { | ... | @@ -92,7 +92,7 @@ pub const CreateOptions = struct { |
| 92 | stack_protector: ?u32 = null, | 92 | stack_protector: ?u32 = null, |
| 93 | red_zone: ?bool = null, | 93 | red_zone: ?bool = null, |
| 94 | unwind_tables: ?std.builtin.UnwindTables = null, | 94 | unwind_tables: ?std.builtin.UnwindTables = null, |
| 95 | sanitize_c: ?bool = null, | 95 | sanitize_c: ?std.zig.SanitizeC = null, |
| 96 | sanitize_thread: ?bool = null, | 96 | sanitize_thread: ?bool = null, |
| 97 | fuzz: ?bool = null, | 97 | fuzz: ?bool = null, |
| 98 | structured_cfg: ?bool = null, | 98 | structured_cfg: ?bool = null, |
| ... | @@ -113,6 +113,7 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module { | ... | @@ -113,6 +113,7 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module { |
| 113 | if (options.inherited.fuzz == true) assert(options.global.any_fuzz); | 113 | if (options.inherited.fuzz == true) assert(options.global.any_fuzz); |
| 114 | if (options.inherited.single_threaded == false) assert(options.global.any_non_single_threaded); | 114 | if (options.inherited.single_threaded == false) assert(options.global.any_non_single_threaded); |
| 115 | if (options.inherited.unwind_tables) |uwt| if (uwt != .none) assert(options.global.any_unwind_tables); | 115 | if (options.inherited.unwind_tables) |uwt| if (uwt != .none) assert(options.global.any_unwind_tables); |
| 116 | if (options.inherited.sanitize_c) |sc| if (sc != .off) assert(options.global.any_sanitize_c != .off); | ||
| 116 | if (options.inherited.error_tracing == true) assert(options.global.any_error_tracing); | 117 | if (options.inherited.error_tracing == true) assert(options.global.any_error_tracing); |
| 117 | 118 | ||
| 118 | const resolved_target = options.inherited.resolved_target orelse options.parent.?.resolved_target; | 119 | const resolved_target = options.inherited.resolved_target orelse options.parent.?.resolved_target; |
| ... | @@ -249,10 +250,18 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module { | ... | @@ -249,10 +250,18 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module { |
| 249 | .ReleaseFast, .ReleaseSmall => false, | 250 | .ReleaseFast, .ReleaseSmall => false, |
| 250 | }; | 251 | }; |
| 251 | 252 | ||
| 252 | const sanitize_c = b: { | 253 | const sanitize_c: std.zig.SanitizeC = b: { |
| 253 | if (options.inherited.sanitize_c) |x| break :b x; | 254 | if (options.inherited.sanitize_c) |x| break :b x; |
| 254 | if (options.parent) |p| break :b p.sanitize_c; | 255 | if (options.parent) |p| break :b p.sanitize_c; |
| 255 | break :b is_safe_mode; | 256 | break :b switch (optimize_mode) { |
| 257 | .Debug => .full, | ||
| 258 | // It's recommended to use the minimal runtime in production | ||
| 259 | // environments due to the security implications of the full runtime. | ||
| 260 | // The minimal runtime doesn't provide much benefit over simply | ||
| 261 | // trapping, however, so we do that instead. | ||
| 262 | .ReleaseSafe => .trap, | ||
| 263 | .ReleaseFast, .ReleaseSmall => .off, | ||
| 264 | }; | ||
| 256 | }; | 265 | }; |
| 257 | 266 | ||
| 258 | const stack_check = b: { | 267 | const stack_check = b: { |
src/clang_options_data.zig+18-4| ... | @@ -3682,7 +3682,14 @@ flagpd1("fno-sanitize-stats"), | ... | @@ -3682,7 +3682,14 @@ flagpd1("fno-sanitize-stats"), |
| 3682 | flagpd1("fno-sanitize-thread-atomics"), | 3682 | flagpd1("fno-sanitize-thread-atomics"), |
| 3683 | flagpd1("fno-sanitize-thread-func-entry-exit"), | 3683 | flagpd1("fno-sanitize-thread-func-entry-exit"), |
| 3684 | flagpd1("fno-sanitize-thread-memory-access"), | 3684 | flagpd1("fno-sanitize-thread-memory-access"), |
| 3685 | flagpd1("fno-sanitize-trap"), | 3685 | .{ |
| 3686 | .name = "fno-sanitize-trap", | ||
| 3687 | .syntax = .flag, | ||
| 3688 | .zig_equivalent = .no_sanitize_trap, | ||
| 3689 | .pd1 = true, | ||
| 3690 | .pd2 = false, | ||
| 3691 | .psl = false, | ||
| 3692 | }, | ||
| 3686 | flagpd1("fno-sanitize-undefined-trap-on-error"), | 3693 | flagpd1("fno-sanitize-undefined-trap-on-error"), |
| 3687 | flagpd1("fno-save-main-program"), | 3694 | flagpd1("fno-save-main-program"), |
| 3688 | flagpd1("fno-save-optimization-record"), | 3695 | flagpd1("fno-save-optimization-record"), |
| ... | @@ -4024,7 +4031,14 @@ flagpd1("fsanitize-stats"), | ... | @@ -4024,7 +4031,14 @@ flagpd1("fsanitize-stats"), |
| 4024 | flagpd1("fsanitize-thread-atomics"), | 4031 | flagpd1("fsanitize-thread-atomics"), |
| 4025 | flagpd1("fsanitize-thread-func-entry-exit"), | 4032 | flagpd1("fsanitize-thread-func-entry-exit"), |
| 4026 | flagpd1("fsanitize-thread-memory-access"), | 4033 | flagpd1("fsanitize-thread-memory-access"), |
| 4027 | flagpd1("fsanitize-trap"), | 4034 | .{ |
| 4035 | .name = "fsanitize-trap", | ||
| 4036 | .syntax = .flag, | ||
| 4037 | .zig_equivalent = .sanitize_trap, | ||
| 4038 | .pd1 = true, | ||
| 4039 | .pd2 = false, | ||
| 4040 | .psl = false, | ||
| 4041 | }, | ||
| 4028 | flagpd1("fsanitize-undefined-trap-on-error"), | 4042 | flagpd1("fsanitize-undefined-trap-on-error"), |
| 4029 | flagpd1("fsave-main-program"), | 4043 | flagpd1("fsave-main-program"), |
| 4030 | flagpd1("fsave-optimization-record"), | 4044 | flagpd1("fsave-optimization-record"), |
| ... | @@ -6592,7 +6606,7 @@ joinpd1("fmacro-prefix-map="), | ... | @@ -6592,7 +6606,7 @@ joinpd1("fmacro-prefix-map="), |
| 6592 | .{ | 6606 | .{ |
| 6593 | .name = "fno-sanitize-trap=", | 6607 | .name = "fno-sanitize-trap=", |
| 6594 | .syntax = .comma_joined, | 6608 | .syntax = .comma_joined, |
| 6595 | .zig_equivalent = .other, | 6609 | .zig_equivalent = .no_sanitize_trap, |
| 6596 | .pd1 = true, | 6610 | .pd1 = true, |
| 6597 | .pd2 = false, | 6611 | .pd2 = false, |
| 6598 | .psl = false, | 6612 | .psl = false, |
| ... | @@ -6864,7 +6878,7 @@ joinpd1("frecord-marker="), | ... | @@ -6864,7 +6878,7 @@ joinpd1("frecord-marker="), |
| 6864 | .{ | 6878 | .{ |
| 6865 | .name = "fsanitize-trap=", | 6879 | .name = "fsanitize-trap=", |
| 6866 | .syntax = .comma_joined, | 6880 | .syntax = .comma_joined, |
| 6867 | .zig_equivalent = .other, | 6881 | .zig_equivalent = .sanitize_trap, |
| 6868 | .pd1 = true, | 6882 | .pd1 = true, |
| 6869 | .pd2 = false, | 6883 | .pd2 = false, |
| 6870 | .psl = false, | 6884 | .psl = false, |
src/glibc.zig+1-1| ... | @@ -1231,7 +1231,7 @@ fn buildSharedLib( | ... | @@ -1231,7 +1231,7 @@ fn buildSharedLib( |
| 1231 | .strip = strip, | 1231 | .strip = strip, |
| 1232 | .stack_check = false, | 1232 | .stack_check = false, |
| 1233 | .stack_protector = 0, | 1233 | .stack_protector = 0, |
| 1234 | .sanitize_c = false, | 1234 | .sanitize_c = .off, |
| 1235 | .sanitize_thread = false, | 1235 | .sanitize_thread = false, |
| 1236 | .red_zone = comp.root_mod.red_zone, | 1236 | .red_zone = comp.root_mod.red_zone, |
| 1237 | .omit_frame_pointer = comp.root_mod.omit_frame_pointer, | 1237 | .omit_frame_pointer = comp.root_mod.omit_frame_pointer, |
src/libcxx.zig+2-2| ... | @@ -182,7 +182,7 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError! | ... | @@ -182,7 +182,7 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError! |
| 182 | .strip = strip, | 182 | .strip = strip, |
| 183 | .stack_check = false, | 183 | .stack_check = false, |
| 184 | .stack_protector = 0, | 184 | .stack_protector = 0, |
| 185 | .sanitize_c = false, | 185 | .sanitize_c = .off, |
| 186 | .sanitize_thread = comp.config.any_sanitize_thread, | 186 | .sanitize_thread = comp.config.any_sanitize_thread, |
| 187 | .red_zone = comp.root_mod.red_zone, | 187 | .red_zone = comp.root_mod.red_zone, |
| 188 | .omit_frame_pointer = comp.root_mod.omit_frame_pointer, | 188 | .omit_frame_pointer = comp.root_mod.omit_frame_pointer, |
| ... | @@ -396,7 +396,7 @@ pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildErr | ... | @@ -396,7 +396,7 @@ pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildErr |
| 396 | .strip = strip, | 396 | .strip = strip, |
| 397 | .stack_check = false, | 397 | .stack_check = false, |
| 398 | .stack_protector = 0, | 398 | .stack_protector = 0, |
| 399 | .sanitize_c = false, | 399 | .sanitize_c = .off, |
| 400 | .sanitize_thread = comp.config.any_sanitize_thread, | 400 | .sanitize_thread = comp.config.any_sanitize_thread, |
| 401 | .red_zone = comp.root_mod.red_zone, | 401 | .red_zone = comp.root_mod.red_zone, |
| 402 | .omit_frame_pointer = comp.root_mod.omit_frame_pointer, | 402 | .omit_frame_pointer = comp.root_mod.omit_frame_pointer, |
src/libtsan.zig+1-1| ... | @@ -95,7 +95,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo | ... | @@ -95,7 +95,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo |
| 95 | .strip = strip, | 95 | .strip = strip, |
| 96 | .stack_check = false, | 96 | .stack_check = false, |
| 97 | .stack_protector = 0, | 97 | .stack_protector = 0, |
| 98 | .sanitize_c = false, | 98 | .sanitize_c = .off, |
| 99 | .sanitize_thread = false, | 99 | .sanitize_thread = false, |
| 100 | .red_zone = comp.root_mod.red_zone, | 100 | .red_zone = comp.root_mod.red_zone, |
| 101 | .omit_frame_pointer = optimize_mode != .Debug and !target.os.tag.isDarwin(), | 101 | .omit_frame_pointer = optimize_mode != .Debug and !target.os.tag.isDarwin(), |
src/libunwind.zig+1-1| ... | @@ -64,7 +64,7 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr | ... | @@ -64,7 +64,7 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr |
| 64 | .red_zone = comp.root_mod.red_zone, | 64 | .red_zone = comp.root_mod.red_zone, |
| 65 | .omit_frame_pointer = comp.root_mod.omit_frame_pointer, | 65 | .omit_frame_pointer = comp.root_mod.omit_frame_pointer, |
| 66 | .valgrind = false, | 66 | .valgrind = false, |
| 67 | .sanitize_c = false, | 67 | .sanitize_c = .off, |
| 68 | .sanitize_thread = false, | 68 | .sanitize_thread = false, |
| 69 | // necessary so that libunwind can unwind through its own stack frames | 69 | // necessary so that libunwind can unwind through its own stack frames |
| 70 | // The old 32-bit x86 variant of SEH doesn't use tables. | 70 | // The old 32-bit x86 variant of SEH doesn't use tables. |
src/main.zig+75-5| ... | @@ -526,7 +526,9 @@ const usage_build_generic = | ... | @@ -526,7 +526,9 @@ const usage_build_generic = |
| 526 | \\ -fno-stack-protector Disable stack protection in safe builds | 526 | \\ -fno-stack-protector Disable stack protection in safe builds |
| 527 | \\ -fvalgrind Include valgrind client requests in release builds | 527 | \\ -fvalgrind Include valgrind client requests in release builds |
| 528 | \\ -fno-valgrind Omit valgrind client requests in debug builds | 528 | \\ -fno-valgrind Omit valgrind client requests in debug builds |
| 529 | \\ -fsanitize-c Enable C undefined behavior detection in unsafe builds | 529 | \\ -fsanitize-c[=mode] Enable C undefined behavior detection in unsafe builds |
| 530 | \\ trap Insert trap instructions on undefined behavior | ||
| 531 | \\ full (Default) Insert runtime calls on undefined behavior | ||
| 530 | \\ -fno-sanitize-c Disable C undefined behavior detection in safe builds | 532 | \\ -fno-sanitize-c Disable C undefined behavior detection in safe builds |
| 531 | \\ -fsanitize-thread Enable Thread Sanitizer | 533 | \\ -fsanitize-thread Enable Thread Sanitizer |
| 532 | \\ -fno-sanitize-thread Disable Thread Sanitizer | 534 | \\ -fno-sanitize-thread Disable Thread Sanitizer |
| ... | @@ -1464,9 +1466,18 @@ fn buildOutputType( | ... | @@ -1464,9 +1466,18 @@ fn buildOutputType( |
| 1464 | } else if (mem.eql(u8, arg, "-fno-omit-frame-pointer")) { | 1466 | } else if (mem.eql(u8, arg, "-fno-omit-frame-pointer")) { |
| 1465 | mod_opts.omit_frame_pointer = false; | 1467 | mod_opts.omit_frame_pointer = false; |
| 1466 | } else if (mem.eql(u8, arg, "-fsanitize-c")) { | 1468 | } else if (mem.eql(u8, arg, "-fsanitize-c")) { |
| 1467 | mod_opts.sanitize_c = true; | 1469 | mod_opts.sanitize_c = .full; |
| 1470 | } else if (mem.startsWith(u8, arg, "-fsanitize-c=")) { | ||
| 1471 | const mode = arg["-fsanitize-c=".len..]; | ||
| 1472 | if (mem.eql(u8, mode, "trap")) { | ||
| 1473 | mod_opts.sanitize_c = .trap; | ||
| 1474 | } else if (mem.eql(u8, mode, "full")) { | ||
| 1475 | mod_opts.sanitize_c = .full; | ||
| 1476 | } else { | ||
| 1477 | fatal("Invalid -fsanitize-c mode: '{s}'. Must be 'trap' or 'full'.", .{mode}); | ||
| 1478 | } | ||
| 1468 | } else if (mem.eql(u8, arg, "-fno-sanitize-c")) { | 1479 | } else if (mem.eql(u8, arg, "-fno-sanitize-c")) { |
| 1469 | mod_opts.sanitize_c = false; | 1480 | mod_opts.sanitize_c = .off; |
| 1470 | } else if (mem.eql(u8, arg, "-fvalgrind")) { | 1481 | } else if (mem.eql(u8, arg, "-fvalgrind")) { |
| 1471 | mod_opts.valgrind = true; | 1482 | mod_opts.valgrind = true; |
| 1472 | } else if (mem.eql(u8, arg, "-fno-valgrind")) { | 1483 | } else if (mem.eql(u8, arg, "-fno-valgrind")) { |
| ... | @@ -2236,7 +2247,7 @@ fn buildOutputType( | ... | @@ -2236,7 +2247,7 @@ fn buildOutputType( |
| 2236 | var recognized_any = false; | 2247 | var recognized_any = false; |
| 2237 | while (san_it.next()) |sub_arg| { | 2248 | while (san_it.next()) |sub_arg| { |
| 2238 | if (mem.eql(u8, sub_arg, "undefined")) { | 2249 | if (mem.eql(u8, sub_arg, "undefined")) { |
| 2239 | mod_opts.sanitize_c = enable; | 2250 | mod_opts.sanitize_c = if (enable) .full else .off; |
| 2240 | recognized_any = true; | 2251 | recognized_any = true; |
| 2241 | } else if (mem.eql(u8, sub_arg, "thread")) { | 2252 | } else if (mem.eql(u8, sub_arg, "thread")) { |
| 2242 | mod_opts.sanitize_thread = enable; | 2253 | mod_opts.sanitize_thread = enable; |
| ... | @@ -2250,6 +2261,49 @@ fn buildOutputType( | ... | @@ -2250,6 +2261,49 @@ fn buildOutputType( |
| 2250 | try cc_argv.appendSlice(arena, it.other_args); | 2261 | try cc_argv.appendSlice(arena, it.other_args); |
| 2251 | } | 2262 | } |
| 2252 | }, | 2263 | }, |
| 2264 | .sanitize_trap, .no_sanitize_trap => |t| { | ||
| 2265 | const enable = t == .sanitize_trap; | ||
| 2266 | var san_it = std.mem.splitScalar(u8, it.only_arg, ','); | ||
| 2267 | var recognized_any = false; | ||
| 2268 | while (san_it.next()) |sub_arg| { | ||
| 2269 | // This logic doesn't match Clang 1:1, but it's probably good enough, and avoids | ||
| 2270 | // significantly complicating the resolution of the options. | ||
| 2271 | if (mem.eql(u8, sub_arg, "undefined")) { | ||
| 2272 | if (mod_opts.sanitize_c) |sc| switch (sc) { | ||
| 2273 | .off => if (enable) { | ||
| 2274 | mod_opts.sanitize_c = .trap; | ||
| 2275 | }, | ||
| 2276 | .trap => if (!enable) { | ||
| 2277 | mod_opts.sanitize_c = .full; | ||
| 2278 | }, | ||
| 2279 | .full => if (enable) { | ||
| 2280 | mod_opts.sanitize_c = .trap; | ||
| 2281 | }, | ||
| 2282 | } else { | ||
| 2283 | if (enable) { | ||
| 2284 | mod_opts.sanitize_c = .trap; | ||
| 2285 | } else { | ||
| 2286 | // This means we were passed `-fno-sanitize-trap=undefined` and nothing else. In | ||
| 2287 | // this case, ideally, we should use whatever value `sanitize_c` resolves to by | ||
| 2288 | // default, except change `trap` to `full`. However, we don't yet know what | ||
| 2289 | // `sanitize_c` will resolve to! So we either have to pick `off` or `full`. | ||
| 2290 | // | ||
| 2291 | // `full` has the potential to be problematic if `optimize_mode` turns out to | ||
| 2292 | // be `ReleaseFast`/`ReleaseSmall` because the user will get a slower and larger | ||
| 2293 | // binary than expected. On the other hand, if `optimize_mode` turns out to be | ||
| 2294 | // `Debug`/`ReleaseSafe`, `off` would mean UBSan would unexpectedly be disabled. | ||
| 2295 | // | ||
| 2296 | // `off` seems very slightly less bad, so let's go with that. | ||
| 2297 | mod_opts.sanitize_c = .off; | ||
| 2298 | } | ||
| 2299 | } | ||
| 2300 | recognized_any = true; | ||
| 2301 | } | ||
| 2302 | } | ||
| 2303 | if (!recognized_any) { | ||
| 2304 | try cc_argv.appendSlice(arena, it.other_args); | ||
| 2305 | } | ||
| 2306 | }, | ||
| 2253 | .linker_script => linker_script = it.only_arg, | 2307 | .linker_script => linker_script = it.only_arg, |
| 2254 | .verbose => { | 2308 | .verbose => { |
| 2255 | verbose_link = true; | 2309 | verbose_link = true; |
| ... | @@ -2766,7 +2820,7 @@ fn buildOutputType( | ... | @@ -2766,7 +2820,7 @@ fn buildOutputType( |
| 2766 | } | 2820 | } |
| 2767 | 2821 | ||
| 2768 | if (mod_opts.sanitize_c) |wsc| { | 2822 | if (mod_opts.sanitize_c) |wsc| { |
| 2769 | if (wsc and mod_opts.optimize_mode == .ReleaseFast) { | 2823 | if (wsc != .off and mod_opts.optimize_mode == .ReleaseFast) { |
| 2770 | mod_opts.optimize_mode = .ReleaseSafe; | 2824 | mod_opts.optimize_mode = .ReleaseSafe; |
| 2771 | } | 2825 | } |
| 2772 | } | 2826 | } |
| ... | @@ -2915,6 +2969,13 @@ fn buildOutputType( | ... | @@ -2915,6 +2969,13 @@ fn buildOutputType( |
| 2915 | create_module.opts.any_non_single_threaded = true; | 2969 | create_module.opts.any_non_single_threaded = true; |
| 2916 | if (mod_opts.sanitize_thread == true) | 2970 | if (mod_opts.sanitize_thread == true) |
| 2917 | create_module.opts.any_sanitize_thread = true; | 2971 | create_module.opts.any_sanitize_thread = true; |
| 2972 | if (mod_opts.sanitize_c) |sc| switch (sc) { | ||
| 2973 | .off => {}, | ||
| 2974 | .trap => if (create_module.opts.any_sanitize_c == .off) { | ||
| 2975 | create_module.opts.any_sanitize_c = .trap; | ||
| 2976 | }, | ||
| 2977 | .full => create_module.opts.any_sanitize_c = .full, | ||
| 2978 | }; | ||
| 2918 | if (mod_opts.fuzz == true) | 2979 | if (mod_opts.fuzz == true) |
| 2919 | create_module.opts.any_fuzz = true; | 2980 | create_module.opts.any_fuzz = true; |
| 2920 | if (mod_opts.unwind_tables) |uwt| switch (uwt) { | 2981 | if (mod_opts.unwind_tables) |uwt| switch (uwt) { |
| ... | @@ -5941,6 +6002,8 @@ pub const ClangArgIterator = struct { | ... | @@ -5941,6 +6002,8 @@ pub const ClangArgIterator = struct { |
| 5941 | gdwarf64, | 6002 | gdwarf64, |
| 5942 | sanitize, | 6003 | sanitize, |
| 5943 | no_sanitize, | 6004 | no_sanitize, |
| 6005 | sanitize_trap, | ||
| 6006 | no_sanitize_trap, | ||
| 5944 | linker_script, | 6007 | linker_script, |
| 5945 | dry_run, | 6008 | dry_run, |
| 5946 | verbose, | 6009 | verbose, |
| ... | @@ -7728,6 +7791,13 @@ fn handleModArg( | ... | @@ -7728,6 +7791,13 @@ fn handleModArg( |
| 7728 | create_module.opts.any_non_single_threaded = true; | 7791 | create_module.opts.any_non_single_threaded = true; |
| 7729 | if (mod_opts.sanitize_thread == true) | 7792 | if (mod_opts.sanitize_thread == true) |
| 7730 | create_module.opts.any_sanitize_thread = true; | 7793 | create_module.opts.any_sanitize_thread = true; |
| 7794 | if (mod_opts.sanitize_c) |sc| switch (sc) { | ||
| 7795 | .off => {}, | ||
| 7796 | .trap => if (create_module.opts.any_sanitize_c == .off) { | ||
| 7797 | create_module.opts.any_sanitize_c = .trap; | ||
| 7798 | }, | ||
| 7799 | .full => create_module.opts.any_sanitize_c = .full, | ||
| 7800 | }; | ||
| 7731 | if (mod_opts.fuzz == true) | 7801 | if (mod_opts.fuzz == true) |
| 7732 | create_module.opts.any_fuzz = true; | 7802 | create_module.opts.any_fuzz = true; |
| 7733 | if (mod_opts.unwind_tables) |uwt| switch (uwt) { | 7803 | if (mod_opts.unwind_tables) |uwt| switch (uwt) { |
src/musl.zig+1-1| ... | @@ -231,7 +231,7 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro | ... | @@ -231,7 +231,7 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro |
| 231 | .strip = strip, | 231 | .strip = strip, |
| 232 | .stack_check = false, | 232 | .stack_check = false, |
| 233 | .stack_protector = 0, | 233 | .stack_protector = 0, |
| 234 | .sanitize_c = false, | 234 | .sanitize_c = .off, |
| 235 | .sanitize_thread = false, | 235 | .sanitize_thread = false, |
| 236 | .red_zone = comp.root_mod.red_zone, | 236 | .red_zone = comp.root_mod.red_zone, |
| 237 | .omit_frame_pointer = comp.root_mod.omit_frame_pointer, | 237 | .omit_frame_pointer = comp.root_mod.omit_frame_pointer, |
test/link/elf.zig+2-2| ... | @@ -2052,7 +2052,7 @@ fn testLargeBss(b: *Build, opts: Options) *Step { | ... | @@ -2052,7 +2052,7 @@ fn testLargeBss(b: *Build, opts: Options) *Step { |
| 2052 | exe.linkLibC(); | 2052 | exe.linkLibC(); |
| 2053 | // Disabled to work around the ELF linker crashing. | 2053 | // Disabled to work around the ELF linker crashing. |
| 2054 | // Can be reproduced on a x86_64-linux host by commenting out the line below. | 2054 | // Can be reproduced on a x86_64-linux host by commenting out the line below. |
| 2055 | exe.root_module.sanitize_c = false; | 2055 | exe.root_module.sanitize_c = .off; |
| 2056 | 2056 | ||
| 2057 | const run = addRunArtifact(exe); | 2057 | const run = addRunArtifact(exe); |
| 2058 | run.expectExitCode(0); | 2058 | run.expectExitCode(0); |
| ... | @@ -3558,7 +3558,7 @@ fn testTlsLargeTbss(b: *Build, opts: Options) *Step { | ... | @@ -3558,7 +3558,7 @@ fn testTlsLargeTbss(b: *Build, opts: Options) *Step { |
| 3558 | exe.linkLibC(); | 3558 | exe.linkLibC(); |
| 3559 | // Disabled to work around the ELF linker crashing. | 3559 | // Disabled to work around the ELF linker crashing. |
| 3560 | // Can be reproduced on a x86_64-linux host by commenting out the line below. | 3560 | // Can be reproduced on a x86_64-linux host by commenting out the line below. |
| 3561 | exe.root_module.sanitize_c = false; | 3561 | exe.root_module.sanitize_c = .off; |
| 3562 | 3562 | ||
| 3563 | const run = addRunArtifact(exe); | 3563 | const run = addRunArtifact(exe); |
| 3564 | run.expectStdOutEqual("3 0 5 0 0 0\n"); | 3564 | run.expectStdOutEqual("3 0 5 0 0 0\n"); |
test/link/glibc_compat/build.zig+3-3| ... | @@ -25,7 +25,7 @@ pub fn build(b: *std.Build) void { | ... | @@ -25,7 +25,7 @@ pub fn build(b: *std.Build) void { |
| 25 | // We disable UBSAN for these tests as the libc being tested here is | 25 | // We disable UBSAN for these tests as the libc being tested here is |
| 26 | // so old, it doesn't even support compiling our UBSAN implementation. | 26 | // so old, it doesn't even support compiling our UBSAN implementation. |
| 27 | exe.bundle_ubsan_rt = false; | 27 | exe.bundle_ubsan_rt = false; |
| 28 | exe.root_module.sanitize_c = false; | 28 | exe.root_module.sanitize_c = .off; |
| 29 | exe.root_module.addCSourceFile(.{ .file = b.path("main.c") }); | 29 | exe.root_module.addCSourceFile(.{ .file = b.path("main.c") }); |
| 30 | // TODO: actually test the output | 30 | // TODO: actually test the output |
| 31 | _ = exe.getEmittedBin(); | 31 | _ = exe.getEmittedBin(); |
| ... | @@ -69,7 +69,7 @@ pub fn build(b: *std.Build) void { | ... | @@ -69,7 +69,7 @@ pub fn build(b: *std.Build) void { |
| 69 | // We disable UBSAN for these tests as the libc being tested here is | 69 | // We disable UBSAN for these tests as the libc being tested here is |
| 70 | // so old, it doesn't even support compiling our UBSAN implementation. | 70 | // so old, it doesn't even support compiling our UBSAN implementation. |
| 71 | exe.bundle_ubsan_rt = false; | 71 | exe.bundle_ubsan_rt = false; |
| 72 | exe.root_module.sanitize_c = false; | 72 | exe.root_module.sanitize_c = .off; |
| 73 | exe.root_module.addCSourceFile(.{ .file = b.path("glibc_runtime_check.c") }); | 73 | exe.root_module.addCSourceFile(.{ .file = b.path("glibc_runtime_check.c") }); |
| 74 | 74 | ||
| 75 | // Only try running the test if the host glibc is known to be good enough. Ideally, the Zig | 75 | // Only try running the test if the host glibc is known to be good enough. Ideally, the Zig |
| ... | @@ -172,7 +172,7 @@ pub fn build(b: *std.Build) void { | ... | @@ -172,7 +172,7 @@ pub fn build(b: *std.Build) void { |
| 172 | // We disable UBSAN for these tests as the libc being tested here is | 172 | // We disable UBSAN for these tests as the libc being tested here is |
| 173 | // so old, it doesn't even support compiling our UBSAN implementation. | 173 | // so old, it doesn't even support compiling our UBSAN implementation. |
| 174 | exe.bundle_ubsan_rt = false; | 174 | exe.bundle_ubsan_rt = false; |
| 175 | exe.root_module.sanitize_c = false; | 175 | exe.root_module.sanitize_c = .off; |
| 176 | 176 | ||
| 177 | // Only try running the test if the host glibc is known to be good enough. Ideally, the Zig | 177 | // Only try running the test if the host glibc is known to be good enough. Ideally, the Zig |
| 178 | // test runner would be able to check this, but see https://github.com/ziglang/zig/pull/17702#issuecomment-1831310453 | 178 | // test runner would be able to check this, but see https://github.com/ziglang/zig/pull/17702#issuecomment-1831310453 |
tools/update_clang_options.zig+8| ... | @@ -288,6 +288,14 @@ const known_options = [_]KnownOpt{ | ... | @@ -288,6 +288,14 @@ const known_options = [_]KnownOpt{ |
| 288 | .name = "fno-sanitize", | 288 | .name = "fno-sanitize", |
| 289 | .ident = "no_sanitize", | 289 | .ident = "no_sanitize", |
| 290 | }, | 290 | }, |
| 291 | .{ | ||
| 292 | .name = "fsanitize-trap", | ||
| 293 | .ident = "sanitize_trap", | ||
| 294 | }, | ||
| 295 | .{ | ||
| 296 | .name = "fno-sanitize-trap", | ||
| 297 | .ident = "no_sanitize_trap", | ||
| 298 | }, | ||
| 291 | .{ | 299 | .{ |
| 292 | .name = "T", | 300 | .name = "T", |
| 293 | .ident = "linker_script", | 301 | .ident = "linker_script", |