[flang] Transform implict none ternaries to bool in `ImplicitRules`
authorJean Perier <jperier@nvidia.com>
Thu, 8 Aug 2019 15:38:01 +0000 (08:38 -0700)
committerJean Perier <jperier@nvidia.com>
Thu, 8 Aug 2019 15:38:01 +0000 (08:38 -0700)
Original-commit: flang-compiler/f18@324567bd2de6722d5e370f5c7ddc46b28762e945
Reviewed-on: https://github.com/flang-compiler/f18/pull/635
Tree-same-pre-rewrite: false

flang/lib/semantics/resolve-names.cc
flang/test/semantics/resolve04.f90

index a561a1e..656b775 100644 (file)
@@ -74,18 +74,19 @@ public:
   // Get the implicit type for identifiers starting with ch. May be null.
   const DeclTypeSpec *GetType(char ch) const;
   // Record the implicit type for this range of characters.
-  void SetType(const DeclTypeSpec &type, parser::Location lo, parser::Location,
-      bool isDefault = false);
+  void SetType(const DeclTypeSpec &type, parser::Location lo, parser::Location);
 
 private:
   static char Incr(char ch);
 
   ImplicitRules *parent_;
   SemanticsContext &context_;
-  bool inheritFromParent_;  // look in parent if not specified here
-  std::optional<bool> isImplicitNoneType_;
-  std::optional<bool> isImplicitNoneExternal_;
-  // map initial character of identifier to nullptr or its default type
+  bool inheritFromParent_{false};  // look in parent if not specified here
+  bool isImplicitNoneType_{false};
+  bool isImplicitNoneExternal_{false};
+  // map_ contains the mapping between letters and types that were defined
+  // by the IMPLICIT statements of the related scope. It does not contain
+  // the default Fortran mappings nor the mapping defined in parents.
   std::map<char, const DeclTypeSpec *> map_;
 
   friend std::ostream &operator<<(std::ostream &, const ImplicitRules &);
@@ -1109,9 +1110,9 @@ private:
 // ImplicitRules implementation
 
 bool ImplicitRules::isImplicitNoneType() const {
-  if (isImplicitNoneType_.has_value()) {
-    return isImplicitNoneType_.value();
-  } else if (inheritFromParent_) {
+  if (isImplicitNoneType_) {
+    return true;
+  } else if (map_.empty() && inheritFromParent_) {
     return parent_->isImplicitNoneType();
   } else {
     return false;  // default if not specified
@@ -1119,8 +1120,8 @@ bool ImplicitRules::isImplicitNoneType() const {
 }
 
 bool ImplicitRules::isImplicitNoneExternal() const {
-  if (isImplicitNoneExternal_.has_value()) {
-    return isImplicitNoneExternal_.value();
+  if (isImplicitNoneExternal_) {
+    return true;
   } else if (inheritFromParent_) {
     return parent_->isImplicitNoneExternal();
   } else {
@@ -1129,7 +1130,7 @@ bool ImplicitRules::isImplicitNoneExternal() const {
 }
 
 const DeclTypeSpec *ImplicitRules::GetType(char ch) const {
-  if (isImplicitNoneType()) {
+  if (isImplicitNoneType_) {
     return nullptr;
   } else if (auto it{map_.find(ch)}; it != map_.end()) {
     return it->second;
@@ -1144,13 +1145,11 @@ const DeclTypeSpec *ImplicitRules::GetType(char ch) const {
   }
 }
 
-// isDefault is set when we are applying the default rules, so it is not
-// an error if the type is already set.
-void ImplicitRules::SetType(const DeclTypeSpec &type, parser::Location lo,
-    parser::Location hi, bool isDefault) {
+void ImplicitRules::SetType(
+    const DeclTypeSpec &type, parser::Location lo, parser::Location hi) {
   for (char ch = *lo; ch; ch = ImplicitRules::Incr(ch)) {
     auto res{map_.emplace(ch, &type)};
-    if (!res.second && !isDefault) {
+    if (!res.second) {
       context_.Say(parser::CharBlock{lo},
           "More than one implicit type specified for '%c'"_err_en_US, ch);
     }
index a464351..d50e7cd 100644 (file)
@@ -1,4 +1,4 @@
-! Copyright (c) 2018, NVIDIA CORPORATION.  All rights reserved.
+! Copyright (c) 2018-2019, NVIDIA CORPORATION.  All rights reserved.
 !
 ! Licensed under the Apache License, Version 2.0 (the "License");
 ! you may not use this file except in compliance with the License.
@@ -35,3 +35,36 @@ contains
     j = 2
   end subroutine
 end subroutine
+
+module m1
+  implicit none
+contains
+  subroutine s1
+    implicit real (a-h)
+    a1 = 1.
+    h1 = 1.
+    !ERROR: No explicit type declared for 'i1'
+    i1 = 1
+    !ERROR: No explicit type declared for 'z1'
+    z1 = 2.
+  contains
+    subroutine ss1
+      implicit integer(f-j) ! overlap with host scope import is OK
+      a2 = 1.
+      h2 = 1
+      i2 = 1
+      !ERROR: No explicit type declared for 'z2'
+      z2 = 2.
+    contains
+      subroutine sss1
+        implicit none
+        !ERROR: No explicit type declared for 'a3'
+        a3 = 1.
+      end subroutine
+    end subroutine
+  end subroutine
+  subroutine s2
+    !ERROR: No explicit type declared for 'b1'
+    b1 = 1.
+  end subroutine
+end module