blob: 5157747f2b18e07b86b57a9c999a1e999ad5cfe0 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
//===- PNaClABICheckTypes.h - Verify PNaCl ABI rules --------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Common type-checking code for module and function-level passes
//
//
//===----------------------------------------------------------------------===//
#include "PNaClABITypeChecker.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Metadata.h"
using namespace llvm;
bool PNaClABITypeChecker::isValidType(const Type *Ty) {
if (VisitedTypes.count(Ty))
return VisitedTypes[Ty];
unsigned Width;
bool Valid = false;
switch (Ty->getTypeID()) {
// Allowed primitive types
case Type::VoidTyID:
case Type::FloatTyID:
case Type::DoubleTyID:
case Type::LabelTyID:
case Type::MetadataTyID:
Valid = true;
break;
// Disallowed primitive types
case Type::HalfTyID:
case Type::X86_FP80TyID:
case Type::FP128TyID:
case Type::PPC_FP128TyID:
case Type::X86_MMXTyID:
Valid = false;
break;
// Derived types
case Type::VectorTyID:
Valid = false;
break;
case Type::IntegerTyID:
Width = cast<const IntegerType>(Ty)->getBitWidth();
Valid = (Width == 1 || Width == 8 || Width == 16 ||
Width == 32 || Width == 64);
break;
case Type::FunctionTyID:
case Type::StructTyID:
case Type::ArrayTyID:
case Type::PointerTyID:
// These types are valid if their contained or pointed-to types are
// valid. Since struct/pointer subtype relationships may be circular,
// mark the current type as valid to avoid infinite recursion
Valid = true;
VisitedTypes[Ty] = true;
for (Type::subtype_iterator I = Ty->subtype_begin(),
E = Ty->subtype_end(); I != E; ++I)
Valid &= isValidType(*I);
break;
// Handle NumTypeIDs, and no default case,
// so we get a warning if new types are added
case Type::NumTypeIDs:
Valid = false;
break;
}
VisitedTypes[Ty] = Valid;
return Valid;
}
Type *PNaClABITypeChecker::checkTypesInConstant(const Constant *V) {
if (!V) return NULL;
if (VisitedConstants.count(V))
return VisitedConstants[V];
if (!isValidType(V->getType())) {
VisitedConstants[V] = V->getType();
return V->getType();
}
// Check for BlockAddress because it contains a non-Constant
// BasicBlock operand.
// TODO(mseaborn): This produces an error which is misleading
// because it complains about the type being "i8*". It should
// instead produce an error saying that BlockAddress and computed
// gotos are not allowed.
if (isa<BlockAddress>(V)) {
VisitedConstants[V] = V->getType();
return V->getType();
}
// Operand values must also be valid. Values may be circular, so
// mark the current value as valid to avoid infinite recursion.
VisitedConstants[V] = NULL;
for (Constant::const_op_iterator I = V->op_begin(),
E = V->op_end(); I != E; ++I) {
Type *Invalid = checkTypesInConstant(cast<Constant>(*I));
if (Invalid) {
VisitedConstants[V] = Invalid;
return Invalid;
}
}
VisitedConstants[V] = NULL;
return NULL;
}
// MDNodes don't support the same way of iterating over operands that Users do
Type *PNaClABITypeChecker::checkTypesInMDNode(const MDNode *N) {
if (VisitedConstants.count(N))
return VisitedConstants[N];
for (unsigned i = 0, e = N->getNumOperands(); i != e; i++) {
if (Value *Op = N->getOperand(i)) {
if (Type *Invalid = checkTypesInConstant(dyn_cast<Constant>(Op))) {
VisitedConstants[N] = Invalid;
return Invalid;
}
}
}
return NULL;
}
|