Skip to content

Commit 4b351cc

Browse files
committed
add a 'language feature' facility for goto programs
This adds a facility to track the language features used by a goto program. The features are stored in the value of a symbol in the symbol table part of a goto model. The default, when not specificd, is 'true', i.e., we conservatively assume that the feature might be in use unless we know otherwise. Checks for three language features not supported by goto symex are added (assembler, function pointers, vectors).
1 parent 1d0ee45 commit 4b351cc

9 files changed

+166
-0
lines changed

jbmc/src/jbmc/jbmc_parse_options.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ Author: Daniel Kroening, [email protected]
2222
#include <goto-programs/goto_check.h>
2323
#include <goto-programs/goto_convert_functions.h>
2424
#include <goto-programs/instrument_preconditions.h>
25+
#include <goto-programs/language_features.h>
2526
#include <goto-programs/loop_ids.h>
2627
#include <goto-programs/remove_returns.h>
2728
#include <goto-programs/remove_skip.h>
@@ -811,6 +812,11 @@ bool jbmc_parse_optionst::process_goto_functions(
811812
log.status() << "Running GOTO functions transformation passes"
812813
<< messaget::eom;
813814

815+
// Our transformations remove function pointers, and
816+
// Java does not have vectors.
817+
clear_language_feature(goto_model, ID_function_pointers);
818+
clear_language_feature(goto_model, ID_vector);
819+
814820
bool using_symex_driven_loading =
815821
options.get_bool_option("symex-driven-lazy-loading");
816822

src/assembler/remove_asm.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ Date: December 2014
2323
#include <util/string_constant.h>
2424

2525
#include <goto-programs/goto_model.h>
26+
#include <goto-programs/language_features.h>
2627
#include <goto-programs/remove_skip.h>
2728

2829
#include "assembler_parser.h"
@@ -39,6 +40,8 @@ class remove_asmt
3940
{
4041
for(auto &f : goto_functions.function_map)
4142
process_function(f.first, f.second);
43+
44+
clear_language_feature(symbol_table, ID_asm);
4245
}
4346

4447
protected:

src/goto-checker/multi_path_symex_checker.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ Author: Daniel Kroening, Peter Schrammel
1313

1414
#include <util/ui_message.h>
1515

16+
#include <goto-programs/language_features.h>
17+
1618
#include <goto-symex/solver_hardness.h>
1719

1820
#include "bmc_util.h"
@@ -27,6 +29,10 @@ multi_path_symex_checkert::multi_path_symex_checkert(
2729
equation_generated(false),
2830
property_decider(options, ui_message_handler, equation, ns)
2931
{
32+
// check the language features used vs. what we support
33+
PRECONDITION(!has_language_feature(goto_model, ID_asm));
34+
PRECONDITION(!has_language_feature(goto_model, ID_function_pointers));
35+
PRECONDITION(!has_language_feature(goto_model, ID_vector));
3036
}
3137

3238
incremental_goto_checkert::resultt multi_path_symex_checkert::

src/goto-programs/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ SRC = allocate_objects.cpp \
3232
json_expr.cpp \
3333
json_goto_trace.cpp \
3434
label_function_pointer_call_sites.cpp \
35+
language_features.cpp \
3536
link_goto_model.cpp \
3637
link_to_library.cpp \
3738
loop_ids.cpp \
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/*******************************************************************\
2+
3+
Module: Language Features
4+
5+
Author: Daniel Kroening, [email protected]
6+
7+
\*******************************************************************/
8+
9+
/// \file
10+
/// Language Features
11+
12+
#include "language_features.h"
13+
14+
#include <util/cprover_prefix.h>
15+
#include <util/namespace.h>
16+
17+
#include "goto_model.h"
18+
19+
static const irep_idt language_features_identifier =
20+
CPROVER_PREFIX "language_features";
21+
22+
static const symbolt *
23+
language_features_symbol(const symbol_tablet &symbol_table)
24+
{
25+
const namespacet ns(symbol_table);
26+
const symbolt *result;
27+
if(!ns.lookup(language_features_identifier, result))
28+
return result;
29+
else
30+
return nullptr;
31+
}
32+
33+
static symbolt &language_features_symbol(symbol_tablet &symbol_table)
34+
{
35+
symbolt *result = symbol_table.get_writeable(language_features_identifier);
36+
37+
if(result == nullptr)
38+
{
39+
// need to add
40+
symbolt new_symbol;
41+
new_symbol.base_name = language_features_identifier;
42+
new_symbol.name = language_features_identifier;
43+
new_symbol.mode =
44+
ID_C; // arbitrary, to make symbolt::is_well_formed() happy
45+
new_symbol.value = exprt(irep_idt());
46+
symbol_table.move(new_symbol, result);
47+
return *result;
48+
}
49+
else
50+
return *result;
51+
}
52+
53+
bool has_language_feature(
54+
const symbol_tablet &symbol_table,
55+
const irep_idt &feature)
56+
{
57+
auto symbol = language_features_symbol(symbol_table);
58+
if(symbol == nullptr)
59+
{
60+
// Legacy model without annotations, we conservatively
61+
// assume that the model might use the feature.
62+
return true;
63+
}
64+
else
65+
{
66+
auto &feature_irep = symbol->value.find(feature);
67+
if(feature_irep.is_nil())
68+
{
69+
// No annotation. We assume that the feature is not used.
70+
return false;
71+
}
72+
else
73+
return symbol->value.get_bool(feature);
74+
}
75+
}
76+
77+
bool has_language_feature(
78+
const abstract_goto_modelt &model,
79+
const irep_idt &feature)
80+
{
81+
return has_language_feature(model.get_symbol_table(), feature);
82+
}
83+
84+
void add_language_feature(symbol_tablet &symbol_table, const irep_idt &feature)
85+
{
86+
auto &symbol = language_features_symbol(symbol_table);
87+
symbol.value.set(feature, true);
88+
}
89+
90+
void add_language_feature(goto_modelt &model, const irep_idt &feature)
91+
{
92+
add_language_feature(model.symbol_table, feature);
93+
}
94+
95+
void clear_language_feature(
96+
symbol_tablet &symbol_table,
97+
const irep_idt &feature)
98+
{
99+
auto &symbol = language_features_symbol(symbol_table);
100+
symbol.value.set(feature, false);
101+
}
102+
103+
void clear_language_feature(goto_modelt &model, const irep_idt &feature)
104+
{
105+
clear_language_feature(model.symbol_table, feature);
106+
}

src/goto-programs/language_features.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*******************************************************************\
2+
3+
Module: Language Features
4+
5+
Author: Daniel Kroening, [email protected]
6+
7+
\*******************************************************************/
8+
9+
/// \file
10+
/// Language Features
11+
12+
#ifndef CPROVER_GOTO_PROGRAMS_LANGUAGE_FEATURES_H
13+
#define CPROVER_GOTO_PROGRAMS_LANGUAGE_FEATURES_H
14+
15+
#include <util/irep.h>
16+
17+
class abstract_goto_modelt;
18+
class goto_modelt;
19+
class symbol_tablet;
20+
21+
/// Returns true when the given goto model indicates that
22+
/// the given language feature might be used.
23+
bool has_language_feature(const abstract_goto_modelt &, const irep_idt &);
24+
bool has_language_feature(const symbol_tablet &, const irep_idt &);
25+
26+
/// Indicate that the given goto model might use
27+
/// the given language feature.
28+
void add_language_feature(goto_modelt &, const irep_idt &);
29+
void add_language_feature(symbol_tablet &, const irep_idt &);
30+
31+
/// Indicate that the given goto model does not use
32+
/// the given language feature.
33+
void clear_language_feature(goto_modelt &, const irep_idt &);
34+
void clear_language_feature(symbol_tablet &, const irep_idt &);
35+
36+
#endif // CPROVER_GOTO_PROGRAMS_LANGUAGE_FEATURES_H

src/goto-programs/remove_function_pointers.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ Author: Daniel Kroening, [email protected]
2828

2929
#include "compute_called_functions.h"
3030
#include "goto_model.h"
31+
#include "language_features.h"
3132
#include "remove_const_function_pointers.h"
3233
#include "remove_skip.h"
3334

@@ -519,6 +520,10 @@ void remove_function_pointerst::operator()(goto_functionst &functions)
519520

520521
if(did_something)
521522
functions.compute_location_numbers();
523+
524+
// We always clear the 'function pointers' feature, even when none
525+
// were present.
526+
clear_language_feature(symbol_table, ID_function_pointers);
522527
}
523528

524529
void remove_function_pointers(

src/goto-programs/remove_vector.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ Date: September 2014
1919
#include <ansi-c/c_expr.h>
2020

2121
#include "goto_model.h"
22+
#include "language_features.h"
2223

2324
static bool have_to_remove_vector(const typet &type);
2425

@@ -379,6 +380,7 @@ void remove_vector(
379380
{
380381
remove_vector(symbol_table);
381382
remove_vector(goto_functions);
383+
clear_language_feature(symbol_table, ID_vector);
382384
}
383385

384386
/// removes vector data type

src/util/irep_ids.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -904,6 +904,7 @@ IREP_ID_TWO(overflow_result_unary_minus, overflow_result-unary-)
904904
IREP_ID_ONE(field_sensitive_ssa)
905905
IREP_ID_ONE(checked_assigns)
906906
IREP_ID_ONE(enum_is_in_range)
907+
IREP_ID_ONE(function_pointers)
907908

908909
// Projects depending on this code base that wish to extend the list of
909910
// available ids should provide a file local_irep_ids.def in their source tree

0 commit comments

Comments
 (0)