Pass an important chunk of tests #36

Merged
davidgmbb merged 16 commits from test-plus into main 2025-06-14 05:07:14 +00:00
4 changed files with 2689 additions and 879 deletions

View File

@ -51,3 +51,6 @@ target_link_libraries(bb PUBLIC llvm_bindings)
add_compile_options(-Wall -Wextra -pedantic -Wpedantic -Werror -Wno-c99-extensions -Wno-unused-function -Wno-missing-designated-field-initializers -fno-signed-char -fwrapv -fno-strict-aliasing)
add_compile_definitions(CMAKE_PREFIX_PATH="${CMAKE_PREFIX_PATH}")
add_compile_definitions(BB_CI=${BB_CI})
# add_compile_options(-fsanitize=address)
# add_link_options(-fsanitize=address)

File diff suppressed because it is too large Load Diff

View File

@ -9,7 +9,7 @@ fn LLVMValueRef llvm_module_create_function(Arena* arena, LLVMModuleRef module,
return function;
}
fn LLVMValueRef llvm_module_create_global_variable(LLVMModuleRef module, LLVMTypeRef type, bool is_constant, LLVMLinkage linkage_type, LLVMValueRef initial_value, String name, LLVMThreadLocalMode thread_local_mode, bool externally_initialized, u32 alignment, LLVMUnnamedAddr unnamed_address)
fn LLVMValueRef llvm_create_global_variable(LLVMModuleRef module, LLVMTypeRef type, bool is_constant, LLVMLinkage linkage_type, LLVMValueRef initial_value, String name, LLVMThreadLocalMode thread_local_mode, bool externally_initialized, u32 alignment, LLVMUnnamedAddr unnamed_address)
{
assert(name.pointer[name.length] == 0);
auto global = LLVMAddGlobal(module, type, (char*)name.pointer);
@ -609,21 +609,19 @@ fn bool contains_no_user_data(Type* type, u64 start, u64 end)
{
case TypeId::structure:
{
u64 offset = 0;
for (auto& field: type->structure.fields)
{
if (offset >= end)
auto field_offset = field.offset;
if (field_offset >= end)
{
break;
}
auto field_start = offset < start ? start - offset : 0;
if (!contains_no_user_data(field.type, field_start, end - offset))
auto field_start = field_offset < start ? start - field_offset : 0;
if (!contains_no_user_data(field.type, field_start, end - field_offset))
{
return false;
}
offset += get_byte_size(field.type);
}
return true;
@ -855,7 +853,7 @@ fn AbiSystemVClassifyResult abi_system_v_classify_type(Type* type, AbiSystemVCla
u64 vector_size = 16;
if (byte_size > 16 && (byte_size != get_byte_size(element_type) || byte_size > vector_size))
if (byte_size > 16 && (byte_size != element_size || byte_size > vector_size))
{
unreachable();
}
@ -2541,7 +2539,6 @@ fn Global* get_enum_name_array_global(Module* module, Type* enum_type)
auto u64_type = uint64(module);
resolve_type_in_place(module, u8_type);
resolve_type_in_place(module, u64_type);
LLVMValueRef name_before = 0;
LLVMValueRef name_constant_buffer[64];
for (u32 i = 0; i < fields.length; i += 1)
@ -2555,11 +2552,9 @@ fn Global* get_enum_name_array_global(Module* module, Type* enum_type)
string_literal("."),
field.name,
};
unsigned address_space = 0;
auto initial_value = LLVMConstStringInContext2(module->llvm.context, (char*)field.name.pointer, field.name.length, false);
u32 alignment = 1;
auto name_global = llvm_module_create_global_variable(module->llvm.module, LLVMArrayType2(u8_type->llvm.abi, field.name.length + null_terminate), is_constant, LLVMInternalLinkage, initial_value, arena_join_string(module->arena, array_to_slice(name_parts)), LLVMNotThreadLocal, false, alignment, LLVMGlobalUnnamedAddr);
name_before = name_global;
auto name_global = llvm_create_global_variable(module->llvm.module, LLVMArrayType2(u8_type->llvm.abi, field.name.length + null_terminate), is_constant, LLVMInternalLinkage, initial_value, arena_join_string(module->arena, array_to_slice(name_parts)), LLVMNotThreadLocal, false, alignment, LLVMGlobalUnnamedAddr);
LLVMValueRef constants[] = {
name_global,
LLVMConstInt(u64_type->llvm.abi, field.name.length, false),
@ -2573,8 +2568,7 @@ fn Global* get_enum_name_array_global(Module* module, Type* enum_type)
auto name_array = LLVMConstArray2(slice_type->llvm.abi, name_constant_buffer, array_element_count);
auto name_array_type = LLVMArrayType2(slice_type->llvm.abi, array_element_count);
auto is_constant = true;
unsigned address_space = 0;
auto name_array_variable = llvm_module_create_global_variable(module->llvm.module, name_array_type, is_constant, LLVMInternalLinkage, name_array, string_literal("name.array.enum"), LLVMNotThreadLocal, false, get_byte_alignment(slice_type), LLVMGlobalUnnamedAddr);
auto name_array_variable = llvm_create_global_variable(module->llvm.module, name_array_type, is_constant, LLVMInternalLinkage, name_array, string_literal("name.array.enum"), LLVMNotThreadLocal, false, get_byte_alignment(slice_type), LLVMGlobalUnnamedAddr);
auto global_type = get_array_type(module, slice_type, array_element_count);
resolve_type_in_place(module, global_type);
@ -4283,9 +4277,8 @@ fn void analyze_type(Module* module, Value* value, Type* expected_type, TypeAnal
auto value_array_variable_type = LLVMArrayType2(enum_value_type, array_element_count);
auto is_constant = true;
LLVMThreadLocalMode thread_local_mode = LLVMNotThreadLocal;
unsigned address_space = 0;
auto externally_initialized = false;
auto value_array_variable = llvm_module_create_global_variable(module->llvm.module, value_array_variable_type, is_constant, LLVMInternalLinkage, value_array, string_literal("value.array.enum"), thread_local_mode, externally_initialized, enum_alignment, LLVMGlobalUnnamedAddr);
auto value_array_variable = llvm_create_global_variable(module->llvm.module, value_array_variable_type, is_constant, LLVMInternalLinkage, value_array, string_literal("value.array.enum"), thread_local_mode, externally_initialized, enum_alignment, LLVMGlobalUnnamedAddr);
auto* entry_block = LLVMAppendBasicBlockInContext(module->llvm.context, llvm_function, "entry");
auto* return_block = LLVMAppendBasicBlockInContext(module->llvm.context, llvm_function, "return_block");
@ -5179,7 +5172,7 @@ fn SliceEmitResult emit_string_literal(Module* module, Value* value)
LLVMThreadLocalMode tlm = LLVMNotThreadLocal;
bool externally_initialized = false;
u32 alignment = 1;
auto global = llvm_module_create_global_variable(module->llvm.module, string_type, is_constant, LLVMInternalLinkage, constant_string, string_literal("conststring"), tlm, externally_initialized, alignment, LLVMGlobalUnnamedAddr);
auto global = llvm_create_global_variable(module->llvm.module, string_type, is_constant, LLVMInternalLinkage, constant_string, string_literal("conststring"), tlm, externally_initialized, alignment, LLVMGlobalUnnamedAddr);
return { global, LLVMConstInt(uint64(module)->llvm.abi, length, false) };
} break;
@ -5216,6 +5209,22 @@ fn void invalidate_analysis(Module* module, Value* value)
{
invalidate_analysis(module, value->unary.value);
} break;
case ValueId::slice_expression:
{
invalidate_analysis(module, value->slice_expression.array_like);
auto start = value->slice_expression.start;
auto end = value->slice_expression.end;
if (start)
{
invalidate_analysis(module, start);
}
if (end)
{
invalidate_analysis(module, end);
}
} break;
default: trap();
}
@ -5552,11 +5561,10 @@ fn LLVMValueRef emit_call(Module* module, Value* value, LLVMValueRef left_llvm,
bool is_constant = true;
LLVMLinkage linkage_type = LLVMInternalLinkage;
LLVMThreadLocalMode thread_local_mode = {};
u32 address_space = 0;
bool externally_initialized = false;
auto alignment = get_byte_alignment(semantic_argument_type);
auto global = llvm_module_create_global_variable(module->llvm.module, semantic_argument_type->llvm.memory, is_constant, linkage_type, semantic_call_argument_value->llvm, string_literal("conststruct"), thread_local_mode, externally_initialized, alignment, LLVMGlobalUnnamedAddr);
auto global = llvm_create_global_variable(module->llvm.module, semantic_argument_type->llvm.memory, is_constant, linkage_type, semantic_call_argument_value->llvm, string_literal("const.struct"), thread_local_mode, externally_initialized, alignment, LLVMGlobalUnnamedAddr);
for (u32 i = 0; i < coerce_fields.length; i += 1)
{
@ -5707,7 +5715,7 @@ fn LLVMValueRef emit_call(Module* module, Value* value, LLVMValueRef left_llvm,
bool externally_initialized = false;
auto alignment = get_byte_alignment(semantic_argument_type);
auto global = llvm_module_create_global_variable(module->llvm.module, semantic_argument_type->llvm.memory, is_constant, linkage_type, semantic_call_argument_value->llvm, string_literal("indirect.const.aggregate"), thread_local_mode, externally_initialized, alignment, LLVMGlobalUnnamedAddr);
auto global = llvm_create_global_variable(module->llvm.module, semantic_argument_type->llvm.memory, is_constant, linkage_type, semantic_call_argument_value->llvm, string_literal("indirect.const.aggregate"), thread_local_mode, externally_initialized, alignment, LLVMGlobalUnnamedAddr);
llvm_abi_argument_value_buffer[abi_argument_count] = global;
abi_argument_count += 1;
@ -5840,7 +5848,6 @@ fn LLVMValueRef emit_call(Module* module, Value* value, LLVMValueRef left_llvm,
auto destination_type = return_abi.semantic_type;
auto source_value = llvm_call;
auto source_type = raw_function_type->function.abi.abi_return_type;
auto destination_size = get_byte_size(destination_type);
@ -6449,11 +6456,10 @@ fn void emit_assignment(Module* module, LLVMValueRef left_llvm, Type* left_type,
bool is_constant = true;
LLVMLinkage linkage_type = LLVMInternalLinkage;
LLVMThreadLocalMode thread_local_mode = {};
u32 address_space = 0;
bool externally_initialized = false;
auto alignment = get_byte_alignment(resolved_value_type);
auto global = llvm_module_create_global_variable(module->llvm.module, value_type->llvm.memory, is_constant, linkage_type, right->llvm, string_literal("array.init"), thread_local_mode, externally_initialized, alignment, LLVMGlobalUnnamedAddr);
auto global = llvm_create_global_variable(module->llvm.module, value_type->llvm.memory, is_constant, linkage_type, right->llvm, string_literal("array.init"), thread_local_mode, externally_initialized, alignment, LLVMGlobalUnnamedAddr);
u64 memcpy_size = get_byte_size(resolved_value_type);
LLVMBuildMemCpy(module->llvm.builder, left_llvm, alignment, global, alignment, LLVMConstInt(uint64_type->llvm.abi, memcpy_size, false));
@ -6526,7 +6532,7 @@ fn void emit_assignment(Module* module, LLVMValueRef left_llvm, Type* left_type,
LLVMLinkage linkage_type = LLVMInternalLinkage;
LLVMThreadLocalMode thread_local_mode = LLVMNotThreadLocal;
bool externally_initialized = false;
auto global = llvm_module_create_global_variable(module->llvm.module, value_type->llvm.memory, is_constant, linkage_type, right->llvm, string_literal("const.aggregate"), thread_local_mode, externally_initialized, alignment, LLVMGlobalUnnamedAddr);
auto global = llvm_create_global_variable(module->llvm.module, value_type->llvm.memory, is_constant, linkage_type, right->llvm, string_literal("const.aggregate"), thread_local_mode, externally_initialized, alignment, LLVMGlobalUnnamedAddr);
LLVMBuildMemCpy(module->llvm.builder, left_llvm, alignment, global, alignment, byte_size_value);
}
else
@ -7068,7 +7074,8 @@ fn void analyze_block(Module* module, Block* block)
fn LLVMValueRef emit_constant_array(Module* module, Slice<Value*> elements, Type* element_type)
{
LLVMValueRef value_buffer[64];
LLVMValueRef value_buffer[128];
assert(elements.length <= array_length(value_buffer));
resolve_type_in_place(module, element_type);
@ -7329,7 +7336,7 @@ fn void emit_value(Module* module, Value* value, TypeKind type_kind, bool expect
assert(array_type->id == TypeId::array);
resolve_type_in_place(module, array_type);
auto alignment = get_byte_alignment(resolved_value_type);
auto value_array_variable = llvm_module_create_global_variable(module->llvm.module, array_type->llvm.memory, is_constant, LLVMInternalLinkage, array_value, string_literal("enum.values"), LLVMNotThreadLocal, 0, alignment, LLVMGlobalUnnamedAddr);
auto value_array_variable = llvm_create_global_variable(module->llvm.module, array_type->llvm.memory, is_constant, LLVMInternalLinkage, array_value, string_literal("enum.values"), LLVMNotThreadLocal, 0, alignment, LLVMGlobalUnnamedAddr);
llvm_value = value_array_variable;
} break;
}
@ -8615,6 +8622,10 @@ fn void analyze_statement(Module* module, Scope* scope, Statement* statement, u3
if (else_clause_index == invalid_clause_index)
{
LLVMPositionBuilderAtEnd(module->llvm.builder, else_block);
if (module->has_debug_info && !build_mode_is_optimized(module->build_mode))
{
emit_intrinsic_call(module, IntrinsicIndex::trap, {}, {});
}
LLVMBuildUnreachable(module->llvm.builder);
LLVMClearInsertionPosition(module->llvm.builder);
}
@ -8678,6 +8689,16 @@ fn void analyze_statement(Module* module, Scope* scope, Statement* statement, u3
Type* aggregate_type = 0;
if (right->kind == ValueKind::left && right->type->id != TypeId::pointer)
{
if (!type_is_slice(right->type))
{
report_error();
}
right->kind = ValueKind::right;
}
switch (right->kind)
{
case ValueKind::right:
@ -9504,7 +9525,7 @@ void emit(Module* module)
bool externally_initialized = false;
auto alignment = get_byte_alignment(global_type);
auto global_llvm = llvm_module_create_global_variable(module->llvm.module, global_type->llvm.memory, is_constant, linkage, global->variable.initial_value->llvm, global->variable.name, thread_local_mode, externally_initialized, alignment, LLVMNoUnnamedAddr);
auto global_llvm = llvm_create_global_variable(module->llvm.module, global_type->llvm.memory, is_constant, linkage, global->variable.initial_value->llvm, global->variable.name, thread_local_mode, externally_initialized, alignment, LLVMNoUnnamedAddr);
global->variable.storage->llvm = global_llvm;
global->variable.storage->type = get_pointer_type(module, global_type);

View File

@ -1937,7 +1937,7 @@ fn Value* parse_left(Module* module, Scope* scope, ValueBuilder builder)
case TokenId::left_bracket:
{
u64 element_count = 0;
Value* value_buffer[64];
Value* value_buffer[128];
skip_space(module);
@ -1976,6 +1976,7 @@ fn Value* parse_left(Module* module, Scope* scope, ValueBuilder builder)
}
auto value = parse_value(module, scope, {});
assert(element_count < array_length(value_buffer));
value_buffer[element_count] = value;
element_count += 1;
@ -2822,7 +2823,7 @@ fn Statement* parse_statement(Module* module, Scope* scope)
Value* right_value_buffer[64];
u64 right_value_count = 0;
right_value_buffer[right_value_count] = parse_value(module, scope, { .kind = ValueKind::left });
right_value_buffer[right_value_count] = parse_value(module, scope, {});
right_value_count += 1;
skip_space(module);
@ -2839,15 +2840,17 @@ fn Statement* parse_statement(Module* module, Scope* scope)
report_error();
}
right_value_buffer[0]->kind = ValueKind::right;
right_value_buffer[right_value_count] = parse_value(module, scope, {});
right_value_count += 1;
expect_character(module, right_parenthesis);
kind = ForEachKind::range;
} break;
case TokenId::right_parenthesis: kind = ForEachKind::slice; break;
case TokenId::right_parenthesis:
{
right_value_buffer[0]->kind = ValueKind::left;
kind = ForEachKind::slice;
} break;
default: report_error();
}