From a1932776a1e2f32ef2ff0f8feab658cf001ef04b Mon Sep 17 00:00:00 2001 From: Kim Shrier Date: Fri, 24 Apr 2026 20:13:07 -0600 Subject: [PATCH] all: support comptime $if bsd (#26983) --- vlib/v/ast/comptime_valid_idents.v | 6 +- vlib/v/gen/c/cgen.v | 5 + .../comptime/comptime_if_bsd_family_test.v | 133 ++++++++++++++++++ 3 files changed, 143 insertions(+), 1 deletion(-) create mode 100644 vlib/v/tests/comptime/comptime_if_bsd_family_test.v diff --git a/vlib/v/ast/comptime_valid_idents.v b/vlib/v/ast/comptime_valid_idents.v index d3ba3ea3a..a851f3d69 100644 --- a/vlib/v/ast/comptime_valid_idents.v +++ b/vlib/v/ast/comptime_valid_idents.v @@ -28,7 +28,11 @@ fn all_valid_comptime_idents() []string { pub fn eval_comptime_not_user_defined_ident(ident string, the_pref &pref.Preferences) !bool { mut is_true := false if ident in valid_comptime_if_os { - if ident_enum_val := pref.os_from_string(ident) { + // `$if bsd` is a family predicate matching any BSD-family target + // (macos, freebsd, openbsd, netbsd, dragonfly), not a specific OS. + if ident == 'bsd' { + is_true = the_pref.os in [.macos, .freebsd, .openbsd, .netbsd, .dragonfly] + } else if ident_enum_val := pref.os_from_string(ident) { if ident_enum_val == the_pref.os { is_true = true } diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 0b802b728..9382f21e3 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -1228,6 +1228,11 @@ pub fn (mut g Gen) init() { if g.table.gostmts > 0 { g.comptime_definitions.writeln('#define __VTHREADS__ (1)') } + if g.pref.os in [.macos, .freebsd, .openbsd, .netbsd, .dragonfly] { + // `#include bsd <...>` and any other code path that emits `defined(__BSD__)` + // needs this; individual BSD/Darwin compilers do not predefine __BSD__. + g.comptime_definitions.writeln('#define __BSD__ (1)') + } if g.pref.gc_mode in [.boehm_full, .boehm_incr, .boehm_full_opt, .boehm_incr_opt, .boehm_leak] { g.comptime_definitions.writeln('#define _VGCBOEHM (1)') } diff --git a/vlib/v/tests/comptime/comptime_if_bsd_family_test.v b/vlib/v/tests/comptime/comptime_if_bsd_family_test.v new file mode 100644 index 000000000..c00876c42 --- /dev/null +++ b/vlib/v/tests/comptime/comptime_if_bsd_family_test.v @@ -0,0 +1,133 @@ +// Tests the `$if bsd` family predicate, which should evaluate to true on +// any BSD-family host (macos, freebsd, openbsd, netbsd, dragonfly) and +// false on every other host. Prior to the fix in +// vlib/v/ast/comptime_valid_idents.v, `$if bsd` was accepted by the parser +// but silently evaluated to false everywhere. + +// host_is_bsd returns the runtime truth: whether this build targets a +// BSD-family OS. Uses the exact-OS predicates, which are independently +// known to work. +fn host_is_bsd() bool { + $if macos { + return true + } + $if freebsd { + return true + } + $if openbsd { + return true + } + $if netbsd { + return true + } + $if dragonfly { + return true + } + return false +} + +// comptime_bsd returns what `$if bsd` resolves to on this host. +fn comptime_bsd() bool { + $if bsd { + return true + } + return false +} + +// comptime_not_bsd returns what `$if !bsd` resolves to on this host. +fn comptime_not_bsd() bool { + $if !bsd { + return true + } + return false +} + +fn test_bsd_matches_exact_bsd_family_targets() { + assert comptime_bsd() == host_is_bsd() +} + +fn test_not_bsd_is_the_inverse_of_bsd() { + assert comptime_not_bsd() == !comptime_bsd() +} + +// An exact-OS predicate implies `bsd` on that OS. This guards against a +// regression where `$if freebsd` and `$if bsd` could disagree on a FreeBSD +// build (for example if someone changed the is_bsd_target() list but not +// the comptime evaluator, or vice versa). +fn test_exact_bsd_os_implies_bsd() { + $if macos { + $if !bsd { + assert false, '`\$if bsd` should be true on macos' + } + } + $if freebsd { + $if !bsd { + assert false, '`\$if bsd` should be true on freebsd' + } + } + $if openbsd { + $if !bsd { + assert false, '`\$if bsd` should be true on openbsd' + } + } + $if netbsd { + $if !bsd { + assert false, '`\$if bsd` should be true on netbsd' + } + } + $if dragonfly { + $if !bsd { + assert false, '`\$if bsd` should be true on dragonfly' + } + } +} + +// Non-BSD hosts must see `$if bsd` as false. +fn test_non_bsd_os_implies_not_bsd() { + $if linux { + $if bsd { + assert false, '`\$if bsd` should be false on linux' + } + } + $if windows { + $if bsd { + assert false, '`\$if bsd` should be false on windows' + } + } + $if solaris { + $if bsd { + assert false, '`\$if bsd` should be false on solaris' + } + } + $if haiku { + $if bsd { + assert false, '`\$if bsd` should be false on haiku' + } + } +} + +// `bsd` must compose with other comptime conditions the same as any +// other OS predicate. +fn test_bsd_in_compound_conditions() { + mut linux_or_bsd := false + $if linux || bsd { + linux_or_bsd = true + } + // On any supported Unix-like host, at least one of these is true. + $if linux { + assert linux_or_bsd + } + $if bsd { + assert linux_or_bsd + } + // On Windows, neither should be true. + $if windows { + assert !linux_or_bsd + } + + mut bsd_and_not_windows := false + $if bsd && !windows { + bsd_and_not_windows = true + } + assert bsd_and_not_windows == comptime_bsd() +} -- 2.39.5