[flang] Fix bug flang-compiler/f18#376, internal error when correcting misparse of...
authorpeter klausler <pklausler@nvidia.com>
Tue, 2 Apr 2019 17:34:45 +0000 (10:34 -0700)
committerpeter klausler <pklausler@nvidia.com>
Tue, 2 Apr 2019 17:59:09 +0000 (10:59 -0700)
Original-commit: flang-compiler/f18@f18a94ef9690c412907c733ac08be6736ea4eaad
Reviewed-on: https://github.com/flang-compiler/f18/pull/378
Tree-same-pre-rewrite: false

flang/lib/semantics/expression.cc
flang/lib/semantics/scope.cc
flang/lib/semantics/scope.h
flang/lib/semantics/symbol.cc

index 27c8174..508d4ac 100644 (file)
@@ -1784,7 +1784,8 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::Expr::DefinedBinary &) {
 // A(1) as a function reference into an array reference or a structure
 // constructor.
 template<typename... A>
-void FixMisparsedFunctionReference(const std::variant<A...> &constU) {
+void FixMisparsedFunctionReference(
+    semantics::SemanticsContext &context, const std::variant<A...> &constU) {
   // The parse tree is updated in situ when resolving an ambiguous parse.
   using uType = std::decay_t<decltype(constU)>;
   auto &u{const_cast<uType &>(constU)};
@@ -1806,12 +1807,11 @@ void FixMisparsedFunctionReference(const std::variant<A...> &constU) {
         }
       } else if (symbol.has<semantics::DerivedTypeDetails>()) {
         if constexpr (common::HasMember<parser::StructureConstructor, uType>) {
-          CHECK(symbol.scope() != nullptr);
-          const semantics::DeclTypeSpec *type{
-              symbol.scope()->FindInstantiatedDerivedType(
-                  semantics::DerivedTypeSpec{symbol})};
-          CHECK(type != nullptr);
-          u = funcRef.ConvertToStructureConstructor(type->derivedTypeSpec());
+          auto &scope{context.FindScope(name->source)};
+          const semantics::DeclTypeSpec &type{
+              scope.FindOrInstantiateDerivedType(
+                  semantics::DerivedTypeSpec{symbol}, context)};
+          u = funcRef.ConvertToStructureConstructor(type.derivedTypeSpec());
         } else {
           common::die("can't fix misparsed function as structure constructor");
         }
@@ -1825,7 +1825,7 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::Expr &expr) {
     // Expression was already checked by ExprChecker
     return std::make_optional<Expr<SomeType>>(expr.typedExpr->v);
   } else {
-    FixMisparsedFunctionReference(expr.u);
+    FixMisparsedFunctionReference(context_, expr.u);
     if (!expr.source.empty()) {
       // Analyze the expression in a specified source position context for
       // better error reporting.
@@ -1838,7 +1838,7 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::Expr &expr) {
 }
 
 MaybeExpr ExpressionAnalyzer::Analyze(const parser::Variable &variable) {
-  FixMisparsedFunctionReference(variable.u);
+  FixMisparsedFunctionReference(context_, variable.u);
   return Analyze(variable.u);
 }
 
index 4ad0e3e..4580d01 100644 (file)
@@ -249,7 +249,7 @@ const DeclTypeSpec *Scope::FindInstantiatedDerivedType(
 }
 
 const DeclTypeSpec &Scope::FindOrInstantiateDerivedType(DerivedTypeSpec &&spec,
-    DeclTypeSpec::Category category, SemanticsContext &semanticsContext) {
+    SemanticsContext &semanticsContext, DeclTypeSpec::Category category) {
   spec.FoldParameterExpressions(semanticsContext.foldingContext());
   if (const DeclTypeSpec * type{FindInstantiatedDerivedType(spec, category)}) {
     return *type;
index 5fe3dee..a7349c7 100644 (file)
@@ -180,8 +180,8 @@ public:
 
   // Returns a matching derived type instance if one exists, otherwise
   // creates one
-  const DeclTypeSpec &FindOrInstantiateDerivedType(
-      DerivedTypeSpec &&, DeclTypeSpec::Category, SemanticsContext &);
+  const DeclTypeSpec &FindOrInstantiateDerivedType(DerivedTypeSpec &&,
+      SemanticsContext &, DeclTypeSpec::Category = DeclTypeSpec::TypeDerived);
 
   // Clones a DerivedType scope into a new derived type instance's scope.
   void InstantiateDerivedType(Scope &, SemanticsContext &) const;
index eb748cf..b474670 100644 (file)
@@ -569,7 +569,7 @@ Symbol &Symbol::Instantiate(
                 }
                 details.ReplaceType(
                     scope.FindOrInstantiateDerivedType(std::move(newSpec),
-                        origType->category(), semanticsContext));
+                        semanticsContext, origType->category()));
               } else if (origType->AsIntrinsic() != nullptr) {
                 const DeclTypeSpec &newType{scope.InstantiateIntrinsicType(
                     *origType, semanticsContext)};