compiler/resolution/lowerIterators.cpp
/* When inlining an iterator, the iterator might throw
   an error. If it does, instead of updating the iterator's
   out error argument, the error should propagate to
   a following error-handling block if one exists.
 */
When inlining an iterator, the iterator might throw
an error. If it does, instead of updating the iterator's
out error argument, the error should propagate to
a following error-handling block if one exists.
When inlining an iterator the iterator might throw an error . If it does instead of updating the iterator ' s out error argument the error should propagate to a following error - handling block if one exists .
static void
replaceErrorFormalWithEnclosingError(SymExpr* se) {
  Symbol* oldSymbol = se->symbol();
  if (oldSymbol->defPoint->parentSymbol != se->parentSymbol &&
      oldSymbol->hasFlag(FLAG_ERROR_VARIABLE)) {
    LabelSymbol* newLabel = NULL;
    Symbol* newError = NULL;
    CallExpr* parentCall = toCallExpr(se->parentExpr);
    INT_ASSERT(parentCall->isPrimitive(PRIM_MOVE) ||
               parentCall->isPrimitive(PRIM_ASSIGN));
    INT_ASSERT(se == parentCall->get(1));
    FnSymbol* inFn = toFnSymbol(se->parentSymbol);
    GotoStmt* fixGoto = NULL;
    for(Expr* cur = se->getStmtExpr(); cur != NULL; cur = cur->next) {
      fixGoto = toGotoStmt(cur);
      if (fixGoto != NULL)
        break;
    }
    INT_ASSERT(fixGoto);
    if (findFollowingCheckErrorBlock(se, newLabel, newError)) {
      se->setSymbol(newError);
      fixGoto->gotoTag = GOTO_ERROR_HANDLING;
      fixGoto->label->replace(new SymExpr(newLabel));
    } else if(canFunctionImplicitlyThrow(inFn)) {
      ArgSymbol* errorArg = findErrorFormalForFn(inFn);
      if (errorArg == NULL) {
        errorArg = addDummyErrorFormalToFn(inFn);
        for_SymbolSymExprs(se, inFn) {
          CallExpr* call = toCallExpr(se->parentExpr);
          addDummyErrorArgumentToCall(call);
        }
      }
      se->setSymbol(errorArg);
      INT_ASSERT(fixGoto->gotoTag == GOTO_RETURN);
    } else {
      VarSymbol* tmp = newTemp("error", dtError);
      parentCall->insertBefore(new DefExpr(tmp));
      se->setSymbol(tmp);
      fixGoto->replace(new CallExpr(gChplUncaughtError, tmp));
    }
  }
}
static void replaceErrorFormalWithEnclosingError ( SymExpr * se ) { Symbol * oldSymbol = se -> symbol ( ) ; if ( oldSymbol -> defPoint -> parentSymbol != se -> parentSymbol && oldSymbol -> hasFlag ( FLAG_ERROR_VARIABLE ) ) { LabelSymbol * newLabel = NULL ; Symbol * newError = NULL ; CallExpr * parentCall = toCallExpr ( se -> parentExpr ) ; INT_ASSERT ( parentCall -> isPrimitive ( PRIM_MOVE ) || parentCall -> isPrimitive ( PRIM_ASSIGN ) ) ; INT_ASSERT ( se == parentCall -> get ( 1 ) ) ; FnSymbol * inFn = toFnSymbol ( se -> parentSymbol ) ; GotoStmt * fixGoto = NULL ; for ( Expr * cur = se -> getStmtExpr ( ) ; cur != NULL ; cur = cur -> next ) { fixGoto = toGotoStmt ( cur ) ; if ( fixGoto != NULL ) break ; } INT_ASSERT ( fixGoto ) ; if ( findFollowingCheckErrorBlock ( se , newLabel , newError ) ) { se -> setSymbol ( newError ) ; fixGoto -> gotoTag = GOTO_ERROR_HANDLING ; fixGoto -> label -> replace ( new SymExpr ( newLabel ) ) ; } else if ( canFunctionImplicitlyThrow ( inFn ) ) { ArgSymbol * errorArg = findErrorFormalForFn ( inFn ) ; if ( errorArg == NULL ) { errorArg = addDummyErrorFormalToFn ( inFn ) ; for_SymbolSymExprs ( se , inFn ) { CallExpr * call = toCallExpr ( se -> parentExpr ) ; addDummyErrorArgumentToCall ( call ) ; } } se -> setSymbol ( errorArg ) ; INT_ASSERT ( fixGoto -> gotoTag == GOTO_RETURN ) ; } else { VarSymbol * tmp = newTemp ( " " , dtError ) ; parentCall -> insertBefore ( new DefExpr ( tmp ) ) ; se -> setSymbol ( tmp ) ; fixGoto -> replace ( new CallExpr ( gChplUncaughtError , tmp ) ) ; } } }
When inlining an iterator, the iterator might throw
an error.
When inlining an iterator the iterator might throw an error .
// This code is only written to handle a PRIM_MOVE/ASSIGN // that is setting the out error argument of the iterator. // This out error argument is no longer available since the // iterator is being inlined. // find the Goto we need to replace // Adjust the current error handling block. // 1. Change the use of the error argument to use the // identified error variable. // 2. Change the Goto to point to the identified error label. // 1. Make sure that the task function has an error argument. // 2. Set that out argument instead of the invalid one. // And adjust callers of this function // Just call gChplUncaughtError