diff --git a/flang/runtime/file.cpp b/flang/runtime/file.cpp --- a/flang/runtime/file.cpp +++ b/flang/runtime/file.cpp @@ -352,7 +352,7 @@ int OpenFile::PendingResult(const Terminator &terminator, int iostat) { int id{nextId_++}; - pending_.reset(&New{}(terminator, id, iostat, std::move(pending_))); + pending_ = New{terminator}(id, iostat, std::move(pending_)); return id; } } // namespace Fortran::runtime::io diff --git a/flang/runtime/io-api.cpp b/flang/runtime/io-api.cpp --- a/flang/runtime/io-api.cpp +++ b/flang/runtime/io-api.cpp @@ -28,9 +28,10 @@ void ** /*scratchArea*/, std::size_t /*scratchBytes*/, const char *sourceFile, int sourceLine) { Terminator oom{sourceFile, sourceLine}; - return &New>{}( - oom, descriptor, sourceFile, sourceLine) - .ioStatementState(); + return &New>{oom}( + descriptor, sourceFile, sourceLine) + .release() + ->ioStatementState(); } Cookie IONAME(BeginInternalArrayListOutput)(const Descriptor &descriptor, @@ -52,9 +53,10 @@ const char *format, std::size_t formatLength, void ** /*scratchArea*/, std::size_t /*scratchBytes*/, const char *sourceFile, int sourceLine) { Terminator oom{sourceFile, sourceLine}; - return &New>{}( - oom, descriptor, format, formatLength, sourceFile, sourceLine) - .ioStatementState(); + return &New>{oom}( + descriptor, format, formatLength, sourceFile, sourceLine) + .release() + ->ioStatementState(); } Cookie IONAME(BeginInternalArrayFormattedOutput)(const Descriptor &descriptor, @@ -78,9 +80,10 @@ void ** /*scratchArea*/, std::size_t /*scratchBytes*/, const char *sourceFile, int sourceLine) { Terminator oom{sourceFile, sourceLine}; - return &New>{}(oom, internal, - internalLength, format, formatLength, sourceFile, sourceLine) - .ioStatementState(); + return &New>{oom}( + internal, internalLength, format, formatLength, sourceFile, sourceLine) + .release() + ->ioStatementState(); } Cookie IONAME(BeginInternalFormattedOutput)(char *internal, @@ -234,8 +237,9 @@ } else { // CLOSE(UNIT=bad unit) is just a no-op Terminator oom{sourceFile, sourceLine}; - return &New{}(oom, sourceFile, sourceLine) - .ioStatementState(); + return &New{oom}(sourceFile, sourceLine) + .release() + ->ioStatementState(); } } diff --git a/flang/runtime/memory.h b/flang/runtime/memory.h --- a/flang/runtime/memory.h +++ b/flang/runtime/memory.h @@ -32,20 +32,32 @@ p = nullptr; } -template struct New { - template - [[nodiscard]] A &operator()(const Terminator &terminator, X &&... x) { - return *new (AllocateMemoryOrCrash(terminator, sizeof(A))) - A{std::forward(x)...}; - } -}; - template struct OwningPtrDeleter { void operator()(A *p) { FreeMemory(p); } }; template using OwningPtr = std::unique_ptr>; +template class SizedNew { +public: + explicit SizedNew(const Terminator &terminator) : terminator_{terminator} {} + template + [[nodiscard]] OwningPtr operator()(std::size_t bytes, X &&... x) { + return OwningPtr{new (AllocateMemoryOrCrash(terminator_, bytes)) + A{std::forward(x)...}}; + } + +private: + const Terminator &terminator_; +}; + +template struct New : public SizedNew { + using SizedNew::SizedNew; + template [[nodiscard]] OwningPtr operator()(X &&... x) { + return SizedNew::operator()(sizeof(A), std::forward(x)...); + } +}; + template struct Allocator { using value_type = A; explicit Allocator(const Terminator &t) : terminator{t} {} diff --git a/flang/runtime/unit-map.cpp b/flang/runtime/unit-map.cpp --- a/flang/runtime/unit-map.cpp +++ b/flang/runtime/unit-map.cpp @@ -64,7 +64,7 @@ } ExternalFileUnit &UnitMap::Create(int n, const Terminator &terminator) { - Chain &chain{New{}(terminator, n)}; + Chain &chain{*New{terminator}(n).release()}; chain.next.reset(&chain); bucket_[Hash(n)].swap(chain.next); // pushes new node as list head return chain.unit; diff --git a/flang/runtime/unit.cpp b/flang/runtime/unit.cpp --- a/flang/runtime/unit.cpp +++ b/flang/runtime/unit.cpp @@ -95,7 +95,7 @@ return *unitMap; } Terminator terminator{__FILE__, __LINE__}; - unitMap = &New{}(terminator); + unitMap = New{terminator}().release(); ExternalFileUnit &out{ExternalFileUnit::LookUpOrCreate(6, terminator)}; out.Predefine(1); out.set_mayRead(false);