From bf4aa9b5561fb84f0a56ef0f1833fd30aa2207d0 Mon Sep 17 00:00:00 2001 From: jakubtomsu <66876057+jakubtomsu@users.noreply.github.com> Date: Fri, 10 Apr 2026 12:47:12 +0200 Subject: [PATCH 1/3] stronger +/- checks in check_target_feature_is_enabled --- src/build_settings.cpp | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/build_settings.cpp b/src/build_settings.cpp index c12107bf7..8eed4c41a 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -2215,18 +2215,25 @@ gb_internal bool check_target_feature_is_enabled(String const &feature, String * } if (feature_str == "") break; - if (!string_set_exists(&build_context.target_features_set, str)) { - String plus_str = concatenate_strings(temporary_allocator(), make_string_c("+"), feature_str); - - if (want_enabled && !string_set_exists(&build_context.target_features_set, plus_str)) { - if (not_enabled) *not_enabled = str; - return false; + String plus_str = concatenate_strings(temporary_allocator(), make_string_c("+"), feature_str); + String minus_str = concatenate_strings(temporary_allocator(), make_string_c("-"), feature_str); + + bool has_raw = string_set_exists(&build_context.target_features_set, str); + bool has_plus = string_set_exists(&build_context.target_features_set, plus_str); + bool has_minus = string_set_exists(&build_context.target_features_set, minus_str); + + bool is_enabled = (has_plus || has_raw) && !has_minus; + + if ((has_plus || has_raw) && has_minus) { + printf("ENTRIES for '%.*s' / '%.*s':\n", LIT(plus_str), LIT(minus_str)); + for (StringSetEntry& str : build_context.target_features_set) { + printf("\thash: %i, next: %i, val: %.*s\n", str.hash, str.next, LIT(str.value)); } } + + GB_ASSERT(!((has_plus || has_raw) && has_minus)); - String minus_str = concatenate_strings(temporary_allocator(), make_string_c("-"), feature_str); - - if (!want_enabled && !string_set_exists(&build_context.target_features_set, minus_str)) { + if (want_enabled != is_enabled) { if (not_enabled) *not_enabled = str; return false; } From 00874e39ad3748f3a829ac8900700a37e07ba70d Mon Sep 17 00:00:00 2001 From: jakubtomsu <66876057+jakubtomsu@users.noreply.github.com> Date: Fri, 10 Apr 2026 12:53:28 +0200 Subject: [PATCH 2/3] fix --- src/build_settings.cpp | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 8eed4c41a..006b0ea0a 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -2218,21 +2218,14 @@ gb_internal bool check_target_feature_is_enabled(String const &feature, String * String plus_str = concatenate_strings(temporary_allocator(), make_string_c("+"), feature_str); String minus_str = concatenate_strings(temporary_allocator(), make_string_c("-"), feature_str); - bool has_raw = string_set_exists(&build_context.target_features_set, str); + bool has_raw = string_set_exists(&build_context.target_features_set, feature_str); bool has_plus = string_set_exists(&build_context.target_features_set, plus_str); bool has_minus = string_set_exists(&build_context.target_features_set, minus_str); + // NOTE(jakubtomsu): this way "feature" and "+feature" is ALWAYS equivalent, + // and also allows the minus sign to do a final override. bool is_enabled = (has_plus || has_raw) && !has_minus; - if ((has_plus || has_raw) && has_minus) { - printf("ENTRIES for '%.*s' / '%.*s':\n", LIT(plus_str), LIT(minus_str)); - for (StringSetEntry& str : build_context.target_features_set) { - printf("\thash: %i, next: %i, val: %.*s\n", str.hash, str.next, LIT(str.value)); - } - } - - GB_ASSERT(!((has_plus || has_raw) && has_minus)); - if (want_enabled != is_enabled) { if (not_enabled) *not_enabled = str; return false; From 10c7b134e1f23ecf0b064725bc6c1ccd8d8bec30 Mon Sep 17 00:00:00 2001 From: jakubtomsu <66876057+jakubtomsu@users.noreply.github.com> Date: Fri, 10 Apr 2026 13:27:42 +0200 Subject: [PATCH 3/3] de-duplicate and canonicalize target_features_set entries --- src/main.cpp | 34 ++++++++++++++++++++++++++-------- src/string.cpp | 7 +++++++ 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 18381f5ee..b4ad8168b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3973,15 +3973,16 @@ int main(int arg_count, char const **arg_ptr) { for (;;) { String item = string_split_iterator(&target_it, ','); if (item == "") break; - - if (*item.text == '+' || *item.text == '-') { - item.text++; - item.len--; + + String stripped_item = item; + if (*stripped_item.text == '+' || *stripped_item.text == '-') { + stripped_item.text++; + stripped_item.len--; } String invalid; - if (!check_target_feature_is_valid_for_target_arch(item, &invalid) && item != str_lit("help")) { - if (item != str_lit("?")) { + if (!check_target_feature_is_valid_for_target_arch(stripped_item, &invalid) && stripped_item != str_lit("help")) { + if (stripped_item != str_lit("?")) { gb_printf_err("Unkown target feature '%.*s'.\n", LIT(invalid)); } gb_printf("Possible -target-features for target %.*s are:\n", LIT(target_arch_names[build_context.metrics.arch])); @@ -4005,8 +4006,25 @@ int main(int arg_count, char const **arg_ptr) { return 1; } - - string_set_add(&build_context.target_features_set, item); + + // Ensure the feature name always has +/- prefix. If there isn't, default to '+' + String feature_str = item; + if (*feature_str.text != '+' && *feature_str.text != '-') { + feature_str = concatenate_strings(temporary_allocator(), make_string_c("+"), feature_str); + } + + // Ensure there is only a single entry for each feature in the target set. + // If the negative exists, override the existing value with the current one. + String neg_feature_str = clone_string(temporary_allocator(), feature_str); + switch (*neg_feature_str.text) { + case '+': *neg_feature_str.text = '-'; break; + case '-': *neg_feature_str.text = '+'; break; + default: GB_ASSERT(false); break; + } + + string_set_remove(&build_context.target_features_set, neg_feature_str); + + string_set_add(&build_context.target_features_set, feature_str); } } diff --git a/src/string.cpp b/src/string.cpp index a4fa85871..977327bcd 100644 --- a/src/string.cpp +++ b/src/string.cpp @@ -508,6 +508,13 @@ gb_internal String filename_without_directory(String s) { return substring(s, gb_max(j+1, 0), s.len); } +gb_internal String clone_string(gbAllocator a, String const &x) { + u8 *data = gb_alloc_array(a, u8, x.len+1); + gb_memmove(data, x.text, x.len); + data[x.len] = 0; + return make_string(data, x.len); +} + gb_internal String concatenate_strings(gbAllocator a, String const &x, String const &y) { isize len = x.len+y.len; u8 *data = gb_alloc_array(a, u8, len+1);