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