Skip to content

Commit 8da41b7

Browse files
committed
Move goto_programt::(const_)targett comparison to a struct
This makes sure no one can inadvertently use less-than comparison on those iterators, which may lead to non-reproducible behaviour (see #6782).
1 parent 26b8027 commit 8da41b7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+326
-178
lines changed

jbmc/src/java_bytecode/java_bytecode_convert_method_class.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,23 @@ class java_bytecode_convert_methodt
240240

241241
public:
242242
typedef std::map<method_offsett, converted_instructiont> address_mapt;
243-
typedef std::pair<const methodt &, const address_mapt &> method_with_amapt;
243+
struct method_with_amapt
244+
{
245+
method_with_amapt(const methodt &m, const address_mapt &a)
246+
: method_with_amap(m, a)
247+
{
248+
}
249+
250+
std::pair<const methodt &, const address_mapt &> method_with_amap;
251+
252+
struct target_less_than // NOLINT(readability/identifiers)
253+
{
254+
bool operator()(const method_offsett &a, const method_offsett &b) const
255+
{
256+
return a < b;
257+
}
258+
};
259+
};
244260
typedef cfg_dominators_templatet<method_with_amapt, method_offsett, false>
245261
java_cfg_dominatorst;
246262

jbmc/src/java_bytecode/java_local_variable_table.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ struct procedure_local_cfg_baset<
4646

4747
void operator()(const method_with_amapt &args)
4848
{
49-
const auto &method=args.first;
50-
const auto &amap=args.second;
49+
const auto &method = args.method_with_amap.first;
50+
const auto &amap = args.method_with_amap.second;
5151
for(const auto &inst : amap)
5252
{
5353
// Map instruction PCs onto node indices:
@@ -109,18 +109,18 @@ struct procedure_local_cfg_baset<
109109
static java_bytecode_convert_methodt::method_offsett
110110
get_first_node(const method_with_amapt &args)
111111
{
112-
return args.second.begin()->first;
112+
return args.method_with_amap.second.begin()->first;
113113
}
114114

115115
static java_bytecode_convert_methodt::method_offsett
116116
get_last_node(const method_with_amapt &args)
117117
{
118-
return (--args.second.end())->first;
118+
return (--args.method_with_amap.second.end())->first;
119119
}
120120

121121
static bool nodes_empty(const method_with_amapt &args)
122122
{
123-
return args.second.empty();
123+
return args.method_with_amap.second.empty();
124124
}
125125
};
126126

src/analyses/ai_storage.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ class ai_storage_baset
100100
class trace_map_storaget : public ai_storage_baset
101101
{
102102
protected:
103-
typedef std::map<locationt, trace_set_ptrt> trace_mapt;
103+
typedef std::map<locationt, trace_set_ptrt, goto_programt::target_less_than>
104+
trace_mapt;
104105
trace_mapt trace_map;
105106

106107
// This retains one part of a shared_ptr to the history object

src/analyses/call_graph.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ class call_grapht
9898
typedef goto_programt::const_targett locationt;
9999

100100
/// Type of a set of callsites
101-
typedef std::set<locationt> locationst;
101+
typedef std::set<locationt, goto_programt::target_less_than> locationst;
102102

103103
/// Type mapping from call-graph edges onto the set of call instructions
104104
/// that make that call.

src/analyses/cfg_dominators.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ template <class P, class T, bool post_dom>
3636
class cfg_dominators_templatet
3737
{
3838
public:
39-
typedef std::set<T> target_sett;
39+
typedef std::set<T, typename P::target_less_than> target_sett;
4040

4141
struct nodet
4242
{
@@ -218,12 +218,12 @@ void cfg_dominators_templatet<P, T, post_dom>::fixedpoint(P &program)
218218
{
219219
if(*n_it==current)
220220
++n_it;
221-
else if(*n_it<*o_it)
221+
else if(typename P::target_less_than()(*n_it, *o_it))
222222
{
223223
changed=true;
224224
node.dominators.erase(n_it++);
225225
}
226-
else if(*o_it<*n_it)
226+
else if(typename P::target_less_than()(*o_it, *n_it))
227227
++o_it;
228228
else
229229
{

src/analyses/dependence_graph.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,9 @@ class dep_graph_domaint:public ai_domain_baset
172172
node_indext node_id;
173173
bool has_changed;
174174

175-
typedef std::set<goto_programt::const_targett> depst;
175+
typedef std::
176+
set<goto_programt::const_targett, goto_programt::target_less_than>
177+
depst;
176178

177179
// Set of locations with control instructions on which the instruction at this
178180
// location has a control dependency on

src/analyses/flow_insensitive_analysis.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,9 @@ class flow_insensitive_analysis_baset
9393
typedef flow_insensitive_abstract_domain_baset statet;
9494
typedef goto_programt::const_targett locationt;
9595

96-
std::set<locationt> seen_locations;
96+
std::set<locationt, goto_programt::target_less_than> seen_locations;
9797

98-
std::map<locationt, unsigned> statistics;
98+
std::map<locationt, unsigned, goto_programt::target_less_than> statistics;
9999

100100
bool seen(const locationt &l)
101101
{
@@ -155,7 +155,11 @@ class flow_insensitive_analysis_baset
155155
protected:
156156
const namespacet &ns;
157157

158-
typedef std::priority_queue<locationt> working_sett;
158+
typedef std::priority_queue<
159+
locationt,
160+
std::vector<locationt>,
161+
goto_programt::target_less_than>
162+
working_sett;
159163

160164
locationt get_next(working_sett &working_set);
161165

src/analyses/is_threaded.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,9 @@ class is_threadedt
4444
}
4545

4646
protected:
47-
typedef std::set<goto_programt::const_targett> is_threaded_sett;
47+
typedef std::
48+
set<goto_programt::const_targett, goto_programt::target_less_than>
49+
is_threaded_sett;
4850
is_threaded_sett is_threaded_set;
4951

5052
void compute(

src/analyses/lexical_loops.h

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,11 @@ Author: Diffblue Ltd
6060
/// * [function] is_backwards_goto() returning a bool.
6161
/// * [function] get_target() which returns an object that needs:
6262
/// * [field] location_number which is an unsigned int.
63-
template <class P, class T>
64-
class lexical_loops_templatet : public loop_analysist<T>
63+
/// \tparam C: comparison to use over `T` typed elements
64+
template <class P, class T, typename C>
65+
class lexical_loops_templatet : public loop_analysist<T, C>
6566
{
66-
typedef loop_analysist<T> parentt;
67+
typedef loop_analysist<T, C> parentt;
6768

6869
public:
6970
typedef typename parentt::loopt lexical_loopt;
@@ -103,16 +104,17 @@ class lexical_loops_templatet : public loop_analysist<T>
103104

104105
typedef lexical_loops_templatet<
105106
const goto_programt,
106-
goto_programt::const_targett>
107+
goto_programt::const_targett,
108+
goto_programt::target_less_than>
107109
lexical_loopst;
108110

109111
#ifdef DEBUG
110112
# include <iostream>
111113
#endif
112114

113115
/// Finds all back-edges and computes the lexical loops
114-
template <class P, class T>
115-
void lexical_loops_templatet<P, T>::compute(P &program)
116+
template <class P, class T, typename C>
117+
void lexical_loops_templatet<P, T, C>::compute(P &program)
116118
{
117119
all_in_lexical_loop_form = true;
118120

@@ -142,8 +144,8 @@ void lexical_loops_templatet<P, T>::compute(P &program)
142144
/// the tail, abandoning the candidate loop if we stray outside the bounds of
143145
/// the lexical region bounded by the head and tail, otherwise recording all
144146
/// instructions that can reach the backedge as falling within the loop.
145-
template <class P, class T>
146-
bool lexical_loops_templatet<P, T>::compute_lexical_loop(
147+
template <class P, class T, typename C>
148+
bool lexical_loops_templatet<P, T, C>::compute_lexical_loop(
147149
T loop_tail,
148150
T loop_head)
149151
{
@@ -152,7 +154,7 @@ bool lexical_loops_templatet<P, T>::compute_lexical_loop(
152154
"loop header should come lexically before the tail");
153155

154156
std::stack<T> stack;
155-
std::set<T> loop_instructions;
157+
std::set<T, C> loop_instructions;
156158

157159
loop_instructions.insert(loop_head);
158160
loop_instructions.insert(loop_tail);

src/analyses/local_cfg.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ class local_cfgt
2929
successorst successors;
3030
};
3131

32-
typedef std::map<goto_programt::const_targett, node_nrt> loc_mapt;
32+
typedef std::
33+
map<goto_programt::const_targett, node_nrt, goto_programt::target_less_than>
34+
loc_mapt;
3335
loc_mapt loc_map;
3436

3537
typedef std::vector<nodet> nodest;

src/analyses/local_may_alias.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,9 @@ class local_may_alias_factoryt
140140
typedef std::map<irep_idt, std::unique_ptr<local_may_aliast> > fkt_mapt;
141141
fkt_mapt fkt_map;
142142

143-
typedef std::map<goto_programt::const_targett, irep_idt > target_mapt;
143+
typedef std::
144+
map<goto_programt::const_targett, irep_idt, goto_programt::target_less_than>
145+
target_mapt;
144146
target_mapt target_map;
145147
};
146148

src/analyses/loop_analysis.h

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,17 @@ Author: Diffblue Ltd
1515

1616
#include <goto-programs/goto_model.h>
1717

18-
template <class T>
18+
template <class T, typename C>
1919
class loop_analysist;
2020

2121
/// A loop, specified as a set of instructions
22-
template <class T>
22+
template <class T, typename C>
2323
class loop_templatet
2424
{
25-
typedef std::set<T> loop_instructionst;
25+
typedef std::set<T, C> loop_instructionst;
2626
loop_instructionst loop_instructions;
2727

28-
friend loop_analysist<T>;
28+
friend loop_analysist<T, C>;
2929

3030
public:
3131
loop_templatet() = default;
@@ -77,13 +77,13 @@ class loop_templatet
7777
}
7878
};
7979

80-
template <class T>
80+
template <class T, typename C>
8181
class loop_analysist
8282
{
8383
public:
84-
typedef loop_templatet<T> loopt;
84+
typedef loop_templatet<T, C> loopt;
8585
// map loop headers to loops
86-
typedef std::map<T, loopt> loop_mapt;
86+
typedef std::map<T, loopt, C> loop_mapt;
8787

8888
loop_mapt loop_map;
8989

@@ -98,10 +98,10 @@ class loop_analysist
9898
loop_analysist() = default;
9999
};
100100

101-
template <typename T>
102-
class loop_with_parent_analysis_templatet : loop_templatet<T>
101+
template <typename T, typename C>
102+
class loop_with_parent_analysis_templatet : loop_templatet<T, C>
103103
{
104-
typedef loop_analysist<T> parent_analysist;
104+
typedef loop_analysist<T, C> parent_analysist;
105105

106106
public:
107107
explicit loop_with_parent_analysis_templatet(parent_analysist &loop_analysis)
@@ -113,14 +113,14 @@ class loop_with_parent_analysis_templatet : loop_templatet<T>
113113
explicit loop_with_parent_analysis_templatet(
114114
parent_analysist &loop_analysis,
115115
InstructionSet &&instructions)
116-
: loop_templatet<T>(std::forward<InstructionSet>(instructions)),
116+
: loop_templatet<T, C>(std::forward<InstructionSet>(instructions)),
117117
loop_analysis(loop_analysis)
118118
{
119119
}
120120

121121
/// Returns true if \p instruction is in \p loop
122122
bool loop_contains(
123-
const typename loop_analysist<T>::loopt &loop,
123+
const typename loop_analysist<T, C>::loopt &loop,
124124
const T instruction) const
125125
{
126126
return loop.loop_instructions.count(instruction);
@@ -141,15 +141,15 @@ class loop_with_parent_analysis_templatet : loop_templatet<T>
141141
parent_analysist &loop_analysis;
142142
};
143143

144-
template <class T>
145-
class linked_loop_analysist : loop_analysist<T>
144+
template <class T, typename C>
145+
class linked_loop_analysist : loop_analysist<T, C>
146146
{
147147
public:
148148
linked_loop_analysist() = default;
149149

150150
/// Returns true if \p instruction is in \p loop
151151
bool loop_contains(
152-
const typename loop_analysist<T>::loopt &loop,
152+
const typename loop_analysist<T, C>::loopt &loop,
153153
const T instruction) const
154154
{
155155
return loop.loop_instructions.count(instruction);
@@ -166,8 +166,8 @@ class linked_loop_analysist : loop_analysist<T>
166166
};
167167

168168
/// Print all natural loops that were found
169-
template <class T>
170-
void loop_analysist<T>::output(std::ostream &out) const
169+
template <class T, typename C>
170+
void loop_analysist<T, C>::output(std::ostream &out) const
171171
{
172172
for(const auto &loop : loop_map)
173173
{

src/analyses/natural_loops.h

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,11 @@ Author: Georg Weissenbacher, [email protected]
4343
/// * [function] is_backwards_goto() returning a bool.
4444
/// * [function] get_target() which returns an object that needs:
4545
/// * [field] location_number which is an unsigned int.
46-
template <class P, class T>
47-
class natural_loops_templatet : public loop_analysist<T>
46+
/// \tparam C: comparison to use over `T` typed elements
47+
template <class P, class T, typename C>
48+
class natural_loops_templatet : public loop_analysist<T, C>
4849
{
49-
typedef loop_analysist<T> parentt;
50+
typedef loop_analysist<T, C> parentt;
5051

5152
public:
5253
typedef typename parentt::loopt natural_loopt;
@@ -80,14 +81,18 @@ class natural_loops_templatet : public loop_analysist<T>
8081

8182
/// A concretized version of
8283
/// \ref natural_loops_templatet<const goto_programt, goto_programt::const_targett>
83-
class natural_loopst:
84-
public natural_loops_templatet<const goto_programt,
85-
goto_programt::const_targett>
84+
class natural_loopst : public natural_loops_templatet<
85+
const goto_programt,
86+
goto_programt::const_targett,
87+
goto_programt::target_less_than>
8688
{
8789
};
8890

89-
typedef natural_loops_templatet<goto_programt, goto_programt::targett>
90-
natural_loops_mutablet;
91+
typedef natural_loops_templatet<
92+
goto_programt,
93+
goto_programt::targett,
94+
goto_programt::target_less_than>
95+
natural_loops_mutablet;
9196

9297
inline void show_natural_loops(const goto_modelt &goto_model, std::ostream &out)
9398
{
@@ -99,8 +104,8 @@ inline void show_natural_loops(const goto_modelt &goto_model, std::ostream &out)
99104
#endif
100105

101106
/// Finds all back-edges and computes the natural loops
102-
template<class P, class T>
103-
void natural_loops_templatet<P, T>::compute(P &program)
107+
template <class P, class T, typename C>
108+
void natural_loops_templatet<P, T, C>::compute(P &program)
104109
{
105110
cfg_dominators(program);
106111

@@ -133,8 +138,8 @@ void natural_loops_templatet<P, T>::compute(P &program)
133138
}
134139

135140
/// Computes the natural loop for a given back-edge (see Muchnick section 7.4)
136-
template<class P, class T>
137-
void natural_loops_templatet<P, T>::compute_natural_loop(T m, T n)
141+
template <class P, class T, typename C>
142+
void natural_loops_templatet<P, T, C>::compute_natural_loop(T m, T n)
138143
{
139144
PRECONDITION(n->location_number <= m->location_number);
140145

0 commit comments

Comments
 (0)