mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-17 23:36:40 +00:00
[flang][Semantics] Ensure deterministic mod file output (#128655)
This PR adds a test to ensure deterministic ordering in `.mod` files. It also includes related changes to prevent non-deterministic symbol ordering caused by pointers outside the cooked source. This issue is particularly noticeable when using Flang as a library and compiling the same files multiple times.
This commit is contained in:
parent
7717a549e9
commit
722c7c0b0f
@ -836,18 +836,6 @@ void ModFileWriter::PutUseExtraAttr(
|
||||
}
|
||||
}
|
||||
|
||||
static inline SourceName NameInModuleFile(const Symbol &symbol) {
|
||||
if (const auto *use{symbol.detailsIf<UseDetails>()}) {
|
||||
if (use->symbol().attrs().test(Attr::PRIVATE)) {
|
||||
// Avoid the use in sorting of names created to access private
|
||||
// specific procedures as a result of generic resolution;
|
||||
// they're not in the cooked source.
|
||||
return use->symbol().name();
|
||||
}
|
||||
}
|
||||
return symbol.name();
|
||||
}
|
||||
|
||||
// Collect the symbols of this scope sorted by their original order, not name.
|
||||
// Generics and namelists are exceptions: they are sorted after other symbols.
|
||||
void CollectSymbols(const Scope &scope, SymbolVector &sorted,
|
||||
@ -882,13 +870,8 @@ void CollectSymbols(const Scope &scope, SymbolVector &sorted,
|
||||
sorted.push_back(symbol);
|
||||
}
|
||||
}
|
||||
// Sort most symbols by name: use of Symbol::ReplaceName ensures the source
|
||||
// location of a symbol's name is the first "real" use.
|
||||
auto sorter{[](SymbolRef x, SymbolRef y) {
|
||||
return NameInModuleFile(*x).begin() < NameInModuleFile(*y).begin();
|
||||
}};
|
||||
std::sort(sorted.begin(), sorted.end(), sorter);
|
||||
std::sort(generics.begin(), generics.end(), sorter);
|
||||
std::sort(sorted.begin(), sorted.end(), SymbolSourcePositionCompare{});
|
||||
std::sort(generics.begin(), generics.end(), SymbolSourcePositionCompare{});
|
||||
sorted.insert(sorted.end(), generics.begin(), generics.end());
|
||||
sorted.insert(sorted.end(), namelist.begin(), namelist.end());
|
||||
for (const auto &pair : scope.commonBlocks()) {
|
||||
|
13
flang/test/Semantics/Inputs/modfile72.f90
Normal file
13
flang/test/Semantics/Inputs/modfile72.f90
Normal file
@ -0,0 +1,13 @@
|
||||
module foo
|
||||
interface do_foo
|
||||
procedure do_foo_impl
|
||||
end interface
|
||||
interface do_bar
|
||||
procedure do_bar_impl
|
||||
end interface
|
||||
contains
|
||||
subroutine do_foo_impl()
|
||||
end
|
||||
subroutine do_bar_impl()
|
||||
end
|
||||
end
|
28
flang/test/Semantics/modfile72.f90
Normal file
28
flang/test/Semantics/modfile72.f90
Normal file
@ -0,0 +1,28 @@
|
||||
! This test verifies that both invocations produce a consistent order in the
|
||||
! generated `.mod` file. Previous versions of Flang exhibited non-deterministic
|
||||
! behavior due to pointers outside the cooked source being used to order symbols
|
||||
! in the `.mod` file.
|
||||
|
||||
! RUN: rm -rf %t && mkdir -p %t
|
||||
! RUN: %flang_fc1 -fsyntax-only -J%t %S/Inputs/modfile72.f90
|
||||
! RUN: %flang_fc1 -fsyntax-only -J%t %s
|
||||
! RUN: cat %t/bar.mod | FileCheck %s
|
||||
|
||||
! RUN: rm -rf %t && mkdir -p %t
|
||||
! RUN: %flang_fc1 -fsyntax-only -J%t %S/Inputs/modfile72.f90 %s
|
||||
! RUN: cat %t/bar.mod | FileCheck %s
|
||||
|
||||
module bar
|
||||
use foo, only : do_foo
|
||||
use foo, only : do_bar
|
||||
contains
|
||||
subroutine do_baz()
|
||||
call do_foo()
|
||||
call do_bar()
|
||||
end
|
||||
end
|
||||
|
||||
! CHECK: use foo,only:do_foo
|
||||
! CHECK-NEXT: use foo,only:do_bar
|
||||
! CHECK-NEXT: use foo,only:foo$foo$do_bar_impl=>do_bar_impl
|
||||
! CHECK-NEXT: use foo,only:foo$foo$do_foo_impl=>do_foo_impl
|
Loading…
x
Reference in New Issue
Block a user