forked from OSchip/llvm-project
[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:
parent
d72fd348f7
commit
3e313d43e1
|
@ -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)))) ||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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(
|
||||
|
|
Loading…
Reference in New Issue