diff --git a/build.zig b/build.zig index 633d11419f..ed84e037ae 100644 --- a/build.zig +++ b/build.zig @@ -861,6 +861,10 @@ fn addCxxKnownPath( } return error.RequiredLibraryNotFound; } + // By default, explicit library paths are not checked for being linker scripts, + // but libc++ may very well be one, so force all inputs to be checked when passing + // an explicit path to libc++. + exe.allow_so_scripts = true; exe.addObjectFile(.{ .cwd_relative = path_unpadded }); // TODO a way to integrate with system c++ include files here diff --git a/src/Sema.zig b/src/Sema.zig index b99852fb0a..70212e0a63 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -35010,6 +35010,7 @@ fn resolvePeerTypesInner( // if there were no actual slices. Else, we want the slice index to report a conflict. var opt_slice_idx: ?usize = null; + var any_abi_aligned = false; var opt_ptr_info: ?InternPool.Key.PtrType = null; var first_idx: usize = undefined; var other_idx: usize = undefined; // We sometimes need a second peer index to report a generic error @@ -35054,17 +35055,14 @@ fn resolvePeerTypesInner( } }; // Note that the align can be always non-zero; Type.ptr will canonicalize it - ptr_info.flags.alignment = Alignment.min( - if (ptr_info.flags.alignment != .none) - ptr_info.flags.alignment - else - try Type.fromInterned(ptr_info.child).abiAlignmentSema(pt), - - if (peer_info.flags.alignment != .none) - peer_info.flags.alignment - else - try Type.fromInterned(peer_info.child).abiAlignmentSema(pt), - ); + if (peer_info.flags.alignment == .none) { + any_abi_aligned = true; + } else if (ptr_info.flags.alignment == .none) { + any_abi_aligned = true; + ptr_info.flags.alignment = peer_info.flags.alignment; + } else { + ptr_info.flags.alignment = ptr_info.flags.alignment.minStrict(peer_info.flags.alignment); + } if (ptr_info.flags.address_space != peer_info.flags.address_space) { return generic_err; @@ -35312,6 +35310,12 @@ fn resolvePeerTypesInner( }, } + if (any_abi_aligned and opt_ptr_info.?.flags.alignment != .none) { + opt_ptr_info.?.flags.alignment = opt_ptr_info.?.flags.alignment.minStrict( + try Type.fromInterned(pointee).abiAlignmentSema(pt), + ); + } + return .{ .success = try pt.ptrTypeSema(opt_ptr_info.?) }; }, diff --git a/src/link/Elf/SharedObject.zig b/src/link/Elf/SharedObject.zig index 8b4f482226..ac3b3857a1 100644 --- a/src/link/Elf/SharedObject.zig +++ b/src/link/Elf/SharedObject.zig @@ -72,6 +72,7 @@ pub const Parsed = struct { pub fn deinit(p: *Parsed, gpa: Allocator) void { gpa.free(p.strtab); + gpa.free(p.sections); gpa.free(p.symtab); gpa.free(p.versyms); gpa.free(p.symbols); diff --git a/src/main.zig b/src/main.zig index 9b245b3eda..291820cb75 100644 --- a/src/main.zig +++ b/src/main.zig @@ -984,6 +984,7 @@ fn buildOutputType( .libc_paths_file = try EnvVar.ZIG_LIBC.get(arena), .native_system_include_paths = &.{}, }; + defer create_module.link_inputs.deinit(gpa); // before arg parsing, check for the NO_COLOR and CLICOLOR_FORCE environment variables // if set, default the color setting to .off or .on, respectively @@ -3682,7 +3683,7 @@ const CreateModule = struct { /// This one is used while collecting CLI options. The set of libs is used /// directly after computing the target and used to compute link_libc, /// link_libcpp, and then the libraries are filtered into - /// `unresolved_linker_inputs` and `windows_libs`. + /// `unresolved_link_inputs` and `windows_libs`. cli_link_inputs: std.ArrayListUnmanaged(link.UnresolvedInput), windows_libs: std.StringArrayHashMapUnmanaged(void), /// The local variable `unresolved_link_inputs` is fed into library @@ -3816,7 +3817,8 @@ fn createModule( // to decide whether to trigger native path detection logic. // Preserves linker input order. var unresolved_link_inputs: std.ArrayListUnmanaged(link.UnresolvedInput) = .empty; - try unresolved_link_inputs.ensureUnusedCapacity(arena, create_module.cli_link_inputs.items.len); + defer unresolved_link_inputs.deinit(gpa); + try unresolved_link_inputs.ensureUnusedCapacity(gpa, create_module.cli_link_inputs.items.len); var any_name_queries_remaining = false; for (create_module.cli_link_inputs.items) |cli_link_input| switch (cli_link_input) { .name_query => |nq| { diff --git a/test/behavior/slice.zig b/test/behavior/slice.zig index 15db19f1e8..4f5367ad85 100644 --- a/test/behavior/slice.zig +++ b/test/behavior/slice.zig @@ -995,3 +995,11 @@ test "sentinel-terminated 0-length slices" { try expect(comptime_known_array_value[0] == 2); try expect(runtime_array_value[0] == 2); } + +test "peer slices keep abi alignment with empty struct" { + var cond: bool = undefined; + cond = false; + const slice = if (cond) &[1]u32{42} else &.{}; + comptime assert(@TypeOf(slice) == []const u32); + try expect(slice.len == 0); +}