Removing the need for the notfirst local variable, and tidy loop structure and error messaging a bit.
Unified · Split
| @@ -5923,69 +5923,58 @@ static void decl_designator(CType *type, Section *sec, unsigned long c, · 5922 unmodified lines | |||
| 5923 | Sym **cur_field, int size_only) | 5923 | Sym **cur_field, int size_only) |
| 5924 | { | 5924 | { |
| 5925 | Sym *s, *f; | 5925 | Sym *s, *f; |
| 5926 | int notfirst, index, index_last, align, l, nb_elems, elem_size; | 5926 | int index, index_last, align, l, nb_elems, elem_size; |
| 5927 | 5927 | ||
| 5928 | notfirst = 0; | ||
| 5929 | elem_size = 0; | 5928 | elem_size = 0; |
| 5930 | nb_elems = 1; | 5929 | nb_elems = 1; |
| 5931 | if (gnu_ext && (l = is_label()) != 0) | 5930 | if (gnu_ext && (l = is_label()) != 0) |
| 5932 | goto struct_field; | 5931 | goto struct_field; |
| 5933 | while (tok == '[' || tok == '.') { | 5932 | /* NOTE: we only support ranges for last designator */ |
| 5933 | while (nb_elems == 1 && (tok == '[' || tok == '.')) { | ||
| 5934 | if (tok == '[') { | 5934 | if (tok == '[') { |
| 5935 | if (!(type->t & VT_ARRAY)) | 5935 | if (!(type->t & VT_ARRAY)) |
| 5936 | expect("array type"); | 5936 | expect("array type"); |
| 5937 | s = type->ref; | ||
| 5938 | next(); | 5937 | next(); |
| 5939 | index = expr_const(); | 5938 | index = index_last = expr_const(); |
| 5940 | if (index < 0 || (s->c >= 0 && index >= s->c)) | ||
| 5941 | tcc_error("invalid index"); | ||
| 5942 | if (tok == TOK_DOTS && gnu_ext) { | 5939 | if (tok == TOK_DOTS && gnu_ext) { |
| 5943 | next(); | 5940 | next(); |
| 5944 | index_last = expr_const(); | 5941 | index_last = expr_const(); |
| 5945 | if (index_last < 0 || | ||
| 5946 | (s->c >= 0 && index_last >= s->c) || | ||
| 5947 | index_last < index) | ||
| 5948 | tcc_error("invalid index"); | ||
| 5949 | } else { | ||
| 5950 | index_last = index; | ||
| 5951 | } | 5942 | } |
| 5952 | skip(']'); | 5943 | skip(']'); |
| 5953 | if (!notfirst) { | 5944 | s = type->ref; |
| 5945 | if (index < 0 || (s->c >= 0 && index_last >= s->c) || | ||
| 5946 | index_last < index) | ||
| 5947 | tcc_error("invalid index"); | ||
| 5948 | if (cur_field) { | ||
| 5954 | (*cur_field)->c = index; | 5949 | (*cur_field)->c = index; |
| 5955 | (*cur_field)->r = index_last; | 5950 | (*cur_field)->r = index_last; |
| 5956 | } | 5951 | } |
| 5957 | type = pointed_type(type); | 5952 | type = pointed_type(type); |
| 5958 | elem_size = type_size(type, &align); | 5953 | elem_size = type_size(type, &align); |
| 5959 | c += index * elem_size; | 5954 | c += index * elem_size; |
| 5960 | /* NOTE: we only support ranges for last designator */ | ||
| 5961 | nb_elems = index_last - index + 1; | 5955 | nb_elems = index_last - index + 1; |
| 5962 | if (nb_elems != 1) { | ||
| 5963 | notfirst = 1; | ||
| 5964 | break; | ||
| 5965 | } | ||
| 5966 | } else { | 5956 | } else { |
| 5967 | next(); | 5957 | next(); |
| 5968 | l = tok; | 5958 | l = tok; |
| 5969 | next(); | ||
| 5970 | struct_field: | 5959 | struct_field: |
| 5960 | next(); | ||
| 5971 | if ((type->t & VT_BTYPE) != VT_STRUCT) | 5961 | if ((type->t & VT_BTYPE) != VT_STRUCT) |
| 5972 | expect("struct/union type"); | 5962 | expect("struct/union type"); |
| 5973 | f = find_field(type, l); | 5963 | f = find_field(type, l); |
| 5974 | if (!f) | 5964 | if (!f) |
| 5975 | expect("field"); | 5965 | expect("field"); |
| 5976 | if (!notfirst) | 5966 | if (cur_field) |
| 5977 | *cur_field = f; | 5967 | *cur_field = f; |
| 5978 | type = &f->type; | 5968 | type = &f->type; |
| 5979 | c += f->c; | 5969 | c += f->c; |
| 5980 | } | 5970 | } |
| 5981 | notfirst = 1; | 5971 | cur_field = NULL; |
| 5982 | } | 5972 | } |
| 5983 | if (notfirst) { | 5973 | if (!cur_field) { |
| 5984 | if (tok == '=') { | 5974 | if (tok == '=') { |
| 5985 | next(); | 5975 | next(); |
| 5986 | } else { | 5976 | } else if (!gnu_ext) { |
| 5987 | if (!gnu_ext) | 5977 | expect("="); |
| 5988 | expect("="); | ||
| 5989 | } | 5978 | } |
| 5990 | } else { | 5979 | } else { |
| 5991 | if (type->t & VT_ARRAY) { | 5980 | if (type->t & VT_ARRAY) { |