[flang-commits] [PATCH] D79851: [Flang] Semantics for SELECT TYPE

Pete Steinfeld via Phabricator via flang-commits flang-commits at lists.llvm.org
Wed May 20 21:30:25 PDT 2020


PeteSteinfeld added inline comments.


================
Comment at: flang/lib/Semantics/resolve-names.cpp:5101-5102
+
+    } else if (evaluate::HasVectorSubscript(
+                   *association.selector.expr)) { // C1158
+      Say(association.selector.source,
----------------
PeteSteinfeld wrote:
> sameeranjoshi wrote:
> > PeteSteinfeld wrote:
> > > C1158 also applies to selectors that are not variables.  Can you please add a check and test for that situation?
> > I was confused from the wordings of standard.
> > This is what I understand,
> > If selector is not a variable => throw respective error
> > if selector is a variable that has a vector subscript -> throw error
> > 
> > Is this what you meant, that I am missing the first check?
> Here's my understanding of C1158 in pseudo code:
>  
> ```
>  if (!selector-is-variable || selector-is-variable-with-vector-subscript) {
>     if (associate-name-appears-in-variable-definition-context ||
>       associate-name-subobject-appears-in-variable-definition-context) {
>       emit error message;
>     }
>   }
> ```
> 
> Suppose you have a function that returns a polymorphic type.  Then, you call that function in a select-type-stmt and associate it with an associate-name.  Then, suppose the associate-name appears on the left-hand side of an assignment statement or you use it as an actual argument to a procedure that has a dummy argument with INTENT(OUT) or INTENT(INOUT).  I think that's the situation that C1158 is trying to avoid.
> 
> So it's OK to use something other than a variable, as long as you don't try to change the value of the associate-name.  In standards-speak, that means that the associate-name can't appear in a "variable definition context" (see section 19.6.7 for details).  Note also that if the selector **is ** a variable, it's OK to use it in a variable definition context.
> 
> In fact, now that I've explained this in more detail.  I don't think that your existing check or test is correct.  To trigger an error, you should have a test where the associate-name appears on the left hand side of an assignment statement in the code of the construct of the SELECT TYPE statement.  The test should look something like this:
> 
> 
> ```
>   select type(func_call(x) => func_result)
>   type is (xxx)
>     call sub_with_inout_param(func_result) ! Bad since func-result is in a variable definition context
>   end select
> ```
> So to implement this check, you'll need to look at all occurrences of the associate-name in the body of the select-type construct and see if the associate-name is associated with something other than a variable **and** if it is used in a variable definition context.  In such cases, you should emit an error message.
> 
> As a model for implementation, you can look in in check-do-forall.cpp.  Constraint C1130 requires that a variable used in a DO CONCURRENT construct must have its locality explicitly specified.  So there's code in there that walks the DO CONCURRENT construct looking for variables that violate this requirement.
> 
> You might also find it useful to call the function WhyNotModifiable() in tools.h to figure out whether a Symbol is modifiable in a Scope.  See section 19.6.7 for details on variable definition contexts.
> 
I've been looking at the existing code in the compiler.  All that you may need to do is add some code to `WhyNotModifiable()` to handle SELECT TYPE associate-names.  I see that there's already a test for a name that's construct associated.  Start by writing tests that cover the two situations for C1158 and see if the appropriate things happen.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D79851/new/

https://reviews.llvm.org/D79851





More information about the flang-commits mailing list