Skip to content

Commit d475cf1

Browse files
Merge pull request #889 from romainbrenguier/bugfix/char-input-type-in-trace
Adding java_type field in json for bit vector values
2 parents 2120a44 + 2c27b41 commit d475cf1

File tree

3 files changed

+76
-45
lines changed

3 files changed

+76
-45
lines changed

src/goto-programs/json_goto_trace.cpp

+18-11
Original file line numberDiff line numberDiff line change
@@ -92,16 +92,8 @@ void convert(
9292
std::string value_string, binary_string, type_string, full_lhs_string;
9393
json_objectt full_lhs_value;
9494

95-
if(step.full_lhs.is_not_nil())
96-
full_lhs_string=from_expr(ns, identifier, step.full_lhs);
97-
98-
#if 0
99-
if(it.full_lhs_value.is_not_nil())
100-
full_lhs_value_string=from_expr(ns, identifier, it.full_lhs_value);
101-
#endif
102-
103-
if(step.full_lhs_value.is_not_nil())
104-
full_lhs_value = json(step.full_lhs_value, ns);
95+
assert(step.full_lhs.is_not_nil());
96+
full_lhs_string=from_expr(ns, identifier, step.full_lhs);
10597

10698
const symbolt *symbol;
10799
irep_idt base_name, display_name;
@@ -114,6 +106,13 @@ void convert(
114106
type_string=from_type(ns, identifier, symbol->type);
115107

116108
json_assignment["mode"]=json_stringt(id2string(symbol->mode));
109+
assert(step.full_lhs_value.is_not_nil());
110+
full_lhs_value=json(step.full_lhs_value, ns, symbol->mode);
111+
}
112+
else
113+
{
114+
assert(step.full_lhs_value.is_not_nil());
115+
full_lhs_value=json(step.full_lhs_value, ns);
117116
}
118117

119118
json_assignment["value"]=full_lhs_value;
@@ -141,14 +140,22 @@ void convert(
141140
json_output["thread"]=json_numbert(std::to_string(step.thread_nr));
142141
json_output["outputID"]=json_stringt(id2string(step.io_id));
143142

143+
// Recovering the mode from the function
144+
irep_idt mode;
145+
const symbolt *function_name;
146+
if(ns.lookup(source_location.get_function(), function_name))
147+
// Failed to find symbol
148+
mode=ID_unknown;
149+
else
150+
mode=function_name->mode;
144151
json_arrayt &json_values=json_output["values"].make_array();
145152

146153
for(const auto &arg : step.io_args)
147154
{
148155
if(arg.is_nil())
149156
json_values.push_back(json_stringt(""));
150157
else
151-
json_values.push_back(json(arg, ns));
158+
json_values.push_back(json(arg, ns, mode));
152159
}
153160

154161
if(!json_location.is_null())

src/util/json_expr.cpp

+53-32
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ Author: Peter Schrammel
1515
#include "std_expr.h"
1616
#include "config.h"
1717
#include "identifier.h"
18+
#include "language.h"
19+
#include <langapi/mode.h>
1820

1921
#include "json_expr.h"
2022

@@ -113,19 +115,26 @@ json_objectt json(const source_locationt &location)
113115
Function: json
114116
115117
Inputs:
118+
type - a type
119+
ns - a namespace
120+
mode - language in which the code was written;
121+
for now ID_C and ID_java are supported
116122
117-
Outputs:
123+
Outputs: a json object
118124
119125
Purpose:
126+
Output a CBMC type in json.
127+
The `mode` argument is used to correctly report types.
120128
121129
\*******************************************************************/
122130

123131
json_objectt json(
124132
const typet &type,
125-
const namespacet &ns)
133+
const namespacet &ns,
134+
const irep_idt &mode)
126135
{
127136
if(type.id()==ID_symbol)
128-
return json(ns.follow(type), ns);
137+
return json(ns.follow(type), ns, mode);
129138

130139
json_objectt result;
131140

@@ -161,7 +170,7 @@ json_objectt json(
161170
else if(type.id()==ID_c_enum_tag)
162171
{
163172
// we return the base type
164-
return json(ns.follow_tag(to_c_enum_tag_type(type)).subtype(), ns);
173+
return json(ns.follow_tag(to_c_enum_tag_type(type)).subtype(), ns, mode);
165174
}
166175
else if(type.id()==ID_fixedbv)
167176
{
@@ -172,7 +181,7 @@ json_objectt json(
172181
else if(type.id()==ID_pointer)
173182
{
174183
result["name"]=json_stringt("pointer");
175-
result["subtype"]=json(type.subtype(), ns);
184+
result["subtype"]=json(type.subtype(), ns, mode);
176185
}
177186
else if(type.id()==ID_bool)
178187
{
@@ -181,13 +190,13 @@ json_objectt json(
181190
else if(type.id()==ID_array)
182191
{
183192
result["name"]=json_stringt("array");
184-
result["subtype"]=json(type.subtype(), ns);
193+
result["subtype"]=json(type.subtype(), ns, mode);
185194
}
186195
else if(type.id()==ID_vector)
187196
{
188197
result["name"]=json_stringt("vector");
189-
result["subtype"]=json(type.subtype(), ns);
190-
result["size"]=json(to_vector_type(type).size(), ns);
198+
result["subtype"]=json(type.subtype(), ns, mode);
199+
result["size"]=json(to_vector_type(type).size(), ns, mode);
191200
}
192201
else if(type.id()==ID_struct)
193202
{
@@ -199,7 +208,7 @@ json_objectt json(
199208
{
200209
json_objectt &e=members.push_back().make_object();
201210
e["name"]=json_stringt(id2string(component.get_name()));
202-
e["type"]=json(component.type(), ns);
211+
e["type"]=json(component.type(), ns, mode);
203212
}
204213
}
205214
else if(type.id()==ID_union)
@@ -212,7 +221,7 @@ json_objectt json(
212221
{
213222
json_objectt &e=members.push_back().make_object();
214223
e["name"]=json_stringt(id2string(component.get_name()));
215-
e["type"]=json(component.type(), ns);
224+
e["type"]=json(component.type(), ns, mode);
216225
}
217226
}
218227
else
@@ -226,16 +235,23 @@ json_objectt json(
226235
Function: json
227236
228237
Inputs:
238+
expr - an expression
239+
ns - a namespace
240+
mode - language in which the code was written;
241+
for now ID_C and ID_java are supported
229242
230-
Outputs:
243+
Outputs: a json object
231244
232245
Purpose:
246+
Output a CBMC expression in json.
247+
The mode is used to correctly report types.
233248
234249
\*******************************************************************/
235250

236251
json_objectt json(
237252
const exprt &expr,
238-
const namespacet &ns)
253+
const namespacet &ns,
254+
const irep_idt &mode)
239255
{
240256
json_objectt result;
241257

@@ -258,42 +274,47 @@ json_objectt json(
258274
type.id()==ID_c_bit_field?type.subtype():
259275
type;
260276

261-
bool is_signed=underlying_type.id()==ID_signedbv;
262-
263-
std::string sig=is_signed?"":"unsigned ";
277+
languaget *lang;
278+
if(mode==ID_unknown)
279+
lang=get_default_language();
280+
else
281+
{
282+
lang=get_language_from_mode(mode);
283+
if(!lang)
284+
lang=get_default_language();
285+
}
264286

265-
if(width==config.ansi_c.char_width)
266-
result["c_type"]=json_stringt(sig+"char");
267-
else if(width==config.ansi_c.int_width)
268-
result["c_type"]=json_stringt(sig+"int");
269-
else if(width==config.ansi_c.short_int_width)
270-
result["c_type"]=json_stringt(sig+"short int");
271-
else if(width==config.ansi_c.long_int_width)
272-
result["c_type"]=json_stringt(sig+"long int");
273-
else if(width==config.ansi_c.long_long_int_width)
274-
result["c_type"]=json_stringt(sig+"long long int");
287+
std::string type_string;
288+
if(!lang->from_type(underlying_type, type_string, ns))
289+
result["type"]=json_stringt(type_string);
290+
else
291+
assert(false && "unknown type");
275292

276293
mp_integer i;
277294
if(!to_integer(expr, i))
278295
result["data"]=json_stringt(integer2string(i));
296+
else
297+
assert(false && "could not convert data to integer");
279298
}
280299
else if(type.id()==ID_c_enum)
281300
{
282301
result["name"]=json_stringt("integer");
283302
result["binary"]=json_stringt(id2string(constant_expr.get_value()));
284303
result["width"]=json_numbert(type.subtype().get_string(ID_width));
285-
result["c_type"]=json_stringt("enum");
304+
result["type"]=json_stringt("enum");
286305

287306
mp_integer i;
288307
if(!to_integer(expr, i))
289308
result["data"]=json_stringt(integer2string(i));
309+
else
310+
assert(false && "could not convert data to integer");
290311
}
291312
else if(type.id()==ID_c_enum_tag)
292313
{
293314
constant_exprt tmp;
294315
tmp.type()=ns.follow_tag(to_c_enum_tag_type(type));
295-
tmp.set_value(constant_expr.get_value());
296-
return json(tmp, ns);
316+
tmp.set_value(to_constant_expr(expr).get_value());
317+
return json(tmp, ns, mode);
297318
}
298319
else if(type.id()==ID_bv)
299320
{
@@ -342,7 +363,7 @@ json_objectt json(
342363
else if(type.id()==ID_c_bool)
343364
{
344365
result["name"]=json_stringt("integer");
345-
result["c_type"]=json_stringt("_Bool");
366+
result["type"]=json_stringt("_Bool");
346367
result["binary"]=json_stringt(expr.get_string(ID_value));
347368
mp_integer b;
348369
to_integer(to_constant_expr(expr), b);
@@ -369,7 +390,7 @@ json_objectt json(
369390
{
370391
json_objectt &e=elements.push_back().make_object();
371392
e["index"]=json_numbert(std::to_string(index));
372-
e["value"]=json(*it, ns);
393+
e["value"]=json(*it, ns, mode);
373394
index++;
374395
}
375396
}
@@ -388,7 +409,7 @@ json_objectt json(
388409
for(unsigned m=0; m<expr.operands().size(); m++)
389410
{
390411
json_objectt &e=members.push_back().make_object();
391-
e["value"]=json(expr.operands()[m], ns);
412+
e["value"]=json(expr.operands()[m], ns, mode);
392413
e["name"]=json_stringt(id2string(components[m].get_name()));
393414
}
394415
}
@@ -400,7 +421,7 @@ json_objectt json(
400421
assert(expr.operands().size()==1);
401422

402423
json_objectt &e=result["member"].make_object();
403-
e["value"]=json(expr.op0(), ns);
424+
e["value"]=json(expr.op0(), ns, mode);
404425
e["name"]=json_stringt(id2string(to_union_expr(expr).get_component_name()));
405426
}
406427
else

src/util/json_expr.h

+5-2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Author: Peter Schrammel
1010
#define CPROVER_UTIL_JSON_EXPR_H
1111

1212
#include "json.h"
13+
#include "irep.h"
1314

1415
class source_locationt;
1516
class typet;
@@ -18,11 +19,13 @@ class namespacet;
1819

1920
json_objectt json(
2021
const exprt &,
21-
const namespacet &);
22+
const namespacet &,
23+
const irep_idt &mode=ID_unknown);
2224

2325
json_objectt json(
2426
const typet &,
25-
const namespacet &);
27+
const namespacet &,
28+
const irep_idt &mode=ID_unknown);
2629

2730
json_objectt json(const source_locationt &);
2831

0 commit comments

Comments
 (0)