diff --git a/flang/lib/Semantics/data-to-inits.cpp b/flang/lib/Semantics/data-to-inits.cpp --- a/flang/lib/Semantics/data-to-inits.cpp +++ b/flang/lib/Semantics/data-to-inits.cpp @@ -30,6 +30,11 @@ // objects and pointers. static constexpr bool removeOriginalInits{false}; +// Impose a hard limit that's more than large enough for real applications but +// small enough to cause artificial stress tests to fail reasonably instead of +// crashing the compiler with a memory allocation failure. +static constexpr auto maxDataInitBytes{std::size_t{1000000000}}; // 1GiB + namespace Fortran::semantics { // Steps through a list of values in a DATA statement set; implements @@ -356,6 +361,13 @@ const SomeExpr *expr{*values_}; if (!expr) { CHECK(exprAnalyzer_.context().AnyFatalError()); + } else if (symbol.size() > maxDataInitBytes) { + evaluate::AttachDeclaration( + exprAnalyzer_.context().Say( + "'%s' is too large to initialize with a DATA statement"_todo_en_US, + symbol.name()), + symbol); + return false; } else if (isPointer) { if (static_cast(offsetSymbol.offset() + offsetSymbol.size()) > symbol.size()) { diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp --- a/flang/lib/Semantics/expression.cpp +++ b/flang/lib/Semantics/expression.cpp @@ -2103,6 +2103,11 @@ if (dataRef && !CheckDataRef(*dataRef)) { return std::nullopt; } + if (dataRef && dataRef->Rank() > 0 && sym->attrs().test(semantics::Attr::NOPASS)) { + // C1529 seems unnecessary and most compilers don't enforce it. + Say(sc.component.source, + "Base of procedure component reference should be scalar when NOPASS component or binding '%s' is referenced"_port_en_US, sc.component.source); + } if (const Symbol *resolution{ GetBindingResolution(dtExpr->GetType(), *sym)}) { AddPassArg(arguments, std::move(*dtExpr), *sym, false);