mirror of
https://github.com/mirror/tinycc.git
synced 2025-02-26 08:00:09 +08:00
Fix type completion for array types as well
like qualifier merging the array sizes are merged as well for the operands of ?:, and they must not statically influence the types of decls. Also fix some style problems, spaces aren't stinky :)
This commit is contained in:
parent
f7779efe58
commit
c4787e3626
81
tccgen.c
81
tccgen.c
@ -2097,8 +2097,8 @@ static inline int is_null_pointer(SValue *p)
|
||||
((p->type.t & VT_BTYPE) == VT_LLONG && p->c.i == 0) ||
|
||||
((p->type.t & VT_BTYPE) == VT_PTR &&
|
||||
(PTR_SIZE == 4 ? (uint32_t)p->c.i == 0 : p->c.i == 0) &&
|
||||
((pointed_type(&p->type)->t&VT_BTYPE)==VT_VOID) &&
|
||||
0==(pointed_type(&p->type)->t&(VT_CONSTANT|VT_VOLATILE))
|
||||
((pointed_type(&p->type)->t & VT_BTYPE) == VT_VOID) &&
|
||||
0 == (pointed_type(&p->type)->t & (VT_CONSTANT | VT_VOLATILE))
|
||||
);
|
||||
}
|
||||
static inline int is_integer_btype(int bt)
|
||||
@ -2823,7 +2823,7 @@ static int compare_types(CType *type1, CType *type2, int unqualified)
|
||||
if (t1 != t2)
|
||||
return 0;
|
||||
/* test more complicated cases */
|
||||
bt1 = t1 & (VT_BTYPE | (unqualified ? 0 : VT_ARRAY) );
|
||||
bt1 = t1 & (VT_BTYPE | VT_ARRAY);
|
||||
if (bt1 == VT_PTR) {
|
||||
type1 = pointed_type(type1);
|
||||
type2 = pointed_type(type2);
|
||||
@ -5565,10 +5565,9 @@ static void expr_cond(void)
|
||||
if (!g)
|
||||
gexpr();
|
||||
|
||||
if ( ((type1=vtop->type).t&VT_BTYPE)==VT_FUNC ) {
|
||||
if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
|
||||
mk_pointer(&vtop->type);
|
||||
type1=vtop->type;
|
||||
}
|
||||
type1 = vtop->type;
|
||||
sv = *vtop; /* save value to handle it later */
|
||||
vtop--; /* no vpop so that FP stack is not flushed */
|
||||
skip(':');
|
||||
@ -5586,10 +5585,9 @@ static void expr_cond(void)
|
||||
if (c == 1)
|
||||
nocode_wanted--;
|
||||
|
||||
if ( ((type2=vtop->type).t&VT_BTYPE)==VT_FUNC ) {
|
||||
if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
|
||||
mk_pointer(&vtop->type);
|
||||
type2=vtop->type;
|
||||
}
|
||||
type2=vtop->type;
|
||||
t1 = type1.t;
|
||||
bt1 = t1 & VT_BTYPE;
|
||||
t2 = type2.t;
|
||||
@ -5600,7 +5598,7 @@ static void expr_cond(void)
|
||||
/* cast operands to correct type according to ISOC rules */
|
||||
if (bt1 == VT_VOID || bt2 == VT_VOID) {
|
||||
type.t = VT_VOID; /* NOTE: as an extension, we accept void on only one side */
|
||||
}else if (is_float(bt1) || is_float(bt2)) {
|
||||
} else if (is_float(bt1) || is_float(bt2)) {
|
||||
if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
|
||||
type.t = VT_LDOUBLE;
|
||||
|
||||
@ -5626,33 +5624,48 @@ static void expr_cond(void)
|
||||
is the other. */
|
||||
if (is_null_pointer (vtop)) type = type1;
|
||||
else if (is_null_pointer (&sv)) type = type2;
|
||||
else{
|
||||
int pbt1, pbt2;
|
||||
if (bt1!=bt2)
|
||||
tcc_error("incompatible types in conditional expressions");
|
||||
pbt1 = (pointed_type(&type1)->t&VT_BTYPE);
|
||||
pbt2 = (pointed_type(&type2)->t&VT_BTYPE);
|
||||
/*pointers to void get preferred, otherwise the pointed to types minus qualifs should be compatible*/
|
||||
type = (pbt1==VT_VOID) ? type1 : type2;
|
||||
if (pbt1!=VT_VOID && pbt2!=VT_VOID){
|
||||
if(!compare_types(pointed_type(&type1), pointed_type(&type2),1/*unqualif*/))
|
||||
else if (bt1 != bt2)
|
||||
tcc_error("incompatible types in conditional expressions");
|
||||
else {
|
||||
CType *pt1 = pointed_type(&type1);
|
||||
CType *pt2 = pointed_type(&type2);
|
||||
int pbt1 = pt1->t & VT_BTYPE;
|
||||
int pbt2 = pt2->t & VT_BTYPE;
|
||||
int newquals, copied = 0;
|
||||
/* pointers to void get preferred, otherwise the
|
||||
pointed to types minus qualifs should be compatible */
|
||||
type = (pbt1 == VT_VOID) ? type1 : type2;
|
||||
if (pbt1 != VT_VOID && pbt2 != VT_VOID) {
|
||||
if(!compare_types(pt1, pt2, 1/*unqualif*/))
|
||||
tcc_warning("pointer type mismatch in conditional expression\n");
|
||||
}
|
||||
{ /*copy the pointer target symbol*/
|
||||
Sym *s;
|
||||
s = sym_push(SYM_FIELD, pointed_type(&type), 0, -1);
|
||||
type.t = VT_PTR | (type.t & VT_STORAGE);
|
||||
type.ref = s;
|
||||
}
|
||||
/*qualifs combine*/
|
||||
pointed_type(&type)->t |= 0
|
||||
|(pointed_type(&type1)->t&(VT_CONSTANT|VT_VOLATILE))
|
||||
|(pointed_type(&type2)->t&(VT_CONSTANT|VT_VOLATILE));
|
||||
/*pointers to incomplete arrays get converted to pointers to completed ones if possible*/
|
||||
if ( (pointed_type(&type1)->t&VT_ARRAY) )
|
||||
/* combine qualifs */
|
||||
newquals = ((pt1->t | pt2->t) & (VT_CONSTANT | VT_VOLATILE));
|
||||
if ((~pointed_type(&type)->t & (VT_CONSTANT | VT_VOLATILE))
|
||||
& newquals)
|
||||
{
|
||||
/* copy the pointer target symbol */
|
||||
type.ref = sym_push(SYM_FIELD, &type.ref->type,
|
||||
0, type.ref->c);
|
||||
copied = 1;
|
||||
pointed_type(&type)->t |= newquals;
|
||||
}
|
||||
/* pointers to incomplete arrays get converted to
|
||||
pointers to completed ones if possible */
|
||||
if (pt1->t & VT_ARRAY
|
||||
&& pt2->t & VT_ARRAY
|
||||
&& pointed_type(&type)->ref->c < 0
|
||||
&& (pt1->ref->c > 0 || pt2->ref->c > 0))
|
||||
{
|
||||
if (!copied)
|
||||
type.ref = sym_push(SYM_FIELD, &type.ref->type,
|
||||
0, type.ref->c);
|
||||
pointed_type(&type)->ref =
|
||||
sym_push(SYM_FIELD, &pointed_type(&type)->ref->type,
|
||||
0, pointed_type(&type)->ref->c);
|
||||
pointed_type(&type)->ref->c =
|
||||
0<pointed_type(&type1)->ref->c ?
|
||||
pointed_type(&type1)->ref->c : pointed_type(&type2)->ref->c;
|
||||
0 < pt1->ref->c ? pt1->ref->c : pt2->ref->c;
|
||||
}
|
||||
}
|
||||
} else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
|
||||
/* XXX: test structure compatibility */
|
||||
|
@ -96,11 +96,20 @@ int main()
|
||||
(void)(sizeof(struct { int x:_Generic( 0?(int (*)[])0 : (int (*)[4])0, int (*)[4]:+1, int (*)[5]:(void)0); }));
|
||||
|
||||
{
|
||||
/* completion shouldn't affect the type of decl */
|
||||
char **argv;
|
||||
_Generic(argv, char**: (void)0);
|
||||
_Generic(0?(char const*)0:argv[0], char const*: (void)0);
|
||||
_Generic(argv, char**: (void)0);
|
||||
}
|
||||
{
|
||||
extern int (*ar)[];
|
||||
(void)(sizeof(struct { int x:_Generic( 0?(int (*)[4])0 : (int (*)[])0, int (*)[4]:+1, int (*)[5]:(void)0); }));
|
||||
(void)(sizeof(struct { int x:_Generic( 0?(int (*)[])0 : (int (*)[4])0, int (*)[4]:+1, int (*)[5]:(void)0); }));
|
||||
(void)(sizeof(struct { int x:_Generic( 0?ar : (int (*)[4])0, int (*)[4]:+1, int (*)[5]:(void)0); }));
|
||||
(void)(sizeof(struct { int x:_Generic( 0?(int (*)[4])0 : ar, int (*)[4]:+1, int (*)[5]:(void)0); }));
|
||||
(void)(sizeof(struct { int x:_Generic( 0?(int (*)[5])0 : ar, int (*)[5]:+1, int (*)[4]:(void)0); }));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user