@@ -80,11 +80,10 @@ struct LinearExecutionWalker : public PostWalker<SubType, VisitorType> {
8080 static void scan (SubType* self, Expression** currp) {
8181 Expression* curr = *currp;
8282
83- auto handleCall = [&](bool isReturn) {
83+ auto handleCall = [&](bool mayThrow, bool isReturn) {
8484 if (!self->connectAdjacentBlocks ) {
85- // Control is nonlinear if we return, or if EH is enabled or may be.
86- if (isReturn || !self->getModule () ||
87- self->getModule ()->features .hasExceptionHandling ()) {
85+ // Control is nonlinear if we return or throw.
86+ if (isReturn || !self->getModule () || mayThrow) {
8887 self->pushTask (SubType::doNoteNonLinear, currp);
8988 }
9089 }
@@ -153,11 +152,31 @@ struct LinearExecutionWalker : public PostWalker<SubType, VisitorType> {
153152 break ;
154153 }
155154 case Expression::Id::CallId: {
156- handleCall (curr->cast <Call>()->isReturn );
155+ auto * call = curr->cast <Call>();
156+
157+ bool mayThrow = !self->getModule () ||
158+ self->getModule ()->features .hasExceptionHandling ();
159+ if (mayThrow && self->getModule ()) {
160+ auto * effects =
161+ self->getModule ()->getFunction (call->target )->effects .get ();
162+
163+ if (effects && !effects->throws_ ) {
164+ mayThrow = false ;
165+ }
166+ }
167+
168+ handleCall (mayThrow, call->isReturn );
157169 return ;
158170 }
159171 case Expression::Id::CallRefId: {
160- handleCall (curr->cast <CallRef>()->isReturn );
172+ auto * callRef = curr->cast <CallRef>();
173+
174+ // TODO: Effect analysis for indirect calls isn't implemented yet.
175+ // Assume any indirect call my throw for now.
176+ bool mayThrow = !self->getModule () ||
177+ self->getModule ()->features .hasExceptionHandling ();
178+
179+ handleCall (mayThrow, callRef->isReturn );
161180 return ;
162181 }
163182 case Expression::Id::TryId: {
0 commit comments