compiler: Allow configuring UBSan mode at the module level.

* 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.
This commit is contained in:
Alex Rønne Petersen
2025-04-16 02:44:55 +02:00
parent 23440fbb99
commit b3537d0f4a
15 changed files with 176 additions and 57 deletions

View File

@@ -24,7 +24,7 @@ omit_frame_pointer: bool,
stack_check: bool,
stack_protector: u32,
red_zone: bool,
sanitize_c: bool,
sanitize_c: std.zig.SanitizeC,
sanitize_thread: bool,
fuzz: bool,
unwind_tables: std.builtin.UnwindTables,
@@ -92,7 +92,7 @@ pub const CreateOptions = struct {
stack_protector: ?u32 = null,
red_zone: ?bool = null,
unwind_tables: ?std.builtin.UnwindTables = null,
sanitize_c: ?bool = null,
sanitize_c: ?std.zig.SanitizeC = null,
sanitize_thread: ?bool = null,
fuzz: ?bool = null,
structured_cfg: ?bool = null,
@@ -113,6 +113,7 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module {
if (options.inherited.fuzz == true) assert(options.global.any_fuzz);
if (options.inherited.single_threaded == false) assert(options.global.any_non_single_threaded);
if (options.inherited.unwind_tables) |uwt| if (uwt != .none) assert(options.global.any_unwind_tables);
if (options.inherited.sanitize_c) |sc| if (sc != .off) assert(options.global.any_sanitize_c != .off);
if (options.inherited.error_tracing == true) assert(options.global.any_error_tracing);
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 {
.ReleaseFast, .ReleaseSmall => false,
};
const sanitize_c = b: {
const sanitize_c: std.zig.SanitizeC = b: {
if (options.inherited.sanitize_c) |x| break :b x;
if (options.parent) |p| break :b p.sanitize_c;
break :b is_safe_mode;
break :b switch (optimize_mode) {
.Debug => .full,
// It's recommended to use the minimal runtime in production
// environments due to the security implications of the full runtime.
// The minimal runtime doesn't provide much benefit over simply
// trapping, however, so we do that instead.
.ReleaseSafe => .trap,
.ReleaseFast, .ReleaseSmall => .off,
};
};
const stack_check = b: {