2 Commits

Author SHA1 Message Date
81e58cf3d5 Fix Option<String> pattern match double-dereference in C codegen
LuxString is typedef char* but the codegen treated it as a struct type,
generating *(LuxString*)(field0) instead of (LuxString)(field0). This
caused a heap-buffer-overflow on any Option<String> pattern match since
it read the string contents as a memory address.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 23:59:47 -05:00
92d443e475 chore: bump version to 0.1.13 2026-02-20 20:41:01 -05:00
3 changed files with 8 additions and 7 deletions

View File

@@ -1,6 +1,6 @@
[package]
name = "lux"
version = "0.1.12"
version = "0.1.13"
edition = "2021"
description = "A functional programming language with first-class effects, schema evolution, and behavioral types"
license = "MIT"

View File

@@ -44,7 +44,7 @@
printf "\n"
printf " \033[1;35m \033[0m\n"
printf " \033[1;35m \033[0m\n"
printf " \033[1;35m \033[0m v0.1.12\n"
printf " \033[1;35m \033[0m v0.1.13\n"
printf "\n"
printf " Functional language with first-class effects\n"
printf "\n"
@@ -62,7 +62,7 @@
packages.default = pkgs.rustPlatform.buildRustPackage {
pname = "lux";
version = "0.1.12";
version = "0.1.13";
src = ./.;
cargoLock.lockFile = ./Cargo.lock;
@@ -79,7 +79,7 @@
};
in muslPkgs.rustPlatform.buildRustPackage {
pname = "lux";
version = "0.1.12";
version = "0.1.13";
src = ./.;
cargoLock.lockFile = ./Cargo.lock;

View File

@@ -5316,11 +5316,12 @@ impl CBackend {
if Self::is_primitive_c_type(&actual_type) {
// For primitive types stored as boxed void*, dereference
self.writeln(&format!("{} {} = *({}*)({});", actual_type, var_name, actual_type, c_expr));
} else if !actual_type.ends_with('*') && actual_type != "void" {
} else if actual_type == "LuxString" || actual_type.ends_with('*') || actual_type == "void" {
// Pointer types (including LuxString which is typedef char*): simple cast
self.writeln(&format!("{} {} = ({})({});", actual_type, var_name, actual_type, c_expr));
} else {
// Struct types: cast to pointer and dereference
self.writeln(&format!("{} {} = *({}*)({});", actual_type, var_name, actual_type, c_expr));
} else {
self.writeln(&format!("{} {} = ({})({});", actual_type, var_name, actual_type, c_expr));
}
self.var_types.insert(var_name.clone(), actual_type);
} else if actual_type.ends_with('*') && actual_type != "void*" {