1 // -*- mode: C++ -*-
2 //
3 // Copyright (c) 2007, 2008, 2010, 2011, 2015, 2017 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 #if HAVE_CONFIG_H
31 #  include <config.h>
32 #endif
33 
34 #include "StatementExpr.h"
35 #include <iostream>
36 #include "CGContext.h"
37 #include "CGOptions.h"
38 #include "FunctionInvocation.h"
39 #include "FunctionInvocationUser.h"
40 #include "Expression.h"
41 #include "Function.h"
42 #include "ExpressionVariable.h"
43 #include "FactMgr.h"
44 #include "Error.h"
45 #include "DepthSpec.h"
46 
47 using namespace std;
48 
49 ///////////////////////////////////////////////////////////////////////////////
50 
51 /*
52  *
53  */
54 StatementExpr *
make_random(CGContext & cg_context)55 StatementExpr::make_random(CGContext &cg_context)
56 {
57 	DEPTH_GUARD_BY_TYPE_RETURN(dtStatementExpr, NULL);
58 	FunctionInvocation *invoke;
59 	// make copies
60 	Effect pre_effect = cg_context.get_accum_effect();
61 	FactMgr* fm = get_fact_mgr(&cg_context);
62 	vector<const Fact*> facts_copy = fm->global_facts;
63 	invoke = FunctionInvocation::make_random(false, cg_context, 0, 0);
64 	ERROR_GUARD(NULL);
65 	if (invoke->failed) {
66 		cg_context.reset_effect_accum(pre_effect);
67 		fm->restore_facts(facts_copy);
68 		delete invoke;
69 		return 0;
70 	}
71 	return new StatementExpr(cg_context.get_current_block(), *invoke);
72 }
73 
74 /*
75  *
76  */
StatementExpr(Block * b,const FunctionInvocation & e)77 StatementExpr::StatementExpr(Block* b, const FunctionInvocation &e)
78 	: Statement(eInvoke, b),
79 	  expr(e)
80 {
81 	// Nothing else to do.
82 }
83 
84 /*
85  *
86  */
StatementExpr(const StatementExpr & se)87 StatementExpr::StatementExpr(const StatementExpr &se)
88 : Statement(se.get_type(), se.parent),
89 	  expr(*se.get_invoke())
90 {
91 	// Nothing else to do.
92 }
93 
94 /*
95  *
96  */
~StatementExpr(void)97 StatementExpr::~StatementExpr(void)
98 {
99 	//delete &expr;
100 }
101 
102 /*
103  *
104  */
105 void
Output(std::ostream & out,FactMgr *,int indent) const106 StatementExpr::Output(std::ostream &out, FactMgr* /*fm*/, int indent) const
107 {
108 	output_tab(out, indent);
109 	expr.Output(out);
110 	out << ";";
111 	outputln(out);
112 }
113 
114 bool
visit_facts(vector<const Fact * > & inputs,CGContext & cg_context) const115 StatementExpr::visit_facts(vector<const Fact*>& inputs, CGContext& cg_context) const
116 {
117 	bool ok = expr.visit_facts(inputs, cg_context);
118 
119 	// save effect
120 	FactMgr* fm = get_fact_mgr(&cg_context);
121 	fm->map_stm_effect[this] = cg_context.get_effect_stm();
122 	return ok;
123 }
124 
125 std::vector<const ExpressionVariable*>
get_dereferenced_ptrs(void) const126 StatementExpr::get_dereferenced_ptrs(void) const
127 {
128 	std::vector<const ExpressionVariable*> vars;
129 	if (get_invoke()->invoke_type == eFuncCall) {
130 		const FunctionInvocationUser* func_call = dynamic_cast<const FunctionInvocationUser*>(get_invoke());
131 		for (size_t i=0; i<func_call->param_value.size(); i++) {
132 			// the parameters might be dereferenced pointers
133 			const Expression* value = func_call->param_value[i];
134 			vector<const ExpressionVariable*> param_ptrs = value->get_dereferenced_ptrs();
135 			vars.insert(vars.end(),  param_ptrs.begin(), param_ptrs.end());
136 		}
137 	}
138 	return vars;
139 }
140 
141 bool
has_uncertain_call_recursive(void) const142 StatementExpr::has_uncertain_call_recursive(void) const
143 {
144 	return expr.has_uncertain_call_recursive();
145 }
146 
147 ///////////////////////////////////////////////////////////////////////////////
148 
149 // Local Variables:
150 // c-basic-offset: 4
151 // tab-width: 4
152 // End:
153 
154 // End of file.
155