From c709f503d7969945f7242a71325c2d4632b32b1c Mon Sep 17 00:00:00 2001 From: Peter Klausler Date: Thu, 31 Mar 2022 12:55:45 -0700 Subject: [PATCH] [flang] Emit a portability warning for padding in COMMON When padding is required in a COMMON block to ensure alignment of a component, emit a portability warning. Differential Revision: https://reviews.llvm.org/D123706 --- flang/lib/Semantics/compute-offsets.cpp | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/flang/lib/Semantics/compute-offsets.cpp b/flang/lib/Semantics/compute-offsets.cpp index ea3b70f..5698ef4 100644 --- a/flang/lib/Semantics/compute-offsets.cpp +++ b/flang/lib/Semantics/compute-offsets.cpp @@ -50,7 +50,8 @@ private: void DoEquivalenceSet(const EquivalenceSet &); SymbolAndOffset Resolve(const SymbolAndOffset &); std::size_t ComputeOffset(const EquivalenceObject &); - void DoSymbol(Symbol &); + // Returns amount of padding that was needed for alignment + std::size_t DoSymbol(Symbol &); SizeAndAlignment GetSizeAndAlignment(const Symbol &, bool entire); std::size_t Align(std::size_t, std::size_t); @@ -150,7 +151,13 @@ void ComputeOffsetsHelper::DoCommonBlock(Symbol &commonBlock) { std::size_t minAlignment{0}; for (auto &object : details.objects()) { Symbol &symbol{*object}; - DoSymbol(symbol); + auto errorSite{ + commonBlock.name().empty() ? symbol.name() : commonBlock.name()}; + if (std::size_t padding{DoSymbol(symbol)}) { + context_.Say(errorSite, + "COMMON block /%s/ requires %zd bytes of padding before '%s' for alignment"_port_en_US, + commonBlock.name(), padding, symbol.name()); + } auto eqIter{equivalenceBlock_.end()}; auto iter{dependents_.find(symbol)}; if (iter == dependents_.end()) { @@ -161,8 +168,6 @@ void ComputeOffsetsHelper::DoCommonBlock(Symbol &commonBlock) { } else { SymbolAndOffset &dep{iter->second}; Symbol &base{*dep.symbol}; - auto errorSite{ - commonBlock.name().empty() ? symbol.name() : commonBlock.name()}; if (const auto *baseBlock{FindCommonBlockContaining(base)}) { if (baseBlock == &commonBlock) { context_.Say(errorSite, @@ -287,19 +292,22 @@ std::size_t ComputeOffsetsHelper::ComputeOffset( return result; } -void ComputeOffsetsHelper::DoSymbol(Symbol &symbol) { +std::size_t ComputeOffsetsHelper::DoSymbol(Symbol &symbol) { if (!symbol.has() && !symbol.has()) { - return; + return 0; } SizeAndAlignment s{GetSizeAndAlignment(symbol, true)}; if (s.size == 0) { - return; + return 0; } + std::size_t previousOffset{offset_}; offset_ = Align(offset_, s.alignment); + std::size_t padding{offset_ - previousOffset}; symbol.set_size(s.size); symbol.set_offset(offset_); offset_ += s.size; alignment_ = std::max(alignment_, s.alignment); + return padding; } auto ComputeOffsetsHelper::GetSizeAndAlignment( -- 2.7.4