// File: /workspace/github_c_makefile_star2_O0/lucvoo[P]sparse-dev/evaluate.c
// Function: check_assignment_types
static int check_assignment_types(struct symbol *target, struct expression **rp,
	const char **typediff)
{
	struct symbol *source = degenerate(*rp);
	struct symbol *t, *s;
	int tclass = classify_type(target, &t);
	int sclass = classify_type(source, &s);

	if (tclass & sclass & TYPE_NUM) {
		if (tclass & TYPE_RESTRICT) {
			/* allowed assignments unfoul */
			if (sclass & TYPE_FOULED && unfoul(s) == t)
				goto Cast;
			if (!restricted_value(*rp, target))
				goto Cast;
			if (s == t)
				return 1;
		} else if (!(sclass & TYPE_RESTRICT))
			goto Cast;
                if (t == &bool_ctype) {
                        if (is_fouled_type(s))
                                warning((*rp)->pos, "%s degrades to integer",
                                        show_typename(s->ctype.base_type));
                        goto Cast;
                }
		*typediff = "different base types";
		return 0;
	}

	if (tclass == TYPE_PTR) {
		unsigned long mod1, mod2;
		unsigned long modl, modr;
		struct symbol *b1, *b2;
		// NULL pointer is always OK
		int is_null = is_null_pointer_constant(*rp);
		if (is_null) {
			if (is_null == NULL_ZERO)
				bad_null(*rp);
			goto Cast;
		}
		if (!(sclass & TYPE_PTR)) {
			*typediff = "different base types";
			return 0;
		}
		b1 = examine_pointer_target(t);
		b2 = examine_pointer_target(s);
		mod1 = t->ctype.modifiers & MOD_IGN;
		mod2 = s->ctype.modifiers & MOD_IGN;
		if (whitelist_pointers(b1, b2)) {
			/*
			 * assignments to/from void * are OK, provided that
			 * we do not remove qualifiers from pointed to [C]
			 * or mix address spaces [sparse].
			 */
			if (t->ctype.as != s->ctype.as) {
				*typediff = "different address spaces";
				return 0;
			}
			/*
			 * If this is a function pointer assignment, it is
			 * actually fine to assign a pointer to const data to
			 * it, as a function pointer points to const data
			 * implicitly, i.e., dereferencing it does not produce
			 * an lvalue.
			 */
			if (b1->type == SYM_FN)
				mod1 |= MOD_CONST;
			if (mod2 & ~mod1 & ~MOD_FUN_ATTR) {
				*typediff = "different modifiers";
				return 0;
			}
			goto Cast;
		}
		/* It's OK if the target is more volatile or const than the source */
		/* It's OK if the source is more pure/noreturn than the target */
		modr = mod1 & ~MOD_REV_QUAL;
		modl = mod2 &  MOD_REV_QUAL;
		*typediff = type_difference(&t->ctype, &s->ctype, modl, modr);
		if (*typediff)
			return 0;
		return 1;
	}

	if ((tclass & TYPE_COMPOUND) && s == t)
		return 1;

	if (tclass & TYPE_NUM) {
		/* XXX: need to turn into comparison with NULL */
		if (t == &bool_ctype && (sclass & TYPE_PTR))
			goto Cast;
		*typediff = "different base types";
		return 0;
	}
	*typediff = "invalid types";
	return 0;

Cast:
	*rp = cast_to(*rp, target);
	return 1;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x80, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq -0x18(%rbp), %rax
movq (%rax), %rdi
callq 0x4c1c0
movq %rax, -0x28(%rbp)
movq -0x10(%rbp), %rdi
leaq -0x30(%rbp), %rsi
callq 0x4bf20
movl %eax, -0x3c(%rbp)
movq -0x28(%rbp), %rdi
leaq -0x38(%rbp), %rsi
callq 0x4bf20
movl %eax, -0x40(%rbp)
movl -0x3c(%rbp), %eax
andl -0x40(%rbp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x519d2
movl -0x3c(%rbp), %eax
andl $0x4, %eax
cmpl $0x0, %eax
je 0x51955
movl -0x40(%rbp), %eax
andl $0x40, %eax
cmpl $0x0, %eax
je 0x51923
movq -0x38(%rbp), %rdi
callq 0x512d0
cmpq -0x30(%rbp), %rax
jne 0x51923
jmp 0x51be9
movq -0x18(%rbp), %rax
movq (%rax), %rdi
movq -0x10(%rbp), %rsi
callq 0x512f0
cmpl $0x0, %eax
jne 0x5193d
jmp 0x51be9
movq -0x38(%rbp), %rax
cmpq -0x30(%rbp), %rax
jne 0x51953
movl $0x1, -0x4(%rbp)
jmp 0x51c0a
jmp 0x51967
movl -0x40(%rbp), %eax
andl $0x4, %eax
cmpl $0x0, %eax
jne 0x51965
jmp 0x51be9
jmp 0x51967
leaq 0x3faaa(%rip), %rax     # 0x91418
cmpq %rax, -0x30(%rbp)
jne 0x519b8
movq -0x38(%rbp), %rdi
callq 0x51c20
cmpl $0xe, %eax
jne 0x519b3
movq -0x18(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x80(%rbp)
movq -0x38(%rbp), %rax
movq 0x60(%rax), %rdi
callq 0x33340
movq %rax, %rdx
movq -0x80(%rbp), %rax
movq 0x8(%rax), %rdi
leaq 0x1a207(%rip), %rsi     # 0x6bbb3
movb $0x0, %al
callq 0x16d80
jmp 0x51be9
movq -0x20(%rbp), %rax
leaq 0x19f6b(%rip), %rcx     # 0x6b92e
movq %rcx, (%rax)
movl $0x0, -0x4(%rbp)
jmp 0x51c0a
cmpl $0x10, -0x3c(%rbp)
jne 0x51b78
movq -0x18(%rbp), %rax
movq (%rax), %rdi
callq 0x51c70
movl %eax, -0x74(%rbp)
cmpl $0x0, -0x74(%rbp)
je 0x51a08
cmpl $0x2, -0x74(%rbp)
jne 0x51a03
movq -0x18(%rbp), %rax
movq (%rax), %rdi
callq 0x51ce0
jmp 0x51be9
movl -0x40(%rbp), %eax
andl $0x10, %eax
cmpl $0x0, %eax
jne 0x51a2d
movq -0x20(%rbp), %rax
leaq 0x19f10(%rip), %rcx     # 0x6b92e
movq %rcx, (%rax)
movl $0x0, -0x4(%rbp)
jmp 0x51c0a
movq -0x30(%rbp), %rdi
callq 0x40260
movq %rax, -0x68(%rbp)
movq -0x38(%rbp), %rdi
callq 0x40260
movq %rax, -0x70(%rbp)
movq -0x30(%rbp), %rax
movq 0x68(%rax), %rax
andq $0x11000e00, %rax       # imm = 0x11000E00
movq %rax, -0x48(%rbp)
movq -0x38(%rbp), %rax
movq 0x68(%rax), %rax
andq $0x11000e00, %rax       # imm = 0x11000E00
movq %rax, -0x50(%rbp)
movq -0x68(%rbp), %rdi
movq -0x70(%rbp), %rsi
callq 0x51d20
cmpl $0x0, %eax
je 0x51b0b
movq -0x30(%rbp), %rax
movq 0x80(%rax), %rax
movq -0x38(%rbp), %rcx
cmpq 0x80(%rcx), %rax
je 0x51ab3
movq -0x20(%rbp), %rax
leaq 0x19ec7(%rip), %rcx     # 0x6b96b
movq %rcx, (%rax)
movl $0x0, -0x4(%rbp)
jmp 0x51c0a
movq -0x68(%rbp), %rax
movl (%rax), %eax
andl $0xff, %eax
cmpl $0x5, %eax
jne 0x51ad1
movq -0x48(%rbp), %rax
orq $0x200, %rax            # imm = 0x200
movq %rax, -0x48(%rbp)
movq -0x50(%rbp), %rax
movq -0x48(%rbp), %rcx
xorq $-0x1, %rcx
andq %rcx, %rax
andq $-0x11000001, %rax      # imm = 0xEEFFFFFF
cmpq $0x0, %rax
je 0x51b06
movq -0x20(%rbp), %rax
leaq 0x19e8d(%rip), %rcx     # 0x6b984
movq %rcx, (%rax)
movl $0x0, -0x4(%rbp)
jmp 0x51c0a
jmp 0x51be9
movq -0x48(%rbp), %rax
andq $-0x11000001, %rax      # imm = 0xEEFFFFFF
movq %rax, -0x60(%rbp)
movq -0x50(%rbp), %rax
andq $0x11000000, %rax       # imm = 0x11000000
movq %rax, -0x58(%rbp)
movq -0x30(%rbp), %rdi
addq $0x48, %rdi
addq $0x18, %rdi
movq -0x38(%rbp), %rsi
addq $0x48, %rsi
addq $0x18, %rsi
movq -0x58(%rbp), %rdx
movq -0x60(%rbp), %rcx
callq 0x4ad70
movq %rax, %rcx
movq -0x20(%rbp), %rax
movq %rcx, (%rax)
movq -0x20(%rbp), %rax
cmpq $0x0, (%rax)
je 0x51b6c
movl $0x0, -0x4(%rbp)
jmp 0x51c0a
movl $0x1, -0x4(%rbp)
jmp 0x51c0a
movl -0x3c(%rbp), %eax
andl $0x20, %eax
cmpl $0x0, %eax
je 0x51b96
movq -0x38(%rbp), %rax
cmpq -0x30(%rbp), %rax
jne 0x51b96
movl $0x1, -0x4(%rbp)
jmp 0x51c0a
movl -0x3c(%rbp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x51bd2
leaq 0x3f870(%rip), %rax     # 0x91418
cmpq %rax, -0x30(%rbp)
jne 0x51bbb
movl -0x40(%rbp), %eax
andl $0x10, %eax
cmpl $0x0, %eax
je 0x51bbb
jmp 0x51be9
movq -0x20(%rbp), %rax
leaq 0x19d68(%rip), %rcx     # 0x6b92e
movq %rcx, (%rax)
movl $0x0, -0x4(%rbp)
jmp 0x51c0a
movq -0x20(%rbp), %rax
leaq 0x1a069(%rip), %rcx     # 0x6bc46
movq %rcx, (%rax)
movl $0x0, -0x4(%rbp)
jmp 0x51c0a
movq -0x18(%rbp), %rax
movq (%rax), %rdi
movq -0x10(%rbp), %rsi
callq 0x4c020
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, (%rax)
movl $0x1, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x80, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)