Fixed diagnostic nondeterministic order bug (pr14901).
authorEnea Zaffanella <zaffanella@cs.unipr.it>
Fri, 15 Feb 2013 20:09:55 +0000 (20:09 +0000)
committerEnea Zaffanella <zaffanella@cs.unipr.it>
Fri, 15 Feb 2013 20:09:55 +0000 (20:09 +0000)
llvm-svn: 175289

clang/lib/Sema/AnalysisBasedWarnings.cpp
clang/test/Sema/uninit-det-order.c [new file with mode: 0644]

index c2b54d0..e9cf7cc 100644 (file)
@@ -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 @@ struct SLocSort {
 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 @@ public:
     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 @@ public:
   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/clang/test/Sema/uninit-det-order.c b/clang/test/Sema/uninit-det-order.c
new file mode 100644 (file)
index 0000000..041c4b0
--- /dev/null
@@ -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
+