diff --git a/stage0/ast.c b/stage0/ast.c index 152ab4ab66..1f52c9f5ff 100644 --- a/stage0/ast.c +++ b/stage0/ast.c @@ -97,6 +97,8 @@ Ast astParse(const char* source, const uint32_t len) { } void astDeinit(Ast* tree) { + if (tree->owns_source) + free((char*)tree->source); free(tree->err_msg); tree->tokens.cap = tree->tokens.len = 0; diff --git a/stage0/ast.h b/stage0/ast.h index aa444c01c4..c907517c2c 100644 --- a/stage0/ast.h +++ b/stage0/ast.h @@ -541,6 +541,7 @@ typedef struct { AstNodeList nodes; AstNodeIndexSlice extra_data; bool has_error; + bool owns_source; char* err_msg; } Ast; diff --git a/stage0/sema.c b/stage0/sema.c index 003b426944..1ceb468bac 100644 --- a/stage0/sema.c +++ b/stage0/sema.c @@ -138,6 +138,11 @@ static void instMapPut(InstMap* map, uint32_t zir_inst, AirInstRef ref) { #define CT_TAG_INT_INFO 3 #define CT_TAG_REIFY_INT 4 +// Helper to read a bool through a pointer, preventing cppcheck from +// assuming the value is unchanged across function calls that receive +// the pointer indirectly (via a struct field). +static bool readBool(const bool* p) { return *p; } + static void ctTrack( Sema* sema, InternPoolIndex ip_idx, uint8_t tag_val, uint32_t val) { if (sema->ct_len < 16) { @@ -1414,6 +1419,7 @@ static Zir loadImportZirFromPath(const char* full_path, Ast* out_ast) { // Parse. *out_ast = astParse(src, (uint32_t)read_len); + out_ast->owns_source = true; // AstGen. Zir zir = astGen(out_ast); @@ -4197,9 +4203,9 @@ static bool analyzeBodyInner( // this block_inline, requiring a post-hoc BLOCK wrapper // for correct lexical scoping. // Ported from src/Sema.zig block_inline need_debug_scope. - volatile bool need_debug_scope = false; + bool need_debug_scope = false; bool* saved_need_debug_scope = block->need_debug_scope; - block->need_debug_scope = (bool*)&need_debug_scope; + block->need_debug_scope = &need_debug_scope; uint32_t block_index = block->instructions_len; bool completed @@ -4212,7 +4218,7 @@ static bool analyzeBodyInner( // ensurePostHoc: always creates a BLOCK when // need_debug_scope is true, even for empty bodies // (producing "phantom" BLOCKs matching upstream AIR). - if (need_debug_scope) { + if (readBool(&need_debug_scope)) { uint32_t new_insts_count = block->instructions_len - block_index; diff --git a/stage0/verbose_air.c b/stage0/verbose_air.c index 52287f05e9..9728e93e69 100644 --- a/stage0/verbose_air.c +++ b/stage0/verbose_air.c @@ -14,8 +14,8 @@ // --- Tag name table (generated from X-macro) --- #define AIR_TAG_STR(e) #e, -static const char* const air_tag_strs[] = { - AIR_INST_FOREACH_TAG(AIR_TAG_STR)}; +static const char* const air_tag_strs[] + = { AIR_INST_FOREACH_TAG(AIR_TAG_STR) }; // Print tag name: strip "AIR_INST_" prefix (9 chars) and lowercase. static void writeTagName(FILE* out, uint8_t tag) { @@ -29,172 +29,172 @@ static void writeTagName(FILE* out, uint8_t tag) { static const char* const ip_static_names[IP_INDEX_PREINTERN_COUNT] = { // Types (0-17): integer types - "u0_type", // 0 - "i0_type", // 1 - "u1_type", // 2 - "u8_type", // 3 - "i8_type", // 4 - "u16_type", // 5 - "i16_type", // 6 - "u29_type", // 7 - "u32_type", // 8 - "i32_type", // 9 - "u64_type", // 10 - "i64_type", // 11 - "u80_type", // 12 - "u128_type", // 13 - "i128_type", // 14 - "u256_type", // 15 - "usize_type", // 16 - "isize_type", // 17 + "u0_type", // 0 + "i0_type", // 1 + "u1_type", // 2 + "u8_type", // 3 + "i8_type", // 4 + "u16_type", // 5 + "i16_type", // 6 + "u29_type", // 7 + "u32_type", // 8 + "i32_type", // 9 + "u64_type", // 10 + "i64_type", // 11 + "u80_type", // 12 + "u128_type", // 13 + "i128_type", // 14 + "u256_type", // 15 + "usize_type", // 16 + "isize_type", // 17 // C types (18-27) - "c_char_type", // 18 - "c_short_type", // 19 - "c_ushort_type", // 20 - "c_int_type", // 21 - "c_uint_type", // 22 - "c_long_type", // 23 - "c_ulong_type", // 24 - "c_longlong_type", // 25 - "c_ulonglong_type", // 26 - "c_longdouble_type", // 27 + "c_char_type", // 18 + "c_short_type", // 19 + "c_ushort_type", // 20 + "c_int_type", // 21 + "c_uint_type", // 22 + "c_long_type", // 23 + "c_ulong_type", // 24 + "c_longlong_type", // 25 + "c_ulonglong_type", // 26 + "c_longdouble_type", // 27 // Float types (28-32) - "f16_type", // 28 - "f32_type", // 29 - "f64_type", // 30 - "f80_type", // 31 - "f128_type", // 32 + "f16_type", // 28 + "f32_type", // 29 + "f64_type", // 30 + "f80_type", // 31 + "f128_type", // 32 // Special types (33-44) - "anyopaque_type", // 33 - "bool_type", // 34 - "void_type", // 35 - "type_type", // 36 - "anyerror_type", // 37 - "comptime_int_type", // 38 + "anyopaque_type", // 33 + "bool_type", // 34 + "void_type", // 35 + "type_type", // 36 + "anyerror_type", // 37 + "comptime_int_type", // 38 "comptime_float_type", // 39 - "noreturn_type", // 40 - "anyframe_type", // 41 - "null_type", // 42 - "undefined_type", // 43 - "enum_literal_type", // 44 + "noreturn_type", // 40 + "anyframe_type", // 41 + "null_type", // 42 + "undefined_type", // 43 + "enum_literal_type", // 44 // Pointer types (45-51) - "ptr_usize_type", // 45 - "ptr_const_comptime_int_type", // 46 - "manyptr_u8_type", // 47 - "manyptr_const_u8_type", // 48 - "manyptr_const_u8_sentinel_0_type", // 49 - "slice_const_u8_type", // 50 - "slice_const_u8_sentinel_0_type", // 51 + "ptr_usize_type", // 45 + "ptr_const_comptime_int_type", // 46 + "manyptr_u8_type", // 47 + "manyptr_const_u8_type", // 48 + "manyptr_const_u8_sentinel_0_type", // 49 + "slice_const_u8_type", // 50 + "slice_const_u8_sentinel_0_type", // 51 // Vector types (52-98) - "vector_8_i8_type", // 52 - "vector_16_i8_type", // 53 - "vector_32_i8_type", // 54 - "vector_64_i8_type", // 55 - "vector_1_u8_type", // 56 - "vector_2_u8_type", // 57 - "vector_4_u8_type", // 58 - "vector_8_u8_type", // 59 - "vector_16_u8_type", // 60 - "vector_32_u8_type", // 61 - "vector_64_u8_type", // 62 - "vector_2_i16_type", // 63 - "vector_4_i16_type", // 64 - "vector_8_i16_type", // 65 - "vector_16_i16_type", // 66 - "vector_32_i16_type", // 67 - "vector_4_u16_type", // 68 - "vector_8_u16_type", // 69 - "vector_16_u16_type", // 70 - "vector_32_u16_type", // 71 - "vector_2_i32_type", // 72 - "vector_4_i32_type", // 73 - "vector_8_i32_type", // 74 - "vector_16_i32_type", // 75 - "vector_4_u32_type", // 76 - "vector_8_u32_type", // 77 - "vector_16_u32_type", // 78 - "vector_2_i64_type", // 79 - "vector_4_i64_type", // 80 - "vector_8_i64_type", // 81 - "vector_2_u64_type", // 82 - "vector_4_u64_type", // 83 - "vector_8_u64_type", // 84 - "vector_1_u128_type", // 85 - "vector_2_u128_type", // 86 - "vector_1_u256_type", // 87 - "vector_4_f16_type", // 88 - "vector_8_f16_type", // 89 - "vector_16_f16_type", // 90 - "vector_32_f16_type", // 91 - "vector_2_f32_type", // 92 - "vector_4_f32_type", // 93 - "vector_8_f32_type", // 94 - "vector_16_f32_type", // 95 - "vector_2_f64_type", // 96 - "vector_4_f64_type", // 97 - "vector_8_f64_type", // 98 + "vector_8_i8_type", // 52 + "vector_16_i8_type", // 53 + "vector_32_i8_type", // 54 + "vector_64_i8_type", // 55 + "vector_1_u8_type", // 56 + "vector_2_u8_type", // 57 + "vector_4_u8_type", // 58 + "vector_8_u8_type", // 59 + "vector_16_u8_type", // 60 + "vector_32_u8_type", // 61 + "vector_64_u8_type", // 62 + "vector_2_i16_type", // 63 + "vector_4_i16_type", // 64 + "vector_8_i16_type", // 65 + "vector_16_i16_type", // 66 + "vector_32_i16_type", // 67 + "vector_4_u16_type", // 68 + "vector_8_u16_type", // 69 + "vector_16_u16_type", // 70 + "vector_32_u16_type", // 71 + "vector_2_i32_type", // 72 + "vector_4_i32_type", // 73 + "vector_8_i32_type", // 74 + "vector_16_i32_type", // 75 + "vector_4_u32_type", // 76 + "vector_8_u32_type", // 77 + "vector_16_u32_type", // 78 + "vector_2_i64_type", // 79 + "vector_4_i64_type", // 80 + "vector_8_i64_type", // 81 + "vector_2_u64_type", // 82 + "vector_4_u64_type", // 83 + "vector_8_u64_type", // 84 + "vector_1_u128_type", // 85 + "vector_2_u128_type", // 86 + "vector_1_u256_type", // 87 + "vector_4_f16_type", // 88 + "vector_8_f16_type", // 89 + "vector_16_f16_type", // 90 + "vector_32_f16_type", // 91 + "vector_2_f32_type", // 92 + "vector_4_f32_type", // 93 + "vector_8_f32_type", // 94 + "vector_16_f32_type", // 95 + "vector_2_f64_type", // 96 + "vector_4_f64_type", // 97 + "vector_8_f64_type", // 98 // More types (99-103) - "optional_noreturn_type", // 99 - "anyerror_void_error_union_type", // 100 - "adhoc_inferred_error_set_type", // 101 - "generic_poison_type", // 102 - "empty_tuple_type", // 103 + "optional_noreturn_type", // 99 + "anyerror_void_error_union_type", // 100 + "adhoc_inferred_error_set_type", // 101 + "generic_poison_type", // 102 + "empty_tuple_type", // 103 // Values (104-123) - "undef", // 104 - "undef_bool", // 105 - "undef_usize", // 106 - "undef_u1", // 107 - "zero", // 108 - "zero_usize", // 109 - "zero_u1", // 110 - "zero_u8", // 111 - "one", // 112 - "one_usize", // 113 - "one_u1", // 114 - "one_u8", // 115 - "four_u8", // 116 - "negative_one", // 117 - "void_value", // 118 - "unreachable_value", // 119 - "null_value", // 120 - "bool_true", // 121 - "bool_false", // 122 - "empty_tuple", // 123 + "undef", // 104 + "undef_bool", // 105 + "undef_usize", // 106 + "undef_u1", // 107 + "zero", // 108 + "zero_usize", // 109 + "zero_u1", // 110 + "zero_u8", // 111 + "one", // 112 + "one_usize", // 113 + "one_u1", // 114 + "one_u8", // 115 + "four_u8", // 116 + "negative_one", // 117 + "void_value", // 118 + "unreachable_value", // 119 + "null_value", // 120 + "bool_true", // 121 + "bool_false", // 122 + "empty_tuple", // 123 }; // --- SimpleType name table --- static const char* const simple_type_names[] = { - "f16", // 0 - "f32", // 1 - "f64", // 2 - "f80", // 3 - "f128", // 4 - "usize", // 5 - "isize", // 6 - "c_char", // 7 - "c_short", // 8 - "c_ushort", // 9 - "c_int", // 10 - "c_uint", // 11 - "c_long", // 12 - "c_ulong", // 13 - "c_longlong", // 14 - "c_ulonglong", // 15 - "c_longdouble", // 16 - "anyopaque", // 17 - "bool", // 18 - "void", // 19 - "type", // 20 - "anyerror", // 21 - "comptime_int", // 22 - "comptime_float", // 23 - "noreturn", // 24 - "null", // 25 - "undefined", // 26 - "enum_literal", // 27 + "f16", // 0 + "f32", // 1 + "f64", // 2 + "f80", // 3 + "f128", // 4 + "usize", // 5 + "isize", // 6 + "c_char", // 7 + "c_short", // 8 + "c_ushort", // 9 + "c_int", // 10 + "c_uint", // 11 + "c_long", // 12 + "c_ulong", // 13 + "c_longlong", // 14 + "c_ulonglong", // 15 + "c_longdouble", // 16 + "anyopaque", // 17 + "bool", // 18 + "void", // 19 + "type", // 20 + "anyerror", // 21 + "comptime_int", // 22 + "comptime_float", // 23 + "noreturn", // 24 + "null", // 25 + "undefined", // 26 + "enum_literal", // 27 "adhoc_inferred_error_set", // 28 - "generic_poison", // 29 + "generic_poison", // 29 }; #define SIMPLE_TYPE_COUNT 30 @@ -219,8 +219,7 @@ static void writeType(FILE* out, const InternPool* ip, InternPoolIndex ty_ip) { InternPoolKey key = ipIndexToKey(ip, ty_ip); switch (key.tag) { case IP_KEY_INT_TYPE: - fprintf(out, "%c%" PRIu16, - key.data.int_type.signedness ? 'i' : 'u', + fprintf(out, "%c%" PRIu16, key.data.int_type.signedness ? 'i' : 'u', key.data.int_type.bits); break; case IP_KEY_SIMPLE_TYPE: @@ -458,8 +457,8 @@ static void writeBlock(FILE* out, const Air* air, const InternPool* ip, uint32_t body_len = air->extra[payload + 1]; body_offset = payload + 2; fprintf(out, ", {\n"); - writeBody(out, air, ip, &air->extra[body_offset], body_len, - indent + 2); + writeBody( + out, air, ip, &air->extra[body_offset], body_len, indent + 2); writeIndent(out, indent); fprintf(out, "}"); } else { @@ -467,8 +466,8 @@ static void writeBlock(FILE* out, const Air* air, const InternPool* ip, uint32_t body_len = air->extra[payload]; body_offset = payload + 1; fprintf(out, ", {\n"); - writeBody(out, air, ip, &air->extra[body_offset], body_len, - indent + 2); + writeBody( + out, air, ip, &air->extra[body_offset], body_len, indent + 2); writeIndent(out, indent); fprintf(out, "}"); } @@ -599,7 +598,8 @@ static void writeDbgVar( AirInstRef operand = air->inst_datas[inst].pl_op.operand; uint32_t payload = air->inst_datas[inst].pl_op.payload; writeInstRef(out, air, ip, operand); - // payload is index into air->extra where the NUL-terminated name is stored. + // payload is index into air->extra where the NUL-terminated name is + // stored. const char* name = (const char*)&air->extra[payload]; fprintf(out, ", \"%s\"", name); } @@ -1075,17 +1075,18 @@ void verboseAirPrint( const char* name = entry->name ? entry->name : "(unnamed)"; // Compute byte sizes matching upstream format. - uint32_t inst_bytes - = air->inst_len * (uint32_t)(sizeof(uint8_t) + sizeof(AirInstData)); + uint32_t inst_bytes = air->inst_len + * (uint32_t)(sizeof(uint8_t) + sizeof(AirInstData)); uint32_t extra_bytes = air->extra_len * (uint32_t)sizeof(uint32_t); - uint32_t total_bytes = (uint32_t)sizeof(Air) + inst_bytes + extra_bytes; + uint32_t total_bytes + = (uint32_t)sizeof(Air) + inst_bytes + extra_bytes; fprintf(out, "# Begin Function AIR: %s:\n", name); fprintf(out, "# Total AIR bytes: %uB\n", total_bytes); - fprintf(out, "# AIR Instructions: %u (%uB)\n", - air->inst_len, inst_bytes); - fprintf(out, "# AIR Extra Data: %u (%uB)\n", - air->extra_len, extra_bytes); + fprintf(out, "# AIR Instructions: %u (%uB)\n", air->inst_len, + inst_bytes); + fprintf(out, "# AIR Extra Data: %u (%uB)\n", air->extra_len, + extra_bytes); // Extract main body from extra[0]. if (air->extra_len > 0) {