Fixed diagnostic nondeterministic order bug (pr14901).


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@175289 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/AnalysisBasedWarnings.cpp b/lib/Sema/AnalysisBasedWarnings.cpp
index c2b54d0..e9cf7cc 100644
--- a/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/lib/Sema/AnalysisBasedWarnings.cpp
@@ -41,6 +41,7 @@
 #include "llvm/ADT/BitVector.h"
 #include "llvm/ADT/FoldingSet.h"
 #include "llvm/ADT/ImmutableMap.h"
+#include "llvm/ADT/MapVector.h"
 #include "llvm/ADT/PostOrderIterator.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/SmallVector.h"
@@ -1149,7 +1150,11 @@
 class UninitValsDiagReporter : public UninitVariablesHandler {
   Sema &S;
   typedef SmallVector<UninitUse, 2> UsesVec;
-  typedef llvm::DenseMap<const VarDecl *, std::pair<UsesVec*, bool> > UsesMap;
+  typedef std::pair<UsesVec*, bool> MappedType;
+  // Prefer using MapVector to DenseMap, so that iteration order will be
+  // the same as insertion order. This is needed to obtain a deterministic
+  // order of diagnostics when calling flushDiagnostics().
+  typedef llvm::MapVector<const VarDecl *, MappedType> UsesMap;
   UsesMap *uses;
   
 public:
@@ -1158,11 +1163,11 @@
     flushDiagnostics();
   }
 
-  std::pair<UsesVec*, bool> &getUses(const VarDecl *vd) {
+  MappedType &getUses(const VarDecl *vd) {
     if (!uses)
       uses = new UsesMap();
 
-    UsesMap::mapped_type &V = (*uses)[vd];
+    MappedType &V = (*uses)[vd];
     UsesVec *&vec = V.first;
     if (!vec)
       vec = new UsesVec();
@@ -1181,12 +1186,10 @@
   void flushDiagnostics() {
     if (!uses)
       return;
-    
-    // FIXME: This iteration order, and thus the resulting diagnostic order,
-    //        is nondeterministic.
+
     for (UsesMap::iterator i = uses->begin(), e = uses->end(); i != e; ++i) {
       const VarDecl *vd = i->first;
-      const UsesMap::mapped_type &V = i->second;
+      const MappedType &V = i->second;
 
       UsesVec *vec = V.first;
       bool hasSelfInit = V.second;
diff --git a/test/Sema/uninit-det-order.c b/test/Sema/uninit-det-order.c
new file mode 100644
index 0000000..041c4b0
--- /dev/null
+++ b/test/Sema/uninit-det-order.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -Wuninitialized -fsyntax-only %s 2>&1 | FileCheck %s
+
+void pr14901(int a) {
+   int b, c;
+   a = b;
+   a = c;
+}
+
+// CHECK: 5:8: warning: variable 'b' is uninitialized when used here
+// CHECK: 4:9: note: initialize the variable 'b' to silence this warning
+// CHECK: 6:8: warning: variable 'c' is uninitialized when used here
+// CHECK: 4:12: note: initialize the variable 'c' to silence this warning
+