From c1df71abcca374156ff5e67c6c3bccd65829d2b1 Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Sun, 24 Nov 2024 08:32:28 -0300 Subject: [PATCH] checker, cgen: fix if define comptime checking (fix #22906) (#22946) --- vlib/v/checker/comptime.v | 10 +++++++++- vlib/v/gen/c/comptime.v | 9 +++++++-- vlib/v/gen/c/testdata/if_define_check_not_set.out | 2 ++ vlib/v/gen/c/testdata/if_define_check_not_set.vv | 12 ++++++++++++ vlib/v/gen/c/testdata/if_define_check_set.out | 2 ++ vlib/v/gen/c/testdata/if_define_check_set.vv | 12 ++++++++++++ vlib/v/pref/pref.v | 6 +++--- 7 files changed, 47 insertions(+), 6 deletions(-) create mode 100644 vlib/v/gen/c/testdata/if_define_check_not_set.out create mode 100644 vlib/v/gen/c/testdata/if_define_check_not_set.vv create mode 100644 vlib/v/gen/c/testdata/if_define_check_set.out create mode 100644 vlib/v/gen/c/testdata/if_define_check_set.vv diff --git a/vlib/v/checker/comptime.v b/vlib/v/checker/comptime.v index 7a94a83397..b99964f233 100644 --- a/vlib/v/checker/comptime.v +++ b/vlib/v/checker/comptime.v @@ -742,7 +742,15 @@ fn (mut c Checker) comptime_if_cond(mut cond ast.Expr, pos token.Pos) ComptimeBr should_record_ident = true is_user_ident = true ident_name = cond.expr.name - return if cond.expr.name in c.pref.compile_defines_all { .eval } else { .skip } + return if cond.expr.name in c.pref.compile_defines { + .eval + } else { + if cond.expr.name in c.pref.compile_defines_all { + ComptimeBranchSkipState.unknown + } else { + ComptimeBranchSkipState.skip + } + } } else { c.error('invalid `\$if` condition', cond.pos) } diff --git a/vlib/v/gen/c/comptime.v b/vlib/v/gen/c/comptime.v index a019af960c..4623968e82 100644 --- a/vlib/v/gen/c/comptime.v +++ b/vlib/v/gen/c/comptime.v @@ -511,12 +511,17 @@ fn (mut g Gen) comptime_if_cond(cond ast.Expr, pkg_exist bool) (bool, bool) { return is_cond_true, false } ast.PostfixExpr { - ifdef := g.comptime_if_to_ifdef((cond.expr as ast.Ident).name, true) or { + dname := (cond.expr as ast.Ident).name + ifdef := g.comptime_if_to_ifdef(dname, true) or { verror(err.str()) return false, true } g.write('defined(${ifdef})') - return true, false + if dname in g.pref.compile_defines_all && dname !in g.pref.compile_defines { + return false, true + } else { + return true, false + } } ast.InfixExpr { match cond.op { diff --git a/vlib/v/gen/c/testdata/if_define_check_not_set.out b/vlib/v/gen/c/testdata/if_define_check_not_set.out new file mode 100644 index 0000000000..b193d3e35a --- /dev/null +++ b/vlib/v/gen/c/testdata/if_define_check_not_set.out @@ -0,0 +1,2 @@ +some_define was not passed + diff --git a/vlib/v/gen/c/testdata/if_define_check_not_set.vv b/vlib/v/gen/c/testdata/if_define_check_not_set.vv new file mode 100644 index 0000000000..b35fa4d923 --- /dev/null +++ b/vlib/v/gen/c/testdata/if_define_check_not_set.vv @@ -0,0 +1,12 @@ +module main + +// vtest vflags: -d some_define= + +fn main() { + $if some_define ? { + println('some_define was passed') + } $else { + println('some_define was not passed') + } + println($d('some_define', 'unknown')) +} diff --git a/vlib/v/gen/c/testdata/if_define_check_set.out b/vlib/v/gen/c/testdata/if_define_check_set.out new file mode 100644 index 0000000000..66e20bd8f0 --- /dev/null +++ b/vlib/v/gen/c/testdata/if_define_check_set.out @@ -0,0 +1,2 @@ +some_define was passed +true diff --git a/vlib/v/gen/c/testdata/if_define_check_set.vv b/vlib/v/gen/c/testdata/if_define_check_set.vv new file mode 100644 index 0000000000..a9d0075628 --- /dev/null +++ b/vlib/v/gen/c/testdata/if_define_check_set.vv @@ -0,0 +1,12 @@ +module main + +// vtest vflags: -d some_define + +fn main() { + $if some_define ? { + println('some_define was passed') + } $else { + println('some_define was not passed') + } + println($d('some_define', 'unknown')) +} diff --git a/vlib/v/pref/pref.v b/vlib/v/pref/pref.v index f694a1d5d8..749843bdef 100644 --- a/vlib/v/pref/pref.v +++ b/vlib/v/pref/pref.v @@ -438,6 +438,7 @@ pub fn parse_args_and_show_errors(known_external_commands []string, args []strin '-nofloat' { res.nofloat = true res.compile_defines_all << 'nofloat' // so that `$if nofloat? {` works + res.compile_defines << 'nofloat' } '-fast-math' { res.fast_math = true @@ -1228,11 +1229,10 @@ fn (mut prefs Preferences) parse_define(define string) { prefs.compile_values[dname] = dvalue prefs.compile_defines_all << dname match dvalue { - '0' {} - '1' { + '' {} + else { prefs.compile_defines << dname } - else {} } }