1 // -*- mode: C++ -*- 2 // 3 // Copyright (c) 2007, 2008, 2010, 2011, 2015 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 #ifdef WIN32 40 #pragma warning(disable : 4786) /* Disable annoying warning messages */ 41 #endif 42 #include <vector> 43 #include <ostream> 44 #include <string> 45 #include "Probabilities.h" 46 using namespace std; 47 48 #ifndef STATEMENT_H 49 #define STATEMENT_H 50 51 /////////////////////////////////////////////////////////////////////////////// 52 53 class CGContext; 54 class Function; 55 class FunctionInvocation; 56 class FunctionInvocationUser; 57 class ExpressionVariable; 58 class FactMgr; 59 class Fact; 60 class Block; 61 class Effect; 62 class CFGEdge; 63 64 template <class Key, class Value> 65 class ProbabilityTable; 66 class StatementGoto; 67 class Variable; 68 class Expression; 69 70 enum eStatementType 71 { 72 eAssign, 73 eBlock, 74 eFor, // Make this a generic loop construct (while/for/do) 75 eIfElse, 76 eInvoke, 77 eReturn, 78 eContinue, 79 eBreak, 80 eGoto, 81 eArrayOp 82 // ..more? try, catch, throw 83 // eHash, 84 }; 85 #define MAX_STATEMENT_TYPE ((eStatementType) (eArrayOp+1)) 86 87 /* 88 * 89 */ 90 class Statement 91 { 92 public: 93 // Factory method. 94 static Statement *make_random(CGContext &cg_context, 95 eStatementType t = MAX_STATEMENT_TYPE); 96 static eStatementType number_to_type(unsigned int value); 97 98 virtual ~Statement(void); 99 get_type(void)100 eStatementType get_type(void) const { return eType; } 101 102 void get_called_funcs(std::vector<const FunctionInvocationUser*>& funcs) const; 103 104 const FunctionInvocation* get_direct_invocation(void) const; 105 visit_facts(vector<const Fact * > &,CGContext &)106 virtual bool visit_facts(vector<const Fact*>& /*inputs*/, CGContext& /*cg_context*/) const {return true;}; 107 108 void output_hash(std::ostream &out, int indent) const; 109 110 bool stm_visit_facts(vector<const Fact*>& inputs, CGContext& cg_context) const; 111 112 bool validate_and_update_facts(vector<const Fact*>& inputs, CGContext& cg_context) const; 113 114 int shortcut_analysis(vector<const Fact*>& inputs, CGContext& cg_context) const; 115 116 bool analyze_with_edges_in(vector<const Fact*>& inputs, CGContext& cg_context) const; 117 118 int find_typed_stmts(vector<const Statement*>& stms, const vector<int>& stmt_types) const; 119 120 bool contains_stmt(const Statement* s) const; 121 122 int find_contained_labels(vector<string>& labels) const; 123 124 bool contains_unfixed_goto(void) const; 125 126 void post_creation_analysis(vector<const Fact*>& pre_facts, const Effect& pre_effect, CGContext& cg_context) const; 127 128 void add_back_return_facts(FactMgr* fm, std::vector<const Fact*>& facts) const; 129 130 bool in_block(const Block* b) const; 131 132 bool dominate(const Statement* s) const; 133 134 int find_edges_in(vector<const CFGEdge*>& edges, bool post_stm, bool back_link) const; 135 136 bool has_edge_in(bool post_dest, bool back_link) const; 137 138 const Statement* find_container_stm(void) const; 139 is_compound(eStatementType t)140 static bool is_compound(eStatementType t) {return t==eBlock || t==eFor || t==eIfElse || t==eArrayOp;} 141 is_ctrl_stmt(void)142 bool is_ctrl_stmt(void) const {return eType == eContinue || eType == eBreak || eType == eGoto;} 143 144 bool is_1st_stm(void) const; 145 146 bool is_jump_target_from_other_blocks(void) const; 147 148 bool read_union_field(void) const; 149 150 virtual void get_blocks(std::vector<const Block*>& /* blks */) const = 0; 151 virtual void get_exprs(std::vector<const Expression*>& /* exps */) const = 0; 152 153 std::string find_jump_label(void) const; 154 int find_jump_sources(std::vector<const StatementGoto*>& gotos) const; 155 156 void set_accumulated_effect_after_block(Effect& eff, const Block* b, CGContext& cg_context) const; 157 has_uncertain_call_recursive(void)158 virtual bool has_uncertain_call_recursive(void) const {return false;} 159 must_return(void)160 virtual bool must_return(void) const {return false;} 161 must_jump(void)162 virtual bool must_jump(void) const {return false;} 163 164 virtual std::vector<const ExpressionVariable*> get_dereferenced_ptrs(void) const; 165 166 void get_referenced_ptrs(std::vector<const Variable*>& ptrs) const; 167 bool is_ptr_used(void) const; 168 169 virtual void Output(std::ostream &out, FactMgr* fm=0, int indent = 0) const = 0; 170 int pre_output(std::ostream &out, FactMgr* fm=0, int indent = 0) const; 171 void post_output(std::ostream &out, FactMgr* fm=0, int indent = 0) const; 172 173 void output_with_assert(std::ostream &out); 174 175 const eStatementType eType; 176 get_current_sid(void)177 static int get_current_sid(void) { return sid; } 178 179 int get_blk_depth(void) const; 180 181 // unique id for each statement 182 int stm_id; 183 Function* func; 184 Block* parent; 185 static const Statement* failed_stm; 186 187 static ProbabilityTable<unsigned int, ProbName> *stmtTable_; 188 protected: 189 Statement(eStatementType st, Block* parent); 190 191 private: 192 static int sid; 193 194 Statement &operator=(const Statement &s); // unimplementable 195 196 static void InitProbabilityTable(); 197 }; 198 199 int find_stm_in_set(const vector<const Statement*>& set, const Statement* s); 200 201 /////////////////////////////////////////////////////////////////////////////// 202 203 #endif // STATEMENT_H 204 205 // Local Variables: 206 // c-basic-offset: 4 207 // tab-width: 4 208 // End: 209 210 // End of file. 211