Mercurial > hg > CbC > CbC_gcc
comparison gcc/fortran/array.c @ 145:1830386684a0
gcc-9.2.0
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 11:34:05 +0900 |
parents | 84e7813d76e9 |
children |
comparison
equal
deleted
inserted
replaced
131:84e7813d76e9 | 145:1830386684a0 |
---|---|
1 /* Array things | 1 /* Array things |
2 Copyright (C) 2000-2018 Free Software Foundation, Inc. | 2 Copyright (C) 2000-2020 Free Software Foundation, Inc. |
3 Contributed by Andy Vaught | 3 Contributed by Andy Vaught |
4 | 4 |
5 This file is part of GCC. | 5 This file is part of GCC. |
6 | 6 |
7 GCC is free software; you can redistribute it and/or modify it under | 7 GCC is free software; you can redistribute it and/or modify it under |
21 #include "config.h" | 21 #include "config.h" |
22 #include "system.h" | 22 #include "system.h" |
23 #include "coretypes.h" | 23 #include "coretypes.h" |
24 #include "options.h" | 24 #include "options.h" |
25 #include "gfortran.h" | 25 #include "gfortran.h" |
26 #include "parse.h" | |
26 #include "match.h" | 27 #include "match.h" |
27 #include "constructor.h" | 28 #include "constructor.h" |
28 | 29 |
29 /**************** Array reference matching subroutines *****************/ | 30 /**************** Array reference matching subroutines *****************/ |
30 | 31 |
64 match_subscript (gfc_array_ref *ar, int init, bool match_star) | 65 match_subscript (gfc_array_ref *ar, int init, bool match_star) |
65 { | 66 { |
66 match m = MATCH_ERROR; | 67 match m = MATCH_ERROR; |
67 bool star = false; | 68 bool star = false; |
68 int i; | 69 int i; |
70 bool saw_boz = false; | |
69 | 71 |
70 i = ar->dimen + ar->codimen; | 72 i = ar->dimen + ar->codimen; |
71 | 73 |
72 gfc_gobble_whitespace (); | 74 gfc_gobble_whitespace (); |
73 ar->c_where[i] = gfc_current_locus; | 75 ar->c_where[i] = gfc_current_locus; |
88 | 90 |
89 if (!star && init) | 91 if (!star && init) |
90 m = gfc_match_init_expr (&ar->start[i]); | 92 m = gfc_match_init_expr (&ar->start[i]); |
91 else if (!star) | 93 else if (!star) |
92 m = gfc_match_expr (&ar->start[i]); | 94 m = gfc_match_expr (&ar->start[i]); |
95 | |
96 if (ar->start[i] && ar->start[i]->ts.type == BT_BOZ) | |
97 { | |
98 gfc_error ("Invalid BOZ literal constant used in subscript at %C"); | |
99 saw_boz = true; | |
100 } | |
93 | 101 |
94 if (m == MATCH_NO) | 102 if (m == MATCH_NO) |
95 gfc_error ("Expected array subscript at %C"); | 103 gfc_error ("Expected array subscript at %C"); |
96 if (m != MATCH_YES) | 104 if (m != MATCH_YES) |
97 return MATCH_ERROR; | 105 return MATCH_ERROR; |
115 else if (init) | 123 else if (init) |
116 m = gfc_match_init_expr (&ar->end[i]); | 124 m = gfc_match_init_expr (&ar->end[i]); |
117 else | 125 else |
118 m = gfc_match_expr (&ar->end[i]); | 126 m = gfc_match_expr (&ar->end[i]); |
119 | 127 |
128 if (ar->end[i] && ar->end[i]->ts.type == BT_BOZ) | |
129 { | |
130 gfc_error ("Invalid BOZ literal constant used in subscript at %C"); | |
131 saw_boz = true; | |
132 } | |
133 | |
120 if (m == MATCH_ERROR) | 134 if (m == MATCH_ERROR) |
121 return MATCH_ERROR; | 135 return MATCH_ERROR; |
122 | 136 |
123 /* See if we have an optional stride. */ | 137 /* See if we have an optional stride. */ |
124 if (gfc_match_char (':') == MATCH_YES) | 138 if (gfc_match_char (':') == MATCH_YES) |
129 return MATCH_ERROR; | 143 return MATCH_ERROR; |
130 } | 144 } |
131 | 145 |
132 m = init ? gfc_match_init_expr (&ar->stride[i]) | 146 m = init ? gfc_match_init_expr (&ar->stride[i]) |
133 : gfc_match_expr (&ar->stride[i]); | 147 : gfc_match_expr (&ar->stride[i]); |
148 | |
149 if (ar->stride[i] && ar->stride[i]->ts.type == BT_BOZ) | |
150 { | |
151 gfc_error ("Invalid BOZ literal constant used in subscript at %C"); | |
152 saw_boz = true; | |
153 } | |
134 | 154 |
135 if (m == MATCH_NO) | 155 if (m == MATCH_NO) |
136 gfc_error ("Expected array subscript stride at %C"); | 156 gfc_error ("Expected array subscript stride at %C"); |
137 if (m != MATCH_YES) | 157 if (m != MATCH_YES) |
138 return MATCH_ERROR; | 158 return MATCH_ERROR; |
140 | 160 |
141 matched: | 161 matched: |
142 if (star) | 162 if (star) |
143 ar->dimen_type[i] = DIMEN_STAR; | 163 ar->dimen_type[i] = DIMEN_STAR; |
144 | 164 |
145 return MATCH_YES; | 165 return (saw_boz ? MATCH_ERROR : MATCH_YES); |
146 } | 166 } |
147 | 167 |
148 | 168 |
149 /* Match an array reference, whether it is the whole array or particular | 169 /* Match an array reference, whether it is the whole array or particular |
150 elements or a section. If init is set, the reference has to consist | 170 elements or a section. If init is set, the reference has to consist |
322 int i; | 342 int i; |
323 | 343 |
324 if (as == NULL) | 344 if (as == NULL) |
325 return; | 345 return; |
326 | 346 |
327 for (i = 0; i < as->rank + as->corank; i++) | 347 if (as->corank == 0) |
328 { | 348 { |
329 gfc_free_expr (as->lower[i]); | 349 for (i = 0; i < as->rank; i++) |
330 gfc_free_expr (as->upper[i]); | 350 { |
351 gfc_free_expr (as->lower[i]); | |
352 gfc_free_expr (as->upper[i]); | |
353 } | |
354 } | |
355 else | |
356 { | |
357 int n = as->rank + as->corank - (as->cotype == AS_EXPLICIT ? 1 : 0); | |
358 for (i = 0; i < n; i++) | |
359 { | |
360 gfc_free_expr (as->lower[i]); | |
361 gfc_free_expr (as->upper[i]); | |
362 } | |
331 } | 363 } |
332 | 364 |
333 free (as); | 365 free (as); |
334 } | 366 } |
335 | 367 |
377 if (as->resolved) | 409 if (as->resolved) |
378 return true; | 410 return true; |
379 | 411 |
380 for (i = 0; i < as->rank + as->corank; i++) | 412 for (i = 0; i < as->rank + as->corank; i++) |
381 { | 413 { |
414 if (i == GFC_MAX_DIMENSIONS) | |
415 return false; | |
416 | |
382 e = as->lower[i]; | 417 e = as->lower[i]; |
383 if (!resolve_array_bound (e, check_constant)) | 418 if (!resolve_array_bound (e, check_constant)) |
384 return false; | 419 return false; |
385 | 420 |
386 e = as->upper[i]; | 421 e = as->upper[i]; |
563 { /* See how current spec meshes with the existing. */ | 598 { /* See how current spec meshes with the existing. */ |
564 case AS_UNKNOWN: | 599 case AS_UNKNOWN: |
565 goto cleanup; | 600 goto cleanup; |
566 | 601 |
567 case AS_IMPLIED_SHAPE: | 602 case AS_IMPLIED_SHAPE: |
568 if (current_type != AS_ASSUMED_SHAPE) | 603 if (current_type != AS_ASSUMED_SIZE) |
569 { | 604 { |
570 gfc_error ("Bad array specification for implied-shape" | 605 gfc_error ("Bad array specification for implied-shape" |
571 " array at %C"); | 606 " array at %C"); |
572 goto cleanup; | 607 goto cleanup; |
573 } | 608 } |
786 /* Something went wrong. */ | 821 /* Something went wrong. */ |
787 gfc_free_array_spec (as); | 822 gfc_free_array_spec (as); |
788 return MATCH_ERROR; | 823 return MATCH_ERROR; |
789 } | 824 } |
790 | 825 |
791 | |
792 /* Given a symbol and an array specification, modify the symbol to | 826 /* Given a symbol and an array specification, modify the symbol to |
793 have that array specification. The error locus is needed in case | 827 have that array specification. The error locus is needed in case |
794 something goes wrong. On failure, the caller must free the spec. */ | 828 something goes wrong. On failure, the caller must free the spec. */ |
795 | 829 |
796 bool | 830 bool |
797 gfc_set_array_spec (gfc_symbol *sym, gfc_array_spec *as, locus *error_loc) | 831 gfc_set_array_spec (gfc_symbol *sym, gfc_array_spec *as, locus *error_loc) |
798 { | 832 { |
799 int i; | 833 int i; |
800 | 834 symbol_attribute *attr; |
835 | |
801 if (as == NULL) | 836 if (as == NULL) |
802 return true; | 837 return true; |
803 | 838 |
839 /* If the symbol corresponds to a submodule module procedure the array spec is | |
840 already set, so do not attempt to set it again here. */ | |
841 attr = &sym->attr; | |
842 if (gfc_submodule_procedure(attr)) | |
843 return true; | |
844 | |
804 if (as->rank | 845 if (as->rank |
805 && !gfc_add_dimension (&sym->attr, sym->name, error_loc)) | 846 && !gfc_add_dimension (&sym->attr, sym->name, error_loc)) |
806 return false; | 847 return false; |
807 | 848 |
808 if (as->corank | 849 if (as->corank |
823 return false; | 864 return false; |
824 } | 865 } |
825 | 866 |
826 if (as->corank) | 867 if (as->corank) |
827 { | 868 { |
828 /* The "sym" has no corank (checked via gfc_add_codimension). Thus | |
829 the codimension is simply added. */ | |
830 gcc_assert (as->rank == 0 && sym->as->corank == 0); | |
831 | |
832 sym->as->cotype = as->cotype; | 869 sym->as->cotype = as->cotype; |
833 sym->as->corank = as->corank; | 870 sym->as->corank = as->corank; |
871 /* Check F2018:C822. */ | |
872 if (sym->as->rank + sym->as->corank > GFC_MAX_DIMENSIONS) | |
873 goto too_many; | |
874 | |
834 for (i = 0; i < as->corank; i++) | 875 for (i = 0; i < as->corank; i++) |
835 { | 876 { |
836 sym->as->lower[sym->as->rank + i] = as->lower[i]; | 877 sym->as->lower[sym->as->rank + i] = as->lower[i]; |
837 sym->as->upper[sym->as->rank + i] = as->upper[i]; | 878 sym->as->upper[sym->as->rank + i] = as->upper[i]; |
838 } | 879 } |
847 sym->as->rank = as->rank; | 888 sym->as->rank = as->rank; |
848 sym->as->type = as->type; | 889 sym->as->type = as->type; |
849 sym->as->cray_pointee = as->cray_pointee; | 890 sym->as->cray_pointee = as->cray_pointee; |
850 sym->as->cp_was_assumed = as->cp_was_assumed; | 891 sym->as->cp_was_assumed = as->cp_was_assumed; |
851 | 892 |
852 for (i = 0; i < sym->as->corank; i++) | 893 /* Check F2018:C822. */ |
894 if (sym->as->rank + sym->as->corank > GFC_MAX_DIMENSIONS) | |
895 goto too_many; | |
896 | |
897 for (i = sym->as->corank - 1; i >= 0; i--) | |
853 { | 898 { |
854 sym->as->lower[as->rank + i] = sym->as->lower[i]; | 899 sym->as->lower[as->rank + i] = sym->as->lower[i]; |
855 sym->as->upper[as->rank + i] = sym->as->upper[i]; | 900 sym->as->upper[as->rank + i] = sym->as->upper[i]; |
856 } | 901 } |
857 for (i = 0; i < as->rank; i++) | 902 for (i = 0; i < as->rank; i++) |
861 } | 906 } |
862 } | 907 } |
863 | 908 |
864 free (as); | 909 free (as); |
865 return true; | 910 return true; |
911 | |
912 too_many: | |
913 | |
914 gfc_error ("rank + corank of %qs exceeds %d at %C", sym->name, | |
915 GFC_MAX_DIMENSIONS); | |
916 return false; | |
866 } | 917 } |
867 | 918 |
868 | 919 |
869 /* Copy an array specification. */ | 920 /* Copy an array specification. */ |
870 | 921 |
1096 | 1147 |
1097 m = gfc_match_expr (&expr); | 1148 m = gfc_match_expr (&expr); |
1098 if (m != MATCH_YES) | 1149 if (m != MATCH_YES) |
1099 return m; | 1150 return m; |
1100 | 1151 |
1152 if (expr->ts.type == BT_BOZ) | |
1153 { | |
1154 gfc_error ("BOZ literal constant at %L cannot appear in an " | |
1155 "array constructor", &expr->where); | |
1156 goto done; | |
1157 } | |
1158 | |
1101 if (expr->expr_type == EXPR_FUNCTION | 1159 if (expr->expr_type == EXPR_FUNCTION |
1102 && expr->ts.type == BT_UNKNOWN | 1160 && expr->ts.type == BT_UNKNOWN |
1103 && strcmp(expr->symtree->name, "null") == 0) | 1161 && strcmp(expr->symtree->name, "null") == 0) |
1104 { | 1162 { |
1105 gfc_error ("NULL() at %C cannot appear in an array constructor"); | 1163 gfc_error ("NULL() at %C cannot appear in an array constructor"); |
1106 gfc_free_expr (expr); | 1164 goto done; |
1107 return MATCH_ERROR; | 1165 } |
1108 } | |
1109 | 1166 |
1110 gfc_constructor_append_expr (result, expr, &gfc_current_locus); | 1167 gfc_constructor_append_expr (result, expr, &gfc_current_locus); |
1111 return MATCH_YES; | 1168 return MATCH_YES; |
1112 } | 1169 |
1113 | 1170 done: |
1171 gfc_free_expr (expr); | |
1172 return MATCH_ERROR; | |
1173 } | |
1174 | |
1175 | |
1176 /* Convert components of an array constructor to the type in ts. */ | |
1177 | |
1178 static match | |
1179 walk_array_constructor (gfc_typespec *ts, gfc_constructor_base head) | |
1180 { | |
1181 gfc_constructor *c; | |
1182 gfc_expr *e; | |
1183 match m; | |
1184 | |
1185 for (c = gfc_constructor_first (head); c; c = gfc_constructor_next (c)) | |
1186 { | |
1187 e = c->expr; | |
1188 if (e->expr_type == EXPR_ARRAY && e->ts.type == BT_UNKNOWN | |
1189 && !e->ref && e->value.constructor) | |
1190 { | |
1191 m = walk_array_constructor (ts, e->value.constructor); | |
1192 if (m == MATCH_ERROR) | |
1193 return m; | |
1194 } | |
1195 else if (!gfc_convert_type_warn (e, ts, 1, 1, true) | |
1196 && e->ts.type != BT_UNKNOWN) | |
1197 return MATCH_ERROR; | |
1198 } | |
1199 return MATCH_YES; | |
1200 } | |
1114 | 1201 |
1115 /* Match an array constructor. */ | 1202 /* Match an array constructor. */ |
1116 | 1203 |
1117 match | 1204 match |
1118 gfc_match_array_constructor (gfc_expr **result) | 1205 gfc_match_array_constructor (gfc_expr **result) |
1239 return MATCH_ERROR; | 1326 return MATCH_ERROR; |
1240 } | 1327 } |
1241 } | 1328 } |
1242 } | 1329 } |
1243 | 1330 |
1244 /* Walk the constructor and ensure type conversion for numeric types. */ | 1331 /* Walk the constructor, and if possible, do type conversion for |
1332 numeric types. */ | |
1245 if (gfc_numeric_ts (&ts)) | 1333 if (gfc_numeric_ts (&ts)) |
1246 { | 1334 { |
1247 c = gfc_constructor_first (head); | 1335 m = walk_array_constructor (&ts, head); |
1248 for (; c; c = gfc_constructor_next (c)) | 1336 if (m == MATCH_ERROR) |
1249 gfc_convert_type (c->expr, &ts, 1); | 1337 return m; |
1250 } | 1338 } |
1251 } | 1339 } |
1252 else | 1340 else |
1253 expr = gfc_get_array_expr (BT_UNKNOWN, 0, &where); | 1341 expr = gfc_get_array_expr (BT_UNKNOWN, 0, &where); |
1254 | 1342 |
1304 | 1392 |
1305 if (gfc_compare_types (&constructor_ts, &expr->ts)) | 1393 if (gfc_compare_types (&constructor_ts, &expr->ts)) |
1306 return 0; | 1394 return 0; |
1307 | 1395 |
1308 if (convert) | 1396 if (convert) |
1309 return gfc_convert_type(expr, &constructor_ts, 1) ? 0 : 1; | 1397 return gfc_convert_type_warn (expr, &constructor_ts, 1, 1, true) ? 0 : 1; |
1310 | 1398 |
1311 gfc_error ("Element in %s array constructor at %L is %s", | 1399 gfc_error ("Element in %s array constructor at %L is %s", |
1312 gfc_typename (&constructor_ts), &expr->where, | 1400 gfc_typename (&constructor_ts), &expr->where, |
1313 gfc_typename (&expr->ts)); | 1401 gfc_typename (expr)); |
1314 | 1402 |
1315 cons_state = CONS_BAD; | 1403 cons_state = CONS_BAD; |
1316 return 1; | 1404 return 1; |
1317 } | 1405 } |
1318 | 1406 |
1676 iter_stack = frame.prev; | 1764 iter_stack = frame.prev; |
1677 | 1765 |
1678 return t; | 1766 return t; |
1679 } | 1767 } |
1680 | 1768 |
1769 /* Variables for noticing if all constructors are empty, and | |
1770 if any of them had a type. */ | |
1771 | |
1772 static bool empty_constructor; | |
1773 static gfc_typespec empty_ts; | |
1681 | 1774 |
1682 /* Expand a constructor into constant constructors without any | 1775 /* Expand a constructor into constant constructors without any |
1683 iterators, calling the work function for each of the expanded | 1776 iterators, calling the work function for each of the expanded |
1684 expressions. The work function needs to either save or free the | 1777 expressions. The work function needs to either save or free the |
1685 passed expression. */ | 1778 passed expression. */ |
1699 continue; | 1792 continue; |
1700 } | 1793 } |
1701 | 1794 |
1702 e = c->expr; | 1795 e = c->expr; |
1703 | 1796 |
1797 if (empty_constructor) | |
1798 empty_ts = e->ts; | |
1799 | |
1704 if (e->expr_type == EXPR_ARRAY) | 1800 if (e->expr_type == EXPR_ARRAY) |
1705 { | 1801 { |
1706 if (!expand_constructor (e->value.constructor)) | 1802 if (!expand_constructor (e->value.constructor)) |
1707 return false; | 1803 return false; |
1708 | 1804 |
1709 continue; | 1805 continue; |
1710 } | 1806 } |
1711 | 1807 |
1808 empty_constructor = false; | |
1712 e = gfc_copy_expr (e); | 1809 e = gfc_copy_expr (e); |
1713 if (!gfc_simplify_expr (e, 1)) | 1810 if (!gfc_simplify_expr (e, 1)) |
1714 { | 1811 { |
1715 gfc_free_expr (e); | 1812 gfc_free_expr (e); |
1716 return false; | 1813 return false; |
1717 } | 1814 } |
1815 e->from_constructor = 1; | |
1718 current_expand.offset = &c->offset; | 1816 current_expand.offset = &c->offset; |
1719 current_expand.repeat = &c->repeat; | 1817 current_expand.repeat = &c->repeat; |
1720 current_expand.component = c->n.component; | 1818 current_expand.component = c->n.component; |
1721 if (!current_expand.expand_work_function(e)) | 1819 if (!current_expand.expand_work_function(e)) |
1722 return false; | 1820 return false; |
1789 expand_save = current_expand; | 1887 expand_save = current_expand; |
1790 current_expand.base = NULL; | 1888 current_expand.base = NULL; |
1791 | 1889 |
1792 iter_stack = NULL; | 1890 iter_stack = NULL; |
1793 | 1891 |
1892 empty_constructor = true; | |
1893 gfc_clear_ts (&empty_ts); | |
1794 current_expand.expand_work_function = expand; | 1894 current_expand.expand_work_function = expand; |
1795 | 1895 |
1796 if (!expand_constructor (e->value.constructor)) | 1896 if (!expand_constructor (e->value.constructor)) |
1797 { | 1897 { |
1798 gfc_constructor_free (current_expand.base); | 1898 gfc_constructor_free (current_expand.base); |
1799 rc = false; | 1899 rc = false; |
1800 goto done; | 1900 goto done; |
1801 } | 1901 } |
1902 | |
1903 /* If we don't have an explicit constructor type, and there | |
1904 were only empty constructors, then take the type from | |
1905 them. */ | |
1906 | |
1907 if (constructor_ts.type == BT_UNKNOWN && empty_constructor) | |
1908 e->ts = empty_ts; | |
1802 | 1909 |
1803 gfc_constructor_free (e->value.constructor); | 1910 gfc_constructor_free (e->value.constructor); |
1804 e->value.constructor = current_expand.base; | 1911 e->value.constructor = current_expand.base; |
1805 | 1912 |
1806 rc = true; | 1913 rc = true; |
2159 dest->var = gfc_copy_expr (src->var); | 2266 dest->var = gfc_copy_expr (src->var); |
2160 dest->start = gfc_copy_expr (src->start); | 2267 dest->start = gfc_copy_expr (src->start); |
2161 dest->end = gfc_copy_expr (src->end); | 2268 dest->end = gfc_copy_expr (src->end); |
2162 dest->step = gfc_copy_expr (src->step); | 2269 dest->step = gfc_copy_expr (src->step); |
2163 dest->unroll = src->unroll; | 2270 dest->unroll = src->unroll; |
2271 dest->ivdep = src->ivdep; | |
2272 dest->vector = src->vector; | |
2273 dest->novector = src->novector; | |
2164 | 2274 |
2165 return dest; | 2275 return dest; |
2166 } | 2276 } |
2167 | 2277 |
2168 | 2278 |
2184 | 2294 |
2185 if (dimen < 0 || dimen > as->rank - 1) | 2295 if (dimen < 0 || dimen > as->rank - 1) |
2186 gfc_internal_error ("spec_dimen_size(): Bad dimension"); | 2296 gfc_internal_error ("spec_dimen_size(): Bad dimension"); |
2187 | 2297 |
2188 if (as->type != AS_EXPLICIT | 2298 if (as->type != AS_EXPLICIT |
2189 || as->lower[dimen]->expr_type != EXPR_CONSTANT | 2299 || !as->lower[dimen] |
2300 || !as->upper[dimen]) | |
2301 return false; | |
2302 | |
2303 if (as->lower[dimen]->expr_type != EXPR_CONSTANT | |
2190 || as->upper[dimen]->expr_type != EXPR_CONSTANT | 2304 || as->upper[dimen]->expr_type != EXPR_CONSTANT |
2191 || as->lower[dimen]->ts.type != BT_INTEGER | 2305 || as->lower[dimen]->ts.type != BT_INTEGER |
2192 || as->upper[dimen]->ts.type != BT_INTEGER) | 2306 || as->upper[dimen]->ts.type != BT_INTEGER) |
2193 return false; | 2307 return false; |
2194 | 2308 |