Skip to content

Commit

Permalink
Merge pull request #691 from ehaas/crash-fixes
Browse files Browse the repository at this point in the history
More crash fixes + update to fuzz build
  • Loading branch information
Vexu authored Apr 23, 2024
2 parents f60a2de + bc9ee42 commit aa52b23
Show file tree
Hide file tree
Showing 12 changed files with 88 additions and 116 deletions.
35 changes: 5 additions & 30 deletions build.zig
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
const std = @import("std");
const Build = std.Build;
const GenerateDef = @import("build/GenerateDef.zig");
const ZigLibDirStep = @import("build/ZigLibDir.zig");

const aro_version = std.SemanticVersion{
.major = 0,
Expand All @@ -11,44 +10,20 @@ const aro_version = std.SemanticVersion{

fn addFuzzStep(b: *Build, target: std.Build.ResolvedTarget, afl_clang_lto_path: []const u8, aro_module: *std.Build.Module) !void {
const fuzz_step = b.step("fuzz", "Build executable for fuzz testing.");
const fuzz_target = blk: {
var query = target.query;
query.ofmt = .c;
break :blk b.resolveTargetQuery(query);
};

const lib_dir_step = try ZigLibDirStep.create(b);

const compiler_rt = b.createModule(.{
.root_source_file = lib_dir_step.getCompilerRTPath(),
});
const fuzz_lib = b.addStaticLibrary(.{
.name = "fuzz-lib",
.root_source_file = .{ .path = "test/fuzz/fuzz_lib.zig" },
.optimize = .Debug,
.target = fuzz_target,
.target = target,
.single_threaded = true,
});
fuzz_lib.root_module.addImport("compiler_rt", compiler_rt);
fuzz_lib.want_lto = true;
fuzz_lib.bundle_compiler_rt = true;
fuzz_lib.pie = true;

fuzz_lib.root_module.addImport("aro", aro_module);
const fuzz_compile = b.addSystemCommand(&.{
afl_clang_lto_path,
"-Wno-incompatible-pointer-types",
"-nostdinc",
"-isystem",
});
fuzz_compile.addDirectoryArg(lib_dir_step.getIncludePath());
fuzz_compile.addArgs(&.{
"-isystem",
"/usr/include",
"-isystem",
"/usr/local/include",
"-std=c99",
});
const fuzz_compile = b.addSystemCommand(&.{afl_clang_lto_path});
fuzz_compile.addFileArg(.{ .path = "test/fuzz/main.c" });
fuzz_compile.addArg("-I");
fuzz_compile.addDirectoryArg(lib_dir_step.getLibPath());
fuzz_compile.addArg("-o");
const fuzz_exe = fuzz_compile.addOutputFileArg("arofuzz");
const fuzz_install = b.addInstallBinFile(fuzz_exe, "arofuzz");
Expand Down
65 changes: 0 additions & 65 deletions build/ZigLibDir.zig

This file was deleted.

25 changes: 16 additions & 9 deletions src/aro/Parser.zig
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ value_map: Tree.ValueMap,

// buffers used during compilation
syms: SymbolStack = .{},
strings: std.ArrayList(u8),
strings: std.ArrayListAligned(u8, 4),
labels: std.ArrayList(Label),
list_buf: NodeList,
decl_buf: NodeList,
Expand Down Expand Up @@ -160,7 +160,7 @@ record: struct {
}

fn addFieldsFromAnonymous(r: @This(), p: *Parser, ty: Type) Error!void {
for (ty.data.record.fields) |f| {
for (ty.getRecord().?.fields) |f| {
if (f.isAnonymousRecord()) {
try r.addFieldsFromAnonymous(p, f.ty.canonicalize(.standard));
} else if (f.name_tok != 0) {
Expand Down Expand Up @@ -688,7 +688,7 @@ pub fn parse(pp: *Preprocessor) Compilation.Error!Tree {
.gpa = pp.comp.gpa,
.arena = arena.allocator(),
.tok_ids = pp.tokens.items(.id),
.strings = std.ArrayList(u8).init(pp.comp.gpa),
.strings = std.ArrayListAligned(u8, 4).init(pp.comp.gpa),
.value_map = Tree.ValueMap.init(pp.comp.gpa),
.data = NodeList.init(pp.comp.gpa),
.labels = std.ArrayList(Label).init(pp.comp.gpa),
Expand Down Expand Up @@ -5466,10 +5466,14 @@ pub const Result = struct {

fn lvalConversion(res: *Result, p: *Parser) Error!void {
if (res.ty.isFunc()) {
const elem_ty = try p.arena.create(Type);
elem_ty.* = res.ty;
res.ty.specifier = .pointer;
res.ty.data = .{ .sub_type = elem_ty };
if (res.ty.isInvalidFunc()) {
res.ty = .{ .specifier = .invalid };
} else {
const elem_ty = try p.arena.create(Type);
elem_ty.* = res.ty;
res.ty.specifier = .pointer;
res.ty.data = .{ .sub_type = elem_ty };
}
try res.implicitCast(p, .function_to_pointer);
} else if (res.ty.isArray()) {
res.val = .{};
Expand Down Expand Up @@ -8018,6 +8022,9 @@ fn stringLiteral(p: *Parser) Error!Result {
const strings_top = p.strings.items.len;
defer p.strings.items.len = strings_top;

const literal_start = mem.alignForward(usize, strings_top, @intFromEnum(char_width));
try p.strings.resize(literal_start);

while (p.tok_i < string_end) : (p.tok_i += 1) {
const this_kind = text_literal.Kind.classify(p.tok_ids[p.tok_i], .string_literal).?;
const slice = this_kind.contentSlice(p.tokSlice(p.tok_i));
Expand Down Expand Up @@ -8068,7 +8075,7 @@ fn stringLiteral(p: *Parser) Error!Result {
switch (char_width) {
.@"1" => p.strings.appendSliceAssumeCapacity(view.bytes),
.@"2" => {
const capacity_slice: []align(@alignOf(u16)) u8 = @alignCast(p.strings.unusedCapacitySlice());
const capacity_slice: []align(@alignOf(u16)) u8 = @alignCast(p.strings.allocatedSlice()[literal_start..]);
const dest_len = std.mem.alignBackward(usize, capacity_slice.len, 2);
const dest = std.mem.bytesAsSlice(u16, capacity_slice[0..dest_len]);
const words_written = std.unicode.utf8ToUtf16Le(dest, view.bytes) catch unreachable;
Expand All @@ -8089,7 +8096,7 @@ fn stringLiteral(p: *Parser) Error!Result {
}
}
p.strings.appendNTimesAssumeCapacity(0, @intFromEnum(char_width));
const slice = p.strings.items[strings_top..];
const slice = p.strings.items[literal_start..];

// TODO this won't do anything if there is a cache hit
const interned_align = mem.alignForward(
Expand Down
2 changes: 1 addition & 1 deletion src/aro/Preprocessor.zig
Original file line number Diff line number Diff line change
Expand Up @@ -976,7 +976,7 @@ fn expr(pp: *Preprocessor, tokenizer: *Tokenizer) MacroError!bool {
.tok_i = @intCast(token_state.tokens_len),
.arena = pp.arena.allocator(),
.in_macro = true,
.strings = std.ArrayList(u8).init(pp.comp.gpa),
.strings = std.ArrayListAligned(u8, 4).init(pp.comp.gpa),

.data = undefined,
.value_map = undefined,
Expand Down
22 changes: 15 additions & 7 deletions src/aro/Type.zig
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,16 @@ pub fn params(ty: Type) []Func.Param {
};
}

/// Returns true if the return value or any param of `ty` is `.invalid`
/// Asserts that ty is a function type
pub fn isInvalidFunc(ty: Type) bool {
if (ty.returnType().is(.invalid)) return true;
for (ty.params()) |param| {
if (param.ty.is(.invalid)) return true;
}
return false;
}

pub fn arrayLen(ty: Type) ?u64 {
return switch (ty.specifier) {
.array, .static_array => ty.data.array.len,
Expand Down Expand Up @@ -1106,7 +1116,7 @@ pub fn alignof(ty: Type, comp: *const Compilation) u29 {
.ulong_long => comp.target.c_type_alignment(.ulonglong),

.bit_int => @min(
std.math.ceilPowerOfTwoPromote(u16, (ty.data.int.bits + 7) / 8),
std.math.ceilPowerOfTwoPromote(u16, (ty.data.int.bits +| 7) / 8),
comp.target.maxIntAlignment(),
),

Expand Down Expand Up @@ -1220,9 +1230,9 @@ pub fn eql(a_param: Type, b_param: Type, comp: *const Compilation, check_qualifi
if (!b.isFunc()) return false;
} else if (a.isArray()) {
if (!b.isArray()) return false;
} else if (a.specifier == .@"enum" and a.data.@"enum".fixed and b.specifier != .@"enum") {
} else if (a.specifier == .@"enum" and b.specifier != .@"enum") {
return a.data.@"enum".tag_ty.eql(b, comp, check_qualifiers);
} else if (b.specifier == .@"enum" and b.data.@"enum".fixed and a.specifier != .@"enum") {
} else if (b.specifier == .@"enum" and a.specifier != .@"enum") {
return a.eql(b.data.@"enum".tag_ty, comp, check_qualifiers);
} else if (a.specifier != b.specifier) return false;

Expand Down Expand Up @@ -1318,10 +1328,8 @@ pub fn integerRank(ty: Type, comp: *const Compilation) usize {
.typeof_expr => ty.data.expr.ty.integerRank(comp),
.attributed => ty.data.attributed.base.integerRank(comp),

.@"enum" => {
std.debug.assert(real.data.@"enum".fixed);
return real.data.@"enum".tag_ty.integerRank(comp);
},
.@"enum" => real.data.@"enum".tag_ty.integerRank(comp),

else => unreachable,
});
}
Expand Down
14 changes: 10 additions & 4 deletions src/aro/Value.zig
Original file line number Diff line number Diff line change
Expand Up @@ -757,10 +757,16 @@ pub fn bitAnd(lhs: Value, rhs: Value, comp: *Compilation) !Value {
const lhs_bigint = lhs.toBigInt(&lhs_space, comp);
const rhs_bigint = rhs.toBigInt(&rhs_space, comp);

const limbs = try comp.gpa.alloc(
std.math.big.Limb,
@max(lhs_bigint.limbs.len, rhs_bigint.limbs.len),
);
const limb_count = if (lhs_bigint.positive and rhs_bigint.positive)
@min(lhs_bigint.limbs.len, rhs_bigint.limbs.len)
else if (lhs_bigint.positive)
lhs_bigint.limbs.len
else if (rhs_bigint.positive)
rhs_bigint.limbs.len
else
@max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1;

const limbs = try comp.gpa.alloc(std.math.big.Limb, limb_count);
defer comp.gpa.free(limbs);
var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined };

Expand Down
1 change: 1 addition & 0 deletions test/cases/alignment.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ _Static_assert(_Alignof(n) == 32, "incorrect alignment");

__attribute__((aligned("foo"))) o;
_Alignas(1.2) p;
_Static_assert(_Alignof(_BitInt(65535)) > 0, "");

#define EXPECTED_ERRORS "alignment.c:1:1: error: '_Alignas' attribute only applies to variables and fields" \
"alignment.c:3:3: error: '_Alignas' attribute only applies to variables and fields" \
Expand Down
5 changes: 5 additions & 0 deletions test/cases/attributed anonymous record.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
struct A{
union {
char a;
} __attribute__((packed));
};
1 change: 1 addition & 0 deletions test/cases/binary expressions.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ _Static_assert(2.0||(2.0 == 2.0), "");
_Static_assert(2.0||(3.0 > 2.0), "");
_Static_assert(2.0||(2.0 && 2.0), "");

_Static_assert((-10 & -1) == -10, "");
#define EXPECTED_ERRORS "binary expressions.c:3:7: error: invalid operands to binary expression ('long' and 'float')" \
"binary expressions.c:6:13: error: invalid operands to binary expression ('char' and 'int *')" \
"binary expressions.c:8:9: error: invalid operands to binary expression ('void (*)(void)' and 'void')" \
Expand Down
18 changes: 18 additions & 0 deletions test/cases/enum pointer.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
enum E {
A,
};

void foo(void) {
int x;
unsigned y;
enum E *p1 = &x;
enum E *p2 = &y;
}

#if __WIN32__
#define EXPECTED_ERRORS "enum pointer.c:9:18: warning: incompatible pointer types initializing 'enum E *' from incompatible type 'unsigned int *' converts between pointers to integer types with different sign [-Wpointer-sign]" \

#else
#define EXPECTED_ERRORS "enum pointer.c:8:18: warning: incompatible pointer types initializing 'enum E *' from incompatible type 'int *' [-Wincompatible-pointer-types]" \

#endif
4 changes: 4 additions & 0 deletions test/cases/functions.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ int (*return_array_ptr(void))[2] {
void no_params(void);
void no_params(int x){}

void invalid_func(__auto_type);
int invalid_int = invalid_func;

#define EXPECTED_ERRORS "functions.c:10:12: error: parameter named 'quux' is missing" \
"functions.c:20:14: error: illegal initializer (only variables can be initialized)" \
"functions.c:18:2: warning: non-void function 'foooo' does not return a value [-Wreturn-type]" \
Expand All @@ -90,4 +93,5 @@ void no_params(int x){}
"functions.c:55:9: error: parameter has incomplete type 'enum EE'" \
"functions.c:79:6: error: redefinition of 'no_params' with a different type" \
"functions.c:78:6: note: previous definition is here" \
"functions.c:81:19: error: '__auto_type' not allowed in function prototype" \

12 changes: 12 additions & 0 deletions test/cases/unaligned u16 string literal.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
struct S {
int x;
};

void foo(void) {
struct S s;
s.y;
}

_Static_assert(u"A");

#define NO_ERROR_VALIDATION

0 comments on commit aa52b23

Please sign in to comment.