From 2f40be7511eb9652181a8d46cd257e233e6a1375 Mon Sep 17 00:00:00 2001 From: Enea Zaffanella Date: Fri, 15 Feb 2013 20:09:55 +0000 Subject: [PATCH] Fixed diagnostic nondeterministic order bug (pr14901). llvm-svn: 175289 --- clang/lib/Sema/AnalysisBasedWarnings.cpp | 17 ++++++++++------- clang/test/Sema/uninit-det-order.c | 13 +++++++++++++ 2 files changed, 23 insertions(+), 7 deletions(-) create mode 100644 clang/test/Sema/uninit-det-order.c diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp index c2b54d0..e9cf7cc 100644 --- a/clang/lib/Sema/AnalysisBasedWarnings.cpp +++ b/clang/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 @@ struct SLocSort { class UninitValsDiagReporter : public UninitVariablesHandler { Sema &S; typedef SmallVector UsesVec; - typedef llvm::DenseMap > UsesMap; + typedef std::pair 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 UsesMap; UsesMap *uses; public: @@ -1158,11 +1163,11 @@ public: flushDiagnostics(); } - std::pair &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 index 0000000..041c4b0 --- /dev/null +++ b/clang/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 + -- 2.7.4