// File: /workspace/github_c_makefile_star2_O3/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %rdx, 0x8(%rsp)
movq %rsi, %rbx
movq %rdi, %r14
movq (%rsi), %rdi
callq 0x32bf6
movq %rax, %r12
movzbl (%r14), %eax
movq %r14, %r13
cmpl $0x3, %eax
jne 0x36da0
movq 0x60(%r14), %r13
movzbl (%r13), %eax
cmpl $0xa, %eax
jne 0x36dc1
movq %r13, %rdi
callq 0x2b0b8
movq %rax, %r13
movzbl (%rax), %eax
cmpl $0x3, %eax
jne 0x36dc1
movq 0x60(%r13), %r13
movzbl (%r13), %eax
cmpl $0x9, %eax
jne 0x36dcf
movq 0x60(%r13), %r13
movzbl (%r13), %eax
cmpl $0x2, %eax
jne 0x36dea
movq 0x60(%r13), %rcx
cmpq 0x291a9(%rip), %rcx     # 0x5ff88
je 0x36df8
cmpq 0x29168(%rip), %rcx     # 0x5ff50
je 0x36dff
movl %eax, %eax
leaq 0x12dbd(%rip), %rcx     # 0x49bb0
movl (%rcx,%rax,4), %ebp
jmp 0x36e04
movl $0x1, %ebp
jmp 0x36e04
movl $0x9, %ebp
movzbl (%r12), %eax
cmpl $0x3, %eax
jne 0x36e18
movq 0x60(%r12), %r12
movzbl (%r12), %eax
cmpl $0xa, %eax
jne 0x36e3a
movq %r12, %rdi
callq 0x2b0b8
movq %rax, %r12
movzbl (%rax), %eax
cmpl $0x3, %eax
jne 0x36e3a
movq 0x60(%r12), %r12
movzbl (%r12), %eax
cmpl $0x9, %eax
jne 0x36e49
movq 0x60(%r12), %r12
movzbl (%r12), %eax
cmpl $0x2, %eax
jne 0x36e65
movq 0x60(%r12), %rcx
cmpq 0x2912e(%rip), %rcx     # 0x5ff88
je 0x36e74
cmpq 0x290ed(%rip), %rcx     # 0x5ff50
je 0x36e7c
movl %eax, %ecx
leaq 0x12d42(%rip), %rdx     # 0x49bb0
movl (%rdx,%rcx,4), %r15d
jmp 0x36e82
movl $0x1, %r15d
jmp 0x36e82
movl $0x9, %r15d
movl %ebp, %ecx
andl $0x1, %ecx
testl %r15d, %ecx
je 0x36ea1
testb $0x4, %bpl
jne 0x36eff
testb $0x4, %r15b
jne 0x36f2c
jmp 0x37129
cmpl $0x10, %ebp
jne 0x36f4b
movq (%rbx), %rdi
movq 0x10(%rdi), %rax
cmpq 0x29100(%rip), %rax     # 0x5ffb8
je 0x37129
testb $0x10, 0x1(%rdi)
je 0x36fbc
callq 0xf54a
testl %eax, %eax
je 0x36fbc
leaq 0x296e4(%rip), %rax     # 0x605c0
cmpl $0x0, (%rax)
je 0x37129
movq (%rbx), %rax
movq 0x8(%rax), %rdi
leaq 0x13041(%rip), %rsi     # 0x49f34
xorl %eax, %eax
callq 0x118fc
jmp 0x37129
testb $0x40, %r15b
je 0x36f10
cmpq %r13, 0x60(%r12)
je 0x37129
movq (%rbx), %rcx
cmpb $0x1, (%rcx)
jne 0x36f23
cmpq $0x0, 0x20(%rcx)
je 0x37129
cmpq %r13, %r12
je 0x37137
cmpq 0x290b5(%rip), %r13     # 0x5ffe8
je 0x36f70
leaq 0x12cd2(%rip), %rax     # 0x49c0e
movq 0x8(%rsp), %rcx
movq %rax, (%rcx)
xorl %eax, %eax
jmp 0x3713c
testb $0x20, %bpl
je 0x36f5f
movl $0x1, %eax
cmpq %r13, %r12
je 0x3713c
testl %ecx, %ecx
jne 0x37112
leaq 0x12fb8(%rip), %rax     # 0x49f26
jmp 0x36f3c
movq %r12, %rcx
cmpl $0x3, %eax
jne 0x36f80
movq 0x60(%r12), %rcx
movzbl (%rcx), %eax
cmpl $0x9, %eax
jne 0x36f8c
movq 0x60(%rcx), %rax
movzbl (%rax), %eax
cmpl $0xe, %eax
jne 0x37129
movq (%rbx), %r15
movq 0x60(%r12), %rdi
callq 0x237c5
movq 0x8(%r15), %rdi
leaq 0x12ee6(%rip), %rsi     # 0x49e93
movq %rax, %rdx
xorl %eax, %eax
callq 0x118fc
jmp 0x37129
testb $0x10, %r15b
je 0x36f35
movq %r13, %rdi
callq 0x2baa4
movq %rax, %r15
movq %r12, %rdi
callq 0x2baa4
movq %r15, %r8
movq 0x68(%r13), %rcx
movq 0x68(%r12), %r15
cmpq %rax, %r8
je 0x370da
cmpq 0x28f53(%rip), %r8      # 0x5ff48
je 0x37187
movq %rax, %rbp
cmpq 0x28f43(%rip), %rax     # 0x5ff48
je 0x37187
movzbl (%r8), %eax
movq %r8, %rdi
cmpl $0x3, %eax
jne 0x3701e
movq 0x60(%r8), %rdi
movzbl (%rdi), %eax
cmpl $0xa, %eax
jne 0x3704e
movq %r8, 0x10(%rsp)
movq %rcx, 0x18(%rsp)
callq 0x2b0b8
movq %rax, %rdi
movzbl (%rax), %eax
cmpl $0x3, %eax
jne 0x37044
movq 0x60(%rdi), %rdi
movzbl (%rdi), %eax
movq 0x18(%rsp), %rcx
movq 0x10(%rsp), %r8
cmpl $0x9, %eax
jne 0x3705a
movq 0x60(%rdi), %rdi
movzbl (%rdi), %eax
cmpl $0x2, %eax
jne 0x370da
movq 0x60(%rdi), %rax
cmpq 0x28f1e(%rip), %rax     # 0x5ff88
jne 0x370da
movzbl (%rbp), %eax
cmpl $0x3, %eax
jne 0x3707d
movq 0x60(%rbp), %rbp
movzbl (%rbp), %eax
cmpl $0xa, %eax
jne 0x370bb
movq %rdi, 0x20(%rsp)
movq %r8, 0x10(%rsp)
movq %rcx, 0x18(%rsp)
movq %rbp, %rdi
callq 0x2b0b8
movq %rax, %rbp
movzbl (%rax), %eax
cmpl $0x3, %eax
jne 0x370ac
movq 0x60(%rbp), %rbp
movzbl (%rbp), %eax
movq 0x18(%rsp), %rcx
movq 0x10(%rsp), %r8
movq 0x20(%rsp), %rdi
cmpl $0x9, %eax
jne 0x370c8
movq 0x60(%rbp), %rbp
movzbl (%rbp), %eax
cmpl $0x2, %eax
jne 0x370da
movq 0x60(%rbp), %rax
cmpq 0x28eb0(%rip), %rax     # 0x5ff88
je 0x3714b
andl $0xe00, %ecx            # imm = 0xE00
andl $0x11000000, %r15d      # imm = 0x11000000
addq $0x60, %r13
addq $0x60, %r12
movq %r13, %rdi
movq %r12, %rsi
movq %r15, %rdx
callq 0x31898
movq %rax, %rcx
movq 0x8(%rsp), %rax
movq %rcx, (%rax)
xorl %eax, %eax
testq %rcx, %rcx
sete %al
jmp 0x3713c
cmpq 0x28ecf(%rip), %r13     # 0x5ffe8
jne 0x36f35
andl $0x10, %r15d
je 0x36f35
movq (%rbx), %rdi
movq %r14, %rsi
callq 0x32aa9
movq %rax, (%rbx)
movl $0x1, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
cmpq %rbp, %rdi
je 0x37187
movl 0x54(%rdi), %edi
movl $0x3800000, %edx        # imm = 0x3800000
movl %edi, %esi
andl %edx, %esi
movl 0x54(%rbp), %eax
cmpl $0x3000000, %esi        # imm = 0x3000000
jne 0x37171
andl %eax, %edx
cmpl $0x3000000, %edx        # imm = 0x3000000
je 0x37187
xorl %edi, %eax
andl $0x3800000, %eax        # imm = 0x3800000
leaq 0x2fcc1(%rip), %rdx     # 0x66e40
orl (%rdx), %eax
jne 0x370da
movq 0x80(%r13), %rax
cmpq 0x80(%r12), %rax
je 0x371a4
leaq 0x12aac(%rip), %rax     # 0x49c4b
jmp 0x36f3c
andl $0xe00, %r15d           # imm = 0xE00
movl %ecx, %eax
orl $0x200, %eax            # imm = 0x200
cmpb $0x5, (%r8)
cmovnel %ecx, %eax
notl %eax
testl %eax, %r15d
je 0x37129
leaq 0x12a99(%rip), %rax     # 0x49c64
jmp 0x36f3c