@@ -2218,6 +2218,70 @@ void c_typecheck_baset::typecheck_side_effect_function_call(
2218
2218
expr.swap (lowered);
2219
2219
return ;
2220
2220
}
2221
+ else if (
2222
+ identifier == CPROVER_PREFIX " r_ok" ||
2223
+ identifier == CPROVER_PREFIX " w_ok" ||
2224
+ identifier == CPROVER_PREFIX " rw_ok" )
2225
+ {
2226
+ if (expr.arguments ().size () != 1 && expr.arguments ().size () != 2 )
2227
+ {
2228
+ throw invalid_source_file_exceptiont{
2229
+ id2string (identifier) + " expects one or two operands" ,
2230
+ f_op.source_location ()};
2231
+ }
2232
+
2233
+ // the first argument must be a pointer
2234
+ auto &pointer_expr = expr.arguments ()[0 ];
2235
+ if (pointer_expr.type ().id () == ID_array)
2236
+ {
2237
+ auto dest_type = pointer_type (void_type ());
2238
+ dest_type.base_type ().set (ID_C_constant, true );
2239
+ implicit_typecast (pointer_expr, dest_type);
2240
+ }
2241
+ else if (pointer_expr.type ().id () != ID_pointer)
2242
+ {
2243
+ throw invalid_source_file_exceptiont{
2244
+ id2string (identifier) + " expects a pointer as first argument" ,
2245
+ f_op.source_location ()};
2246
+ }
2247
+
2248
+ // The second argument, when given, is a size_t.
2249
+ // When not given, use the pointer subtype.
2250
+ exprt size_expr;
2251
+
2252
+ if (expr.arguments ().size () == 2 )
2253
+ {
2254
+ implicit_typecast (expr.arguments ()[1 ], size_type ());
2255
+ size_expr = expr.arguments ()[1 ];
2256
+ }
2257
+ else
2258
+ {
2259
+ // Won't do void *
2260
+ const auto &subtype =
2261
+ to_pointer_type (pointer_expr.type ()).base_type ();
2262
+ if (subtype.id () == ID_empty)
2263
+ {
2264
+ throw invalid_source_file_exceptiont{
2265
+ id2string (identifier) +
2266
+ " expects a size when given a void pointer" ,
2267
+ f_op.source_location ()};
2268
+ }
2269
+
2270
+ auto size_expr_opt = size_of_expr (subtype, *this );
2271
+ CHECK_RETURN (size_expr_opt.has_value ());
2272
+ size_expr = std::move (size_expr_opt.value ());
2273
+ }
2274
+
2275
+ irep_idt id = identifier == CPROVER_PREFIX " r_ok" ? ID_r_ok
2276
+ : identifier == CPROVER_PREFIX " w_ok" ? ID_w_ok
2277
+ : ID_rw_ok;
2278
+
2279
+ r_or_w_ok_exprt ok_expr (id, pointer_expr, size_expr);
2280
+ ok_expr.add_source_location () = expr.source_location ();
2281
+
2282
+ expr.swap (ok_expr);
2283
+ return ;
2284
+ }
2221
2285
else if (
2222
2286
auto gcc_polymorphic = typecheck_gcc_polymorphic_builtin (
2223
2287
identifier, expr.arguments (), f_op.source_location ()))
@@ -3145,70 +3209,6 @@ exprt c_typecheck_baset::do_special_functions(
3145
3209
3146
3210
return std::move (malloc_expr);
3147
3211
}
3148
- else if (
3149
- identifier == CPROVER_PREFIX " r_ok" ||
3150
- identifier == CPROVER_PREFIX " w_ok" || identifier == CPROVER_PREFIX " rw_ok" )
3151
- {
3152
- if (expr.arguments ().size () != 1 && expr.arguments ().size () != 2 )
3153
- {
3154
- error ().source_location = f_op.source_location ();
3155
- error () << identifier << " expects one or two operands" << eom;
3156
- throw 0 ;
3157
- }
3158
-
3159
- typecheck_function_call_arguments (expr);
3160
-
3161
- // the first argument must be a pointer
3162
- const auto &pointer_expr = expr.arguments ()[0 ];
3163
- if (pointer_expr.type ().id () != ID_pointer)
3164
- {
3165
- error ().source_location = f_op.source_location ();
3166
- error () << identifier << " expects a pointer as first argument" << eom;
3167
- throw 0 ;
3168
- }
3169
-
3170
- // The second argument, when given, is a size_t.
3171
- // When not given, use the pointer subtype.
3172
- exprt size_expr;
3173
-
3174
- if (expr.arguments ().size () == 2 )
3175
- {
3176
- implicit_typecast (expr.arguments ()[1 ], size_type ());
3177
- size_expr = expr.arguments ()[1 ];
3178
- }
3179
- else
3180
- {
3181
- // Won't do void *
3182
- const auto &subtype = to_pointer_type (pointer_expr.type ()).base_type ();
3183
- if (subtype.id () == ID_empty)
3184
- {
3185
- error ().source_location = f_op.source_location ();
3186
- error () << identifier << " expects a size when given a void pointer"
3187
- << eom;
3188
- throw 0 ;
3189
- }
3190
-
3191
- auto size_expr_opt = size_of_expr (subtype, *this );
3192
- if (!size_expr_opt.has_value ())
3193
- {
3194
- error ().source_location = f_op.source_location ();
3195
- error () << identifier << " was given object pointer without size"
3196
- << eom;
3197
- throw 0 ;
3198
- }
3199
-
3200
- size_expr = std::move (size_expr_opt.value ());
3201
- }
3202
-
3203
- irep_idt id = identifier == CPROVER_PREFIX " r_ok"
3204
- ? ID_r_ok
3205
- : identifier == CPROVER_PREFIX " w_ok" ? ID_w_ok : ID_rw_ok;
3206
-
3207
- r_or_w_ok_exprt ok_expr (id, pointer_expr, size_expr);
3208
- ok_expr.add_source_location () = source_location;
3209
-
3210
- return std::move (ok_expr);
3211
- }
3212
3212
else if (
3213
3213
(identifier == CPROVER_PREFIX " old" ) ||
3214
3214
(identifier == CPROVER_PREFIX " loop_entry" ))
0 commit comments