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 | static inline CType *pointed_type(CType *type); | 74 | static inline CType *pointed_type(CType *type); |
| 75 | static int is_compatible_types(CType *type1, CType *type2); | 75 | static int is_compatible_types(CType *type1, CType *type2); |
| 76 | static int parse_btype(CType *type, AttributeDef *ad); | 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 | static void parse_expr_type(CType *type); | 78 | static void parse_expr_type(CType *type); |
| 79 | static void decl_initializer(CType *type, Section *sec, unsigned long c, int first, int size_only); | 79 | static void decl_initializer(CType *type, Section *sec, unsigned long c, int first, int size_only); |
| 80 | static void block(int *bsym, int *csym, int is_expr); | 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 | v = 0; | 3586 | v = 0; |
| 3587 | type1 = btype; | 3587 | type1 = btype; |
| 3588 | if (tok != ':') { | 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 | if (v == 0) { | 3591 | if (v == 0) { |
| 3591 | if ((type1.t & VT_BTYPE) != VT_STRUCT) | 3592 | if ((type1.t & VT_BTYPE) != VT_STRUCT) |
| 3592 | expect("identifier"); | 3593 | expect("identifier"); |
| @@ -3964,7 +3965,7 @@ static int asm_label_instr(void) · 371 unmodified lines | |||
| 3964 | return v; | 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 | int n, l, t1, arg_size, align; | 3970 | int n, l, t1, arg_size, align; |
| 3970 | Sym **plast, *s, *first; | 3971 | Sym **plast, *s, *first; |
| @@ -3972,25 +3973,25 @@ static void post_type(CType *type, AttributeDef *ad, int storage) · 1 unmodified line | |||
| 3972 | CType pt; | 3973 | CType pt; |
| 3973 | 3974 | ||
| 3974 | if (tok == '(') { | 3975 | if (tok == '(') { |
| 3975 | /* function declaration */ | 3976 | /* function type, or recursive declarator (return if so) */ |
| 3976 | next(); | 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 | first = NULL; | 3988 | first = NULL; |
| 3979 | plast = &first; | 3989 | plast = &first; |
| 3980 | arg_size = 0; | 3990 | arg_size = 0; |
| 3981 | if (tok != ')') { | 3991 | if (l) { |
| 3982 | for(;;) { | 3992 | for(;;) { |
| 3983 | /* read param name and compute offset */ | 3993 | /* read param name and compute offset */ |
| 3984 | if (l != FUNC_OLD) { | 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 | if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')') | 3995 | if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')') |
| 3995 | break; | 3996 | break; |
| 3996 | type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT); | 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 | tcc_error("parameter declared as void"); | 3999 | tcc_error("parameter declared as void"); |
| 3999 | arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE; | 4000 | arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE; |
| 4000 | } else { | 4001 | } else { |
| 4001 | old_proto: | ||
| 4002 | n = tok; | 4002 | n = tok; |
| 4003 | if (n < TOK_UIDENT) | 4003 | if (n < TOK_UIDENT) |
| 4004 | expect("identifier"); | 4004 | expect("identifier"); |
| @@ -4017,10 +4017,11 @@ static void post_type(CType *type, AttributeDef *ad, int storage) · 12 unmodified lines | |||
| 4017 | next(); | 4017 | next(); |
| 4018 | break; | 4018 | break; |
| 4019 | } | 4019 | } |
| 4020 | if (l == FUNC_NEW && !parse_btype(&pt, &ad1)) | ||
| 4021 | tcc_error("invalid type"); | ||
| 4020 | } | 4022 | } |
| 4021 | } | 4023 | } else |
| 4022 | /* if no parameters, then old type prototype */ | 4024 | /* if no parameters, then old type prototype */ |
| 4023 | if (l == 0) | ||
| 4024 | l = FUNC_OLD; | 4025 | l = FUNC_OLD; |
| 4025 | skip(')'); | 4026 | skip(')'); |
| 4026 | /* NOTE: const is ignored in returned type as it has a special | 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 | skip(']'); | 4074 | skip(']'); |
| 4074 | /* parse next post type */ | 4075 | /* parse next post type */ |
| 4075 | post_type(type, ad, storage); | 4076 | post_type(type, ad, storage, 0); |
| 4076 | if (type->t == VT_FUNC) | 4077 | if (type->t == VT_FUNC) |
| 4077 | tcc_error("declaration of an array of functions"); | 4078 | tcc_error("declaration of an array of functions"); |
| 4078 | t1 |= type->t & VT_VLA; | 4079 | t1 |= type->t & VT_VLA; |
| @@ -4098,20 +4099,25 @@ static void post_type(CType *type, AttributeDef *ad, int storage) · 19 unmodified lines | |||
| 4098 | type->t = (t1 ? VT_VLA : VT_ARRAY) | VT_PTR; | 4099 | type->t = (t1 ? VT_VLA : VT_ARRAY) | VT_PTR; |
| 4099 | type->ref = s; | 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 | in 'type'. 'td' is a bitmask indicating which kind of type decl is | 4106 | in 'type'. 'td' is a bitmask indicating which kind of type decl is |
| 4105 | expected. 'type' should contain the basic type. 'ad' is the | 4107 | expected. 'type' should contain the basic type. 'ad' is the |
| 4106 | attribute definition of the basic type. It can be modified by | 4108 | attribute definition of the basic type. It can be modified by |
| 4107 | type_decl(). | 4109 | type_decl(). If this (possibly abstract) declarator is a pointer chain |
| 4108 | */ | 4110 | it returns the innermost pointed to type (equals *type, but is a different |
| 4109 | static void type_decl(CType *type, AttributeDef *ad, int *v, int td) | 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; | 4114 | CType *post, *ret; |
| 4112 | CType type1, *type2; | ||
| 4113 | int qualifiers, storage; | 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 | while (tok == '*') { | 4121 | while (tok == '*') { |
| 4116 | qualifiers = 0; | 4122 | qualifiers = 0; |
| 4117 | redo: | 4123 | redo: |
| @@ -4139,51 +4145,38 @@ static void type_decl(CType *type, AttributeDef *ad, int *v, int td) · 21 unmodified lines | |||
| 4139 | } | 4145 | } |
| 4140 | mk_pointer(type); | 4146 | mk_pointer(type); |
| 4141 | type->t |= qualifiers; | 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 | if (tok == '(') { | 4153 | if (tok == '(') { |
| 4148 | next(); | 4154 | /* This is possibly a parameter type list for abstract declarators |
| 4149 | /* XXX: this is not correct to modify 'ad' at this point, but | 4155 | ('int ()'), use post_type for testing this. */ |
| 4150 | the syntax is not clear */ | 4156 | if (!post_type(type, ad, 0, td)) { |
| 4151 | if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) | 4157 | /* It's not, so it's a nested declarator, and the post operations |
| 4152 | parse_attribute(ad); | 4158 | apply to the innermost pointed to type (if any). */ |
| 4153 | type_decl(&type1, ad, v, td); | 4159 | /* XXX: this is not correct to modify 'ad' at this point, but |
| 4154 | skip(')'); | 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 | } else { | 4170 | } else { |
| 4156 | /* type identifier */ | 4171 | if (!(td & TYPE_ABSTRACT)) |
| 4157 | if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) { | 4172 | expect("identifier"); |
| 4158 | *v = tok; | 4173 | *v = 0; |
| 4159 | next(); | ||
| 4160 | } else { | ||
| 4161 | if (!(td & TYPE_ABSTRACT)) | ||
| 4162 | expect("identifier"); | ||
| 4163 | *v = 0; | ||
| 4164 | } | ||
| 4165 | } | 4174 | } |
| 4166 | storage = type->t & VT_STORAGE; | 4175 | post_type(post, ad, storage, 0); |
| 4167 | type->t &= ~VT_STORAGE; | ||
| 4168 | post_type(type, ad, storage); | ||
| 4169 | type->t |= storage; | ||
| 4170 | if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) | 4176 | if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) |
| 4171 | parse_attribute(ad); | 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 | type->t |= storage; | 4178 | type->t |= storage; |
| 4179 | return ret; | ||
| 4187 | } | 4180 | } |
| 4188 | 4181 | ||
| 4189 | /* compute the lvalue VT_LVAL_xxx needed to match type t. */ | 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 | #if 0 | 6917 | #if 0 |
| 6925 | { | 6918 | { |
| 6926 | char buf[500]; | 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 | printf("type = '%s'\n", buf); | 6921 | printf("type = '%s'\n", buf); |
| 6929 | } | 6922 | } |
| 6930 | #endif | 6923 | #endif |
| @@ -6,4 +6,38 @@ enum E const *e2; · 5 unmodified lines | |||
| 6 | struct S *s; | 6 | struct S *s; |
| 7 | const struct S *s1; | 7 | const struct S *s1; |
| 8 | struct S const *s2; | 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 | int main () { return 0; } | 43 | int main () { return 0; } |