authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-10-10 02:30:34+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-10-10 02:30:34+02:00
log2556cae4543b7f67d6547257f6684c8ea0e12ab7
treef6c2740a1ce87f8375e516f82e45623da1ecd97e
parent3f3e88e7b455bb458839d0d59eb4c50699aeadbf
parentaa8c774e0f15617137f56eb15c667e259b3be75a

Merge pull request 'default to LLVM and ReleaseSafe for fuzzing' (#36108) from gooncreeper/zig:fuzzing-default-llvm into master

Reviewed-on: https://codeberg.org/ziglang/zig/pulls/36108 Reviewed-by: Andrew Kelley <andrew@ziglang.org>

8 files changed, 28 insertions(+), 16 deletions(-)

build.zig+1-1
...@@ -883,7 +883,7 @@ fn addWasiUpdateStep(b: *std.Build, version: [:0]const u8) !void {...@@ -883,7 +883,7 @@ fn addWasiUpdateStep(b: *std.Build, version: [:0]const u8) !void {
883}883}
884884
885const AddCompilerModOptions = struct {885const AddCompilerModOptions = struct {
886 optimize: std.lang.Optimize,886 optimize: ?std.lang.Optimize,
887 target: std.Build.ResolvedTarget,887 target: std.Build.ResolvedTarget,
888 strip: ?bool = null,888 strip: ?bool = null,
889 valgrind: ?bool = null,889 valgrind: ?bool = null,
lib/init/src/main.zig+1-1
...@@ -45,7 +45,7 @@ test "fuzz example" {...@@ -45,7 +45,7 @@ test "fuzz example" {
4545
46fn testOne(context: void, smith: *std.testing.Smith) !void {46fn testOne(context: void, smith: *std.testing.Smith) !void {
47 _ = context;47 _ = context;
48 // Try command `zig build test --fuzz -Doptimize=ReleaseFast` to see if it manages to fail this test case!48 // Try running `zig build test --fuzz` and see if it manages to fail this test case!
4949
50 const gpa = std.testing.allocator;50 const gpa = std.testing.allocator;
51 var list: std.ArrayList(u8) = .empty;51 var list: std.ArrayList(u8) = .empty;
lib/std/Build.zig+3-3
...@@ -1190,14 +1190,14 @@ pub const StandardOptimizeOptionOptions = struct {...@@ -1190,14 +1190,14 @@ pub const StandardOptimizeOptionOptions = struct {
1190 preferred_optimize_mode: ?std.builtin.Optimize = null,1190 preferred_optimize_mode: ?std.builtin.Optimize = null,
1191};1191};
11921192
1193pub fn standardOptimizeOption(b: *Build, options: StandardOptimizeOptionOptions) std.builtin.Optimize {1193pub fn standardOptimizeOption(b: *Build, options: StandardOptimizeOptionOptions) ?std.builtin.Optimize {
1194 const graph = b.graph;1194 const graph = b.graph;
11951195
1196 if (options.preferred_optimize_mode) |mode| {1196 if (options.preferred_optimize_mode) |mode| {
1197 if (b.option(bool, "release", "optimize for end users") orelse (graph.release_mode != .off)) {1197 if (b.option(bool, "release", "optimize for end users") orelse (graph.release_mode != .off)) {
1198 return mode;1198 return mode;
1199 } else {1199 } else {
1200 return .debug;1200 return null;
1201 }1201 }
1202 }1202 }
12031203
...@@ -1210,7 +1210,7 @@ pub fn standardOptimizeOption(b: *Build, options: StandardOptimizeOptionOptions)...@@ -1210,7 +1210,7 @@ pub fn standardOptimizeOption(b: *Build, options: StandardOptimizeOptionOptions)
1210 }1210 }
12111211
1212 return switch (graph.release_mode) {1212 return switch (graph.release_mode) {
1213 .off => .debug,1213 .off => null,
1214 .any => {1214 .any => {
1215 std.debug.print("the project does not declare a preferred optimization mode. choose: --release=fast, --release=safe, or --release=small\n", .{});1215 std.debug.print("the project does not declare a preferred optimization mode. choose: --release=fast, --release=safe, or --release=small\n", .{});
1216 process.exit(1);1216 process.exit(1);
src/Compilation/Config.zig+9-1
...@@ -147,6 +147,7 @@ pub const ResolveError = error{...@@ -147,6 +147,7 @@ pub const ResolveError = error{
147 TargetRequiresPie,147 TargetRequiresPie,
148 SanitizeThreadRequiresPie,148 SanitizeThreadRequiresPie,
149 SanitizeThreadRequiresLlvmBackend,149 SanitizeThreadRequiresLlvmBackend,
150 FuzzRequiresLlvmBackend,
150 BackendLacksErrorTracing,151 BackendLacksErrorTracing,
151 LlvmLibraryUnavailable,152 LlvmLibraryUnavailable,
152 LldUnavailable,153 LldUnavailable,
...@@ -196,7 +197,8 @@ pub fn resolve(options: Options) ResolveError!Config {...@@ -196,7 +197,8 @@ pub fn resolve(options: Options) ResolveError!Config {
196 break :b options.use_lib_llvm orelse true;197 break :b options.use_lib_llvm orelse true;
197 };198 };
198199
199 const root_optimize_mode = options.root_optimize_mode orelse .debug;200 const root_optimize_mode = options.root_optimize_mode orelse
201 @as(std.lang.OptimizeMode, if (options.any_fuzz) .safe else .debug);
200202
201 // Make a decision on whether to use Clang or Aro for translate-c and compiling C files.203 // Make a decision on whether to use Clang or Aro for translate-c and compiling C files.
202 const c_frontend: CFrontend = b: {204 const c_frontend: CFrontend = b: {
...@@ -349,6 +351,12 @@ pub fn resolve(options: Options) ResolveError!Config {...@@ -349,6 +351,12 @@ pub fn resolve(options: Options) ResolveError!Config {
349 break :b true;351 break :b true;
350 }352 }
351353
354 if (options.any_fuzz) {
355 // Fuzzing instrumentation requires the LLVM backend.
356 if (options.use_llvm == false) return error.FuzzRequiresLlvmBackend;
357 break :b true;
358 }
359
352 if (options.use_llvm) |x| break :b x;360 if (options.use_llvm) |x| break :b x;
353361
354 // If we cannot use LLVM libraries, then our own backends will be a362 // If we cannot use LLVM libraries, then our own backends will be a
src/main.zig+1
...@@ -4328,6 +4328,7 @@ fn createModule(...@@ -4328,6 +4328,7 @@ fn createModule(
4328 error.TargetRequiresPie => fatal("the specified target requires position independent executables", .{}),4328 error.TargetRequiresPie => fatal("the specified target requires position independent executables", .{}),
4329 error.SanitizeThreadRequiresPie => fatal("thread sanitization requires position independent executables", .{}),4329 error.SanitizeThreadRequiresPie => fatal("thread sanitization requires position independent executables", .{}),
4330 error.SanitizeThreadRequiresLlvmBackend => fatal("thread sanitization requires the LLVM backend", .{}),4330 error.SanitizeThreadRequiresLlvmBackend => fatal("thread sanitization requires the LLVM backend", .{}),
4331 error.FuzzRequiresLlvmBackend => fatal("fuzzing requires the LLVM backend", .{}),
4331 error.BackendLacksErrorTracing => fatal("the selected backend has not yet implemented error return tracing", .{}),4332 error.BackendLacksErrorTracing => fatal("the selected backend has not yet implemented error return tracing", .{}),
4332 error.LlvmLibraryUnavailable => fatal("zig was compiled without LLVM libraries", .{}),4333 error.LlvmLibraryUnavailable => fatal("zig was compiled without LLVM libraries", .{}),
4333 error.LldUnavailable => fatal("zig was compiled without LLD libraries", .{}),4334 error.LldUnavailable => fatal("zig was compiled without LLD libraries", .{}),
test/standalone/dependency_options/build.zig+3-3
...@@ -10,14 +10,14 @@ pub fn build(b: *std.Build) !void {...@@ -10,14 +10,14 @@ pub fn build(b: *std.Build) !void {
1010
11 const none_specified_mod = none_specified.module("dummy");11 const none_specified_mod = none_specified.module("dummy");
12 if (!none_specified_mod.resolved_target.?.query.eql(b.graph.host.query)) return error.TestFailed;12 if (!none_specified_mod.resolved_target.?.query.eql(b.graph.host.query)) return error.TestFailed;
13 const expected_optimize: std.builtin.Optimize = switch (b.graph.release_mode) {13 const expected_optimize: ?std.builtin.OptimizeMode = switch (b.graph.release_mode) {
14 .off => .debug,14 .off => null,
15 .any => unreachable,15 .any => unreachable,
16 .fast => .fast,16 .fast => .fast,
17 .safe => .safe,17 .safe => .safe,
18 .small => .small,18 .small => .small,
19 };19 };
20 if (none_specified_mod.optimize.? != expected_optimize) return error.TestFailed;20 if (none_specified_mod.optimize != expected_optimize) return error.TestFailed;
2121
22 // Passing null is the same as not specifying the option,22 // Passing null is the same as not specifying the option,
23 // so this should resolve to the same cached dependency instance.23 // so this should resolve to the same cached dependency instance.
test/standalone/posix/build.zig+1-1
...@@ -55,7 +55,7 @@ pub fn build(b: *std.Build) void {...@@ -55,7 +55,7 @@ pub fn build(b: *std.Build) void {
55 }55 }
56}56}
5757
58fn run_exe(b: *std.Build, optimize: std.builtin.Optimize, case: *const Case, target: std.Build.ResolvedTarget, link_libc: bool) *std.Build.Step.Run {58fn run_exe(b: *std.Build, optimize: ?std.builtin.Optimize, case: *const Case, target: std.Build.ResolvedTarget, link_libc: bool) *std.Build.Step.Run {
59 const exe_name = b.fmt("test-posix-{s}{s}{s}", .{59 const exe_name = b.fmt("test-posix-{s}{s}{s}", .{
60 std.fs.path.stem(case.src_path),60 std.fs.path.stem(case.src_path),
61 if (link_libc) "-libc" else "",61 if (link_libc) "-libc" else "",
test/tests.zig+9-6
...@@ -20,7 +20,7 @@ pub const LinkContext = @import("src/Link.zig");...@@ -20,7 +20,7 @@ pub const LinkContext = @import("src/Link.zig");
20const ModuleTestTarget = struct {20const ModuleTestTarget = struct {
21 linkage: ?std.builtin.LinkMode = null,21 linkage: ?std.builtin.LinkMode = null,
22 target: std.Target.Query = .{},22 target: std.Target.Query = .{},
23 optimize_mode: std.builtin.Optimize = .debug,23 optimize_mode: ?std.builtin.Optimize = .debug,
24 link_libc: ?bool = null,24 link_libc: ?bool = null,
25 single_threaded: ?bool = null,25 single_threaded: ?bool = null,
26 use_llvm: ?bool = null,26 use_llvm: ?bool = null,
...@@ -2795,7 +2795,7 @@ pub const ModuleTestOptions = struct {...@@ -2795,7 +2795,7 @@ pub const ModuleTestOptions = struct {
27952795
2796 pub const TestOnly = union(enum) {2796 pub const TestOnly = union(enum) {
2797 default: void,2797 default: void,
2798 fuzz: OptimizeMode,2798 fuzz: ?OptimizeMode,
2799 };2799 };
2800};2800};
28012801
...@@ -2896,6 +2896,9 @@ fn addOneModuleTest(...@@ -2896,6 +2896,9 @@ fn addOneModuleTest(
2896 options: ModuleTestOptions,2896 options: ModuleTestOptions,
2897) void {2897) void {
2898 const target = &resolved_target.result;2898 const target = &resolved_target.result;
2899 const optimize_suffix = if (test_target.optimize_mode) |mode| switch (mode) {
2900 inline else => |t| "-" ++ @tagName(t),
2901 } else "";
2899 const libc_suffix = if (test_target.link_libc == true) "-libc" else "";2902 const libc_suffix = if (test_target.link_libc == true) "-libc" else "";
2900 const model_txt = target.cpu.model.name;2903 const model_txt = target.cpu.model.name;
29012904
...@@ -2948,11 +2951,11 @@ fn addOneModuleTest(...@@ -2948,11 +2951,11 @@ fn addOneModuleTest(
29482951
2949 for (options.include_paths) |include_path| these_tests.root_module.addIncludePath(b.path(include_path));2952 for (options.include_paths) |include_path| these_tests.root_module.addIncludePath(b.path(include_path));
29502953
2951 const qualified_name = b.fmt("{s}-{s}-{s}-{t}{s}{s}{s}{s}{s}{s}", .{2954 const qualified_name = b.fmt("{s}-{s}-{s}{s}{s}{s}{s}{s}{s}{s}", .{
2952 options.name,2955 options.name,
2953 triple_txt,2956 triple_txt,
2954 model_txt,2957 model_txt,
2955 test_target.optimize_mode,2958 optimize_suffix,
2956 libc_suffix,2959 libc_suffix,
2957 single_threaded_suffix,2960 single_threaded_suffix,
2958 backend_suffix,2961 backend_suffix,
...@@ -3087,11 +3090,11 @@ fn addOneModuleTest(...@@ -3087,11 +3090,11 @@ fn addOneModuleTest(
3087 }3090 }
3088}3091}
30893092
3090pub fn wouldUseLlvm(use_llvm: ?bool, query: std.Target.Query, optimize_mode: OptimizeMode) bool {3093pub fn wouldUseLlvm(use_llvm: ?bool, query: std.Target.Query, optimize_mode: ?OptimizeMode) bool {
3091 if (comptime builtin.cpu.arch.endian() == .big) return true; // https://github.com/ziglang/zig/issues/259613094 if (comptime builtin.cpu.arch.endian() == .big) return true; // https://github.com/ziglang/zig/issues/25961
3092 if (use_llvm) |x| return x;3095 if (use_llvm) |x| return x;
3093 if (query.ofmt == .c) return false;3096 if (query.ofmt == .c) return false;
3094 switch (optimize_mode) {3097 switch (optimize_mode orelse .debug) {
3095 .debug => {},3098 .debug => {},
3096 else => return true,3099 else => return true,
3097 }3100 }