From: Peter Klausler Date: Mon, 12 Dec 2022 21:58:07 +0000 (-0800) Subject: [flang] Impose DATA initialization size limit to avoid crashing X-Git-Tag: upstream/17.0.6~23404 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=815fddfa1782ac2bb416f6c878e0c0c7f4f3575f;p=platform%2Fupstream%2Fllvm.git [flang] Impose DATA initialization size limit to avoid crashing 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 --- diff --git a/flang/lib/Semantics/data-to-inits.cpp b/flang/lib/Semantics/data-to-inits.cpp index 70d1653..77d6107 100644 --- a/flang/lib/Semantics/data-to-inits.cpp +++ b/flang/lib/Semantics/data-to-inits.cpp @@ -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 @@ -356,6 +361,13 @@ bool DataInitializationCompiler::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(offsetSymbol.offset() + offsetSymbol.size()) > symbol.size()) { diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp index daf763c..897f327 100644 --- a/flang/lib/Semantics/expression.cpp +++ b/flang/lib/Semantics/expression.cpp @@ -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);