[flang-commits] [flang] b05c8c5 - [flang] Make implicit conversion explicit in assignment

Tim Keith via flang-commits flang-commits at lists.llvm.org
Sat May 9 09:11:23 PDT 2020


Author: Tim Keith
Date: 2020-05-09T09:11:00-07:00
New Revision: b05c8c5756e473e9ec51ed65869f6ed42c552404

URL: https://github.com/llvm/llvm-project/commit/b05c8c5756e473e9ec51ed65869f6ed42c552404
DIFF: https://github.com/llvm/llvm-project/commit/b05c8c5756e473e9ec51ed65869f6ed42c552404.diff

LOG: [flang] Make implicit conversion explicit in assignment

When intrinsic types are assigned there are some implicit conversions
that take place. This change make them explicit in the types
representation of assignments.

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

Added: 
    

Modified: 
    flang/lib/Semantics/expression.cpp

Removed: 
    


################################################################################
diff  --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp
index 9306f702aabb..cc7faef24640 100644
--- a/flang/lib/Semantics/expression.cpp
+++ b/flang/lib/Semantics/expression.cpp
@@ -184,6 +184,8 @@ class ArgumentAnalyzer {
   std::optional<ActualArgument> AnalyzeExpr(const parser::Expr &);
   bool AreConformable() const;
   const Symbol *FindBoundOp(parser::CharBlock, int passIndex);
+  void AddAssignmentConversion(
+      const DynamicType &lhsType, const DynamicType &rhsType);
   bool OkLogicalIntegerAssignment(TypeCategory lhs, TypeCategory rhs);
   std::optional<DynamicType> GetType(std::size_t) const;
   int GetRank(std::size_t) const;
@@ -2809,6 +2811,9 @@ std::optional<ProcedureRef> ArgumentAnalyzer::TryDefinedAssignment() {
   Tristate isDefined{
       semantics::IsDefinedAssignment(lhsType, lhsRank, rhsType, rhsRank)};
   if (isDefined == Tristate::No) {
+    if (lhsType && rhsType) {
+      AddAssignmentConversion(*lhsType, *rhsType);
+    }
     return std::nullopt; // user-defined assignment not allowed for these args
   }
   auto restorer{context_.GetContextualMessages().SetLocation(source_)};
@@ -2939,6 +2944,19 @@ const Symbol *ArgumentAnalyzer::FindBoundOp(
   return result;
 }
 
+// If there is an implicit conversion between intrinsic types, make it explicit
+void ArgumentAnalyzer::AddAssignmentConversion(
+    const DynamicType &lhsType, const DynamicType &rhsType) {
+  if (lhsType.category() == rhsType.category() &&
+      lhsType.kind() == rhsType.kind()) {
+    // no conversion necessary
+  } else if (auto rhsExpr{evaluate::ConvertToType(lhsType, MoveExpr(1))}) {
+    actuals_[1] = ActualArgument{*rhsExpr};
+  } else {
+    actuals_[1] = std::nullopt;
+  }
+}
+
 std::optional<DynamicType> ArgumentAnalyzer::GetType(std::size_t i) const {
   return i < actuals_.size() ? actuals_[i].value().GetType() : std::nullopt;
 }


        


More information about the flang-commits mailing list