Skip to content

Commit 0cd1057

Browse files
Merge pull request #1198 from peterschrammel/fix-json-output-constants
Fix language-specific printing of constants in JSON output
2 parents 561f38d + 28ca28d commit 0cd1057

File tree

5 files changed

+75
-48
lines changed

5 files changed

+75
-48
lines changed
292 Bytes
Binary file not shown.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
public class Test {
2+
boolean test(Object x) {
3+
if(x==null)
4+
return false;
5+
return true;
6+
}
7+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
CORE
2+
Test.class
3+
--cover location --trace --json-ui --function Test.test
4+
activate-multi-line-match
5+
EXIT=0
6+
SIGNAL=0
7+
"outputID": "return",\n *"sourceLocation": \{\n *"file": "Test\.java",\n *"function": "java::Test\.test:\(Ljava/lang/Object;\)Z",\n *"line": "3"\n *\},\n *"stepType": "output",\n *"thread": 0,\n *"values": \[\n *\{\n *"binary": "00000000",\n *"data": "false",\n *"name": "integer",\n *"type": "boolean",\n *"width": 8
8+
"inputID": "arg1a",\n *"internal": true,\n *"mode": "java",\n *"sourceLocation": \{\n *"file": "Test\.java",\n *"function": "java::Test\.test:\(Ljava/lang/Object;\)Z",\n *"line": "3"\n *\},\n *"stepType": "input",\n *"thread": 0,\n *"values": \[\n *\{\n *"data": "null",\n *"name": "pointer",\n *"type": "struct java\.lang\.Object \{ __CPROVER_string @class_identifier; boolean @lock; \} \*"
9+
--
10+
^warning: ignoring

src/goto-programs/json_goto_trace.cpp

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,10 @@ Author: Daniel Kroening
1313

1414
#include "json_goto_trace.h"
1515

16-
#include <cassert>
17-
1816
#include <util/json_expr.h>
1917
#include <util/arith_tools.h>
2018
#include <util/config.h>
19+
#include <util/invariant.h>
2120

2221
#include <langapi/language_util.h>
2322

@@ -194,7 +193,9 @@ void convert(
194193
std::string value_string, binary_string, type_string, full_lhs_string;
195194
json_objectt full_lhs_value;
196195

197-
assert(step.full_lhs.is_not_nil());
196+
DATA_INVARIANT(
197+
step.full_lhs.is_not_nil(),
198+
"full_lhs in assignment must not be nil");
198199
exprt simplified=simplify_array_access(step.full_lhs);
199200
full_lhs_string=from_expr(ns, identifier, simplified);
200201

@@ -214,7 +215,9 @@ void convert(
214215
}
215216
else
216217
{
217-
assert(step.full_lhs_value.is_not_nil());
218+
DATA_INVARIANT(
219+
step.full_lhs_value.is_not_nil(),
220+
"full_lhs_value in assignment must not be nil");
218221
full_lhs_value=json(step.full_lhs_value, ns);
219222
}
220223

@@ -251,6 +254,7 @@ void convert(
251254
mode=ID_unknown;
252255
else
253256
mode=function_name->mode;
257+
json_output["mode"]=json_stringt(id2string(mode));
254258
json_arrayt &json_values=json_output["values"].make_array();
255259

256260
for(const auto &arg : step.io_args)
@@ -276,14 +280,23 @@ void convert(
276280
json_input["thread"]=json_numbert(std::to_string(step.thread_nr));
277281
json_input["inputID"]=json_stringt(id2string(step.io_id));
278282

283+
// Recovering the mode from the function
284+
irep_idt mode;
285+
const symbolt *function_name;
286+
if(ns.lookup(source_location.get_function(), function_name))
287+
// Failed to find symbol
288+
mode=ID_unknown;
289+
else
290+
mode=function_name->mode;
291+
json_input["mode"]=json_stringt(id2string(mode));
279292
json_arrayt &json_values=json_input["values"].make_array();
280293

281294
for(const auto &arg : step.io_args)
282295
{
283296
if(arg.is_nil())
284297
json_values.push_back(json_stringt(""));
285298
else
286-
json_values.push_back(json(arg, ns));
299+
json_values.push_back(json(arg, ns, mode));
287300
}
288301

289302
if(!json_location.is_null())

src/util/json_expr.cpp

Lines changed: 40 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ Author: Peter Schrammel
2121
#include "config.h"
2222
#include "identifier.h"
2323
#include "language.h"
24+
#include "invariant.h"
25+
2426
#include <langapi/mode.h>
2527

2628
#include <memory>
@@ -228,6 +230,27 @@ json_objectt json(
228230

229231
if(expr.id()==ID_constant)
230232
{
233+
std::unique_ptr<languaget> lang;
234+
if(mode==ID_unknown)
235+
lang=std::unique_ptr<languaget>(get_default_language());
236+
else
237+
{
238+
lang=std::unique_ptr<languaget>(get_language_from_mode(mode));
239+
if(!lang)
240+
lang=std::unique_ptr<languaget>(get_default_language());
241+
}
242+
243+
const typet &underlying_type=
244+
type.id()==ID_c_bit_field?type.subtype():
245+
type;
246+
247+
std::string type_string;
248+
bool error=lang->from_type(underlying_type, type_string, ns);
249+
CHECK_RETURN(!error);
250+
251+
std::string value_string;
252+
lang->from_expr(expr, value_string, ns);
253+
231254
const constant_exprt &constant_expr=to_constant_expr(expr);
232255
if(type.id()==ID_unsignedbv ||
233256
type.id()==ID_signedbv ||
@@ -238,45 +261,16 @@ json_objectt json(
238261
result["name"]=json_stringt("integer");
239262
result["binary"]=json_stringt(id2string(constant_expr.get_value()));
240263
result["width"]=json_numbert(std::to_string(width));
241-
242-
const typet &underlying_type=
243-
type.id()==ID_c_bit_field?type.subtype():
244-
type;
245-
246-
std::unique_ptr<languaget> lang;
247-
if(mode==ID_unknown)
248-
lang=std::unique_ptr<languaget>(get_default_language());
249-
else
250-
{
251-
lang=std::unique_ptr<languaget>(get_language_from_mode(mode));
252-
if(!lang)
253-
lang=std::unique_ptr<languaget>(get_default_language());
254-
}
255-
256-
std::string type_string;
257-
if(!lang->from_type(underlying_type, type_string, ns))
258-
result["type"]=json_stringt(type_string);
259-
else
260-
assert(false && "unknown type");
261-
262-
mp_integer i;
263-
if(!to_integer(expr, i))
264-
result["data"]=json_stringt(integer2string(i));
265-
else
266-
assert(false && "could not convert data to integer");
264+
result["type"]=json_stringt(type_string);
265+
result["data"]=json_stringt(value_string);
267266
}
268267
else if(type.id()==ID_c_enum)
269268
{
270269
result["name"]=json_stringt("integer");
271270
result["binary"]=json_stringt(id2string(constant_expr.get_value()));
272271
result["width"]=json_numbert(type.subtype().get_string(ID_width));
273272
result["type"]=json_stringt("enum");
274-
275-
mp_integer i;
276-
if(!to_integer(expr, i))
277-
result["data"]=json_stringt(integer2string(i));
278-
else
279-
assert(false && "could not convert data to integer");
273+
result["data"]=json_stringt(value_string);
280274
}
281275
else if(type.id()==ID_c_enum_tag)
282276
{
@@ -309,17 +303,20 @@ json_objectt json(
309303
else if(type.id()==ID_pointer)
310304
{
311305
result["name"]=json_stringt("pointer");
306+
result["type"]=json_stringt(type_string);
312307
exprt simpl_expr=simplify_json_expr(expr, ns);
313308
if(simpl_expr.get(ID_value)==ID_NULL ||
314309
// remove typecast on NULL
315310
(simpl_expr.id()==ID_constant && simpl_expr.type().id()==ID_pointer &&
316311
simpl_expr.op0().get(ID_value)==ID_NULL))
317-
result["data"]=json_stringt("NULL");
312+
result["data"]=json_stringt(value_string);
318313
else if(simpl_expr.id()==ID_symbol)
319314
{
320315
const irep_idt &ptr_id=to_symbol_expr(simpl_expr).get_identifier();
321316
identifiert identifier(id2string(ptr_id));
322-
assert(!identifier.components.empty());
317+
DATA_INVARIANT(
318+
!identifier.components.empty(),
319+
"pointer identifier should have non-empty components");
323320
result["data"]=json_stringt(identifier.components.back());
324321
}
325322
}
@@ -332,11 +329,10 @@ json_objectt json(
332329
else if(type.id()==ID_c_bool)
333330
{
334331
result["name"]=json_stringt("integer");
335-
result["type"]=json_stringt("_Bool");
332+
result["width"]=json_numbert(type.get_string(ID_width));
333+
result["type"]=json_stringt(type_string);
336334
result["binary"]=json_stringt(expr.get_string(ID_value));
337-
mp_integer b;
338-
to_integer(to_constant_expr(expr), b);
339-
result["data"]=json_stringt(integer2string(b));
335+
result["data"]=json_stringt(value_string);
340336
}
341337
else if(type.id()==ID_string)
342338
{
@@ -372,7 +368,9 @@ json_objectt json(
372368
{
373369
const struct_typet &struct_type=to_struct_type(type);
374370
const struct_typet::componentst &components=struct_type.components();
375-
assert(components.size()==expr.operands().size());
371+
DATA_INVARIANT(
372+
components.size()==expr.operands().size(),
373+
"number of struct components should match with its type");
376374

377375
json_arrayt &members=result["members"].make_array();
378376
for(unsigned m=0; m<expr.operands().size(); m++)
@@ -387,11 +385,10 @@ json_objectt json(
387385
{
388386
result["name"]=json_stringt("union");
389387

390-
assert(expr.operands().size()==1);
391-
388+
const union_exprt &union_expr=to_union_expr(expr);
392389
json_objectt &e=result["member"].make_object();
393-
e["value"]=json(expr.op0(), ns, mode);
394-
e["name"]=json_stringt(id2string(to_union_expr(expr).get_component_name()));
390+
e["value"]=json(union_expr.op(), ns, mode);
391+
e["name"]=json_stringt(id2string(union_expr.get_component_name()));
395392
}
396393
else
397394
result["name"]=json_stringt("unknown");

0 commit comments

Comments
 (0)