[flang] Fix bug determining type of statement entity
authorTim Keith <tkeith@nvidia.com>
Fri, 22 Feb 2019 23:56:39 +0000 (15:56 -0800)
committerGitHub <noreply@github.com>
Thu, 28 Feb 2019 18:38:17 +0000 (10:38 -0800)
A statement entity (`data-i-do-variable` or `ac-do-variable`) that
doesn't have a type specified gets the type it would have in the
enclosing scope. That means if there is a visible variable with the
same name, the statement entity gets its type. We were failing to
do that and just applying the implicit rules.

Original-commit: flang-compiler/f18@72bc7c29ba8d4be6a7c93080bb7fac7a3bc73577
Reviewed-on: https://github.com/flang-compiler/f18/pull/305
Tree-same-pre-rewrite: false

flang/lib/semantics/resolve-names.cc
flang/test/semantics/resolve30.f90
flang/test/semantics/symbol05.f90

index 549f1e5..8bebe31 100644 (file)
@@ -3631,31 +3631,32 @@ Symbol *DeclarationVisitor::DeclareLocalEntity(const parser::Name &name) {
 
 Symbol *DeclarationVisitor::DeclareStatementEntity(const parser::Name &name,
     const std::optional<parser::IntegerTypeSpec> &type) {
+  const DeclTypeSpec *declTypeSpec{nullptr};
   if (auto *prev{FindSymbol(name)}) {
     if (prev->owner() == currScope()) {
       SayAlreadyDeclared(name, *prev);
       return nullptr;
     }
     name.symbol = nullptr;
+    declTypeSpec = prev->GetType();
   }
   Symbol &symbol{DeclareEntity<ObjectEntityDetails>(name, {})};
-  if (symbol.has<ObjectEntityDetails>()) {
-    const DeclTypeSpec *declTypeSpec{nullptr};
-    if (type.has_value()) {
-      BeginDeclTypeSpec();
-      DeclarationVisitor::Post(*type);
-      declTypeSpec = GetDeclTypeSpec();
-      EndDeclTypeSpec();
-    }
-    if (declTypeSpec != nullptr) {
-      SetType(name, *declTypeSpec);
-    } else {
-      ApplyImplicitRules(symbol);
-    }
-    CheckScalarIntegerType(name);
-    return Resolve(name, &symbol);
+  if (!symbol.has<ObjectEntityDetails>()) {
+    return nullptr;  // error was reported in DeclareEntity
   }
-  return nullptr;
+  if (type.has_value()) {
+    BeginDeclTypeSpec();
+    DeclarationVisitor::Post(*type);
+    declTypeSpec = GetDeclTypeSpec();
+    EndDeclTypeSpec();
+  }
+  if (declTypeSpec != nullptr) {
+    SetType(name, *declTypeSpec);
+  } else {
+    ApplyImplicitRules(symbol);
+  }
+  CheckScalarIntegerType(name);
+  return Resolve(name, &symbol);
 }
 
 // Set the type of an entity or report an error.
index 91d8778..e5b1eef 100644 (file)
@@ -28,3 +28,23 @@ subroutine s2
     y = 1
   end block
 end
+
+subroutine s3
+  implicit none
+  integer :: i, j
+  block
+    import, none
+    !ERROR: No explicit type declared for 'i'
+    real :: a(16) = [(i, i=1, 16)]
+    !ERROR: No explicit type declared for 'j'
+    data(a(j), j=1, 16) / 16 * 0.0 /
+  end block
+end
+
+subroutine s4
+  real :: i, j
+  !ERROR: Variable 'i' is not integer
+  real :: a(16) = [(i, i=1, 16)]
+  !ERROR: Variable 'j' is not integer
+  data(a(j), j=1, 16) / 16 * 0.0 /
+end
index a0d24e9..14c346b 100644 (file)
@@ -55,12 +55,17 @@ end subroutine
 
 !DEF: /s3 Subprogram
 subroutine s3
+ !DEF: /s3/j ObjectEntity INTEGER(8)
+ integer(kind=8) j
  block
   !DEF: /s3/Block1/t DerivedType
   type :: t
    !DEF: /s3/Block1/t/x ObjectEntity REAL(4)
    !DEF: /s3/Block1/t/ImpliedDos1/i (implicit) ObjectEntity INTEGER(4)
    real :: x(10) = [(i, i=1,10)]
+   !DEF: /s3/Block1/t/y ObjectEntity REAL(4)
+   !DEF: /s3/Block1/t/ImpliedDos2/j ObjectEntity INTEGER(8)
+   real :: y(10) = [(j, j=1,10)]
   end type
  end block
 end subroutine