Skip to content

Commit

Permalink
Fix bugs
Browse files Browse the repository at this point in the history
* better address infinite loop issue
* fix problem with instantiation type for type variables
  • Loading branch information
mppf committed Aug 7, 2020
1 parent 2f1db84 commit f0f5785
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 14 deletions.
15 changes: 10 additions & 5 deletions compiler/resolution/ResolutionCandidate.cpp
Expand Up @@ -521,13 +521,18 @@ Type* getInstantiationType(Type* actualType, Symbol* actualSym,
}

bool inOrOutFormal(ArgSymbol* formal) {
return (formal->intent == INTENT_IN ||
formal->originalIntent == INTENT_IN ||
formal->intent == INTENT_CONST_IN ||
// Rule out type/param variables
if (formal->hasFlag(FLAG_TYPE_VARIABLE) ||
formal->hasFlag(FLAG_PARAM) ||
formal->intent == INTENT_TYPE ||
formal->originalIntent == INTENT_TYPE ||
formal->intent == INTENT_PARAM ||
formal->originalIntent == INTENT_PARAM)
return false;

return (formal->originalIntent == INTENT_IN ||
formal->originalIntent == INTENT_CONST_IN ||
formal->intent == INTENT_OUT ||
formal->originalIntent == INTENT_OUT ||
formal->intent == INTENT_INOUT ||
formal->originalIntent == INTENT_INOUT);
}

Expand Down
34 changes: 25 additions & 9 deletions compiler/resolution/functionResolution.cpp
Expand Up @@ -428,6 +428,29 @@ Type* getCopyTypeDuringResolution(Type* t) {
return t;
}

static Type* canCoerceToCopyType(Type* actualType, Symbol* actualSym,
Type* formalType, ArgSymbol* formalSym,
FnSymbol* fn) {

Type* copyType = NULL;

if (isSyncType(actualType) || isSingleType(actualType)) {
copyType = getCopyTypeDuringResolution(actualType);
} else if (isAliasingArray(actualType) ||
actualType->symbol->hasFlag(FLAG_ITERATOR_RECORD)) {
// Is the formal an array type? If not, coercion to copy
// will not be relevant.
// This check is here to avoid an infinite loop.
if (formalType == dtAny ||
formalType->symbol->hasFlag(FLAG_ARRAY)) {
copyType = getCopyTypeDuringResolution(actualType);
}
}

if (copyType == dtUnknown) copyType = NULL;
return copyType;
}

FnSymbol* getInitCopyDuringResolution(Type* type) {
std::map<Type*, FnSymbol*>::iterator it = initCopyMap.find(type);

Expand Down Expand Up @@ -1559,15 +1582,8 @@ bool canCoerce(Type* actualType,
return true;
}

// TODO: if we can avoid an inifinite loop, it would be better
// for the below to always call getCopyTypeDuringResolution
// in order to make canCoerce more consistent.
if ((isSyncType(actualType) || isSingleType(actualType)) ||
(formalSym != NULL &&
(formalSym->originalIntent == INTENT_IN ||
formalSym->originalIntent == INTENT_CONST_IN ||
formalSym->originalIntent == INTENT_INOUT))) {
Type* copyType = getCopyTypeDuringResolution(actualType);
if (Type* copyType = canCoerceToCopyType(actualType, actualSym,
formalType, formalSym, fn)) {
if (copyType != actualType) {
return canDispatch(copyType, actualSym, formalType, formalSym, fn,
promotes, paramNarrows);
Expand Down

0 comments on commit f0f5785

Please sign in to comment.