[flang] Don't resolve component names to components in derived-type definition scope
authorPeter Klausler <pklausler@nvidia.com>
Mon, 24 Oct 2022 18:22:22 +0000 (11:22 -0700)
committerPeter Klausler <pklausler@nvidia.com>
Sun, 30 Oct 2022 20:37:47 +0000 (13:37 -0700)
We implemented 19.3.4p1 literally in name resolution:

  A component name has the scope of its derived-type definition. Outside the type definition,
  it may also appear within a designator of a component of a structure of that type or as a
  component keyword in a structure constructor for that type.

and within the derived-type definition would resolve the "bare"
names of components in specification inquiries and other contexts to
those components, not to any symbols in the enclosing scopes.

It turns out that most Fortran compilers resolve only "bare" names thus
when they are type parameters, and the names of data and procedure components
do not shadow exterior symbols.  Adjust name resolution to follow that
precedent rather than what seems to be clear language in the standard.

Differential Revision: https://reviews.llvm.org/D136984

flang/docs/Extensions.md
flang/lib/Semantics/resolve-names.cpp
flang/test/Semantics/resolve104.f90
flang/test/Semantics/symbol14.f90

index 63f85ba..d0d715d 100644 (file)
@@ -478,3 +478,15 @@ end module
   standard and not allowed by most other compilers.
   If the `USE`-associated entity of the same name is not a procedure,
   most compilers disallow it as well.
+
+* Fortran 2018 19.3.4p1: "A component name has the scope of its derived-type
+  definition.  Outside the type definition, it may also appear ..." which
+  seems to imply that within its derived-type definition, a component
+  name is in its scope, and at least shadows any entity of the same name
+  in the enclosing scope and might be read, thanks to the "also", to mean
+  that a "bare" reference to the name could be used in a specification inquiry.
+  However, most other compilers do not allow a component to shadow exterior
+  symbols, much less appear in specification inquiries, and there are
+  application codes that expect exterior symbols whose names match
+  components to be visible in a derived-type definition's default initialization
+  expressions, and so f18 follows that precedent.
index 2c21896..58d31b9 100644 (file)
@@ -2267,9 +2267,7 @@ Symbol *ScopeHandler::FindSymbol(const parser::Name &name) {
 Symbol *ScopeHandler::FindSymbol(const Scope &scope, const parser::Name &name) {
   if (scope.IsDerivedType()) {
     if (Symbol * symbol{scope.FindComponent(name.source)}) {
-      if (!symbol->has<ProcBindingDetails>() &&
-          !symbol->has<GenericDetails>() &&
-          !symbol->test(Symbol::Flag::ParentComp)) {
+      if (symbol->has<TypeParamDetails>()) {
         return Resolve(name, symbol);
       }
     }
index 3b5bea4..d082981 100644 (file)
@@ -33,7 +33,7 @@ module m2
     integer, kind :: dtypeParam = 4
     type(baseType(dtypeParam)) :: baseField
     !ERROR: KIND parameter value (343) of intrinsic type REAL did not resolve to a supported value
-    real(baseField%baseParam) :: realField
+    real(dtypeParam) :: realField
   end type dtype
 
   type(dtype) :: v1
index 611c43a..2b75411 100644 (file)
@@ -1,6 +1,5 @@
 ! RUN: %python %S/test_symbols.py %s %flang_fc1
-! "Bare" uses of type parameters and components
-
+! "Bare" uses of type parameters
  !DEF: /MainProgram1/t1 DerivedType
  !DEF: /MainProgram1/t1/k TypeParam INTEGER(4)
  type :: t1(k)
@@ -18,7 +17,7 @@
   real :: b(k)
   !DEF: /MainProgram1/t2/c ObjectEntity REAL(4)
   !DEF: /MainProgram1/size INTRINSIC, PURE (Function) ProcEntity
-  !REF: /MainProgram1/t1/a
+  !DEF: /MainProgram1/a (Implicit) ObjectEntity REAL(4)
   real :: c(size(a))
   !REF: /MainProgram1/t1
   !DEF: /MainProgram1/t2/x ObjectEntity TYPE(t1(k=666_4))