// File: /workspace/github_c_makefile_star2_O0/markdryan[P]subtilis/frontend/parser_mem.c
// Function: subtilis_parser_append_exp
subtilis_exp_t *subtilis_parser_append_exp(subtilis_parser_t *p,
					   subtilis_token_t *t,
					   subtilis_error_t *err)
{
	bool check_size;
	bool tmp;
	subtilis_exp_t *objs[3] = {NULL};
	subtilis_exp_t *retval = NULL;
	const subtilis_symbol_t *s;
	size_t i;

	prv_append_statement(p, t, objs, err);
	if (err->type != SUBTILIS_ERROR_OK)
		return NULL;

	retval = subtilis_type_if_dup(objs[0], err);
	if (err->type != SUBTILIS_ERROR_OK)
		goto cleanup;

	tmp = objs[0]->temporary;

	subtilis_type_if_append(p, objs[0], objs[1], objs[2], err);
	objs[0] = NULL;
	objs[1] = NULL;
	objs[2] = NULL;
	if (err->type != SUBTILIS_ERROR_OK)
		goto cleanup;

	/*
	 * If we're appending to a non-temporary variable with a ref
	 * count of 1 we  need to temporarily increase its reference
	 * count for the remainder of the current block.  This is to prevent
	 * a use after free error  which can happen when appending to an
	 * existing variable and then assigning the return value to that same
	 * variable.
	 *
	 * We could just push the existing reference, rather than making a copy
	 * and make some fake entry in the symbol table, with a size of 0, but
	 * this seems a bit hacky.  Would result in smaller code if we could get
	 * it to work though.
	 */

	if (subtilis_type_if_is_reference(&retval->type) && !tmp) {
		check_size = !subtilis_type_if_is_array(&retval->type);
		s = subtilis_symbol_table_insert_tmp(p->local_st, &retval->type,
						     NULL, err);
		if (err->type != SUBTILIS_ERROR_OK)
			goto cleanup;

		subtilis_reference_type_init_ref(p, SUBTILIS_IR_REG_LOCAL,
						 s->loc, retval->exp.ir_op.reg,
						 check_size, true, err);
		if (err->type != SUBTILIS_ERROR_OK)
			goto cleanup;

		subtilis_reference_type_push_reference(
		    p, &retval->type, SUBTILIS_IR_REG_LOCAL, s->loc, err);
		if (err->type != SUBTILIS_ERROR_OK)
			goto cleanup;
	}

	return retval;

cleanup:
	subtilis_exp_delete(retval);

	for (i = 0; i < 3; i++)
		subtilis_exp_delete(objs[i]);

	return NULL;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
leaq -0x40(%rbp), %rdi
xorl %esi, %esi
movl $0x18, %edx
callq 0x12110
movq $0x0, -0x48(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
leaq -0x40(%rbp), %rdx
movq -0x20(%rbp), %rcx
callq 0x2fe40
movq -0x20(%rbp), %rax
cmpl $0x0, (%rax)
je 0x30017
movq $0x0, -0x8(%rbp)
jmp 0x30192
movq -0x40(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x47d20
movq %rax, -0x48(%rbp)
movq -0x20(%rbp), %rax
cmpl $0x0, (%rax)
je 0x30036
jmp 0x30156
movq -0x40(%rbp), %rax
cmpq $0x0, 0x158(%rax)
setne %al
andb $0x1, %al
movb %al, -0x22(%rbp)
movq -0x10(%rbp), %rdi
movq -0x40(%rbp), %rsi
movq -0x38(%rbp), %rdx
movq -0x30(%rbp), %rcx
movq -0x20(%rbp), %r8
callq 0x487d0
movq $0x0, -0x40(%rbp)
movq $0x0, -0x38(%rbp)
movq $0x0, -0x30(%rbp)
movq -0x20(%rbp), %rax
cmpl $0x0, (%rax)
je 0x30089
jmp 0x30156
movq -0x48(%rbp), %rdi
callq 0x4a090
testb $0x1, %al
jne 0x3009b
jmp 0x3014c
testb $0x1, -0x22(%rbp)
jne 0x3014c
movq -0x48(%rbp), %rdi
callq 0x49ff0
xorb $-0x1, %al
andb $0x1, %al
movb %al, -0x21(%rbp)
movq -0x10(%rbp), %rax
movq 0x68(%rax), %rdi
movq -0x48(%rbp), %rsi
movq -0x20(%rbp), %rcx
xorl %eax, %eax
movl %eax, %edx
callq 0x3c920
movq %rax, -0x50(%rbp)
movq -0x20(%rbp), %rax
cmpl $0x0, (%rax)
je 0x300dd
jmp 0x30156
movq -0x10(%rbp), %rdi
movq -0x50(%rbp), %rax
movq (%rax), %rdx
movq -0x48(%rbp), %rax
movq 0x148(%rax), %rcx
movb -0x21(%rbp), %r8b
movq -0x20(%rbp), %rax
movl $0x2, %esi
movl $0x1, %r9d
andb $0x1, %r8b
movzbl %r8b, %r8d
movq %rax, (%rsp)
callq 0x6cb60
movq -0x20(%rbp), %rax
cmpl $0x0, (%rax)
je 0x30122
jmp 0x30156
movq -0x10(%rbp), %rdi
movq -0x48(%rbp), %rsi
movq -0x50(%rbp), %rax
movq (%rax), %rcx
movq -0x20(%rbp), %r8
movl $0x2, %edx
callq 0x6d540
movq -0x20(%rbp), %rax
cmpl $0x0, (%rax)
je 0x3014a
jmp 0x30156
jmp 0x3014c
movq -0x48(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x30192
movq -0x48(%rbp), %rdi
callq 0x36ee0
movq $0x0, -0x58(%rbp)
cmpq $0x3, -0x58(%rbp)
jae 0x3018a
movq -0x58(%rbp), %rax
movq -0x40(%rbp,%rax,8), %rdi
callq 0x36ee0
movq -0x58(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x58(%rbp)
jmp 0x30167
movq $0x0, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x60, %rsp
popq %rbp
retq
nopl (%rax)