From 0818c5396667ff20e48992457dc4e8d24c55904f Mon Sep 17 00:00:00 2001 From: Jean Perier Date: Thu, 8 Aug 2019 08:38:01 -0700 Subject: [PATCH] [flang] Transform implict none ternaries to bool in `ImplicitRules` 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 | 33 +++++++++++++------------- flang/test/semantics/resolve04.f90 | 35 +++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 18 deletions(-) diff --git a/flang/lib/semantics/resolve-names.cc b/flang/lib/semantics/resolve-names.cc index a561a1e069a9..656b77567da9 100644 --- a/flang/lib/semantics/resolve-names.cc +++ b/flang/lib/semantics/resolve-names.cc @@ -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 isImplicitNoneType_; - std::optional 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 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); } diff --git a/flang/test/semantics/resolve04.f90 b/flang/test/semantics/resolve04.f90 index a46435134132..d50e7cd6116a 100644 --- a/flang/test/semantics/resolve04.f90 +++ b/flang/test/semantics/resolve04.f90 @@ -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