diff options
| -rw-r--r-- | llvm/lib/VMCore/Type.cpp | 30 | ||||
| -rw-r--r-- | llvm/unittests/VMCore/TypesTest.cpp | 30 | 
2 files changed, 50 insertions, 10 deletions
| diff --git a/llvm/lib/VMCore/Type.cpp b/llvm/lib/VMCore/Type.cpp index c6f35580e15..5e9a00fc085 100644 --- a/llvm/lib/VMCore/Type.cpp +++ b/llvm/lib/VMCore/Type.cpp @@ -464,19 +464,26 @@ void StructType::setBody(ArrayRef<Type*> Elements, bool isPacked) {  void StructType::setName(StringRef Name) {    if (Name == getName()) return; -  // If this struct already had a name, remove its symbol table entry. -  if (SymbolTableEntry) { -    getContext().pImpl->NamedStructTypes.erase(getName()); -    SymbolTableEntry = 0; -  } -   +  StringMap<StructType *> &SymbolTable = getContext().pImpl->NamedStructTypes; +  typedef StringMap<StructType *>::MapEntryTy EntryTy; + +  // If this struct already had a name, remove its symbol table entry. Don't +  // delete the data yet because it may be part of the new name. +  if (SymbolTableEntry) +    SymbolTable.remove((EntryTy *)SymbolTableEntry); +    // If this is just removing the name, we're done. -  if (Name.empty()) +  if (Name.empty()) { +    if (SymbolTableEntry) { +      // Delete the old string data. +      ((EntryTy *)SymbolTableEntry)->Destroy(SymbolTable.getAllocator()); +      SymbolTableEntry = 0; +    }      return; +  }    // Look up the entry for the name. -  StringMapEntry<StructType*> *Entry = -    &getContext().pImpl->NamedStructTypes.GetOrCreateValue(Name); +  EntryTy *Entry = &getContext().pImpl->NamedStructTypes.GetOrCreateValue(Name);    // While we have a name collision, try a random rename.    if (Entry->getValue()) { @@ -497,7 +504,10 @@ void StructType::setName(StringRef Name) {    // Okay, we found an entry that isn't used.  It's us!    Entry->setValue(this); -     + +  // Delete the old string data. +  if (SymbolTableEntry) +    ((EntryTy *)SymbolTableEntry)->Destroy(SymbolTable.getAllocator());    SymbolTableEntry = Entry;  } diff --git a/llvm/unittests/VMCore/TypesTest.cpp b/llvm/unittests/VMCore/TypesTest.cpp new file mode 100644 index 00000000000..0416643221e --- /dev/null +++ b/llvm/unittests/VMCore/TypesTest.cpp @@ -0,0 +1,30 @@ +//===- llvm/unittest/VMCore/TypesTest.cpp - Type unit tests ---------------===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/DerivedTypes.h" +#include "llvm/LLVMContext.h" +#include "gtest/gtest.h" +using namespace llvm; + +namespace { + +TEST(TypesTest, StructType) { +  LLVMContext C; + +  // PR13522 +  StructType *Struct = StructType::create(C, "FooBar"); +  EXPECT_EQ("FooBar", Struct->getName()); +  Struct->setName(Struct->getName().substr(0, 3)); +  EXPECT_EQ("Foo", Struct->getName()); +  Struct->setName(""); +  EXPECT_TRUE(Struct->getName().empty()); +  EXPECT_FALSE(Struct->hasName()); +} + +}  // end anonymous namespace | 

