diff options
author | Steven Wu <stevenwu@apple.com> | 2023-02-02 15:07:16 -0800 |
---|---|---|
committer | Steven Wu <stevenwu@apple.com> | 2023-02-02 15:16:20 -0800 |
commit | 0480748ea6728392886931b8470969ae17aaa91f (patch) | |
tree | bcabf0a48345ba67755101263d9be79b7bedcf40 /clang/lib/Parse/ParseDecl.cpp | |
parent | bf07de38b05e4c952beb4009aa15060d0e4f7cc7 (diff) | |
download | llvm-0480748ea6728392886931b8470969ae17aaa91f.zip llvm-0480748ea6728392886931b8470969ae17aaa91f.tar.gz llvm-0480748ea6728392886931b8470969ae17aaa91f.tar.bz2 |
[DeclContext] Sort the Decls before adding into DeclContext
Fix a non-deterministic issue in clang module generation, which the
anonymous declaration number from a function context is not
deterministic. This is due to the unstable iteration order for decls in
scope so the order after moving the decls into function decl context is
not deterministic.
From https://reviews.llvm.org/D135118, we can't use a set that preserves
the order without the performance penalty. Fix the issue by sorting the
decls based on raw encoding of their source location.
rdar://104097976
Reviewed By: akyrtzi, vsapsai
Differential Revision: https://reviews.llvm.org/D141625
Diffstat (limited to 'clang/lib/Parse/ParseDecl.cpp')
-rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index e6812ac..96c25ba 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -6987,6 +6987,15 @@ void Parser::ParseFunctionDeclarator(Declarator &D, continue; DeclsInPrototype.push_back(ND); } + // Sort DeclsInPrototype based on raw encoding of the source location. + // Scope::decls() is iterating over a SmallPtrSet so sort the Decls before + // moving to DeclContext. This provides a stable ordering for traversing + // Decls in DeclContext, which is important for tasks like ASTWriter for + // deterministic output. + llvm::sort(DeclsInPrototype, [](Decl *D1, Decl *D2) { + return D1->getLocation().getRawEncoding() < + D2->getLocation().getRawEncoding(); + }); } // Remember that we parsed a function type, and remember the attributes. |