Fix PR22750: non-determinism causes assertion failure in DWARF generation
authorDario Domizioli <dario.domizioli@gmail.com>
Tue, 3 Mar 2015 18:40:53 +0000 (18:40 +0000)
committerDario Domizioli <dario.domizioli@gmail.com>
Tue, 3 Mar 2015 18:40:53 +0000 (18:40 +0000)
The cause of the issue is the interaction of two factors:
1) When generating a DW_TAG_imported_declaration DIE which imports another
   imported declaration, the code in AsmPrinter/DwarfCompileUnit.cpp
   asserts that the second imported declaration must already have a DIE.
2) There is a non-determinism in the order in which imported declarations
   within the same scope are processed.
Because of the non-determinism (2), it is possible that an imported
declaration is processed before another one it depends on, breaking the
assumption in (1).

The source of the non-determinism is that the imported declaration
DIDescriptors are sorted by scope in DwarfDebug::beginModule(); however that
sort is not a stable_sort, therefore the order of the declarations within
the same scope is not preserved. The attached patch changes the std::sort to
a std::stable_sort and it fixes the problem.

Test omitted due to it being non-deterministic and depending on the
implementation of std::sort.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@231100 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/AsmPrinter/DwarfDebug.cpp

index 1cc0581b83410180ce28ff10c275a8e0c9f94263..6367694026d25a34f6d73df895453c4650506022 100644 (file)
@@ -477,8 +477,11 @@ void DwarfDebug::beginModule() {
       ScopesWithImportedEntities.push_back(std::make_pair(
           DIImportedEntity(ImportedEntities.getElement(i)).getContext(),
           ImportedEntities.getElement(i)));
-    std::sort(ScopesWithImportedEntities.begin(),
-              ScopesWithImportedEntities.end(), less_first());
+    // Stable sort to preserve the order of appearance of imported entities.
+    // This is to avoid out-of-order processing of interdependent declarations
+    // within the same scope, e.g. { namespace A = base; namespace B = A; }
+    std::stable_sort(ScopesWithImportedEntities.begin(),
+                     ScopesWithImportedEntities.end(), less_first());
     DIArray GVs = CUNode.getGlobalVariables();
     for (unsigned i = 0, e = GVs.getNumElements(); i != e; ++i)
       CU.getOrCreateGlobalVariableDIE(DIGlobalVariable(GVs.getElement(i)));