Skip to content

Commit c3512a4

Browse files
committed
Handle null pointer constants of _BitInt type
1 parent de16366 commit c3512a4

File tree

3 files changed

+58
-19
lines changed

3 files changed

+58
-19
lines changed

parse.c

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,7 @@ static Node *assign(Token **rest, Token *tok);
226226
static long_double_t eval_double(Node *node);
227227
static void eval_fp(Node *node, FPVal *fval);
228228
static uint64_t *eval_bitint(Node *node);
229+
static uint64_t *eval_bitint_clean(Node *node);
229230
static Node *conditional(Token **rest, Token *tok);
230231
static Node *new_add(Node *lhs, Node *rhs, Token *tok);
231232
static Node *new_sub(Node *lhs, Node *rhs, Token *tok);
@@ -2412,9 +2413,8 @@ write_gvar_data(Relocation *cur, Initializer *init, char *buf, int offset, EvalK
24122413
}
24132414

24142415
if (init->ty->kind == TY_BITINT) {
2415-
uint64_t *data = eval_bitint(node);
2416-
if (init->ty->bit_cnt < init->ty->size * 8)
2417-
eval_bitint_sign_ext(init->ty->bit_cnt, data, init->ty->size * 8, init->ty->is_unsigned);
2416+
uint64_t *data = eval_bitint_clean(node);
2417+
24182418
memcpy(buf + offset, data, init->ty->size);
24192419
free(data);
24202420
return cur;
@@ -3538,6 +3538,23 @@ bool is_const_fp(Node *node, FPVal *fval) {
35383538
return !failed;
35393539
}
35403540

3541+
bool is_const_zero_bitint(Node *node) {
3542+
bool failed = false;
3543+
bool *prev = eval_recover;
3544+
eval_recover = &failed;
3545+
3546+
char *data = (char *)eval_bitint_clean(node);
3547+
3548+
eval_recover = prev;
3549+
if (failed)
3550+
return false;
3551+
3552+
for (int i = 0; i < node->ty->size; i++)
3553+
if (data[i] != 0)
3554+
return false;
3555+
return true;
3556+
}
3557+
35413558
static int64_t const_expr2(Token **rest, Token *tok, Type **ty) {
35423559
Node *node = conditional(rest, tok);
35433560
add_type(node);
@@ -3777,6 +3794,15 @@ static uint64_t *eval_bitint(Node *node) {
37773794
return (void *)eval_error(node);
37783795
}
37793796

3797+
static uint64_t *eval_bitint_clean(Node *node) {
3798+
uint64_t *data = eval_bitint(node);
3799+
3800+
Type *ty = node->ty;
3801+
if (ty->bit_cnt < ty->size * 8)
3802+
eval_bitint_sign_ext(ty->bit_cnt, data, ty->size * 8, ty->is_unsigned);
3803+
return data;
3804+
}
3805+
37803806
static Node *atomic_op(Node *binary, bool return_old) {
37813807
// ({
37823808
// T *addr = &obj; T old = *addr; T new;

slimcc.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ typedef struct Member Member;
9595
typedef struct Relocation Relocation;
9696
typedef struct LocalLabel LocalLabel;
9797
typedef struct EnumVal EnumVal;
98+
typedef union FPVal FPVal;
9899
typedef struct AsmContext AsmContext;
99100
typedef struct FuncObj FuncObj;
100101

@@ -647,6 +648,10 @@ Obj *parse(Token *tok);
647648
Token *skip_paren(Token *tok);
648649
Obj *new_lvar(Type *ty);
649650
bool is_const_var(Obj *var);
651+
bool is_const_expr(Node *node, int64_t *val);
652+
bool is_const_fp(Node *node, FPVal *fval);
653+
bool is_const_zero_bitint(Node *node);
654+
Obj *eval_var_opt(Node *node, int *ofs, bool let_array, bool let_atomic);
650655
bool equal_tok(Token *a, Token *b);
651656
char *new_unique_name(void);
652657
Obj *get_symbol_var(char *);
@@ -695,13 +700,13 @@ struct EnumVal {
695700
int64_t val;
696701
};
697702

698-
typedef union {
703+
union FPVal {
699704
uint64_t chunk[2];
700705
uint32_t chunk32[4];
701706
long_double_t ld;
702707
double d;
703708
float f;
704-
} FPVal;
709+
};
705710

706711
typedef enum {
707712
TY_VOID,
@@ -845,8 +850,6 @@ bool is_redundant_cast(Node *expr, Type *ty);
845850
bool is_compatible(Type *t1, Type *t2);
846851
bool is_compatible2(Type *t1, Type *t2);
847852
bool is_record_compat(Type *t1, Type *t2);
848-
bool is_const_expr(Node *node, int64_t *val);
849-
bool is_const_fp(Node *node, FPVal *fval);
850853
bool is_nullptr(Node *node);
851854
bool is_ptr(Type *ty);
852855
int next_pow_of_two(int val);
@@ -870,7 +873,6 @@ Type *new_derived_type(Type *newty, QualMask qual, Type *ty, Token *tok);
870873
Type *aligned_type(int align, Type *ty);
871874
Type *qual_type(QualMask msk, Type *ty, Token *tok);
872875
void cvqual_type(Type **ty_p, Type *ty2);
873-
Obj *eval_var_opt(Node *node, int *ofs, bool let_array, bool let_atomic);
874876
bool mem_iter(Member **mem);
875877
Node *assign_cast(Type *to, Node *expr);
876878

type.c

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -291,11 +291,11 @@ static void cast_if_not(Type *ty, Node **node) {
291291
}
292292

293293
static bool int_to_ptr(Node **node) {
294-
if (!is_integer((*node)->ty))
295-
return false;
296-
if ((*node)->ty->size != ty_nullptr->size)
294+
if (is_integer((*node)->ty) || (*node)->ty->kind == TY_BITINT) {
297295
*node = new_cast(*node, pointer_to(ty_void));
298-
return true;
296+
return true;
297+
}
298+
return false;
299299
}
300300

301301
static bool match_enum_val(EnumVal **e, int64_t val, Token *name) {
@@ -584,6 +584,9 @@ bool is_nullptr(Node *node) {
584584
node->ty->kind == TY_PTR && is_compatible2(node->ty->base, ty_void))
585585
node = node->m.lhs;
586586

587+
if (node->ty->kind == TY_BITINT)
588+
return is_const_zero_bitint(node);
589+
587590
int64_t val;
588591
return is_integer(node->ty) && is_const_expr(node, &val) && val == 0;
589592
}
@@ -643,10 +646,14 @@ static Type *cond_ptr_conv(Node **lhs, Node **rhs, Node **cond) {
643646
Type *ty1 = (*lhs)->ty;
644647
Type *ty2 = (*rhs)->ty;
645648

646-
if (ty1->kind == TY_PTR && (int_to_ptr(rhs) || is_nullptr(*rhs)))
649+
if (ty1->kind == TY_NULLPTR && ty2->kind == TY_NULLPTR)
650+
return ty_nullptr;
651+
652+
if (ty1->kind == TY_PTR && is_ptr(ty2) && is_nullptr(*rhs))
647653
return ty1;
648-
if (ty2->kind == TY_PTR && (int_to_ptr(lhs) || is_nullptr(*lhs)))
654+
if (ty2->kind == TY_PTR && is_ptr(ty1) && is_nullptr(*lhs))
649655
return ty2;
656+
650657
if (ty1->kind == TY_PTR && ty2->kind == TY_PTR) {
651658
if (ty1->base->kind == TY_VOID || ty2->base->kind == TY_VOID)
652659
return pointer_to(qual_type(ty1->base->qual | ty2->base->qual, ty_void, NULL));
@@ -656,10 +663,13 @@ static Type *cond_ptr_conv(Node **lhs, Node **rhs, Node **cond) {
656663

657664
return pointer_to(ty_void);
658665
}
659-
if (ty1->kind == TY_NULLPTR && ty2->kind == TY_NULLPTR)
660-
return ty_nullptr;
661666

662-
internal_error();
667+
if (ty1->kind == TY_PTR && int_to_ptr(rhs))
668+
return ty1;
669+
if (ty2->kind == TY_PTR && int_to_ptr(lhs))
670+
return ty2;
671+
672+
error_tok((*cond)->tok, "invalid operand");
663673
}
664674

665675
static void add_int_type(Node *node) {
@@ -785,8 +795,9 @@ void add_type(Node *node) {
785795
node->ty = ty_int;
786796
ptr_convert(&node->m.lhs);
787797
ptr_convert(&node->m.rhs);
788-
if ((is_ptr(node->m.lhs->ty) && (is_ptr(node->m.rhs->ty) || int_to_ptr(&node->m.rhs))) ||
789-
(is_ptr(node->m.rhs->ty) && (is_ptr(node->m.lhs->ty) || int_to_ptr(&node->m.lhs))))
798+
if ((is_ptr(node->m.lhs->ty) && is_ptr(node->m.rhs->ty)) ||
799+
(is_ptr(node->m.lhs->ty) && int_to_ptr(&node->m.rhs)) ||
800+
(is_ptr(node->m.rhs->ty) && int_to_ptr(&node->m.lhs)))
790801
return;
791802
usual_arith_conv(&node->m.lhs, &node->m.rhs);
792803
return;

0 commit comments

Comments
 (0)