Skip to content

Commit aff7dfb

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

File tree

3 files changed

+39
-8
lines changed

3 files changed

+39
-8
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: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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
}

0 commit comments

Comments
 (0)