[PATCH] D81101: [flang] Fix crash on erroneous expressions

Pete Steinfeld via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 4 13:53:16 PDT 2020


PeteSteinfeld updated this revision to Diff 268586.
PeteSteinfeld added a comment.

It turned out that the problem was that I was fetching subexpressions of type
`parser::Expr`, which are not guaranteed to have a non-null `typedExpr`.  I
fixed this by only grabbing the top-level expression from which to gather
arguments as part of the DO loop analysis.  This, in turn, exposed a problem
where I wasn't collecting all of the actual arguments in an expression.  This
was caused by the fact that I wasn't recursing through the rest of the 
expression after finding an argument.  I fixed this by recursing through the
argument in the member function in `CollectActualArgumentsHelper`.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D81101/new/

https://reviews.llvm.org/D81101

Files:
  flang/lib/Semantics/check-do-forall.cpp
  flang/lib/Semantics/check-do-forall.h
  flang/test/Semantics/resolve91.f90


Index: flang/test/Semantics/resolve91.f90
===================================================================
--- flang/test/Semantics/resolve91.f90
+++ flang/test/Semantics/resolve91.f90
@@ -44,3 +44,15 @@
     real, dimension(:), pointer :: realArray => localArray
   end type
 end module m4
+
+module m6
+  integer, dimension(3) :: iarray
+  !ERROR: Derived type 'ubound' not found
+  character(len=ubound(iarray)(1)) :: first
+end module m6
+
+module m7
+  integer, dimension(2) :: iarray
+  !ERROR: Derived type 'ubound' not found
+  integer :: ivar = ubound(iarray)(1)
+end module m7
Index: flang/lib/Semantics/check-do-forall.h
===================================================================
--- flang/lib/Semantics/check-do-forall.h
+++ flang/lib/Semantics/check-do-forall.h
@@ -50,6 +50,7 @@
   void Leave(const parser::ForallStmt &);
   void Leave(const parser::ForallAssignmentStmt &s);
   void Enter(const parser::ExitStmt &);
+  void Enter(const parser::Expr &);
   void Leave(const parser::Expr &);
   void Leave(const parser::InquireSpec &);
   void Leave(const parser::IoControlSpec &);
Index: flang/lib/Semantics/check-do-forall.cpp
===================================================================
--- flang/lib/Semantics/check-do-forall.cpp
+++ flang/lib/Semantics/check-do-forall.cpp
@@ -1034,7 +1034,8 @@
   CollectActualArgumentsHelper() : Base{*this} {}
   using Base::operator();
   ActualArgumentSet operator()(const evaluate::ActualArgument &arg) const {
-    return ActualArgumentSet{arg};
+    return Combine(ActualArgumentSet{arg},
+        CollectActualArgumentsHelper{}(arg.UnwrapExpr()));
   }
 };
 
@@ -1044,11 +1045,18 @@
 
 template ActualArgumentSet CollectActualArguments(const SomeExpr &);
 
+static int exprDepth{0};
+
+void DoForallChecker::Enter(const parser::Expr &parsedExpr) { ++exprDepth; }
+
 void DoForallChecker::Leave(const parser::Expr &parsedExpr) {
-  if (const SomeExpr * expr{GetExpr(parsedExpr)}) {
-    ActualArgumentSet argSet{CollectActualArguments(*expr)};
-    for (const evaluate::ActualArgumentRef &argRef : argSet) {
-      CheckIfArgIsDoVar(*argRef, parsedExpr.source, context_);
+  CHECK(exprDepth > 0);
+  if (--exprDepth == 0) { // Only check top level expressions
+    if (const SomeExpr * expr{GetExpr(parsedExpr)}) {
+      ActualArgumentSet argSet{CollectActualArguments(*expr)};
+      for (const evaluate::ActualArgumentRef &argRef : argSet) {
+        CheckIfArgIsDoVar(*argRef, parsedExpr.source, context_);
+      }
     }
   }
 }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D81101.268586.patch
Type: text/x-patch
Size: 2513 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200604/93607701/attachment.bin>


More information about the llvm-commits mailing list