14
14
#include < util/arith_tools.h>
15
15
#include < util/c_types.h>
16
16
#include < util/expr_initializer.h>
17
+ #include < util/expr_util.h>
18
+ #include < util/fresh_symbol.h>
17
19
#include < util/invariant_utils.h>
18
20
#include < util/optional.h>
19
21
#include < util/pointer_offset_size.h>
@@ -203,24 +205,7 @@ void goto_symext::symex_allocate(
203
205
code_assignt (lhs, typecast_exprt::conditional_cast (rhs, lhs.type ())));
204
206
}
205
207
206
- irep_idt get_symbol (const exprt &src)
207
- {
208
- if (src.id ()==ID_typecast)
209
- return get_symbol (to_typecast_expr (src).op ());
210
- else if (src.id ()==ID_address_of)
211
- {
212
- exprt op=to_address_of_expr (src).object ();
213
- if (op.id ()==ID_symbol &&
214
- op.get_bool (ID_C_SSA_symbol))
215
- return to_ssa_expr (op).get_object_name ();
216
- else
217
- return irep_idt ();
218
- }
219
- else
220
- return irep_idt ();
221
- }
222
-
223
- void goto_symext::symex_gcc_builtin_va_arg_next (
208
+ void goto_symext::symex_gcc_builtin_va_start (
224
209
statet &state,
225
210
const exprt &lhs,
226
211
const side_effect_exprt &code)
@@ -230,42 +215,48 @@ void goto_symext::symex_gcc_builtin_va_arg_next(
230
215
if (lhs.is_nil ())
231
216
return ; // ignore
232
217
233
- exprt tmp=code.op0 ();
234
- state.rename (tmp, ns); // to allow constant propagation
235
- do_simplify (tmp);
236
- irep_idt id=get_symbol (tmp);
237
-
238
- const auto zero = zero_initializer (lhs.type (), code.source_location (), ns);
239
- CHECK_RETURN (zero.has_value ());
240
- exprt rhs (*zero);
218
+ // create an array holding pointers to the parameters, starting with the
219
+ // parameter that the operand points to
220
+ const exprt &op = skip_typecast (code.op0 ());
221
+ // this must be the address of a symbol
222
+ const irep_idt &start_parameter =
223
+ to_symbol_expr (to_address_of_expr (op).object ()).get_identifier ();
241
224
242
- if (!id.empty ())
225
+ exprt::operandst va_arg_operands;
226
+ bool parameter_id_found = false ;
227
+ for (auto ¶meter : state.top ().parameter_names )
243
228
{
244
- // strip last name off id to get function name
245
- std::size_t pos=id2string (id).rfind (" ::" );
246
- if (pos!=std::string::npos)
247
- {
248
- irep_idt function_identifier=std::string (id2string (id), 0 , pos);
249
- std::string base=id2string (function_identifier)+" ::va_arg" ;
250
-
251
- if (has_prefix (id2string (id), base))
252
- id=base+std::to_string (
253
- safe_string2unsigned (
254
- std::string (id2string (id), base.size (), std::string::npos))+1 );
255
- else
256
- id=base+" 0" ;
257
-
258
- const symbolt *symbol;
259
- if (!ns.lookup (id, symbol))
260
- {
261
- const symbol_exprt symbol_expr (symbol->name , symbol->type );
262
- rhs = typecast_exprt::conditional_cast (
263
- address_of_exprt (symbol_expr), lhs.type ());
264
- }
265
- }
266
- }
229
+ if (!parameter_id_found && parameter == start_parameter)
230
+ parameter_id_found = true ;
267
231
268
- symex_assign (state, code_assignt (lhs, rhs));
232
+ va_arg_operands.push_back (typecast_exprt::conditional_cast (
233
+ address_of_exprt{ns.lookup (parameter).symbol_expr ()},
234
+ pointer_type (empty_typet{})));
235
+ }
236
+ const std::size_t va_arg_size = va_arg_operands.size ();
237
+ array_exprt array{std::move (va_arg_operands),
238
+ array_typet{pointer_type (empty_typet{}),
239
+ from_integer (va_arg_size, size_type ())}};
240
+
241
+ symbolt &va_array = get_fresh_aux_symbol (
242
+ array.type (),
243
+ id2string (state.source .function_id ),
244
+ " va_args" ,
245
+ state.source .pc ->source_location ,
246
+ ns.lookup (state.source .function_id ).mode ,
247
+ state.symbol_table );
248
+ va_array.value = array;
249
+
250
+ state.rename (array, ns);
251
+ do_simplify (array);
252
+ symex_assign (state, code_assignt{va_array.symbol_expr (), std::move (array)});
253
+
254
+ address_of_exprt rhs{
255
+ index_exprt{va_array.symbol_expr (), from_integer (0 , index_type ())}};
256
+ state.rename (rhs, ns);
257
+ symex_assign (
258
+ state,
259
+ code_assignt{lhs, typecast_exprt::conditional_cast (rhs, lhs.type ())});
269
260
}
270
261
271
262
irep_idt get_string_argument_rec (const exprt &src)
0 commit comments