[flang] Accept polymorphic component element in storage_size
[llvm-project.git] / flang / docs / LabelResolution.md
blobc1227a8bc35a10b3192777a4d9a893bf6ed0a2fe
1 <!--===- docs/LabelResolution.md 
2   
3    Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4    See https://llvm.org/LICENSE.txt for license information.
5    SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6   
7 -->
9 # Semantics: Resolving Labels and Construct Names
11 ```eval_rst
12 .. contents::
13    :local:
14 ```
16 ## Overview
18 After the Fortran input file(s) has been parsed into a syntax tree, the compiler must check that the program checks semantically.  Target labels must be checked and violations of legal semantics should be reported to the user.
20 This is the detailed design document on how these labels will be semantically checked.  Legal semantics may result in rewrite operations on the syntax tree.  Semantics violations will be reported as errors to the user.
22 ## Requirements
24 - Input: a parse tree that decomposes the Fortran program unit
25 - Output:
26    * **Success** returns true
27      (Additionally, the parse tree may be rewritten on success to capture the nested DO loop structure explicitly from any _label-do-stmt_ type loops.)
28    * **Failure** returns false, instantiates (a container of) error message(s) to indicate the problem(s)
31 ### Label generalities (6.2.5)
33 Enforcement of the general label constraints.  There are three sorts of label usage. Labels can serve 
34    1. as a _label-do-stmt_ block range marker
35    1. as branching (control flow) targets
36    1. as specification annotations (`FORMAT` statements) for data transfer statements (I/O constructs)
38 Labels are related to the standard definition of inclusive scope.  For example, control-flow arcs are not allowed to originate from one inclusive scope and target statements outside of that inclusive scope.
40 Inclusive scope is defined as a tree structure of nested scoping constructs. A statement, _s_, is said to be *in* the same inclusive scope as another statement, _t_, if and only if _s_ and _t_ are in the same scope or _t_ is in one of the enclosing scopes of _s_, otherwise _s_ is *not in* the same inclusive scope as _t_. (Inclusive scope is unidirectional and is always from innermost scopes to outermost scopes.)
42 #### Semantic Checks
44 - labels range from 1 to 99999, inclusive (6.2.5 note 2)
45   * handled automatically by the parser, but add a range check
46 - labels must be pairwise distinct within their program unit scope (6.2.5 para 2)
47   * if redundant labels appear &rarr; error redundant labels
48   * the total number of unique statement labels may have a limit
51 ### Labels Used for `DO` Loop Ranging
53 #### _label-do-stmt_ (R1121)
55 A _label-do-stmt_ is a control construct that results in the iterative execution of a number of statements.  A _label-do-stmt_ has a (possibly shared, _nonblock-do-construct_) _label_ that will be called the loop target label.  The statements to be executed will be the range from the _label-do-stmt_ to the statement identified by the loop target label, inclusive. This range of statements will be called the loop's body and logically forms a _do-block_.
57 A _label-do-stmt_ is quite similar to a _block-do-construct_ in semantics, but the parse tree is different in that the parser does not impose a _do-block_ structure on the loop body.
59 In F18, the nonblock `DO` construct has been removed.  For legacy support (through F08), we will need to handle nonblock `DO` constructs.  In F18, the following legacy code is an error.
61 ```fortran
62   DO 100 I = 1, 100
63     DO 100 J = 1, 100
64       ...
65  100 CONTINUE
66 ```
68 ##### Semantic Checks
70 - the loop body target label must exist in the scope (F18:C1133; F08:C815, C817, C819)
71   * if the label does not appear, error of missing label
72 - the loop body target label must be, lexically, after the _label-do-stmt_ (R1119)
73   * if the label appears lexically preceding the `DO`, error of malformed `DO`
74 - control cannot transfer into the body from outside the _do-block_
75   * Exceptions (errors demoted to warnings)
76     - some implementations relax enforcement of this and allow `GOTO`s from the loop body to "extended ranges" and back again (PGI & gfortan appear to allow, NAG & Intel do not.)
77     - should some form of "extended ranges" for _do-constructs_ be supported, it should still be limited and not include parallel loops such as `DO CONCURRENT` or loops annotated with OpenACC or OpenMP directives.
78   * `GOTO`s into the `DO`s inclusive scope, error/warn of invalid transfer of control
79 - requires that the loop terminating statement for a _label-do-stmt_ be either an `END DO` or a `CONTINUE`
80   * Exception
81     - earlier standards allowed other statements to be terminators
83 Semantics for F08 and earlier that support sharing the loop terminating statement in a _nonblock-do-construct_ between multiple loops
84 - some statements cannot be _do-term-action-stmt_ (F08:C816)
85   * a _do-term-action-stmt_ is an _action-stmt_ but does not include _arithmetic-if-stmt_, _continue-stmt_, _cycle-stmt_, _end-function-stmt_, _end-mp-subprogram-stmt_, _end-program-stmt_, _end-subroutine-stmt_, _error-stop-stmt_, _exit-stmt_, _goto-stmt_, _return-stmt_, or _stop-stmt_
86     - if the term action statement is forbidden, error invalid statement in `DO` loop term position
87 - some statements cannot be _do-term-shared-stmt_ (F08:C818)
88   * this is the case as in our above example where two different nested loops share the same terminating statement (`100 continue`)
89   * a _do-term-shared-stmt_ is an _action-stmt_ with all the same exclusions as a _do-term-action-stmt_ except a _continue-stmt_ **is** allowed
90     - if the term shared action statement is forbidden, error invalid statement in term position
92 If the `DO` loop is a `DO CONCURRENT` construct, there are additional constraints (11.1.7.5).
93 - a _return-stmt_ is not allowed (C1136)
94 - image control statements are not allowed (C1137)
95 - branches must be from a statement and to a statement that both reside within the `DO CONCURRENT` (C1138)
96 - impure procedures shall not be called (C1139)
97 - deallocation of polymorphic objects is not allowed (C1140)
98 - references to `IEEE_GET_FLAG`, `IEEE_SET_HALTING_MODE`, and `IEEE_GET_HALTING_MODE` cannot appear in the body of a `DO CONCURRENT` (C1141)
99 - the use of the `ADVANCE=` specifier by an I/O statement in the body of a `DO CONCURRENT` is not allowed (11.1.7.5, para 5)
101 ### Labels Used in Branching
103 #### _goto-stmt_ (11.2.2, R1157)
105 A `GOTO` statement is a simple, direct transfer of control from the `GOTO` to the labelled statement.
107 ##### Semantic Checks
109 - the labelled statement that is the target of a `GOTO` (11.2.1 constraints)
110   - must refer to a label that is in inclusive scope of the computed `GOTO` statement (C1169)
111     * if a label does not exist, error nonexistent label
112     * if a label is out of scope, error out of inclusive scope
113   - the branch target statement must be valid
114     * if the statement is not allowed as a branch target, error not a valid branch target
115 - the labelled statement must be a branch target statement
116   * a branch target statement is any of _action-stmt_, _associate-stmt_, _end-associate-stmt_, _if-then-stmt_, _end-if-stmt_, _select-case-stmt_, _end-select-stmt_, _select-rank-stmt_, _end-select-rank-stmt_, _select-type-stmt_, _end-select-type-stmt_, _do-stmt_, _end-do-stmt_, _block-stmt_, _end-block-stmt_, _critical-stmt_, _end-critical-stmt_, _forall-construct-stmt_, _forall-stmt_, _where-construct-stmt_, _end-function-stmt_, _end-mp-subprogram-stmt_, _end-program-stmt_, or _end-subroutine-stmt_. (11.2.1)
117   * Some deleted features that were _action-stmt_ in older standards include _arithmetic-if-stmt_, _assign-stmt_, _assigned-goto-stmt_, and _pause-stmt_. For legacy mode support, these statements should be considered _action-stmt_.
120 #### _computed-goto-stmt_ (11.2.3, R1158)
122 The computed `GOTO` statement is analogous to a `switch` statement in C++.
124 ```fortran
125   GOTO ( label-list ) [,] scalar-int-expr
128 ##### Semantics Checks
130 - each label in _label-list_ (11.2.1 constraints, same as `GOTO`)
131   - must refer to a label that is in inclusive scope of the computed `GOTO` statement (C1170)
132     * if a label does not exist, error nonexistent label
133     * if a label is out of scope, error out of inclusive scope
134   - the branch target statement must be valid
135     * if the statement is not allowed as a branch target, error not a valid branch target
136 - the _scalar-int-expr_ needs to have `INTEGER` type
137   * check the type of the expression (type checking done elsewhere)
140 #### R853 _arithmetic-if-stmt_ (F08:8.2.4)
142 This control-flow construct is deleted in F18.
144 ```fortran
145   IF (scalar-numeric-expr) label1,label2,label3
148 The arithmetic if statement is like a three-way branch operator. If the scalar numeric expression is less than zero goto _label-1_, else if the variable is equal to zero goto _label-2_, else if the variable is greater than zero goto _label-3_.
150 ##### Semantics Checks
152 - the labels in the _arithmetic-if-stmt_ triple must all be present in the inclusive scope (F08:C848)
153   * if a label does not exist, error nonexistent label
154   * if a label is out of scope, error out of inclusive scope
155 - the _scalar-numeric-expr_ must not be `COMPLEX` (F08:C849)
156   * check the type of the expression (type checking done elsewhere)
159 #### _alt-return-spec_ (15.5.1, R1525)
161 These are a Fortran control-flow construct for combining a return from a subroutine with a branch to a labelled statement in the calling routine all in one operation. A typical implementation is for the subroutine to return a hidden integer, which is used as a key in the calling code to then, possibly, branch to a labelled statement in inclusive scope.
163 The labels are passed by the calling routine. We want to check those labels at the call-site, that is instances of _alt-return-spec_.
165 ##### Semantics Checks
167 - each _alt-return-spec_ (11.2.1 constraints, same as `GOTO`)
168   - must refer to a label that is in inclusive scope of the `CALL` statement
169     * if a label does not exist, error nonexistent label
170     * if a label is out of scope, error out of inclusive scope
171   - the branch target statement must be valid
172     * if the statement is not allowed as a branch target, error not a valid branch target
175 #### **END**, **EOR**, **ERR** specifiers (12.11)
177 These specifiers can appear in I/O statements and can transfer control to specific labelled statements under exceptional conditions like end-of-file, end-of-record, and other error conditions.  (The PGI compiler adds code to test the results from the runtime routines to determine if these branches should take place.)
179 ##### Semantics Checks
181 - each END, EOR, and ERR specifier (11.2.1 constraints, same as `GOTO`)
182   - must refer to a label that is in inclusive scope of the I/O statement
183     * if a label does not exist, error nonexistent label
184     * if a label is out of scope, error out of inclusive scope
185   - the branch target statement must be valid
186     * if the statement is not allowed as a branch target, error not a valid branch target
188 #### _assigned-goto-stmt_ and _assign-stmt_ (F90:8.2.4)
190 Deleted feature since Fortran 95.
192 The _assigned-goto-stmt_ and _assign-stmt_ were _action-stmt_ in the Fortran 90 standard. They are included here for completeness. This pair of obsolete statements can (will) be enabled as part of the compiler's legacy Fortran support.
194 The _assign-stmt_ stores a _label_ in an integer variable.  The _assigned-goto-stmt_ will then transfer control to the _label_ stored in that integer variable.
196 ```fortran
197   ASSIGN 10 TO i
198   ...
199   GOTO i (10,20,30)
202 ##### Semantic Checks
204 - an _assigned-goto-stmt_ cannot be a _do-term-action-stmt_ (F90:R829)
205 - an _assigned-goto-stmt_ cannot be a _do-term-shared-stmt_ (F90:R833)
206 - constraints from (F90:R839)
207   - each _label_ in an optional _label-list_ must be the statement label of a branch target statement that appears in the same scoping unit as the _assigned-goto-stmt_
208   - _scalar-int-variable_ (`i` in the example above) must be named and of type default integer
209   - an integer variable that has been assigned a label may only be referenced in an _assigned-goto_ or as a format specifier in an I/O statement
210   - when an I/O statement with a _format-specifier_ that is an integer variable is executed or when an _assigned-goto_ is executed, the variable must have been assigned a _label_
211   - an integer variable can only be assigned a label via the `ASSIGN` statement
212   - the label assigned to the variable must be in the same scoping unit as the _assigned-goto_ that branches to the _label_ value
213   - if the parameterized list of labels is present, the label value assigned to the integer variable must appear in that _label-list_
214   - a distinct _label_ can appear more than once in the _label-list_
216 Some interpretation is needed as the terms of the older standard are different.
218 A "scoping unit" is defined as
219   - a derived-type definition
220   - a procedure interface body, excluding derived-types and interfaces contained within it
221   - a program unit or subprogram, excluding derived-types, interfaces, and subprograms contained within it
223 This is a more lax definition of scope than inclusive scope.
225 A _named variable_ distinguishes a variable such as, `i`, from an element of an array, `a(i)`, for example.
227 ### Labels used in I/O
229 #### Data transfer statements
231 In data transfer (I/O) statements (e.g., `READ`), the user can specify a `FMT=` specifier that can take a label as its argument. (R1215)
233 ##### Semantic Checks
235 - if the `FMT=` specifier has a label as its argument (C1230)
236   - the label must correspond to a `FORMAT` statement
237     * if the statement is not a `FORMAT`, error statement must be a `FORMAT`
238   - the labelled `FORMAT` statement must be in the same inclusive scope as the originating data transfer statement (also in 2008)
239     * if the label statement does not exist, error label does not exist
240     * if the label statement is not in scope, error label is not in inclusive scope
241   - Exceptions (errors demoted to warnings)
242     - PGI extension: referenced `FORMAT` statements may appear in a host procedure
243     - Possible relaxation: the scope of the referenced `FORMAT` statement may be ignored, allowing a `FORMAT` to be referenced from any scope in the compilation.
245 ### Construct Name generalities
247 Various Fortran constructs can have names. These include
248   - the `WHERE` construct (10.2.3)
249   - the `FORALL` construct (10.2.4)
250   - the `ASSOCIATE` construct (11.1.3)
251   - the `BLOCK` construct (11.1.4)
252   - the `CHANGE TEAM` construct (11.1.5)
253   - the `CRITICAL` construct (11.1.6)
254   - the `DO` construct (11.1.7)
255   - the `IF` construct (11.1.8)
256   - the `SELECT CASE` construct (11.1.9)
257   - the `SELECT RANK` construct (11.1.10)
258   - the `SELECT TYPE` construct (11.1.11)
260 #### Semantics Checks
262 A construct name is a name formed under 6.2.2.  A name is an identifier. Identifiers are parsed by the parser.
263   - the maximum length of a name is 63 characters (C601)
265 Names must either not be given for the construct or used throughout when specified.
266 - if a construct is given a name, the construct's `END` statement must also specify the same name (`WHERE` C1033, `FORALL` C1035, ...)
267 - `WHERE` has additional `ELSEWHERE` clauses
268 - `IF` has additional `ELSE IF` and `ELSE` clauses
269 - `SELECT CASE` has additional `CASE` clauses
270 - `SELECT RANK` has additional `RANK` clauses
271 - `SELECT TYPE` has additional _type-guard-stmt_
272 These additional statements must meet the same constraint as the `END` of the construct. Names must match, if present, or there must be no names for any of the clauses.
274 ### `CYCLE` statement (11.1.7.4.4)
276 The `CYCLE` statement takes an optional _do-construct-name_.
278 #### Semantics Checks
280 - if the `CYCLE` has a _construct-name_, then the `CYCLE` statement must appear within that named _do-construct_ (C1134)
281 - if the `CYCLE` does not have a _do-construct-name_, the `CYCLE` statement must appear within a _do-construct_ (C1134)
283 ### `EXIT` statement (11.1.12)
285 The `EXIT` statement takes an optional _construct-name_.
287 #### Semantics Checks
289 - if the `EXIT` has a _construct-name_, then the `EXIT` statement must appear within that named construct (C1166)
290 - if the `EXIT` does not have a _construct-name_, the `EXIT` statement must appear within a _do-construct_ (C1166)
291 - an _exit-stmt_ must not appear in a `DO CONCURRENT` if the `EXIT` belongs to the `DO CONCURRENT` or an outer construct enclosing the `DO CONCURRENT` (C1167)
292 - an _exit-stmt_ must not appear in a `CHANGE TEAM` (`CRITICAL`) if the `EXIT` belongs to an outer construct enclosing the `CHANGE TEAM` (`CRITICAL`) (C1168)