From 2b6f1c061df223c364fe821ff1009cbe041defcc Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Fri, 30 Jan 2026 13:10:54 +0100 Subject: [PATCH] Fix of evaluation order warning. --- lib/std/core/types.c3 | 10 +++++----- src/compiler/sema_expr.c | 9 ++++++--- src/compiler/sema_internal.h | 2 ++ src/compiler/semantic_analyser.c | 11 +++++++++++ 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/lib/std/core/types.c3 b/lib/std/core/types.c3 index 359d37776..6ab71b1d5 100644 --- a/lib/std/core/types.c3 +++ b/lib/std/core/types.c3 @@ -329,8 +329,8 @@ macro lower_to_atomic_compatible_type($Type) @const $endswitch } -macro bool is_promotable_to_floatlike($Type) @const => types::is_floatlike($Type) || types::is_int($Type); -macro bool is_promotable_to_float($Type) @const => types::is_float($Type) || types::is_int($Type); +macro bool is_promotable_to_floatlike($Type) @const => types::is_floatlike($Type) ||| types::is_int($Type); +macro bool is_promotable_to_float($Type) @const => types::is_float($Type) ||| types::is_int($Type); macro bool is_same_vector_type($Type1, $Type2) @const { @@ -345,7 +345,7 @@ macro bool has_equals($Type) @const => $defined(($Type){} == ($Type){}); macro bool is_equatable_type($Type) @const { - $if $defined($Type.less) || $defined($Type.compare_to) || $defined($Type.equals): + $if $defined($Type.less) ||| $defined($Type.compare_to) ||| $defined($Type.equals): return true; $else return $Type.is_eq; @@ -357,7 +357,7 @@ macro bool is_equatable_type($Type) @const *> macro bool implements_copy($Type) @const { - return $defined($Type.copy) && $defined($Type.free); + return $defined($Type.copy) &&& $defined($Type.free); } macro bool @equatable_value(#value) @const @@ -367,7 +367,7 @@ macro bool @equatable_value(#value) @const macro bool @comparable_value(#value) @const { - $if $defined(#value.less) || $defined(#value.compare_to): + $if $defined(#value.less) ||| $defined(#value.compare_to): return true; $else return $typeof(#value).is_ordered; diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index f576cfd88..cd861b1e7 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -5106,7 +5106,8 @@ static inline bool sema_expr_analyse_type_access(SemaContext *context, Expr *exp { if (decl->unit->module->stage < ANALYSIS_POST_REGISTER) { - SEMA_WARN(expr, "There might be a method '%s' for %s, but methods for the type have not yet been completely registered, so a warning is issued.", name, type_quoted_error_string(parent_type)); + bool err = SEMA_WARN_STRICT(expr, "There might be a method '%s' for %s, but methods for the type have not yet been completely registered, so a warning is issued.", name, type_quoted_error_string(parent_type)); + if (err) return false; } goto MISSING_REF; } @@ -5595,7 +5596,8 @@ CONTINUE: Decl *decl = type->decl; if (!decl->unit || decl->unit->module->stage < ANALYSIS_POST_REGISTER) { - SEMA_WARN(expr, "Methods are not fully determined for %s at this point.", decl->name); + bool err = SEMA_WARN(expr, "Methods are not fully determined for %s at this point.", decl->name); + if (err) return false; } // Interface, prefer interface methods. if (decl->decl_kind == DECL_INTERFACE) @@ -6627,7 +6629,8 @@ CHECK_DEEPER: ASSERT(type_is_user_defined(parent_type)); if (missing_ref && parent_type->decl->unit->module->stage < ANALYSIS_POST_REGISTER) { - SEMA_WARN(expr, "There might be a method '%s' for %s, but methods have not yet been completely registered, so analysis fails.", kw, type_quoted_error_string(parent->type)); + bool err = SEMA_WARN_STRICT(expr, "There might be a method '%s' for %s, but methods have not yet been completely registered, so analysis fails.", kw, type_quoted_error_string(parent->type)); + if (err) return false; } if (parent_type->type_kind == TYPE_INTERFACE) { diff --git a/src/compiler/sema_internal.h b/src/compiler/sema_internal.h index c650ed7cb..6c681da40 100644 --- a/src/compiler/sema_internal.h +++ b/src/compiler/sema_internal.h @@ -18,6 +18,7 @@ #define UINT20_MAX 1048575U #define SEMA_WARN(_node, ...) (sema_warn_at(context, (_node)->span, __VA_ARGS__)) +#define SEMA_WARN_STRICT(_node, ...) (sema_warn_very_strict(context, (_node)->span, __VA_ARGS__)) #define SEMA_ERROR(_node, ...) sema_error_at(context, (_node)->span, __VA_ARGS__) #define RETURN_SEMA_ERROR(_node, ...) do { sema_error_at(context, (_node)->span, __VA_ARGS__); return false; } while (0) #define RETURN_VAL_SEMA_ERROR(val__, _node, ...) do { sema_error_at(context, (_node)->span, __VA_ARGS__); return (val__); } while (0) @@ -59,6 +60,7 @@ TokenType sema_splitpathref(const char *string, ArraySize len, Path **path_ref, void sema_print_inline(SemaContext *context, SourceSpan span_original); void sema_error_at(SemaContext *context, SourceSpan span, const char *message, ...); bool sema_warn_at(SemaContext *context, SourceSpan span, const char *message, ...); +bool sema_warn_very_strict(SemaContext *context, SourceSpan span, const char *message, ...); void sema_context_init(SemaContext *context, CompilationUnit *unit); void sema_context_destroy(SemaContext *context); diff --git a/src/compiler/semantic_analyser.c b/src/compiler/semantic_analyser.c index c13a3f3ba..e5e8a3ccb 100644 --- a/src/compiler/semantic_analyser.c +++ b/src/compiler/semantic_analyser.c @@ -609,6 +609,17 @@ void sema_error_at(SemaContext *context, SourceSpan span, const char *message, . sema_print_inline(context, span); } +bool sema_warn_very_strict(SemaContext *context, SourceSpan span, const char *message, ...) +{ + if (compiler.build.validation_level < VALIDATION_OBNOXIOUS) return false; + va_list list; + va_start(list, message); + sema_verror_range(span, message, list); + va_end(list); + sema_print_inline(context, span); + return true; +} + bool sema_warn_at(SemaContext *context, SourceSpan span, const char *message, ...) { bool is_warn = compiler.build.validation_level < VALIDATION_STRICT;