diff --git a/src/check_expr.cpp b/src/check_expr.cpp index aa3d67dae..f258253f5 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -2955,6 +2955,12 @@ void convert_to_typed(CheckerContext *c, Operand *operand, Type *target_type) { if (check_is_assignable_to(c, operand, elem)) { operand->mode = Addressing_Value; } else { + if (operand->value.kind == ExactValue_String && is_type_u8_array(t)) { + String s = operand->value.value_string; + if (s.len == t->Array.count) { + break; + } + } operand->mode = Addressing_Invalid; convert_untyped_error(c, operand, target_type); return; diff --git a/src/ir.cpp b/src/ir.cpp index 819442030..e8378bb97 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -7801,7 +7801,9 @@ irValue *ir_build_expr_internal(irProcedure *proc, Ast *expr) { if (tv.value.kind != ExactValue_Invalid) { // NOTE(bill): Edge case - if (tv.value.kind != ExactValue_Compound && + if (is_type_u8_array(tv.type) && tv.value.kind == ExactValue_String) { + return ir_add_module_constant(proc->module, tv.type, tv.value); + } else if (tv.value.kind != ExactValue_Compound && is_type_array(tv.type)) { Type *elem = core_array_type(tv.type); ExactValue value = convert_exact_value_for_type(tv.value, elem); diff --git a/src/ir_print.cpp b/src/ir_print.cpp index 0605058ee..3ca9954ef 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -745,7 +745,7 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type * ir_write_byte(f, ']'); return; - } else if (is_type_array(type) && + } else if (is_type_array(type) && value.kind != ExactValue_Invalid && value.kind != ExactValue_String && value.kind != ExactValue_Compound) { @@ -796,7 +796,11 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type * GB_ASSERT(is_type_array(type)); ir_write_str_lit(f, "c\""); ir_print_escape_string(f, str, false, false); - ir_write_str_lit(f, "\\00\""); + if (type->Array.count == str.len) { + ir_write_str_lit(f, "\""); + } else { + ir_write_str_lit(f, "\\00\""); + } } else if (is_type_cstring(t)) { // HACK NOTE(bill): This is a hack but it works because strings are created at the very end // of the .ll file @@ -810,7 +814,7 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type * ir_write_str_lit(f, ", "); ir_print_type(f, m, t_i32); ir_write_str_lit(f, " 0, i32 0)"); - }else { + } else { // HACK NOTE(bill): This is a hack but it works because strings are created at the very end // of the .ll file irValue *str_array = ir_add_global_string_array(m, str); diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index ea5081be4..d47c45401 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -5126,7 +5126,15 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc LLVMValueRef data = LLVMConstStringInContext(ctx, cast(char const *)value.value_string.text, cast(unsigned)value.value_string.len, - false); + false /*DontNullTerminate*/); + res.value = data; + return res; + } else if (is_type_u8_array(type) && value.kind == ExactValue_String) { + GB_ASSERT(type->Array.count == value.value_string.len); + LLVMValueRef data = LLVMConstStringInContext(ctx, + cast(char const *)value.value_string.text, + cast(unsigned)value.value_string.len, + true /*DontNullTerminate*/); res.value = data; return res; } else if (is_type_array(type) && diff --git a/src/parser.hpp b/src/parser.hpp index aa288304e..cd0d59a48 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -646,7 +646,7 @@ struct AstCommonStuff { u16 viral_state_flags; AstFile * file; Scope * scope; - TypeAndValue tav; + TypeAndValue tav; // TODO(bill): Make this a pointer to minimize pointer size }; struct Ast { @@ -655,7 +655,7 @@ struct Ast { u16 viral_state_flags; AstFile * file; Scope * scope; - TypeAndValue tav; + TypeAndValue tav; // TODO(bill): Make this a pointer to minimize pointer size // IMPORTANT NOTE(bill): This must be at the end since the AST is allocated to be size of the variant union { diff --git a/src/types.cpp b/src/types.cpp index 1147beb33..8c39b9979 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -1221,6 +1221,13 @@ bool is_type_u8_slice(Type *t) { } return false; } +bool is_type_u8_array(Type *t) { + t = base_type(t); + if (t->kind == Type_Array) { + return is_type_u8(t->Array.elem); + } + return false; +} bool is_type_u8_ptr(Type *t) { t = base_type(t); if (t->kind == Type_Pointer) {