Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ jobs:
- name: IR regression tests
run: |
make check-snapshot || exit 1
- name: Sanitizer-enabled stage 0 tests
env:
CC: ${{ matrix.compiler }}
run: |
make check-sanitizer || exit 1
- name: Unit tests
run: |
make check || exit 1
Expand All @@ -48,6 +53,7 @@ jobs:
apt-get install -yqq build-essential
run: |
make config ARCH=arm
make check-sanitizer || exit 1
make check || exit 1

coding-style:
Expand Down
17 changes: 16 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ SNAPSHOTS := $(foreach SNAPSHOT_ARCH,$(ARCHS), $(patsubst tests/%.c, tests/snaps

all: config bootstrap

sanitizer: CFLAGS += -fsanitize=address -fsanitize=undefined -fno-omit-frame-pointer -O0
sanitizer: LDFLAGS += -fsanitize=address -fsanitize=undefined
sanitizer: config $(OUT)/$(STAGE0)-sanitizer
$(VECHO) " Built stage 0 compiler with sanitizers\n"

ifeq (,$(filter $(ARCH),$(ARCHS)))
$(error Support ARM and RISC-V only. Select the target with "ARCH=arm" or "ARCH=riscv")
endif
Expand Down Expand Up @@ -81,6 +86,12 @@ check-stage2: $(OUT)/$(STAGE2) $(TESTBINS) tests/driver.sh
$(VECHO) " TEST STAGE 2\n"
tests/driver.sh 2

check-sanitizer: $(OUT)/$(STAGE0)-sanitizer tests/driver.sh
$(VECHO) " TEST STAGE 0 (with sanitizers)\n"
$(Q)cp $(OUT)/$(STAGE0)-sanitizer $(OUT)/shecc
tests/driver.sh 0
$(Q)rm $(OUT)/shecc

check-snapshots: $(OUT)/$(STAGE0) $(SNAPSHOTS) tests/check-snapshots.sh
$(Q)$(foreach SNAPSHOT_ARCH, $(ARCHS), $(MAKE) distclean config check-snapshot ARCH=$(SNAPSHOT_ARCH) --silent;)
$(VECHO) "Switching backend back to %s\n" $(ARCH)
Expand Down Expand Up @@ -123,7 +134,11 @@ $(OUT)/inliner: tools/inliner.c

$(OUT)/$(STAGE0): $(OUT)/libc.inc $(OBJS)
$(VECHO) " LD\t$@\n"
$(Q)$(CC) $(OBJS) -o $@
$(Q)$(CC) $(OBJS) $(LDFLAGS) -o $@

$(OUT)/$(STAGE0)-sanitizer: $(OUT)/libc.inc $(OBJS)
$(VECHO) " LD\t$@ (with sanitizers)\n"
$(Q)$(CC) $(OBJS) $(LDFLAGS) -o $@

$(OUT)/$(STAGE1): $(OUT)/$(STAGE0)
$(Q)$(STAGE1_CHECK_CMD)
Expand Down
19 changes: 10 additions & 9 deletions src/globals.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,9 @@ void *arena_alloc(arena_t *arena, int size)
abort();
}

/* Align to PTR_SIZE bytes */
size = (size + PTR_SIZE - 1) & ~(PTR_SIZE - 1);
/* Align to sizeof(void*) bytes for host compatibility */
int alignment = sizeof(void *);
size = (size + alignment - 1) & ~(alignment - 1);

if (!arena->head || arena->head->offset + size > arena->head->capacity) {
/* Need a new block: choose capacity = max(DEFAULT_ARENA_SIZE,
Expand Down Expand Up @@ -307,17 +308,17 @@ symbol_t *arena_alloc_symbol(void)

constant_t *arena_alloc_constant(void)
{
return arena_alloc(GENERAL_ARENA, sizeof(constant_t));
return arena_calloc(GENERAL_ARENA, 1, sizeof(constant_t));
}

alias_t *arena_alloc_alias(void)
{
return arena_alloc(GENERAL_ARENA, sizeof(alias_t));
return arena_calloc(GENERAL_ARENA, 1, sizeof(alias_t));
}

macro_t *arena_alloc_macro(void)
{
return arena_alloc(GENERAL_ARENA, sizeof(macro_t));
return arena_calloc(GENERAL_ARENA, 1, sizeof(macro_t));
}

bb_traversal_args_t *arena_alloc_traversal_args(void)
Expand Down Expand Up @@ -613,7 +614,7 @@ ph2_ir_t *add_existed_ph2_ir(ph2_ir_t *ph2_ir)

ph2_ir_t *add_ph2_ir(opcode_t op)
{
ph2_ir_t *ph2_ir = arena_alloc(BB_ARENA, sizeof(ph2_ir_t));
ph2_ir_t *ph2_ir = arena_calloc(BB_ARENA, 1, sizeof(ph2_ir_t));
ph2_ir->op = op;
/* Set safe defaults; arch-lowering may annotate later */
ph2_ir->next = NULL;
Expand All @@ -630,7 +631,7 @@ void set_var_liveout(var_t *var, int end)

block_t *add_block(block_t *parent, func_t *func, macro_t *macro)
{
block_t *blk = arena_alloc(BLOCK_ARENA, sizeof(block_t));
block_t *blk = arena_calloc(BLOCK_ARENA, 1, sizeof(block_t));

blk->parent = parent;
blk->func = func;
Expand Down Expand Up @@ -884,7 +885,7 @@ func_t *find_func(char *func_name)
/* Create a basic block and set the scope of variables to 'parent' block */
basic_block_t *bb_create(block_t *parent)
{
basic_block_t *bb = arena_alloc(BB_ARENA, sizeof(basic_block_t));
basic_block_t *bb = arena_calloc(BB_ARENA, 1, sizeof(basic_block_t));

for (int i = 0; i < MAX_BB_PRED; i++) {
bb->prev[i].bb = NULL;
Expand Down Expand Up @@ -1000,7 +1001,7 @@ void add_insn(block_t *block,

bb->scope = block;

insn_t *n = arena_alloc(INSN_ARENA, sizeof(insn_t));
insn_t *n = arena_calloc(INSN_ARENA, 1, sizeof(insn_t));
n->opcode = op;
n->rd = rd;
n->rs1 = rs1;
Expand Down
27 changes: 15 additions & 12 deletions src/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ var_t *require_var(block_t *blk)
var_list->elements = new_locals;
}

var_t *var = arena_alloc(BLOCK_ARENA, sizeof(var_t));
var_t *var = arena_calloc(BLOCK_ARENA, 1, sizeof(var_t));
var_list->elements[var_list->size++] = var;
var->consumed = -1;
var->base = var;
Expand Down Expand Up @@ -3232,7 +3232,8 @@ basic_block_t *read_body_statement(block_t *parent, basic_block_t *bb)
else if (lex_accept(T_decrement))
prefix_op = OP_sub;
/* must be an identifier or asterisk (for pointer dereference) */
if (!lex_peek(T_identifier, token) && !lex_peek(T_asterisk, NULL))
bool has_asterisk = lex_peek(T_asterisk, NULL);
if (!lex_peek(T_identifier, token) && !has_asterisk)
error("Unexpected token");

/* handle macro parameter substitution for statements */
Expand Down Expand Up @@ -3350,14 +3351,16 @@ basic_block_t *read_body_statement(block_t *parent, basic_block_t *bb)
return bb;
}

/* is a function call? */
func = find_func(token);
if (func) {
lex_expect(T_identifier);
read_func_call(func, parent, &bb);
perform_side_effect(parent, bb);
lex_expect(T_semicolon);
return bb;
/* is a function call? Skip function call check when has_asterisk is true */
if (!has_asterisk) {
func = find_func(token);
if (func) {
lex_expect(T_identifier);
read_func_call(func, parent, &bb);
perform_side_effect(parent, bb);
lex_expect(T_semicolon);
return bb;
}
}

/* handle pointer dereference expressions like *ptr = value */
Expand Down Expand Up @@ -3792,7 +3795,7 @@ void parse_internal(void)
/* set starting point of global stack manually */
GLOBAL_FUNC = add_func("", true);
GLOBAL_FUNC->stack_size = 4;
GLOBAL_FUNC->bbs = arena_alloc(BB_ARENA, sizeof(basic_block_t));
GLOBAL_FUNC->bbs = arena_calloc(BB_ARENA, 1, sizeof(basic_block_t));

/* built-in types */
TY_void = add_named_type("void");
Expand Down Expand Up @@ -3829,7 +3832,7 @@ void parse_internal(void)
func->return_def.type = TY_int;
func->num_params = 0;
func->va_args = 1;
func->bbs = arena_alloc(BB_ARENA, sizeof(basic_block_t));
func->bbs = arena_calloc(BB_ARENA, 1, sizeof(basic_block_t));

/* lexer initialization */
SOURCE->size = 0;
Expand Down
2 changes: 1 addition & 1 deletion src/reg-alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ void refresh(basic_block_t *bb, insn_t *insn)

ph2_ir_t *bb_add_ph2_ir(basic_block_t *bb, opcode_t op)
{
ph2_ir_t *n = arena_alloc(BB_ARENA, sizeof(ph2_ir_t));
ph2_ir_t *n = arena_calloc(BB_ARENA, 1, sizeof(ph2_ir_t));
n->op = op;
/* Ensure deterministic defaults for newly created IR nodes */
n->next = NULL; /* well-formed singly linked list */
Expand Down
4 changes: 2 additions & 2 deletions src/ssa.c
Original file line number Diff line number Diff line change
Expand Up @@ -583,7 +583,7 @@ bool insert_phi_insn(basic_block_t *bb, var_t *var)
return false;

insn_t *head = bb->insn_list.head;
insn_t *n = arena_alloc(INSN_ARENA, sizeof(insn_t));
insn_t *n = arena_calloc(INSN_ARENA, 1, sizeof(insn_t));
n->opcode = OP_phi;
n->rd = var;
n->rs1 = var;
Expand Down Expand Up @@ -805,7 +805,7 @@ void solve_phi_params(void)

void append_unwound_phi_insn(basic_block_t *bb, var_t *dest, var_t *rs)
{
insn_t *n = arena_alloc(INSN_ARENA, sizeof(insn_t));
insn_t *n = arena_calloc(INSN_ARENA, 1, sizeof(insn_t));
n->opcode = OP_unwound_phi;
n->rd = dest;
n->rs1 = rs;
Expand Down