[flang] Fix correction of misparsed struct const as actual arg, and semantics of MODULE PROCEDURE in INTERFACE

Original-commit: flang-compiler/f18@6c86de6cef
Reviewed-on: https://github.com/flang-compiler/f18/pull/477
Tree-same-pre-rewrite: false
This commit is contained in:
peter klausler 2019-06-03 12:18:52 -07:00
parent d72fd348f7
commit 3e313d43e1
5 changed files with 29 additions and 27 deletions

View File

@ -3311,9 +3311,11 @@ TYPE_PARSER(construct<ActualArgSpec>(
// expr | variable | procedure-name | proc-component-ref |
// alt-return-spec
// N.B. the "procedure-name" and "proc-component-ref" alternatives can't
// yet be distinguished from "variable".
TYPE_PARSER(construct<ActualArg>(variable) / lookAhead(","_tok || ")"_tok) ||
construct<ActualArg>(expr) ||
// yet be distinguished from "variable", many instances of which can't be
// distinguished from "expr" anyway (to do so would misparse structure
// constructors and function calls as array elements).
// Semantics sorts it all out later.
TYPE_PARSER(construct<ActualArg>(expr) ||
construct<ActualArg>(Parser<AltReturnSpec>{}) ||
extension<LanguageFeature::PercentRefAndVal>(construct<ActualArg>(
construct<ActualArg::PercentRef>("%REF" >> parenthesized(variable)))) ||

View File

@ -3100,9 +3100,7 @@ struct ActualArg {
WRAPPER_CLASS(PercentVal, Expr); // %VAL(x) extension
UNION_CLASS_BOILERPLATE(ActualArg);
ActualArg(Expr &&x) : u{common::Indirection<Expr>(std::move(x))} {}
ActualArg(Variable &&x) : u{common::Indirection<Variable>(std::move(x))} {}
std::variant<common::Indirection<Expr>, common::Indirection<Variable>, Name,
ProcComponentRef, AltReturnSpec, PercentRef, PercentVal>
std::variant<common::Indirection<Expr>, AltReturnSpec, PercentRef, PercentVal>
u;
};

View File

@ -1473,9 +1473,9 @@ auto ExpressionAnalyzer::Procedure(const parser::ProcedureDesignator &pd,
pd.u);
}
static const Symbol *AssumedTypeDummy(const parser::Variable &v) {
static const Symbol *AssumedTypeDummy(const parser::Expr &x) {
if (const auto *designator{
std::get_if<common::Indirection<parser::Designator>>(&v.u)}) {
std::get_if<common::Indirection<parser::Designator>>(&x.u)}) {
if (const auto *dataRef{
std::get_if<parser::DataRef>(&designator->value().u)}) {
if (const auto *name{std::get_if<parser::Name>(&dataRef->u)}) {
@ -1508,19 +1508,12 @@ MaybeExpr ExpressionAnalyzer::Analyze(
const Symbol *assumedTypeDummy{nullptr};
std::visit(
common::visitors{
[&](const common::Indirection<parser::Variable> &v) {
if (!(assumedTypeDummy = AssumedTypeDummy(v.value()))) {
actualArgExpr = Analyze(v.value());
}
},
[&](const common::Indirection<parser::Expr> &x) {
actualArgExpr = Analyze(x.value());
},
[&](const parser::Name &n) {
Say("TODO: procedure name actual arg"_err_en_US);
},
[&](const parser::ProcComponentRef &) {
Say("TODO: proc component ref actual arg"_err_en_US);
// TODO: Distinguish & handle procedure name and
// proc-component-ref
if (!(assumedTypeDummy = AssumedTypeDummy(x.value()))) {
actualArgExpr = Analyze(x.value());
}
},
[&](const parser::AltReturnSpec &) {
Say("alternate return specification may not appear on function reference"_err_en_US);
@ -1850,8 +1843,8 @@ static void FixMisparsedFunctionReference(
common::die("can't fix misparsed function as array reference");
}
} else if (const auto *name{std::get_if<parser::Name>(&proc.u)}) {
// Don't convert a procedure component reference into a structure
// constructor, but do check for a misparsed bare name.
// A procedure component reference can't be a structure
// constructor; only check calls to bare names.
const Symbol *derivedType{nullptr};
if (symbol.has<semantics::DerivedTypeDetails>()) {
derivedType = &symbol;

View File

@ -2086,9 +2086,18 @@ void InterfaceVisitor::ResolveSpecificsInGeneric(Symbol &generic) {
continue;
}
if (kind == ProcedureKind::ModuleProcedure) {
const auto *d{symbol->detailsIf<SubprogramNameDetails>()};
if (!d || d->kind() != SubprogramKind::Module) {
Say(*name, "'%s' is not a module procedure"_err_en_US);
if (const auto *nd{symbol->detailsIf<SubprogramNameDetails>()}) {
if (nd->kind() != SubprogramKind::Module) {
Say(*name, "'%s' is not a module procedure"_err_en_US);
}
} else {
// USE-associated procedure
const auto *sd{symbol->detailsIf<SubprogramDetails>()};
CHECK(sd != nullptr);
if (symbol->owner().kind() != Scope::Kind::Module ||
sd->isInterface()) {
Say(*name, "'%s' is not a module procedure"_err_en_US);
}
}
}
if (!namesSeen.insert(name->source).second) {

View File

@ -568,9 +568,9 @@ Symbol &Symbol::Instantiate(
const DeclTypeSpec &newType{scope.InstantiateIntrinsicType(
*origType, semanticsContext)};
details.ReplaceType(newType);
} else {
} else if (origType->category() != DeclTypeSpec::ClassStar) {
common::die("instantiated component has type that is "
"neither intrinsic nor derived");
"neither intrinsic, derived, nor CLASS(*)");
}
}
details.set_init(