-
Notifications
You must be signed in to change notification settings - Fork 139
/
Type.h
320 lines (259 loc) · 10.9 KB
/
Type.h
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
// -*- mode: C++ -*-
//
// Copyright (c) 2007, 2008, 2010, 2011, 2013, 2014, 2015, 2016 The University of Utah
// All rights reserved.
//
// This file is part of `csmith', a random generator of C programs.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This file was derived from a random program generator written by Bryan
// Turner. The attributions in that file was:
//
// Random Program Generator
// Bryan Turner (bryan.turner@pobox.com)
// July, 2005
//
#ifndef TYPE_H
#define TYPE_H
///////////////////////////////////////////////////////////////////////////////
#include <string>
#include <ostream>
#include <vector>
#include "CommonMacros.h"
#include "StatementAssign.h"
#include "CVQualifiers.h"
template <class Name> class Enumerator;
using namespace std;
#define SIZE_UNKNOWN 0xFFFF
/*
*
*/
enum eTypeDesc
{
eSimple,
ePointer,
eUnion,
eStruct,
};
#define MAX_TYPE_DESC ((eTypeDesc) (eStruct+1))
/*
*
*/
enum eSimpleType
{
eVoid,
eChar,
eInt,
eShort,
eLong,
eLongLong,
eUChar,
eUInt,
eUShort,
eULong,
eFloat,
// eDouble,
eULongLong,
eInt128,
eUInt128,
};
#define MAX_SIMPLE_TYPES ((eSimpleType) (eUInt128+1))
enum eMatchType
{
eExact,
eConvert,
eDereference,
eDerefExact,
eFlexible,
};
/*
*
*/
class Type
{
public:
// Pseudo-factory method. This is `choose_random()' rather than
// `make_random()' because the returned object is not fresh.
static const Type *choose_random();
static const Type *choose_random_nonvoid();
// choose a random integer type
static const Type *choose_random_simple(void);
// choose a random pointer type
static const Type* choose_random_pointer_type(void);
static const Type *choose_random_struct_from_type(const Type* type, bool no_volatile);
static void get_all_ok_struct_union_types(vector<Type *> &ok_types, bool no_const, bool no_volatile, bool need_int_field, bool bStruct);
static bool if_struct_will_have_assign_ops();
static bool if_union_will_have_assign_ops();
bool has_int_field() const;
bool signed_overflow_possible() const;
static const Type* choose_random_struct_union_type(vector<Type *> &ok_types);
static const Type * choose_random_nonvoid_nonvolatile(void);
static bool has_pointer_type(void);
static const Type* random_type_from_type(const Type* type, bool no_volatile=false, bool strict_simple_type=false);
static void copy_all_fields_types(vector<const Type*> &dest_types, vector<const Type*> &src_types);
static void reset_accum_types(vector<const Type*> &accum_types);
static void delete_useless_structs(vector<const Type*> &all_types, vector<const Type*> &accum_types);
static void init_is_bitfield_enumerator(Enumerator<string> &enumerator, int bitfield_prob);
static void init_fields_enumerator(Enumerator<std::string> &enumerator,
Enumerator<string> &bitfield_enumerator,
int type_bound, int qual_bound, int bitfield_qual_bound);
static bool make_one_normal_field_by_enum(Enumerator<string> &enumerator, vector<const Type*> &all_types,
vector<CVQualifiers> &all_quals, vector<const Type*> &fields,
vector<CVQualifiers> &quals, vector<int> &fields_length, int i);
static bool make_one_bitfield_by_enum(Enumerator<string> &enumerator,
vector<CVQualifiers> &all_bitfield_quals,
vector<const Type*> &random_fields,
vector<CVQualifiers> &qualifiers,
vector<int> &fields_length,
int index, bool &last_is_zero);
static int get_bitfield_length(int length_flag);
static void make_all_struct_types_(Enumerator<string> &bitfields_enumerator, vector<const Type*> &accum_types,
vector<const Type*> &all_types, vector<CVQualifiers> &all_quals,
vector<CVQualifiers> &all_bitfield_quals);
static void make_all_struct_types_with_bitfields(Enumerator<string> &enumerator,
Enumerator<string> &bitfields_enumerator,
vector<const Type*> &accum_types, vector<const Type*> &all_types,
vector<CVQualifiers> &all_quals, vector<CVQualifiers> &all_bitfield_quals);
static void make_all_struct_types(int level, vector<const Type*> &accum_types);
static void make_all_struct_union_types();
// make a random struct or union type
static Type* make_random_struct_type(void);
static Type* make_random_union_type(void);
static void make_one_bitfield(vector<const Type*> &random_fields,
vector<CVQualifiers> &qualifiers,
vector<int> &fields_length);
static void make_one_struct_field(vector<const Type*> &random_fields,
vector<CVQualifiers> &qualifiers,
vector<int> &fields_length,
bool structHasAssignOps);
static void make_one_union_field(vector<const Type*> &fields, vector<CVQualifiers> &qfers, vector<int> &lens);
static void make_full_bitfields_struct_fields(size_t field_cnt, vector<const Type*> &random_fields,
vector<CVQualifiers> &qualifiers,
vector<int> &fields_length,
bool structHasAssignOps);
static void make_normal_struct_fields(size_t field_cnt, vector<const Type*> &random_fields,
vector<CVQualifiers> &qualifiers,
vector<int> &fields_length,
bool structHasAssignOps);
// make a random pointer type
static Type* make_random_pointer_type(void);
static const Type *get_type_from_string(const string &type_string);
// generate all simple types except void and long long(if it is not allowed)
static void GenerateSimpleTypes(void);
void get_type_sizeof_string(std::string &s) const;
// For choosing a random, non-void `eSimpleType'.
static eSimpleType choose_random_nonvoid_simple(void);
// select a type for LHS
static const Type *SelectLType(bool no_volatile, eAssignOps op);
static bool has_aggregate_field(const vector<const Type *> &fields);
static bool has_longlong_field(const vector<const Type *> &fields);
explicit Type(eSimpleType simple_type);
Type(vector<const Type*>& fields, bool isStruct, bool packed,
vector<CVQualifiers> &qfers, vector<int> &fields_length, bool hasAssignOps, bool hasImplicitNontrivialAssignOps);
Type(vector<unsigned int>& array_dims, eSimpleType st);
explicit Type(const Type* t);
~Type(void);
static const Type &get_simple_type(eSimpleType simple_type);
static void doFinalization(void);
const Type* get_base_type(void) const;
int get_indirect_level(void) const;
int get_struct_depth(void) const;
void get_int_subfield_names(string prefix, vector<string>& names,
vector<const Type *>& types, const vector<int>& excluded_fields) const;
bool is_signed(void) const;
bool is_long_long(void) const {
return ((eType == eSimple) && (simple_type == eLongLong || simple_type == eULongLong));
}
const Type* to_unsigned(void) const;
bool is_pointer_to_char(void) const { return ptr_type && ptr_type->eType == eSimple && (ptr_type->simple_type==eChar || ptr_type->simple_type==eUChar);}
bool is_signed_char() const {
return ((eType == eSimple) && (simple_type == eChar));
}
bool is_float() const {
return ((eType == eSimple) && (simple_type == eFloat));
}
bool is_promotable(const Type* t) const;
bool is_convertable(const Type* t) const;
bool is_derivable(const Type* t) const;
bool is_dereferenced_from(const Type* t) const;
bool is_equivalent(const Type* t) const;
bool needs_cast(const Type* t) const;
bool is_unamed_padding(size_t index) const;
bool is_full_bitfields_struct() const;
bool is_bitfield(size_t index) const ;
bool has_bitfields() const;
bool has_padding(void) const;
bool contain_pointer_field(void) const;
bool is_const_struct_union() const;
bool is_volatile_struct_union() const;
bool has_assign_ops() const { return has_assign_ops_; }
bool has_implicit_nontrivial_assign_ops() const {
return has_implicit_nontrivial_assign_ops_;
}
bool is_int(void) const { return eType == eSimple && simple_type != eVoid;}
bool is_aggregate(void) const { return eType == eStruct || eType == eUnion;}
bool match(const Type* t, enum eMatchType mt) const;
unsigned long SizeInBytes(void) const;
void Output(std::ostream &) const;
std::string printf_directive(void) const;
static Type* find_pointer_type(const Type* t, bool add);
static Type* find_type(const Type* t);
// private:
eTypeDesc eType;
const Type *ptr_type;
eSimpleType simple_type;
vector<unsigned int> dimensions; // for array types
vector<const Type*> fields; // for struct/union types
unsigned int sid; // sequence id, for struct/union types
bool used; // whether any variable declared with this type
bool printed; // whether this struct/union has been printed in the random program
const bool packed_; // whether this struct/union should be packed
bool has_assign_ops_; // assign ops are needed if we have:
// struct S0 foo; volatile struct S0 bar; ... foo=bar;
bool has_implicit_nontrivial_assign_ops_; // if a struct has a struct with assign ops as a field,
// than the former struct also has assign ops;
// also true if struct itself has assign ops
vector<CVQualifiers> qfers_; // conresponds to each element of fields
// It's a tradeoff between the current implementation and the
// need of struct's level type qualifiers.
vector<int> bitfields_length_; // -1 means it's a regular field
static Type *void_type;
private:
DISALLOW_COPY_AND_ASSIGN(Type);
static const Type *simple_types[MAX_SIMPLE_TYPES];
// Package init.
friend void GenerateAllTypes(void);
};
void GenerateAllTypes(void);
const Type * get_int_type(void);
void OutputStructUnionDeclarations(std::ostream &);
void OutputStructAssignOps(Type* type, std::ostream &out, bool vol);
void OutputStructUnion(Type* type, std::ostream &out);
///////////////////////////////////////////////////////////////////////////////
#endif // TYPE_H
// Local Variables:
// c-basic-offset: 4
// tab-width: 4
// End:
// End of file.