[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