summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Bitcode
diff options
context:
space:
mode:
authorTobias Grosser <tobias@grosser.es>2013-07-26 04:16:55 +0000
committerTobias Grosser <tobias@grosser.es>2013-07-26 04:16:55 +0000
commit0a8e12fdbbf54e81954b091ac9fb11cd5f5148e1 (patch)
treee73051e3c61bbe3d9dbd725f92c111e6f6cc4782 /llvm/lib/Bitcode
parentad9a53c510343b65e30700ef2126734ca90ab0b0 (diff)
downloadbcm5719-llvm-0a8e12fdbbf54e81954b091ac9fb11cd5f5148e1.tar.gz
bcm5719-llvm-0a8e12fdbbf54e81954b091ac9fb11cd5f5148e1.zip
Make .bc en/decoding of AttrKind stable
The bitcode representation attribute kinds are encoded into / decoded from should be independent of the current set of LLVM attributes and their position in the AttrKind enum. This patch explicitly encodes attributes to fixed bitcode values. With this patch applied, LLVM does not silently misread attributes written by LLVM 3.3. We also enhance the decoding slightly such that an error message is printed if an unknown AttrKind encoding was dected. Bonus: Dropping bitcode attributes from AttrKind is now easy, as old AttrKinds do not need to be kept to support the Bitcode reader. llvm-svn: 187186
Diffstat (limited to 'llvm/lib/Bitcode')
-rw-r--r--llvm/lib/Bitcode/Reader/BitcodeReader.cpp132
-rw-r--r--llvm/lib/Bitcode/Reader/BitcodeReader.h1
-rw-r--r--llvm/lib/Bitcode/Writer/BitcodeWriter.cpp87
3 files changed, 216 insertions, 4 deletions
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index cf827c5d4b0..e6d7b50b489 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -12,6 +12,7 @@
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/AutoUpgrade.h"
+#include "llvm/Bitcode/LLVMBitCodes.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/InlineAsm.h"
@@ -22,6 +23,7 @@
#include "llvm/Support/DataStream.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
using namespace llvm;
enum {
@@ -506,6 +508,125 @@ bool BitcodeReader::ParseAttributeBlock() {
}
}
+bool BitcodeReader::ParseAttrKind(uint64_t Code, Attribute::AttrKind *Kind) {
+ switch (Code) {
+ case bitc::ATTR_KIND_ALIGNMENT:
+ *Kind = Attribute::Alignment;
+ return false;
+ case bitc::ATTR_KIND_ALWAYS_INLINE:
+ *Kind = Attribute::AlwaysInline;
+ return false;
+ case bitc::ATTR_KIND_BUILTIN:
+ *Kind = Attribute::Builtin;
+ return false;
+ case bitc::ATTR_KIND_BY_VAL:
+ *Kind = Attribute::ByVal;
+ return false;
+ case bitc::ATTR_KIND_COLD:
+ *Kind = Attribute::Cold;
+ return false;
+ case bitc::ATTR_KIND_INLINE_HINT:
+ *Kind = Attribute::InlineHint;
+ return false;
+ case bitc::ATTR_KIND_IN_REG:
+ *Kind = Attribute::InReg;
+ return false;
+ case bitc::ATTR_KIND_MIN_SIZE:
+ *Kind = Attribute::MinSize;
+ return false;
+ case bitc::ATTR_KIND_NAKED:
+ *Kind = Attribute::Naked;
+ return false;
+ case bitc::ATTR_KIND_NEST:
+ *Kind = Attribute::Nest;
+ return false;
+ case bitc::ATTR_KIND_NO_ALIAS:
+ *Kind = Attribute::NoAlias;
+ return false;
+ case bitc::ATTR_KIND_NO_BUILTIN:
+ *Kind = Attribute::NoBuiltin;
+ return false;
+ case bitc::ATTR_KIND_NO_CAPTURE:
+ *Kind = Attribute::NoCapture;
+ return false;
+ case bitc::ATTR_KIND_NO_DUPLICATE:
+ *Kind = Attribute::NoDuplicate;
+ return false;
+ case bitc::ATTR_KIND_NO_IMPLICIT_FLOAT:
+ *Kind = Attribute::NoImplicitFloat;
+ return false;
+ case bitc::ATTR_KIND_NO_INLINE:
+ *Kind = Attribute::NoInline;
+ return false;
+ case bitc::ATTR_KIND_NON_LAZY_BIND:
+ *Kind = Attribute::NonLazyBind;
+ return false;
+ case bitc::ATTR_KIND_NO_RED_ZONE:
+ *Kind = Attribute::NoRedZone;
+ return false;
+ case bitc::ATTR_KIND_NO_RETURN:
+ *Kind = Attribute::NoReturn;
+ return false;
+ case bitc::ATTR_KIND_NO_UNWIND:
+ *Kind = Attribute::NoUnwind;
+ return false;
+ case bitc::ATTR_KIND_OPTIMIZE_FOR_SIZE:
+ *Kind = Attribute::OptimizeForSize;
+ return false;
+ case bitc::ATTR_KIND_READ_NONE:
+ *Kind = Attribute::ReadNone;
+ return false;
+ case bitc::ATTR_KIND_READ_ONLY:
+ *Kind = Attribute::ReadOnly;
+ return false;
+ case bitc::ATTR_KIND_RETURNED:
+ *Kind = Attribute::Returned;
+ return false;
+ case bitc::ATTR_KIND_RETURNS_TWICE:
+ *Kind = Attribute::ReturnsTwice;
+ return false;
+ case bitc::ATTR_KIND_S_EXT:
+ *Kind = Attribute::SExt;
+ return false;
+ case bitc::ATTR_KIND_STACK_ALIGNMENT:
+ *Kind = Attribute::StackAlignment;
+ return false;
+ case bitc::ATTR_KIND_STACK_PROTECT:
+ *Kind = Attribute::StackProtect;
+ return false;
+ case bitc::ATTR_KIND_STACK_PROTECT_REQ:
+ *Kind = Attribute::StackProtectReq;
+ return false;
+ case bitc::ATTR_KIND_STACK_PROTECT_STRONG:
+ *Kind = Attribute::StackProtectStrong;
+ return false;
+ case bitc::ATTR_KIND_STRUCT_RET:
+ *Kind = Attribute::StructRet;
+ return false;
+ case bitc::ATTR_KIND_SANITIZE_ADDRESS:
+ *Kind = Attribute::SanitizeAddress;
+ return false;
+ case bitc::ATTR_KIND_SANITIZE_THREAD:
+ *Kind = Attribute::SanitizeThread;
+ return false;
+ case bitc::ATTR_KIND_SANITIZE_MEMORY:
+ *Kind = Attribute::SanitizeMemory;
+ return false;
+ case bitc::ATTR_KIND_UW_TABLE:
+ *Kind = Attribute::UWTable;
+ return false;
+ case bitc::ATTR_KIND_Z_EXT:
+ *Kind = Attribute::ZExt;
+ return false;
+ default:
+ std::string Buf;
+ raw_string_ostream fmt(Buf);
+ fmt << "Unknown attribute kind (" << Code << ")";
+ fmt.flush();
+ return Error(Buf.c_str());
+ }
+}
+
bool BitcodeReader::ParseAttributeGroupBlock() {
if (Stream.EnterSubBlock(bitc::PARAMATTR_GROUP_BLOCK_ID))
return Error("Malformed block record");
@@ -545,9 +666,16 @@ bool BitcodeReader::ParseAttributeGroupBlock() {
AttrBuilder B;
for (unsigned i = 2, e = Record.size(); i != e; ++i) {
if (Record[i] == 0) { // Enum attribute
- B.addAttribute(Attribute::AttrKind(Record[++i]));
+ Attribute::AttrKind Kind;
+ if (ParseAttrKind(Record[++i], &Kind))
+ return true;
+
+ B.addAttribute(Kind);
} else if (Record[i] == 1) { // Align attribute
- if (Attribute::AttrKind(Record[++i]) == Attribute::Alignment)
+ Attribute::AttrKind Kind;
+ if (ParseAttrKind(Record[++i], &Kind))
+ return true;
+ if (Kind == Attribute::Alignment)
B.addAlignmentAttr(Record[++i]);
else
B.addStackAlignmentAttr(Record[++i]);
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.h b/llvm/lib/Bitcode/Reader/BitcodeReader.h
index e4de4ab7c7c..b095447675a 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.h
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.h
@@ -321,6 +321,7 @@ private:
return getFnValueByID(ValNo, Ty);
}
+ bool ParseAttrKind(uint64_t Code, Attribute::AttrKind *Kind);
bool ParseModule(bool Resume);
bool ParseAttributeBlock();
bool ParseAttributeGroupBlock();
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
index 08b72a46913..311c233024f 100644
--- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -161,6 +161,89 @@ static void WriteStringRecord(unsigned Code, StringRef Str,
Stream.EmitRecord(Code, Vals, AbbrevToUse);
}
+static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {
+ switch (Kind) {
+ case Attribute::Alignment:
+ return bitc::ATTR_KIND_ALIGNMENT;
+ case Attribute::AlwaysInline:
+ return bitc::ATTR_KIND_ALWAYS_INLINE;
+ case Attribute::Builtin:
+ return bitc::ATTR_KIND_BUILTIN;
+ case Attribute::ByVal:
+ return bitc::ATTR_KIND_BY_VAL;
+ case Attribute::Cold:
+ return bitc::ATTR_KIND_COLD;
+ case Attribute::InlineHint:
+ return bitc::ATTR_KIND_INLINE_HINT;
+ case Attribute::InReg:
+ return bitc::ATTR_KIND_IN_REG;
+ case Attribute::MinSize:
+ return bitc::ATTR_KIND_MIN_SIZE;
+ case Attribute::Naked:
+ return bitc::ATTR_KIND_NAKED;
+ case Attribute::Nest:
+ return bitc::ATTR_KIND_NEST;
+ case Attribute::NoAlias:
+ return bitc::ATTR_KIND_NO_ALIAS;
+ case Attribute::NoBuiltin:
+ return bitc::ATTR_KIND_NO_BUILTIN;
+ case Attribute::NoCapture:
+ return bitc::ATTR_KIND_NO_CAPTURE;
+ case Attribute::NoDuplicate:
+ return bitc::ATTR_KIND_NO_DUPLICATE;
+ case Attribute::NoImplicitFloat:
+ return bitc::ATTR_KIND_NO_IMPLICIT_FLOAT;
+ case Attribute::NoInline:
+ return bitc::ATTR_KIND_NO_INLINE;
+ case Attribute::NonLazyBind:
+ return bitc::ATTR_KIND_NON_LAZY_BIND;
+ case Attribute::NoRedZone:
+ return bitc::ATTR_KIND_NO_RED_ZONE;
+ case Attribute::NoReturn:
+ return bitc::ATTR_KIND_NO_RETURN;
+ case Attribute::NoUnwind:
+ return bitc::ATTR_KIND_NO_UNWIND;
+ case Attribute::OptimizeForSize:
+ return bitc::ATTR_KIND_OPTIMIZE_FOR_SIZE;
+ case Attribute::ReadNone:
+ return bitc::ATTR_KIND_READ_NONE;
+ case Attribute::ReadOnly:
+ return bitc::ATTR_KIND_READ_ONLY;
+ case Attribute::Returned:
+ return bitc::ATTR_KIND_RETURNED;
+ case Attribute::ReturnsTwice:
+ return bitc::ATTR_KIND_RETURNS_TWICE;
+ case Attribute::SExt:
+ return bitc::ATTR_KIND_S_EXT;
+ case Attribute::StackAlignment:
+ return bitc::ATTR_KIND_STACK_ALIGNMENT;
+ case Attribute::StackProtect:
+ return bitc::ATTR_KIND_STACK_PROTECT;
+ case Attribute::StackProtectReq:
+ return bitc::ATTR_KIND_STACK_PROTECT_REQ;
+ case Attribute::StackProtectStrong:
+ return bitc::ATTR_KIND_STACK_PROTECT_STRONG;
+ case Attribute::StructRet:
+ return bitc::ATTR_KIND_STRUCT_RET;
+ case Attribute::SanitizeAddress:
+ return bitc::ATTR_KIND_SANITIZE_ADDRESS;
+ case Attribute::SanitizeThread:
+ return bitc::ATTR_KIND_SANITIZE_THREAD;
+ case Attribute::SanitizeMemory:
+ return bitc::ATTR_KIND_SANITIZE_MEMORY;
+ case Attribute::UWTable:
+ return bitc::ATTR_KIND_UW_TABLE;
+ case Attribute::ZExt:
+ return bitc::ATTR_KIND_Z_EXT;
+ case Attribute::EndAttrKinds:
+ llvm_unreachable("Can not encode end-attribute kinds marker.");
+ case Attribute::None:
+ llvm_unreachable("Can not encode none-attribute.");
+ }
+
+ llvm_unreachable("Trying to encode unknown attribute");
+}
+
static void WriteAttributeGroupTable(const ValueEnumerator &VE,
BitstreamWriter &Stream) {
const std::vector<AttributeSet> &AttrGrps = VE.getAttributeGroups();
@@ -182,10 +265,10 @@ static void WriteAttributeGroupTable(const ValueEnumerator &VE,
Attribute Attr = *I;
if (Attr.isEnumAttribute()) {
Record.push_back(0);
- Record.push_back(Attr.getKindAsEnum());
+ Record.push_back(getAttrKindEncoding(Attr.getKindAsEnum()));
} else if (Attr.isAlignAttribute()) {
Record.push_back(1);
- Record.push_back(Attr.getKindAsEnum());
+ Record.push_back(getAttrKindEncoding(Attr.getKindAsEnum()));
Record.push_back(Attr.getValueAsInt());
} else {
StringRef Kind = Attr.getKindAsString();
OpenPOWER on IntegriCloud