Skip to content

Commit

Permalink
Merge pull request #786 from Vexu/long-double-fix
Browse files Browse the repository at this point in the history
Fix long double casting when same size as double
  • Loading branch information
Vexu authored Oct 14, 2024
2 parents a077096 + 9906d47 commit a0d5cc3
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 25 deletions.
31 changes: 11 additions & 20 deletions src/aro/Parser.zig
Original file line number Diff line number Diff line change
Expand Up @@ -5804,8 +5804,8 @@ pub const Result = struct {
// if either is a float cast to that type
if (a.ty.isFloat() or b.ty.isFloat()) {
const float_types = [6][2]Type.Specifier{
.{ .complex_long_double, .long_double },
.{ .complex_float128, .float128 },
.{ .complex_long_double, .long_double },
.{ .complex_double, .double },
.{ .complex_float, .float },
// No `_Complex __fp16` type
Expand All @@ -5814,20 +5814,9 @@ pub const Result = struct {
};
const a_spec = a.ty.canonicalize(.standard).specifier;
const b_spec = b.ty.canonicalize(.standard).specifier;
if (p.comp.target.cTypeBitSize(.longdouble) == 128) {
if (try a.floatConversion(b, a_spec, b_spec, p, float_types[0])) return;
}
if (try a.floatConversion(b, a_spec, b_spec, p, float_types[1])) return;
if (p.comp.target.cTypeBitSize(.longdouble) >= p.comp.target.cTypeBitSize(.double)) {
if (try a.floatConversion(b, a_spec, b_spec, p, float_types[0])) return;
for (float_types) |ft| {
if (try a.floatConversion(b, a_spec, b_spec, p, ft)) return;
}
if (try a.floatConversion(b, a_spec, b_spec, p, float_types[2])) return;
if (p.comp.target.cTypeBitSize(.longdouble) >= p.comp.target.cTypeBitSize(.float)) {
if (try a.floatConversion(b, a_spec, b_spec, p, float_types[0])) return;
}
if (try a.floatConversion(b, a_spec, b_spec, p, float_types[3])) return;
if (try a.floatConversion(b, a_spec, b_spec, p, float_types[4])) return;
if (try a.floatConversion(b, a_spec, b_spec, p, float_types[5])) return;
unreachable;
}

Expand Down Expand Up @@ -6843,8 +6832,8 @@ fn castExpr(p: *Parser) Error!Result {
switch (p.tok_ids[p.tok_i]) {
.builtin_choose_expr => return p.builtinChooseExpr(),
.builtin_va_arg => return p.builtinVaArg(),
.builtin_offsetof => return p.builtinOffsetof(false),
.builtin_bitoffsetof => return p.builtinOffsetof(true),
.builtin_offsetof => return p.builtinOffsetof(.bytes),
.builtin_bitoffsetof => return p.builtinOffsetof(.bits),
.builtin_types_compatible_p => return p.typesCompatible(),
// TODO: other special-cased builtins
else => {},
Expand Down Expand Up @@ -6968,7 +6957,9 @@ fn builtinVaArg(p: *Parser) Error!Result {
}) };
}

fn builtinOffsetof(p: *Parser, want_bits: bool) Error!Result {
const OffsetKind = enum { bits, bytes };

fn builtinOffsetof(p: *Parser, offset_kind: OffsetKind) Error!Result {
const builtin_tok = p.tok_i;
p.tok_i += 1;

Expand All @@ -6993,7 +6984,7 @@ fn builtinOffsetof(p: *Parser, want_bits: bool) Error!Result {

_ = try p.expectToken(.comma);

const offsetof_expr = try p.offsetofMemberDesignator(ty, want_bits);
const offsetof_expr = try p.offsetofMemberDesignator(ty, offset_kind);

try p.expectClosing(l_paren, .r_paren);

Expand All @@ -7009,7 +7000,7 @@ fn builtinOffsetof(p: *Parser, want_bits: bool) Error!Result {
}

/// offsetofMemberDesignator: IDENTIFIER ('.' IDENTIFIER | '[' expr ']' )*
fn offsetofMemberDesignator(p: *Parser, base_ty: Type, want_bits: bool) Error!Result {
fn offsetofMemberDesignator(p: *Parser, base_ty: Type, offset_kind: OffsetKind) Error!Result {
errdefer p.skipTo(.r_paren);
const base_field_name_tok = try p.expectIdentifier();
const base_field_name = try StrInt.intern(p.comp, p.tokSlice(base_field_name_tok));
Expand Down Expand Up @@ -7062,7 +7053,7 @@ fn offsetofMemberDesignator(p: *Parser, base_ty: Type, want_bits: bool) Error!Re
},
else => break,
};
const val = try Value.int(if (want_bits) total_offset else total_offset / 8, p.comp);
const val = try Value.int(if (offset_kind == .bits) total_offset else total_offset / 8, p.comp);
return Result{ .ty = base_ty, .val = val, .node = lhs.node };
}

Expand Down
2 changes: 1 addition & 1 deletion src/backend/Object/Elf.zig
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ pub fn finish(elf: *Elf, file: std.fs.File) !void {
var buf_writer = std.io.bufferedWriter(file.writer());
const w = buf_writer.writer();

var num_sections: std.elf.Elf64_Half = additional_sections;
var num_sections: std.elf.Half = additional_sections;
var relocations_len: std.elf.Elf64_Off = 0;
var sections_len: std.elf.Elf64_Off = 0;
{
Expand Down
5 changes: 3 additions & 2 deletions test/cases/fp16 parameter.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
//aro-args --target=x86_64-linux-gnu
__fp16 foo(__fp16 param) {
return 0;
}

#define EXPECTED_ERRORS "fp16 parameter.c:1:19: error: parameters cannot have __fp16 type; did you forget * ?" \
"fp16 parameter.c:1:11: error: function return value cannot have __fp16 type; did you forget * ?" \
#define EXPECTED_ERRORS "fp16 parameter.c:2:19: error: parameters cannot have __fp16 type; did you forget * ?" \
"fp16 parameter.c:2:11: error: function return value cannot have __fp16 type; did you forget * ?" \

22 changes: 20 additions & 2 deletions test/runner.zig
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ pub fn main() !void {
if (pp.defines.get("TESTS_SKIPPED")) |macro| {
if (macro.is_func or macro.tokens.len != 1 or macro.tokens[0].id != .pp_num) {
fail_count += 1;
std.debug.print("{s}:\n", .{case});
std.debug.print("invalid TESTS_SKIPPED, definition should contain exactly one integer literal {}\n", .{macro});
continue;
}
Expand All @@ -265,12 +266,14 @@ pub fn main() !void {
if (only_preprocess) {
if (try checkExpectedErrors(&pp, &buf)) |some| {
if (!some) {
std.debug.print("in case {s}\n", .{case});
fail_count += 1;
continue;
}
} else {
aro.Diagnostics.render(&comp, std.io.tty.detectConfig(std.io.getStdErr()));
if (comp.diagnostics.errors != 0) {
std.debug.print("in case {s}\n", .{case});
fail_count += 1;
continue;
}
Expand Down Expand Up @@ -299,6 +302,7 @@ pub fn main() !void {
ok_count += 1;
} else {
fail_count += 1;
std.debug.print("{s}:\n", .{case});
std.debug.print("\n====== expected to find: =========\n", .{});
std.debug.print("{s}", .{expected_output});
std.debug.print("\n======== but did not find it in this: =========\n", .{});
Expand All @@ -319,7 +323,10 @@ pub fn main() !void {
var tree = aro.Parser.parse(&pp) catch |err| switch (err) {
error.FatalError => {
if (try checkExpectedErrors(&pp, &buf)) |some| {
if (some) ok_count += 1 else fail_count += 1;
if (some) ok_count += 1 else {
std.debug.print("in case {s}\n", .{case});
fail_count += 1;
}
}
continue;
},
Expand All @@ -337,6 +344,7 @@ pub fn main() !void {

try tree.dump(.no_color, actual_ast.writer());
std.testing.expectEqualStrings(expected_ast, actual_ast.items) catch {
std.debug.print("in case {s}\n", .{case});
fail_count += 1;
break;
};
Expand All @@ -347,6 +355,7 @@ pub fn main() !void {
if (tree.nodes.items(.tag)[@intFromEnum(decl)] == .fn_def) break tree.nodes.items(.data)[@intFromEnum(decl)];
} else {
fail_count += 1;
std.debug.print("{s}:\n", .{case});
std.debug.print("EXPECTED_TYPES requires a function to be defined\n", .{});
break;
};
Expand All @@ -363,6 +372,7 @@ pub fn main() !void {
if (str.id == .macro_ws) continue;
if (str.id != .string_literal) {
fail_count += 1;
std.debug.print("{s}:\n", .{case});
std.debug.print("EXPECTED_TYPES tokens must be string literals (found {s})\n", .{@tagName(str.id)});
continue :next_test;
}
Expand All @@ -373,6 +383,7 @@ pub fn main() !void {
const actual_type = actual.types.items[i];
if (!std.mem.eql(u8, expected_type, actual_type)) {
fail_count += 1;
std.debug.print("{s}:\n", .{case});
std.debug.print("expected type '{s}' did not match actual type '{s}'\n", .{
expected_type,
actual_type,
Expand All @@ -382,6 +393,7 @@ pub fn main() !void {
}
if (i != actual.types.items.len) {
fail_count += 1;
std.debug.print("{s}:\n", .{case});
std.debug.print(
"EXPECTED_TYPES count differs: expected {d} found {d}\n",
.{ i, actual.types.items.len },
Expand All @@ -391,7 +403,10 @@ pub fn main() !void {
}

if (try checkExpectedErrors(&pp, &buf)) |some| {
if (some) ok_count += 1 else fail_count += 1;
if (some) ok_count += 1 else {
std.debug.print("in case {s}\n", .{case});
fail_count += 1;
}
continue;
}

Expand All @@ -408,12 +423,14 @@ pub fn main() !void {

if (macro.is_func) {
fail_count += 1;
std.debug.print("{s}:\n", .{case});
std.debug.print("invalid EXPECTED_OUTPUT {}\n", .{macro});
continue;
}

if (macro.tokens.len != 1 or macro.tokens[0].id != .string_literal) {
fail_count += 1;
std.debug.print("{s}:\n", .{case});
std.debug.print("EXPECTED_OUTPUT takes exactly one string", .{});
continue;
}
Expand Down Expand Up @@ -456,6 +473,7 @@ pub fn main() !void {

if (!std.mem.eql(u8, expected_output, stdout)) {
fail_count += 1;
std.debug.print("{s}:\n", .{case});
std.debug.print(
\\
\\======= expected output =======
Expand Down

0 comments on commit a0d5cc3

Please sign in to comment.