[flang-commits] [flang] 815fddf - [flang] Impose DATA initialization size limit to avoid crashing

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Sat Dec 17 07:27:49 PST 2022


Author: Peter Klausler
Date: 2022-12-17T07:27:31-08:00
New Revision: 815fddfa1782ac2bb416f6c878e0c0c7f4f3575f

URL: https://github.com/llvm/llvm-project/commit/815fddfa1782ac2bb416f6c878e0c0c7f4f3575f
DIFF: https://github.com/llvm/llvm-project/commit/815fddfa1782ac2bb416f6c878e0c0c7f4f3575f.diff

LOG: [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

Added: 
    

Modified: 
    flang/lib/Semantics/data-to-inits.cpp
    flang/lib/Semantics/expression.cpp

Removed: 
    


################################################################################
diff  --git a/flang/lib/Semantics/data-to-inits.cpp b/flang/lib/Semantics/data-to-inits.cpp
index 70d16532d240d..77d6107a93d38 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<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()) {

diff  --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp
index daf763c440d2f..897f3271f7521 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);


        


More information about the flang-commits mailing list