[flang] Fix bug setting type from association expression
authorTim Keith <tkeith@nvidia.com>
Mon, 11 Feb 2019 18:49:48 +0000 (10:49 -0800)
committerTim Keith <tkeith@nvidia.com>
Mon, 11 Feb 2019 18:49:48 +0000 (10:49 -0800)
When an association selector is an expression, we get the type of the
associate-name from the type of the expression. If that is a derived
type, we were failing to get the derived type scope in copy of the
type that was made. That meant the component names were not resolved.

The fix is to copy the scope in the copy and move constructors of
`DerivedTypeSpec`. As a result, `DerivedTypeSpec::Instantiate` cannot
assume that the `scope_` is not set.

Original-commit: flang-compiler/f18@79eaa8c47fc0f1c1c71bf2760ec0a1e39e2a55ac
Reviewed-on: https://github.com/flang-compiler/f18/pull/281
Tree-same-pre-rewrite: false

flang/lib/semantics/type.cc
flang/test/semantics/symbol11.f90

index 464e1bd..e48028f 100644 (file)
 namespace Fortran::semantics {
 
 DerivedTypeSpec::DerivedTypeSpec(const DerivedTypeSpec &that)
-  : typeSymbol_{that.typeSymbol_}, parameters_{that.parameters_} {}
+  : typeSymbol_{that.typeSymbol_}, scope_{that.scope_}, parameters_{
+                                                            that.parameters_} {}
 
 DerivedTypeSpec::DerivedTypeSpec(DerivedTypeSpec &&that)
-  : typeSymbol_{that.typeSymbol_}, parameters_{std::move(that.parameters_)} {}
+  : typeSymbol_{that.typeSymbol_}, scope_{that.scope_}, parameters_{std::move(
+                                                            that.parameters_)} {
+}
 
 void DerivedTypeSpec::set_scope(const Scope &scope) {
   CHECK(!scope_);
@@ -66,7 +69,6 @@ void DerivedTypeSpec::FoldParameterExpressions(
 
 void DerivedTypeSpec::Instantiate(
     Scope &containingScope, SemanticsContext &semanticsContext) {
-  CHECK(scope_ == nullptr);
   Scope &newScope{containingScope.MakeScope(Scope::Kind::DerivedType)};
   newScope.set_derivedTypeSpec(*this);
   scope_ = &newScope;
index 4127ae5..43f123f 100644 (file)
@@ -84,12 +84,38 @@ subroutine s3
    !DEF: /s3/Block1/y TARGET AssocEntity TYPE(t2)
    !REF: /s3/t2/a2
    i = y%a2
-   type is (integer(kind=8))
-    !REF: /s3/i
-    !DEF: /s3/Block2/y TARGET AssocEntity INTEGER(8)
-    i = y
-   class default
-    !DEF: /s3/Block3/y TARGET AssocEntity CLASS(t1)
-    print *, y
+  type is (integer(kind=8))
+   !REF: /s3/i
+   !DEF: /s3/Block2/y TARGET AssocEntity INTEGER(8)
+   i = y
+  class default
+   !DEF: /s3/Block3/y TARGET AssocEntity CLASS(t1)
+   print *, y
  end select
 end subroutine
+
+!DEF: /s4 Subprogram
+subroutine s4
+ !DEF: /s4/t1 DerivedType
+ type :: t1
+  !DEF: /s4/t1/a ObjectEntity REAL(4)
+  real :: a
+ end type
+ !DEF: /s4/t2 DerivedType
+ type :: t2
+  !REF: /s4/t1
+  !DEF: /s4/t2/b ObjectEntity TYPE(t1)
+  type(t1) :: b
+ end type
+ !REF: /s4/t2
+ !DEF: /s4/x ObjectEntity TYPE(t2)
+ type(t2) :: x
+ !DEF: /s4/Block1/y AssocEntity TYPE(t1)
+ !REF: /s4/x
+ !REF: /s4/t2/b
+ associate(y => x%b)
+  !REF: /s4/Block1/y
+  !REF: /s4/t1/a
+  y%a = 0.0
+ end associate
+end subroutine