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