From ee35001732cd762e90fa396365c2c7d77aa5282f Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Thu, 17 Jul 2025 14:44:12 +0200 Subject: [PATCH] Suppress codegen of panic printing with when panic messages are set to "off". Implicit linking of libc math when libc math functions are used. --- lib/std/core/allocators/libc_allocator.c3 | 5 +- lib/std/core/builtin.c3 | 72 ++++++++++---------- lib/std/core/env.c3 | 1 + lib/std/math/math.c3 | 83 ++++++++++++----------- releasenotes.md | 2 + src/compiler/compiler.c | 1 + src/compiler/linker.c | 6 -- 7 files changed, 86 insertions(+), 84 deletions(-) diff --git a/lib/std/core/allocators/libc_allocator.c3 b/lib/std/core/allocators/libc_allocator.c3 index e2675ccff..4acecf4c6 100644 --- a/lib/std/core/allocators/libc_allocator.c3 +++ b/lib/std/core/allocators/libc_allocator.c3 @@ -8,12 +8,9 @@ import libc; <* The LibcAllocator is a wrapper around malloc to conform to the Allocator interface. *> -typedef LibcAllocator (Allocator, Printable) = uptr; +typedef LibcAllocator (Allocator) = uptr; const LibcAllocator LIBC_ALLOCATOR = {}; -fn String LibcAllocator.to_string(&self, Allocator allocator) @dynamic => "Libc allocator".copy(allocator); -fn usz? LibcAllocator.to_format(&self, Formatter *format) @dynamic => format.print("Libc allocator"); - module std::core::mem::allocator @if(env::POSIX); import std::os; import libc; diff --git a/lib/std/core/builtin.c3 b/lib/std/core/builtin.c3 index 0fe540b09..1bc11df8f 100644 --- a/lib/std/core/builtin.c3 +++ b/lib/std/core/builtin.c3 @@ -96,7 +96,7 @@ macro anycast(any v, $Type) @builtin return ($Type*)v.ptr; } -fn bool print_backtrace(String message, int backtraces_to_ignore) @if(env::NATIVE_STACKTRACE) => @stack_mem(0x1100; Allocator smem) +fn bool print_backtrace(String message, int backtraces_to_ignore) @if (env::NATIVE_STACKTRACE) => @stack_mem(0x1100; Allocator smem) { void*[256] buffer; void*[] backtraces = backtrace::capture_current(&buffer); @@ -132,17 +132,17 @@ fn bool print_backtrace(String message, int backtraces_to_ignore) @if(env::NATIV fn void default_panic(String message, String file, String function, uint line) @if(env::NATIVE_STACKTRACE) { - $if $defined(io::stderr): - if (!print_backtrace(message, 2)) - { - io::eprintfn("\nERROR: '%s', in %s (%s:%d)", message, function, file, line); - } + $if $defined(io::stderr) && env::PANIC_MSG: + if (!print_backtrace(message, 2)) + { + io::eprintfn("\nERROR: '%s', in %s (%s:%d)", message, function, file, line); + } $endif $$trap(); } -macro void abort(String string = "Unrecoverable error reached", ...) @builtin @noreturn +macro void abort(String string = "Unrecoverable error reached", ...) @format(0) @builtin @noreturn { panicf(string, $$FILE, $$FUNC, $$LINE, $vasplat); $$trap(); @@ -150,20 +150,22 @@ macro void abort(String string = "Unrecoverable error reached", ...) @builtin @n bool in_panic @local = false; -fn void default_panic(String message, String file, String function, uint line) @if(!env::NATIVE_STACKTRACE) +fn void default_panic(String message, String file, String function, uint line) @if (!env::NATIVE_STACKTRACE) { - if (in_panic) - { - io::eprintn("Panic inside of panic."); - return; - } - in_panic = true; - $if $defined(io::stderr): - io::eprint("\nERROR: '"); - io::eprint(message); - io::eprintfn("', in %s (%s:%d)", function, file, line); + $if $defined(io::stderr) && env::PANIC_MSG: + if (in_panic) + { + io::eprintn("Panic inside of panic."); + return; + } + in_panic = true; + $if $defined(io::stderr): + io::eprint("\nERROR: '"); + io::eprint(message); + io::eprintfn("', in %s (%s:%d)", function, file, line); + $endif + in_panic = false; $endif - in_panic = false; $$trap(); } @@ -173,21 +175,23 @@ PanicFn panic = &default_panic; fn void panicf(String fmt, String file, String function, uint line, args...) { - if (in_panic) - { - io::eprint("Panic inside of panic: "); - io::eprintn(fmt); - return; - } - in_panic = true; - @stack_mem(512; Allocator allocator) - { - DString s; - s.init(allocator); - s.appendf(fmt, ...args); - in_panic = false; - panic(s.str_view(), file, function, line); - }; + $if $defined(io::stderr) && env::PANIC_MSG: + if (in_panic) + { + io::eprint("Panic inside of panic: "); + io::eprintn(fmt); + return; + } + in_panic = true; + @stack_mem(512; Allocator allocator) + { + DString s; + s.init(allocator); + s.appendf(fmt, ...args); + in_panic = false; + panic(s.str_view(), file, function, line); + }; + $endif } <* diff --git a/lib/std/core/env.c3 b/lib/std/core/env.c3 index 65669fdc4..22e56f8e8 100644 --- a/lib/std/core/env.c3 +++ b/lib/std/core/env.c3 @@ -137,6 +137,7 @@ const bool BACKTRACE = $$BACKTRACE; const usz LLVM_VERSION = $$LLVM_VERSION; const bool BENCHMARKING = $$BENCHMARKING; const bool TESTING = $$TESTING; +const bool PANIC_MSG = $$PANIC_MSG; const MemoryEnvironment MEMORY_ENV = MemoryEnvironment.from_ordinal($$MEMORY_ENVIRONMENT); const bool TRACK_MEMORY = DEBUG_SYMBOLS && (COMPILER_SAFE_MODE || TESTING); const bool X86_64 = ARCH_TYPE == X86_64; diff --git a/lib/std/math/math.c3 b/lib/std/math/math.c3 index f986dbb46..d46e336f4 100644 --- a/lib/std/math/math.c3 +++ b/lib/std/math/math.c3 @@ -6,6 +6,9 @@ import std::math::complex; import std::math::matrix; import std::math::quaternion; +attrdef @MathLibc(name) = @extern(name), @link(env::POSIX, "m"); +attrdef @LinkMath = @link(env::POSIX, "m"); + const E = 2.718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427427466; const LOG2E = 1.44269504088896340735992468100189214; // log2(e) const LOG10E = 0.434294481903251827651128918916605082; // log10(e) @@ -232,14 +235,14 @@ macro asinh(x) <* @require values::@is_floatlike(x) : `The input must be a floating point value or float vector` *> -macro ceil(x) => $$ceil(x); +macro ceil(x) @LinkMath => $$ceil(x); <* Ceil for compile time evaluation. @require @typeis($input, double) || @typeis($input, float) : "Only float and double may be used" *> -macro @ceil($input) @const => $$ceil($input); +macro @ceil($input) @const @LinkMath => $$ceil($input); <* Constrain the value to lie within the given interval. @@ -253,18 +256,18 @@ macro @ceil($input) @const => $$ceil($input); @require values::@assign_to(lower, x) : `The lower bound must be convertable to the value type.` @require values::@assign_to(upper, x) : `The upper bound must be convertable to the value type.` *> -macro clamp(x, lower, upper) => $$max(($typeof(x))lower, $$min(x, ($typeof(x))upper)); +macro clamp(x, lower, upper) @LinkMath => $$max(($typeof(x))lower, $$min(x, ($typeof(x))upper)); <* @require values::@is_promotable_to_floatlike(mag) : `The input must be a number value or float vector` @require $defined(($typeof(values::promote_int(mag)))mag) : `It's not possible to cast the sign to the type of the magnitude` *> -macro copysign(mag, sgn) => $$copysign(values::promote_int_same(mag, sgn), ($typeof(values::promote_int_same(mag, sgn)))sgn); +macro copysign(mag, sgn) @LinkMath => $$copysign(values::promote_int_same(mag, sgn), ($typeof(values::promote_int_same(mag, sgn)))sgn); <* @require values::@is_promotable_to_floatlike(x) : `The input must be a number value or float vector` *> -macro cos(x) => $$cos(values::promote_int(x)); +macro cos(x) @LinkMath => $$cos(values::promote_int(x)); <* @require values::@is_promotable_to_floatlike(x) : `The input must be a number value or float vector` @@ -294,17 +297,17 @@ macro cotanh(x) => (exp(2.0 * x) + 1.0) / (exp(2.0 * x) - 1.0); <* @require values::@is_promotable_to_floatlike(x) : `The input must be a number value or float vector` *> -macro exp(x) => $$exp(values::promote_int(x)); +macro exp(x) @LinkMath => $$exp(values::promote_int(x)); <* @require values::@is_promotable_to_floatlike(x) : `The input must be a number value or float vector` *> -macro exp2(x) => $$exp2(values::promote_int(x)); +macro exp2(x) @LinkMath => $$exp2(values::promote_int(x)); <* @require values::@is_promotable_to_floatlike(x) : `The input must be a number value or float vector` *> -macro floor(x) => $$floor(values::promote_int(x)); +macro floor(x) @LinkMath => $$floor(values::promote_int(x)); <* @require values::@is_promotable_to_floatlike(a) : `The input must be a number or float vector` @@ -313,7 +316,7 @@ macro floor(x) => $$floor(values::promote_int(x)); @require values::@is_same_vector_type(a, b) : `The input types must be equal` @require values::@is_same_vector_type(a, c) : `The input types must match` *> -macro fma(a, b, c) => $$fma(a, b, c); +macro fma(a, b, c) @LinkMath => $$fma(a, b, c); <* @@ -326,13 +329,13 @@ macro hypot(x, y) => sqrt(sqr(x) + sqr(y)); <* @require values::@is_promotable_to_floatlike(x) : `The input must be a number or a float vector` *> -macro ln(x) => $$log(values::promote_int(x)); +macro ln(x) @LinkMath => $$log(values::promote_int(x)); <* @require values::@is_promotable_to_floatlike(x) : `The input must be a number or a float vector` @require values::@is_promotable_to_floatlike(base) : `The base must be a number or a float vector` *> -macro log(x, base) +macro log(x, base) @LinkMath { return $$log(values::promote_int_same(x, base)) / $$log(values::promote_int_same(base, x)); } @@ -340,12 +343,12 @@ macro log(x, base) <* @require values::@is_promotable_to_floatlike(x) : `The input must be a number or a float vector` *> -macro log2(x) => $$log2(values::promote_int(x)); +macro log2(x) @LinkMath => $$log2(values::promote_int(x)); <* @require values::@is_promotable_to_floatlike(x) : `The input must be a number or a float vector` *> -macro log10(x) => $$log10(values::promote_int(x)); +macro log10(x) @LinkMath => $$log10(values::promote_int(x)); <* @require types::is_numerical($typeof(x)) : `The input must be a floating point value or float vector` @@ -1012,33 +1015,33 @@ macro void float.set_word(float* f, uint u) => *f = bitcast(u, float); macro double scalbn(double x, int n) => _scalbn(x, n); -extern fn double _atan(double x) @extern("atan"); -extern fn float _atanf(float x) @extern("atanf"); -extern fn double _atan2(double, double) @extern("atan2"); -extern fn float _atan2f(float, float) @extern("atan2f"); +extern fn double _atan(double x) @MathLibc("atan"); +extern fn float _atanf(float x) @MathLibc("atanf"); +extern fn double _atan2(double, double) @MathLibc("atan2"); +extern fn float _atan2f(float, float) @MathLibc("atan2f"); -extern fn void _sincos(double, double*, double*) @extern("__sincos") @link("m") @if(env::DARWIN); -extern fn void _sincosf(float, float*, float*) @extern("__sincosf") @link("m") @if(env::DARWIN); +extern fn void _sincos(double, double*, double*) @MathLibc("__sincos") @if(env::DARWIN); +extern fn void _sincosf(float, float*, float*) @MathLibc("__sincosf") @if(env::DARWIN); -extern fn void _sincos(double, double*, double*) @extern("sincos") @link("m") @if(!env::DARWIN && !env::WIN32); -extern fn void _sincosf(float, float*, float*) @extern("sincosf") @link("m") @if(!env::DARWIN && !env::WIN32); +extern fn void _sincos(double, double*, double*) @MathLibc("sincos") @if(!env::DARWIN && !env::WIN32); +extern fn void _sincosf(float, float*, float*) @MathLibc("sincosf") @if(!env::DARWIN && !env::WIN32); fn void _sincos(double a, double* s, double* c) @extern("sincos") @if(env::WIN32) { *s = sin(a); *c = cos(a); } fn void _sincosf(float a, float* s, float* c) @extern("sincosf") @if(env::WIN32) { *s = sin(a); *c = cos(a); } -extern fn double _tan(double x) @extern("tan"); -extern fn float _tanf(float x) @extern("tanf"); -extern fn double _scalbn(double x, int n) @extern("scalbn"); -extern fn double _acos(double x) @extern("acos"); -extern fn double _asin(double x) @extern("asin"); -extern fn double _acosh(double x) @extern("acosh"); -extern fn double _asinh(double x) @extern("asinh"); -extern fn double _atanh(double x) @extern("atanh"); -extern fn float _acosf(float x) @extern("acosf"); -extern fn float _asinf(float x) @extern("asinf"); -extern fn float _acoshf(float x) @extern("acoshf"); -extern fn float _asinhf(float x) @extern("asinhf"); -extern fn float _atanhf(float x) @extern("atanhf"); +extern fn double _tan(double x) @MathLibc("tan"); +extern fn float _tanf(float x) @MathLibc("tanf"); +extern fn double _scalbn(double x, int n) @MathLibc("scalbn"); +extern fn double _acos(double x) @MathLibc("acos"); +extern fn double _asin(double x) @MathLibc("asin"); +extern fn double _acosh(double x) @MathLibc("acosh"); +extern fn double _asinh(double x) @MathLibc("asinh"); +extern fn double _atanh(double x) @MathLibc("atanh"); +extern fn float _acosf(float x) @MathLibc("acosf"); +extern fn float _asinf(float x) @MathLibc("asinf"); +extern fn float _acoshf(float x) @MathLibc("acoshf"); +extern fn float _asinhf(float x) @MathLibc("asinhf"); +extern fn float _atanhf(float x) @MathLibc("atanhf"); fn double _frexp(double x, int* e) @@ -1092,21 +1095,21 @@ fn float _frexpf(float x, int* e) } } -macro overflow_add_helper(x, y) @local +macro overflow_add_helper(x, y) @local @LinkMath { $typeof(x) res @noinit; if ($$overflow_add(x, y, &res)) return OVERFLOW?; return res; } -macro overflow_sub_helper(x, y) @local +macro overflow_sub_helper(x, y) @local @LinkMath { $typeof(x) res @noinit; if ($$overflow_sub(x, y, &res)) return OVERFLOW?; return res; } -macro overflow_mul_helper(x, y) @local +macro overflow_mul_helper(x, y) @local @LinkMath { $typeof(x) res @noinit; if ($$overflow_mul(x, y, &res)) return OVERFLOW?; @@ -1120,7 +1123,7 @@ macro overflow_mul_helper(x, y) @local @require values::@is_flat_intlike(a) &&& values::@is_flat_intlike(b) : "a and b must both be integer or integer vector based" @require $defined(*out) &&& values::@is_same_type(*out, a) : "out must be a pointer of the same type as a and b" *> -macro bool overflow_add(a, b, out) => $$overflow_add(a, b, out); +macro bool overflow_add(a, b, out) @LinkMath => $$overflow_add(a, b, out); <* @param [&out] out : "Where the result of the subtraction is stored" @@ -1129,7 +1132,7 @@ macro bool overflow_add(a, b, out) => $$overflow_add(a, b, out); @require values::@is_flat_intlike(a) &&& values::@is_flat_intlike(b) : "a and b must both be integer or integer vector based" @require $defined(*out) &&& values::@is_same_type(*out, a) : "out must be a pointer of the same type as a and b" *> -macro bool overflow_sub(a, b, out) => $$overflow_sub(a, b, out); +macro bool overflow_sub(a, b, out) @LinkMath => $$overflow_sub(a, b, out); <* @param [&out] out : "Where the result of the multiplication is stored" @@ -1138,7 +1141,7 @@ macro bool overflow_sub(a, b, out) => $$overflow_sub(a, b, out); @require values::@is_flat_intlike(a) &&& values::@is_flat_intlike(b) : "a and b must both be integer or integer vector based" @require $defined(*out) &&& values::@is_same_type(*out, a) : "out must be a pointer of the same type as a and b" *> -macro bool overflow_mul(a, b, out) => $$overflow_mul(a, b, out); +macro bool overflow_mul(a, b, out) @LinkMath => $$overflow_mul(a, b, out); <* @require types::is_vector($Type) || ($Type.kindof == ARRAY &&& types::is_numerical($typefrom($Type.inner))) diff --git a/releasenotes.md b/releasenotes.md index 10418d70d..fd3236b35 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -19,6 +19,8 @@ - Multiline contract comments #2113 - Removed the use of temp allocator in backtrace printing. - `env::AUTHORS` and `env::AUTHOR_EMAILS` added. +- Suppress codegen of panic printing with when panic messages are set to "off". +- Implicit linking of libc math when libc math functions are used. ### Fixes - mkdir/rmdir would not work properly with substring paths on non-windows platforms. diff --git a/src/compiler/compiler.c b/src/compiler/compiler.c index f4178aa6d..f1eb2ea33 100644 --- a/src/compiler/compiler.c +++ b/src/compiler/compiler.c @@ -1473,6 +1473,7 @@ void compile() setup_int_define("COMPILER_SIZE_OPT_LEVEL", (uint64_t)compiler.build.optsize, type_int); setup_bool_define("COMPILER_SAFE_MODE", safe_mode_enabled()); setup_bool_define("DEBUG_SYMBOLS", compiler.build.debug_info == DEBUG_INFO_FULL); + setup_bool_define("PANIC_MSG", compiler.build.feature.panic_level != PANIC_OFF); setup_bool_define("BACKTRACE", compiler.build.show_backtrace != SHOW_BACKTRACE_OFF); #if LLVM_AVAILABLE setup_int_define("LLVM_VERSION", llvm_version_major, type_int); diff --git a/src/compiler/linker.c b/src/compiler/linker.c index 45a7b7a2e..da7b05e25 100644 --- a/src/compiler/linker.c +++ b/src/compiler/linker.c @@ -268,7 +268,6 @@ static void linker_setup_macos(const char ***args_ref, Linker linker_type) error_exit("Cannot crosslink MacOS without providing --macossdk."); } linking_add_link(&compiler.linking, "System"); - linking_add_link(&compiler.linking, "m"); add_plain_arg("-syslibroot"); add_quote_arg(compiler.build.macos.sysroot); if (is_no_pie(compiler.platform.reloc_model)) add_plain_arg("-no_pie"); @@ -407,7 +406,6 @@ static void linker_setup_linux(const char ***args_ref, Linker linker_type, bool add_plain_arg("-nostdlib"); return; } - linking_add_link(&compiler.linking, "m"); if (compiler.build.debug_info == DEBUG_INFO_FULL) { add_plain_arg("-rdynamic"); @@ -452,7 +450,6 @@ static void linker_setup_linux(const char ***args_ref, Linker linker_type, bool add_concat_file_arg(crt_dir, "crtn.o"); add_concat_quote_arg("-L", crt_dir); add_plain_arg("--dynamic-linker=/lib64/ld-linux-x86-64.so.2"); - linking_add_link(&compiler.linking, "m"); linking_add_link(&compiler.linking, "pthread"); linking_add_link(&compiler.linking, "c"); add_plain_arg("-L/usr/lib/"); @@ -528,14 +525,12 @@ static void linker_setup_android(const char ***args_ref, Linker linker_type, boo add_plain_arg(scratch_buffer_copy()); add_plain_arg("-ldl"); - add_plain_arg("-lm"); add_plain_arg("-lc"); } static void linker_setup_freebsd(const char ***args_ref, Linker linker_type, bool is_dylib) { if (linker_type == LINKER_CC) { - linking_add_link(&compiler.linking, "m"); linking_add_link(&compiler.linking, "pthread"); return; } @@ -573,7 +568,6 @@ static void linker_setup_freebsd(const char ***args_ref, Linker linker_type, boo add_concat_quote_arg("-L", crt_dir); add_plain_arg("--dynamic-linker=/libexec/ld-elf.so.1"); linking_add_link(&compiler.linking, "c"); - linking_add_link(&compiler.linking, "m"); linking_add_link(&compiler.linking, "gcc"); linking_add_link(&compiler.linking, "gcc_s");