YAMLTraits.h: replace DenseMap that used a bad implementation of DenseMapInfo

for StringRef with a StringMap

The bug is that the empty key compares equal to the tombstone key.

Also added an assertion to DenseMap to catch similar bugs in future.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@187866 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Dmitri Gribenko 2013-08-07 05:51:27 +00:00
parent 235089bdae
commit 9e8eafa0f0
4 changed files with 8 additions and 12 deletions

View File

@ -606,6 +606,9 @@ public:
}
void init(unsigned InitBuckets) {
assert(!KeyInfoT::isEqual(this->getEmptyKey(), this->getTombstoneKey()) &&
"Bad implementation of KeyInfoT: empty key and tombstone key "
"should be different");
if (allocateBuckets(InitBuckets)) {
this->BaseT::initEmpty();
} else {

View File

@ -14,7 +14,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Twine.h"
@ -760,15 +760,7 @@ private:
}
static inline bool classof(const MapHNode *) { return true; }
struct StrMappingInfo {
static StringRef getEmptyKey() { return StringRef(); }
static StringRef getTombstoneKey() { return StringRef(" ", 0); }
static unsigned getHashValue(StringRef const val) {
return llvm::HashString(val); }
static bool isEqual(StringRef const lhs,
StringRef const rhs) { return lhs.equals(rhs); }
};
typedef llvm::DenseMap<StringRef, HNode*, StrMappingInfo> NameToNode;
typedef llvm::StringMap<HNode*> NameToNode;
bool isValidKey(StringRef key);

View File

@ -13,6 +13,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/Object/YAML.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;

View File

@ -127,8 +127,8 @@ void Input::endMapping() {
return;
for (MapHNode::NameToNode::iterator i = MN->Mapping.begin(),
End = MN->Mapping.end(); i != End; ++i) {
if (!MN->isValidKey(i->first)) {
setError(i->second, Twine("unknown key '") + i->first + "'");
if (!MN->isValidKey(i->first())) {
setError(i->second, Twine("unknown key '") + i->first() + "'");
break;
}
}