Skip to content

Commit

Permalink
[flang] Impose DATA initialization size limit to avoid crashing
Browse files Browse the repository at this point in the history
Impose a large but finite limit on the size of a variable being
initialized in a DATA statement to provide a readable error message
for artificial test cases that's better than a memory allocation
failure crash.

Differential Revision: https://reviews.llvm.org/D140146
  • Loading branch information
klausler committed Dec 17, 2022
1 parent 10539ec commit 815fddf
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 0 deletions.
12 changes: 12 additions & 0 deletions flang/lib/Semantics/data-to-inits.cpp
Expand Up @@ -30,6 +30,11 @@ static constexpr bool makeDefaultInitializationExplicit{false};
// 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
Expand Down Expand Up @@ -356,6 +361,13 @@ bool DataInitializationCompiler<DSV>::InitElement(
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<std::size_t>(offsetSymbol.offset() + offsetSymbol.size()) >
symbol.size()) {
Expand Down
5 changes: 5 additions & 0 deletions flang/lib/Semantics/expression.cpp
Expand Up @@ -2103,6 +2103,11 @@ auto ExpressionAnalyzer::AnalyzeProcedureComponentRef(
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);
Expand Down

0 comments on commit 815fddf

Please sign in to comment.