llvm.org GIT mirror llvm / e7bc5bb
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@187186 91177308-0d34-0410-b5e6-96231b3b80d8 Tobias Grosser 7 years ago
6 changed file(s) with 493 addition(s) and 4 deletion(s). Raw diff Collapse all Expand all
329329 enum UseListCodes {
330330 USELIST_CODE_ENTRY = 1 // USELIST_CODE_ENTRY: TBD.
331331 };
332
333 enum AttributeKindCodes {
334 // = 0 is unused
335 ATTR_KIND_ALIGNMENT = 1,
336 ATTR_KIND_ALWAYS_INLINE = 2,
337 ATTR_KIND_BY_VAL = 3,
338 ATTR_KIND_INLINE_HINT = 4,
339 ATTR_KIND_IN_REG = 5,
340 ATTR_KIND_MIN_SIZE = 6,
341 ATTR_KIND_NAKED = 7,
342 ATTR_KIND_NEST = 8,
343 ATTR_KIND_NO_ALIAS = 9,
344 ATTR_KIND_NO_BUILTIN = 10,
345 ATTR_KIND_NO_CAPTURE = 11,
346 ATTR_KIND_NO_DUPLICATE = 12,
347 ATTR_KIND_NO_IMPLICIT_FLOAT = 13,
348 ATTR_KIND_NO_INLINE = 14,
349 ATTR_KIND_NON_LAZY_BIND = 15,
350 ATTR_KIND_NO_RED_ZONE = 16,
351 ATTR_KIND_NO_RETURN = 17,
352 ATTR_KIND_NO_UNWIND = 18,
353 ATTR_KIND_OPTIMIZE_FOR_SIZE = 19,
354 ATTR_KIND_READ_NONE = 20,
355 ATTR_KIND_READ_ONLY = 21,
356 ATTR_KIND_RETURNED = 22,
357 ATTR_KIND_RETURNS_TWICE = 23,
358 ATTR_KIND_S_EXT = 24,
359 ATTR_KIND_STACK_ALIGNMENT = 25,
360 ATTR_KIND_STACK_PROTECT = 26,
361 ATTR_KIND_STACK_PROTECT_REQ = 27,
362 ATTR_KIND_STACK_PROTECT_STRONG = 28,
363 ATTR_KIND_STRUCT_RET = 29,
364 ATTR_KIND_SANITIZE_ADDRESS = 30,
365 ATTR_KIND_SANITIZE_THREAD = 31,
366 ATTR_KIND_SANITIZE_MEMORY = 32,
367 ATTR_KIND_UW_TABLE = 33,
368 ATTR_KIND_Z_EXT = 34,
369 ATTR_KIND_BUILTIN = 35,
370 ATTR_KIND_COLD = 36
371 };
372
332373 } // End bitc namespace
333374 } // End llvm namespace
334375
1111 #include "llvm/ADT/SmallString.h"
1212 #include "llvm/ADT/SmallVector.h"
1313 #include "llvm/AutoUpgrade.h"
14 #include "llvm/Bitcode/LLVMBitCodes.h"
1415 #include "llvm/IR/Constants.h"
1516 #include "llvm/IR/DerivedTypes.h"
1617 #include "llvm/IR/InlineAsm.h"
2122 #include "llvm/Support/DataStream.h"
2223 #include "llvm/Support/MathExtras.h"
2324 #include "llvm/Support/MemoryBuffer.h"
25 #include "llvm/Support/raw_ostream.h"
2426 using namespace llvm;
2527
2628 enum {
505507 }
506508 }
507509
510 bool BitcodeReader::ParseAttrKind(uint64_t Code, Attribute::AttrKind *Kind) {
511 switch (Code) {
512 case bitc::ATTR_KIND_ALIGNMENT:
513 *Kind = Attribute::Alignment;
514 return false;
515 case bitc::ATTR_KIND_ALWAYS_INLINE:
516 *Kind = Attribute::AlwaysInline;
517 return false;
518 case bitc::ATTR_KIND_BUILTIN:
519 *Kind = Attribute::Builtin;
520 return false;
521 case bitc::ATTR_KIND_BY_VAL:
522 *Kind = Attribute::ByVal;
523 return false;
524 case bitc::ATTR_KIND_COLD:
525 *Kind = Attribute::Cold;
526 return false;
527 case bitc::ATTR_KIND_INLINE_HINT:
528 *Kind = Attribute::InlineHint;
529 return false;
530 case bitc::ATTR_KIND_IN_REG:
531 *Kind = Attribute::InReg;
532 return false;
533 case bitc::ATTR_KIND_MIN_SIZE:
534 *Kind = Attribute::MinSize;
535 return false;
536 case bitc::ATTR_KIND_NAKED:
537 *Kind = Attribute::Naked;
538 return false;
539 case bitc::ATTR_KIND_NEST:
540 *Kind = Attribute::Nest;
541 return false;
542 case bitc::ATTR_KIND_NO_ALIAS:
543 *Kind = Attribute::NoAlias;
544 return false;
545 case bitc::ATTR_KIND_NO_BUILTIN:
546 *Kind = Attribute::NoBuiltin;
547 return false;
548 case bitc::ATTR_KIND_NO_CAPTURE:
549 *Kind = Attribute::NoCapture;
550 return false;
551 case bitc::ATTR_KIND_NO_DUPLICATE:
552 *Kind = Attribute::NoDuplicate;
553 return false;
554 case bitc::ATTR_KIND_NO_IMPLICIT_FLOAT:
555 *Kind = Attribute::NoImplicitFloat;
556 return false;
557 case bitc::ATTR_KIND_NO_INLINE:
558 *Kind = Attribute::NoInline;
559 return false;
560 case bitc::ATTR_KIND_NON_LAZY_BIND:
561 *Kind = Attribute::NonLazyBind;
562 return false;
563 case bitc::ATTR_KIND_NO_RED_ZONE:
564 *Kind = Attribute::NoRedZone;
565 return false;
566 case bitc::ATTR_KIND_NO_RETURN:
567 *Kind = Attribute::NoReturn;
568 return false;
569 case bitc::ATTR_KIND_NO_UNWIND:
570 *Kind = Attribute::NoUnwind;
571 return false;
572 case bitc::ATTR_KIND_OPTIMIZE_FOR_SIZE:
573 *Kind = Attribute::OptimizeForSize;
574 return false;
575 case bitc::ATTR_KIND_READ_NONE:
576 *Kind = Attribute::ReadNone;
577 return false;
578 case bitc::ATTR_KIND_READ_ONLY:
579 *Kind = Attribute::ReadOnly;
580 return false;
581 case bitc::ATTR_KIND_RETURNED:
582 *Kind = Attribute::Returned;
583 return false;
584 case bitc::ATTR_KIND_RETURNS_TWICE:
585 *Kind = Attribute::ReturnsTwice;
586 return false;
587 case bitc::ATTR_KIND_S_EXT:
588 *Kind = Attribute::SExt;
589 return false;
590 case bitc::ATTR_KIND_STACK_ALIGNMENT:
591 *Kind = Attribute::StackAlignment;
592 return false;
593 case bitc::ATTR_KIND_STACK_PROTECT:
594 *Kind = Attribute::StackProtect;
595 return false;
596 case bitc::ATTR_KIND_STACK_PROTECT_REQ:
597 *Kind = Attribute::StackProtectReq;
598 return false;
599 case bitc::ATTR_KIND_STACK_PROTECT_STRONG:
600 *Kind = Attribute::StackProtectStrong;
601 return false;
602 case bitc::ATTR_KIND_STRUCT_RET:
603 *Kind = Attribute::StructRet;
604 return false;
605 case bitc::ATTR_KIND_SANITIZE_ADDRESS:
606 *Kind = Attribute::SanitizeAddress;
607 return false;
608 case bitc::ATTR_KIND_SANITIZE_THREAD:
609 *Kind = Attribute::SanitizeThread;
610 return false;
611 case bitc::ATTR_KIND_SANITIZE_MEMORY:
612 *Kind = Attribute::SanitizeMemory;
613 return false;
614 case bitc::ATTR_KIND_UW_TABLE:
615 *Kind = Attribute::UWTable;
616 return false;
617 case bitc::ATTR_KIND_Z_EXT:
618 *Kind = Attribute::ZExt;
619 return false;
620 default:
621 std::string Buf;
622 raw_string_ostream fmt(Buf);
623 fmt << "Unknown attribute kind (" << Code << ")";
624 fmt.flush();
625 return Error(Buf.c_str());
626 }
627 }
628
508629 bool BitcodeReader::ParseAttributeGroupBlock() {
509630 if (Stream.EnterSubBlock(bitc::PARAMATTR_GROUP_BLOCK_ID))
510631 return Error("Malformed block record");
544665 AttrBuilder B;
545666 for (unsigned i = 2, e = Record.size(); i != e; ++i) {
546667 if (Record[i] == 0) { // Enum attribute
547 B.addAttribute(Attribute::AttrKind(Record[++i]));
668 Attribute::AttrKind Kind;
669 if (ParseAttrKind(Record[++i], &Kind))
670 return true;
671
672 B.addAttribute(Kind);
548673 } else if (Record[i] == 1) { // Align attribute
549 if (Attribute::AttrKind(Record[++i]) == Attribute::Alignment)
674 Attribute::AttrKind Kind;
675 if (ParseAttrKind(Record[++i], &Kind))
676 return true;
677 if (Kind == Attribute::Alignment)
550678 B.addAlignmentAttr(Record[++i]);
551679 else
552680 B.addStackAlignmentAttr(Record[++i]);
320320 return getFnValueByID(ValNo, Ty);
321321 }
322322
323 bool ParseAttrKind(uint64_t Code, Attribute::AttrKind *Kind);
323324 bool ParseModule(bool Resume);
324325 bool ParseAttributeBlock();
325326 bool ParseAttributeGroupBlock();
160160 Stream.EmitRecord(Code, Vals, AbbrevToUse);
161161 }
162162
163 static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {
164 switch (Kind) {
165 case Attribute::Alignment:
166 return bitc::ATTR_KIND_ALIGNMENT;
167 case Attribute::AlwaysInline:
168 return bitc::ATTR_KIND_ALWAYS_INLINE;
169 case Attribute::Builtin:
170 return bitc::ATTR_KIND_BUILTIN;
171 case Attribute::ByVal:
172 return bitc::ATTR_KIND_BY_VAL;
173 case Attribute::Cold:
174 return bitc::ATTR_KIND_COLD;
175 case Attribute::InlineHint:
176 return bitc::ATTR_KIND_INLINE_HINT;
177 case Attribute::InReg:
178 return bitc::ATTR_KIND_IN_REG;
179 case Attribute::MinSize:
180 return bitc::ATTR_KIND_MIN_SIZE;
181 case Attribute::Naked:
182 return bitc::ATTR_KIND_NAKED;
183 case Attribute::Nest:
184 return bitc::ATTR_KIND_NEST;
185 case Attribute::NoAlias:
186 return bitc::ATTR_KIND_NO_ALIAS;
187 case Attribute::NoBuiltin:
188 return bitc::ATTR_KIND_NO_BUILTIN;
189 case Attribute::NoCapture:
190 return bitc::ATTR_KIND_NO_CAPTURE;
191 case Attribute::NoDuplicate:
192 return bitc::ATTR_KIND_NO_DUPLICATE;
193 case Attribute::NoImplicitFloat:
194 return bitc::ATTR_KIND_NO_IMPLICIT_FLOAT;
195 case Attribute::NoInline:
196 return bitc::ATTR_KIND_NO_INLINE;
197 case Attribute::NonLazyBind:
198 return bitc::ATTR_KIND_NON_LAZY_BIND;
199 case Attribute::NoRedZone:
200 return bitc::ATTR_KIND_NO_RED_ZONE;
201 case Attribute::NoReturn:
202 return bitc::ATTR_KIND_NO_RETURN;
203 case Attribute::NoUnwind:
204 return bitc::ATTR_KIND_NO_UNWIND;
205 case Attribute::OptimizeForSize:
206 return bitc::ATTR_KIND_OPTIMIZE_FOR_SIZE;
207 case Attribute::ReadNone:
208 return bitc::ATTR_KIND_READ_NONE;
209 case Attribute::ReadOnly:
210 return bitc::ATTR_KIND_READ_ONLY;
211 case Attribute::Returned:
212 return bitc::ATTR_KIND_RETURNED;
213 case Attribute::ReturnsTwice:
214 return bitc::ATTR_KIND_RETURNS_TWICE;
215 case Attribute::SExt:
216 return bitc::ATTR_KIND_S_EXT;
217 case Attribute::StackAlignment:
218 return bitc::ATTR_KIND_STACK_ALIGNMENT;
219 case Attribute::StackProtect:
220 return bitc::ATTR_KIND_STACK_PROTECT;
221 case Attribute::StackProtectReq:
222 return bitc::ATTR_KIND_STACK_PROTECT_REQ;
223 case Attribute::StackProtectStrong:
224 return bitc::ATTR_KIND_STACK_PROTECT_STRONG;
225 case Attribute::StructRet:
226 return bitc::ATTR_KIND_STRUCT_RET;
227 case Attribute::SanitizeAddress:
228 return bitc::ATTR_KIND_SANITIZE_ADDRESS;
229 case Attribute::SanitizeThread:
230 return bitc::ATTR_KIND_SANITIZE_THREAD;
231 case Attribute::SanitizeMemory:
232 return bitc::ATTR_KIND_SANITIZE_MEMORY;
233 case Attribute::UWTable:
234 return bitc::ATTR_KIND_UW_TABLE;
235 case Attribute::ZExt:
236 return bitc::ATTR_KIND_Z_EXT;
237 case Attribute::EndAttrKinds:
238 llvm_unreachable("Can not encode end-attribute kinds marker.");
239 case Attribute::None:
240 llvm_unreachable("Can not encode none-attribute.");
241 }
242
243 llvm_unreachable("Trying to encode unknown attribute");
244 }
245
163246 static void WriteAttributeGroupTable(const ValueEnumerator &VE,
164247 BitstreamWriter &Stream) {
165248 const std::vector &AttrGrps = VE.getAttributeGroups();
181264 Attribute Attr = *I;
182265 if (Attr.isEnumAttribute()) {
183266 Record.push_back(0);
184 Record.push_back(Attr.getKindAsEnum());
267 Record.push_back(getAttrKindEncoding(Attr.getKindAsEnum()));
185268 } else if (Attr.isAlignAttribute()) {
186269 Record.push_back(1);
187 Record.push_back(Attr.getKindAsEnum());
270 Record.push_back(getAttrKindEncoding(Attr.getKindAsEnum()));
188271 Record.push_back(Attr.getValueAsInt());
189272 } else {
190273 StringRef Kind = Attr.getKindAsString();
0 ; RUN: llvm-dis < %s.bc| FileCheck %s
1
2 ; attributes-3.3.ll.bc was generated by passing this file to llvm-as-3.3.
3 ; The test checks that LLVM does not silently misread attributes of
4 ; older bitcode files.
5
6 define void @f1(i8 zeroext)
7 ; CHECK: define void @f1(i8 zeroext)
8 {
9 ret void;
10 }
11
12 define void @f2(i8 signext)
13 ; CHECK: define void @f2(i8 signext)
14 {
15 ret void;
16 }
17
18 define void @f3() noreturn
19 ; CHECK: define void @f3() #0
20 {
21 ret void;
22 }
23
24 define void @f4(i8 inreg)
25 ; CHECK: define void @f4(i8 inreg)
26 {
27 ret void;
28 }
29
30 define void @f5(i8* sret)
31 ; CHECK: define void @f5(i8* sret)
32 {
33 ret void;
34 }
35
36 define void @f6() nounwind
37 ; CHECK: define void @f6() #1
38 {
39 ret void;
40 }
41
42 define void @f7(i8* noalias)
43 ; CHECK: define void @f7(i8* noalias)
44 {
45 ret void;
46 }
47
48 define void @f8(i8* byval)
49 ; CHECK: define void @f8(i8* byval)
50 {
51 ret void;
52 }
53
54 define void @f9(i8* nest)
55 ; CHECK: define void @f9(i8* nest)
56 {
57 ret void;
58 }
59
60 define void @f10() readnone
61 ; CHECK: define void @f10() #2
62 {
63 ret void;
64 }
65
66 define void @f11() readonly
67 ; CHECK: define void @f11() #3
68 {
69 ret void;
70 }
71
72 define void @f12() noinline
73 ; CHECK: define void @f12() #4
74 {
75 ret void;
76 }
77
78 define void @f13() alwaysinline
79 ; CHECK: define void @f13() #5
80 {
81 ret void;
82 }
83
84 define void @f14() optsize
85 ; CHECK: define void @f14() #6
86 {
87 ret void;
88 }
89
90 define void @f15() ssp
91 ; CHECK: define void @f15() #7
92 {
93 ret void;
94 }
95
96 define void @f16() sspreq
97 ; CHECK: define void @f16() #8
98 {
99 ret void;
100 }
101
102 define void @f17(i8 align 4)
103 ; CHECK: define void @f17(i8 align 4)
104 {
105 ret void;
106 }
107
108 define void @f18(i8* nocapture)
109 ; CHECK: define void @f18(i8* nocapture)
110 {
111 ret void;
112 }
113
114 define void @f19() noredzone
115 ; CHECK: define void @f19() #9
116 {
117 ret void;
118 }
119
120 define void @f20() noimplicitfloat
121 ; CHECK: define void @f20() #10
122 {
123 ret void;
124 }
125
126 define void @f21() naked
127 ; CHECK: define void @f21() #11
128 {
129 ret void;
130 }
131
132 define void @f22() inlinehint
133 ; CHECK: define void @f22() #12
134 {
135 ret void;
136 }
137
138 define void @f23() alignstack(4)
139 ; CHECK: define void @f23() #13
140 {
141 ret void;
142 }
143
144 define void @f24() returns_twice
145 ; CHECK: define void @f24() #14
146 {
147 ret void;
148 }
149
150 define void @f25() uwtable
151 ; CHECK: define void @f25() #15
152 {
153 ret void;
154 }
155
156 define void @f26() nonlazybind
157 ; CHECK: define void @f26() #16
158 {
159 ret void;
160 }
161
162 define void @f27() sanitize_address
163 ; CHECK: define void @f27() #17
164 {
165 ret void;
166 }
167 define void @f28() sanitize_thread
168 ; CHECK: define void @f28() #18
169 {
170 ret void;
171 }
172 define void @f29() sanitize_memory
173 ; CHECK: define void @f29() #19
174 {
175 ret void;
176 }
177
178 define void @f30() "cpu"="cortex-a8"
179 ; CHECK: define void @f30() #20
180 {
181 ret void;
182 }
183
184 define i8 @f31(i8 returned %A)
185 ; CHECK: define i8 @f31(i8 returned %A)
186 {
187 ret i8 %A;
188 }
189
190 define void @f32() sspstrong
191 ; CHECK: define void @f32() #21
192 {
193 ret void;
194 }
195
196 define void @f33() minsize
197 ; CHECK: define void @f33() #22
198 {
199 ret void;
200 }
201
202 declare void @nobuiltin()
203
204 define void @f34()
205 ; CHECK: define void @f34()
206 {
207 call void @nobuiltin() nobuiltin
208 ; CHECK: call void @nobuiltin() #23
209 ret void;
210 }
211
212 ; CHECK: attributes #0 = { noreturn }
213 ; CHECK: attributes #1 = { nounwind }
214 ; CHECK: attributes #2 = { readnone }
215 ; CHECK: attributes #3 = { readonly }
216 ; CHECK: attributes #4 = { noinline }
217 ; CHECK: attributes #5 = { alwaysinline }
218 ; CHECK: attributes #6 = { optsize }
219 ; CHECK: attributes #7 = { ssp }
220 ; CHECK: attributes #8 = { sspreq }
221 ; CHECK: attributes #9 = { noredzone }
222 ; CHECK: attributes #10 = { noimplicitfloat }
223 ; CHECK: attributes #11 = { naked }
224 ; CHECK: attributes #12 = { inlinehint }
225 ; CHECK: attributes #13 = { alignstack=4 }
226 ; CHECK: attributes #14 = { returns_twice }
227 ; CHECK: attributes #15 = { uwtable }
228 ; CHECK: attributes #16 = { nonlazybind }
229 ; CHECK: attributes #17 = { sanitize_address }
230 ; CHECK: attributes #18 = { sanitize_thread }
231 ; CHECK: attributes #19 = { sanitize_memory }
232 ; CHECK: attributes #20 = { "cpu"="cortex-a8" }
233 ; CHECK: attributes #21 = { sspstrong }
234 ; CHECK: attributes #22 = { minsize }
235 ; CHECK: attributes #23 = { nobuiltin }