Various corner cases for declarator parsing were incorrect. This reorganizes and fixes it, and somewhat simplifies it as well.
Unified · Split
| @@ -74,7 +74,7 @@ static void gen_cast(CType *type); · 73 unmodified lines | ||
| 74 | 74 | static inline CType *pointed_type(CType *type); |
| 75 | 75 | static int is_compatible_types(CType *type1, CType *type2); |
| 76 | 76 | static int parse_btype(CType *type, AttributeDef *ad); |
| 77 | −static void type_decl(CType *type, AttributeDef *ad, int *v, int td); | |
| 77 | +static CType *type_decl(CType *type, AttributeDef *ad, int *v, int td); | |
| 78 | 78 | static void parse_expr_type(CType *type); |
| 79 | 79 | static void decl_initializer(CType *type, Section *sec, unsigned long c, int first, int size_only); |
| 80 | 80 | static void block(int *bsym, int *csym, int is_expr); |
| @@ -3586,7 +3586,8 @@ static void struct_decl(CType *type, AttributeDef *ad, int u) · 3505 unmodified lines | ||
| 3586 | 3586 | v = 0; |
| 3587 | 3587 | type1 = btype; |
| 3588 | 3588 | if (tok != ':') { |
| 3589 | − type_decl(&type1, &ad1, &v, TYPE_DIRECT | TYPE_ABSTRACT); | |
| 3589 | + if (tok != ';') | |
| 3590 | + type_decl(&type1, &ad1, &v, TYPE_DIRECT); | |
| 3590 | 3591 | if (v == 0) { |
| 3591 | 3592 | if ((type1.t & VT_BTYPE) != VT_STRUCT) |
| 3592 | 3593 | expect("identifier"); |
| @@ -3964,7 +3965,7 @@ static int asm_label_instr(void) · 371 unmodified lines | ||
| 3964 | 3965 | return v; |
| 3965 | 3966 | } |
| 3966 | 3967 | |
| 3967 | −static void post_type(CType *type, AttributeDef *ad, int storage) | |
| 3968 | +static int post_type(CType *type, AttributeDef *ad, int storage, int td) | |
| 3968 | 3969 | { |
| 3969 | 3970 | int n, l, t1, arg_size, align; |
| 3970 | 3971 | Sym **plast, *s, *first; |
| @@ -3972,25 +3973,25 @@ static void post_type(CType *type, AttributeDef *ad, int storage) · 1 unmodified line | ||
| 3972 | 3973 | CType pt; |
| 3973 | 3974 | |
| 3974 | 3975 | if (tok == '(') { |
| 3975 | − /* function declaration */ | |
| 3976 | + /* function type, or recursive declarator (return if so) */ | |
| 3976 | 3977 | next(); |
| 3977 | − l = 0; | |
| 3978 | + if (td && !(td & TYPE_ABSTRACT)) | |
| 3979 | + return 0; | |
| 3980 | + if (tok == ')') | |
| 3981 | + l = 0; | |
| 3982 | + else if (parse_btype(&pt, &ad1)) | |
| 3983 | + l = FUNC_NEW; | |
| 3984 | + else if (td) | |
| 3985 | + return 0; | |
| 3986 | + else | |
| 3987 | + l = FUNC_OLD; | |
| 3978 | 3988 | first = NULL; |
| 3979 | 3989 | plast = &first; |
| 3980 | 3990 | arg_size = 0; |
| 3981 | − if (tok != ')') { | |
| 3991 | + if (l) { | |
| 3982 | 3992 | for(;;) { |
| 3983 | 3993 | /* read param name and compute offset */ |
| 3984 | 3994 | if (l != FUNC_OLD) { |
| 3985 | − if (!parse_btype(&pt, &ad1)) { | |
| 3986 | − if (l) { | |
| 3987 | − tcc_error("invalid type"); | |
| 3988 | − } else { | |
| 3989 | − l = FUNC_OLD; | |
| 3990 | − goto old_proto; | |
| 3991 | − } | |
| 3992 | − } | |
| 3993 | − l = FUNC_NEW; | |
| 3994 | 3995 | if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')') |
| 3995 | 3996 | break; |
| 3996 | 3997 | type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT); |
| @@ -3998,7 +3999,6 @@ static void post_type(CType *type, AttributeDef *ad, int storage) · 1 unmodified line | ||
| 3998 | 3999 | tcc_error("parameter declared as void"); |
| 3999 | 4000 | arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE; |
| 4000 | 4001 | } else { |
| 4001 | − old_proto: | |
| 4002 | 4002 | n = tok; |
| 4003 | 4003 | if (n < TOK_UIDENT) |
| 4004 | 4004 | expect("identifier"); |
| @@ -4017,10 +4017,11 @@ static void post_type(CType *type, AttributeDef *ad, int storage) · 12 unmodified lines | ||
| 4017 | 4017 | next(); |
| 4018 | 4018 | break; |
| 4019 | 4019 | } |
| 4020 | + if (l == FUNC_NEW && !parse_btype(&pt, &ad1)) | |
| 4021 | + tcc_error("invalid type"); | |
| 4020 | 4022 | } |
| 4021 | − } | |
| 4022 | − /* if no parameters, then old type prototype */ | |
| 4023 | − if (l == 0) | |
| 4023 | + } else | |
| 4024 | + /* if no parameters, then old type prototype */ | |
| 4024 | 4025 | l = FUNC_OLD; |
| 4025 | 4026 | skip(')'); |
| 4026 | 4027 | /* NOTE: const is ignored in returned type as it has a special |
| @@ -4072,7 +4073,7 @@ static void post_type(CType *type, AttributeDef *ad, int storage) · 45 unmodified lines | ||
| 4072 | 4073 | } |
| 4073 | 4074 | skip(']'); |
| 4074 | 4075 | /* parse next post type */ |
| 4075 | − post_type(type, ad, storage); | |
| 4076 | + post_type(type, ad, storage, 0); | |
| 4076 | 4077 | if (type->t == VT_FUNC) |
| 4077 | 4078 | tcc_error("declaration of an array of functions"); |
| 4078 | 4079 | t1 |= type->t & VT_VLA; |
| @@ -4098,20 +4099,25 @@ static void post_type(CType *type, AttributeDef *ad, int storage) · 19 unmodified lines | ||
| 4098 | 4099 | type->t = (t1 ? VT_VLA : VT_ARRAY) | VT_PTR; |
| 4099 | 4100 | type->ref = s; |
| 4100 | 4101 | } |
| 4102 | + return 1; | |
| 4101 | 4103 | } |
| 4102 | 4104 | |
| 4103 | −/* Parse a type declaration (except basic type), and return the type | |
| 4105 | +/* Parse a type declarator (except basic type), and return the type | |
| 4104 | 4106 | in 'type'. 'td' is a bitmask indicating which kind of type decl is |
| 4105 | 4107 | expected. 'type' should contain the basic type. 'ad' is the |
| 4106 | 4108 | attribute definition of the basic type. It can be modified by |
| 4107 | − type_decl(). | |
| 4108 | − */ | |
| 4109 | −static void type_decl(CType *type, AttributeDef *ad, int *v, int td) | |
| 4109 | + type_decl(). If this (possibly abstract) declarator is a pointer chain | |
| 4110 | + it returns the innermost pointed to type (equals *type, but is a different | |
| 4111 | + pointer), otherwise returns type itself, that's used for recursive calls. */ | |
| 4112 | +static CType *type_decl(CType *type, AttributeDef *ad, int *v, int td) | |
| 4110 | 4113 | { |
| 4111 | − Sym *s; | |
| 4112 | − CType type1, *type2; | |
| 4114 | + CType *post, *ret; | |
| 4113 | 4115 | int qualifiers, storage; |
| 4114 | 4116 | |
| 4117 | + /* recursive type, remove storage bits first, apply them later again */ | |
| 4118 | + storage = type->t & VT_STORAGE; | |
| 4119 | + type->t &= ~VT_STORAGE; | |
| 4120 | + post = ret = type; | |
| 4115 | 4121 | while (tok == '*') { |
| 4116 | 4122 | qualifiers = 0; |
| 4117 | 4123 | redo: |
| @@ -4139,51 +4145,38 @@ static void type_decl(CType *type, AttributeDef *ad, int *v, int td) · 21 unmodified lines | ||
| 4139 | 4145 | } |
| 4140 | 4146 | mk_pointer(type); |
| 4141 | 4147 | type->t |= qualifiers; |
| 4148 | + if (ret == type) | |
| 4149 | + /* innermost pointed to type is the one for the first derivation */ | |
| 4150 | + ret = pointed_type(type); | |
| 4142 | 4151 | } |
| 4143 | 4152 | |
| 4144 | − /* recursive type */ | |
| 4145 | − /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */ | |
| 4146 | − type1.t = 0; /* XXX: same as int */ | |
| 4147 | 4153 | if (tok == '(') { |
| 4148 | − next(); | |
| 4149 | − /* XXX: this is not correct to modify 'ad' at this point, but | |
| 4150 | − the syntax is not clear */ | |
| 4151 | − if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) | |
| 4152 | − parse_attribute(ad); | |
| 4153 | − type_decl(&type1, ad, v, td); | |
| 4154 | − skip(')'); | |
| 4154 | + /* This is possibly a parameter type list for abstract declarators | |
| 4155 | + ('int ()'), use post_type for testing this. */ | |
| 4156 | + if (!post_type(type, ad, 0, td)) { | |
| 4157 | + /* It's not, so it's a nested declarator, and the post operations | |
| 4158 | + apply to the innermost pointed to type (if any). */ | |
| 4159 | + /* XXX: this is not correct to modify 'ad' at this point, but | |
| 4160 | + the syntax is not clear */ | |
| 4161 | + if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) | |
| 4162 | + parse_attribute(ad); | |
| 4163 | + post = type_decl(type, ad, v, td); | |
| 4164 | + skip(')'); | |
| 4165 | + } | |
| 4166 | + } else if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) { | |
| 4167 | + /* type identifier */ | |
| 4168 | + *v = tok; | |
| 4169 | + next(); | |
| 4155 | 4170 | } else { |
| 4156 | − /* type identifier */ | |
| 4157 | − if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) { | |
| 4158 | − *v = tok; | |
| 4159 | − next(); | |
| 4160 | − } else { | |
| 4161 | − if (!(td & TYPE_ABSTRACT)) | |
| 4162 | − expect("identifier"); | |
| 4163 | − *v = 0; | |
| 4164 | − } | |
| 4171 | + if (!(td & TYPE_ABSTRACT)) | |
| 4172 | + expect("identifier"); | |
| 4173 | + *v = 0; | |
| 4165 | 4174 | } |
| 4166 | − storage = type->t & VT_STORAGE; | |
| 4167 | − type->t &= ~VT_STORAGE; | |
| 4168 | − post_type(type, ad, storage); | |
| 4169 | − type->t |= storage; | |
| 4175 | + post_type(post, ad, storage, 0); | |
| 4170 | 4176 | if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) |
| 4171 | 4177 | parse_attribute(ad); |
| 4172 | − | |
| 4173 | − if (!type1.t) | |
| 4174 | − return; | |
| 4175 | − /* append type at the end of type1 */ | |
| 4176 | − type2 = &type1; | |
| 4177 | − for(;;) { | |
| 4178 | − s = type2->ref; | |
| 4179 | − type2 = &s->type; | |
| 4180 | − if (!type2->t) { | |
| 4181 | − *type2 = *type; | |
| 4182 | − break; | |
| 4183 | − } | |
| 4184 | − } | |
| 4185 | − *type = type1; | |
| 4186 | 4178 | type->t |= storage; |
| 4179 | + return ret; | |
| 4187 | 4180 | } |
| 4188 | 4181 | |
| 4189 | 4182 | /* compute the lvalue VT_LVAL_xxx needed to match type t. */ |
| @@ -6924,7 +6917,7 @@ static int decl0(int l, int is_for_loop_init) · 2734 unmodified lines | ||
| 6924 | 6917 | #if 0 |
| 6925 | 6918 | { |
| 6926 | 6919 | char buf[500]; |
| 6927 | − type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL)); | |
| 6920 | + type_to_str(buf, sizeof(buf), &type, get_tok_str(v, NULL)); | |
| 6928 | 6921 | printf("type = '%s'\n", buf); |
| 6929 | 6922 | } |
| 6930 | 6923 | #endif |
| @@ -6,4 +6,38 @@ enum E const *e2; · 5 unmodified lines | ||
| 6 | 6 | struct S *s; |
| 7 | 7 | const struct S *s1; |
| 8 | 8 | struct S const *s2; |
| 9 | + | |
| 10 | +/* Various strangely looking declarators, which are all valid | |
| 11 | + and have to map to the same numbered typedefs. */ | |
| 12 | +typedef int (*fptr1)(); | |
| 13 | +int f1 (int (), int); | |
| 14 | +typedef int (*fptr2)(int x); | |
| 15 | +int f2 (int (int x), int); | |
| 16 | +typedef int (*fptr3)(int); | |
| 17 | +int f3 (int (int), int); | |
| 18 | +typedef int (*fptr4[4])(int); | |
| 19 | +int f4 (int (*[4])(int), int); | |
| 20 | +typedef int (*fptr5)(fptr1); | |
| 21 | +int f5 (int (int()), fptr1); | |
| 22 | +int f1 (fptr1 fp, int i) | |
| 23 | +{ | |
| 24 | + return (*fp)(i); | |
| 25 | +} | |
| 26 | +int f2 (fptr2 fp, int i) | |
| 27 | +{ | |
| 28 | + return (*fp)(i); | |
| 29 | +} | |
| 30 | +int f3 (fptr3 fp, int i) | |
| 31 | +{ | |
| 32 | + return (*fp)(i); | |
| 33 | +} | |
| 34 | +int f4 (fptr4 fp, int i) | |
| 35 | +{ | |
| 36 | + return (*fp[i])(i); | |
| 37 | +} | |
| 38 | +int f5 (fptr5 fp, fptr1 i) | |
| 39 | +{ | |
| 40 | + return fp(i); | |
| 41 | +} | |
| 42 | +int f8 (int ([4]), int); | |
| 9 | 43 | int main () { return 0; } |