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