[flang] [NFC] Repair build with GCC 7.3
authorpeter klausler <pklausler@nvidia.com>
Tue, 22 Jun 2021 18:29:14 +0000 (11:29 -0700)
committerpeter klausler <pklausler@nvidia.com>
Tue, 22 Jun 2021 20:52:30 +0000 (13:52 -0700)
Work around two problems with GCC 7.3.
One is its inability to implement "constexpr operator=(...) = default;"
in a class with a std::optional<> component; another is a legitimate-
looking warning about an unused variable.

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

flang/include/flang/Evaluate/type.h
flang/lib/Evaluate/formatting.cpp
flang/lib/Evaluate/type.cpp
flang/lib/Semantics/check-declarations.cpp

index 124fb39..6ab09f6 100644 (file)
@@ -142,6 +142,11 @@ public:
     return charLengthParamValue_;
   }
   constexpr std::optional<std::int64_t> knownLength() const {
+#if !__clang__ && __GNUC__ == 7
+    if (knownLength_ < 0) {
+      return std::nullopt;
+    }
+#endif
     return knownLength_;
   }
   std::optional<Expr<SubscriptInteger>> GetCharLength() const;
@@ -217,7 +222,12 @@ private:
   TypeCategory category_{TypeCategory::Derived}; // overridable default
   int kind_{0};
   const semantics::ParamValue *charLengthParamValue_{nullptr};
+#if !__clang__ && __GNUC__ == 7
+  // GCC 7's optional<> lacks a constexpr operator=
+  std::int64_t knownLength_{-1};
+#else
   std::optional<std::int64_t> knownLength_;
+#endif
   const semantics::DerivedTypeSpec *derived_{nullptr}; // TYPE(T), CLASS(T)
 };
 
index 25ed470..5b5ae25 100644 (file)
@@ -475,10 +475,10 @@ std::string DynamicType::AsFortran() const {
   if (derived_) {
     CHECK(category_ == TypeCategory::Derived);
     return DerivedTypeSpecAsFortran(*derived_);
-  } else if (charLengthParamValue_ || knownLength_) {
+  } else if (charLengthParamValue_ || knownLength()) {
     std::string result{"CHARACTER(KIND="s + std::to_string(kind_) + ",LEN="};
-    if (knownLength_) {
-      result += std::to_string(*knownLength_) + "_8";
+    if (knownLength()) {
+      result += std::to_string(*knownLength()) + "_8";
     } else if (charLengthParamValue_->isAssumed()) {
       result += '*';
     } else if (charLengthParamValue_->isDeferred()) {
index 1c28c56..22ea3ea 100644 (file)
@@ -109,15 +109,15 @@ template <typename A> inline bool PointeeComparison(const A *x, const A *y) {
 bool DynamicType::operator==(const DynamicType &that) const {
   return category_ == that.category_ && kind_ == that.kind_ &&
       PointeeComparison(charLengthParamValue_, that.charLengthParamValue_) &&
-      knownLength_.has_value() == that.knownLength_.has_value() &&
-      (!knownLength_ || *knownLength_ == *that.knownLength_) &&
+      knownLength().has_value() == that.knownLength().has_value() &&
+      (!knownLength() || *knownLength() == *that.knownLength()) &&
       PointeeComparison(derived_, that.derived_);
 }
 
 std::optional<Expr<SubscriptInteger>> DynamicType::GetCharLength() const {
   if (category_ == TypeCategory::Character) {
-    if (knownLength_) {
-      return AsExpr(Constant<SubscriptInteger>(*knownLength_));
+    if (knownLength()) {
+      return AsExpr(Constant<SubscriptInteger>(*knownLength()));
     } else if (charLengthParamValue_) {
       if (auto length{charLengthParamValue_->GetExplicit()}) {
         return ConvertToType<SubscriptInteger>(std::move(*length));
@@ -194,7 +194,7 @@ bool DynamicType::IsAssumedLengthCharacter() const {
 bool DynamicType::IsNonConstantLengthCharacter() const {
   if (category_ != TypeCategory::Character) {
     return false;
-  } else if (knownLength_) {
+  } else if (knownLength()) {
     return false;
   } else if (!charLengthParamValue_) {
     return true;
index ddf0a01..5d063f1 100644 (file)
@@ -2209,15 +2209,14 @@ void DistinguishabilityHelper::Check(const Scope &scope) {
   for (const auto &[name, info] : nameToInfo_) {
     auto count{info.size()};
     for (std::size_t i1{0}; i1 < count - 1; ++i1) {
-      const auto &[kind1, symbol1, proc1] = info[i1];
+      const auto &[kind, symbol, proc]{info[i1]};
       for (std::size_t i2{i1 + 1}; i2 < count; ++i2) {
-        const auto &[kind2, symbol2, proc2] = info[i2];
-        auto distinguishable{kind1.IsName()
+        auto distinguishable{kind.IsName()
                 ? evaluate::characteristics::Distinguishable
                 : evaluate::characteristics::DistinguishableOpOrAssign};
-        if (!distinguishable(proc1, proc2)) {
-          SayNotDistinguishable(
-              GetTopLevelUnitContaining(scope), name, kind1, symbol1, symbol2);
+        if (!distinguishable(proc, info[i2].procedure)) {
+          SayNotDistinguishable(GetTopLevelUnitContaining(scope), name, kind,
+              symbol, info[i2].symbol);
         }
       }
     }