@@ -2218,6 +2218,78 @@ 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
+ error ().source_location = f_op.source_location ();
2229
+ error () << identifier << " expects one or two operands" << eom;
2230
+ throw 0 ;
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
+ error ().source_location = f_op.source_location ();
2244
+ error () << identifier << " expects a pointer as first argument"
2245
+ << eom;
2246
+ throw 0 ;
2247
+ }
2248
+
2249
+ // The second argument, when given, is a size_t.
2250
+ // When not given, use the pointer subtype.
2251
+ exprt size_expr;
2252
+
2253
+ if (expr.arguments ().size () == 2 )
2254
+ {
2255
+ implicit_typecast (expr.arguments ()[1 ], size_type ());
2256
+ size_expr = expr.arguments ()[1 ];
2257
+ }
2258
+ else
2259
+ {
2260
+ // Won't do void *
2261
+ const auto &subtype =
2262
+ to_pointer_type (pointer_expr.type ()).base_type ();
2263
+ if (subtype.id () == ID_empty)
2264
+ {
2265
+ error ().source_location = f_op.source_location ();
2266
+ error () << identifier << " expects a size when given a void pointer"
2267
+ << eom;
2268
+ throw 0 ;
2269
+ }
2270
+
2271
+ auto size_expr_opt = size_of_expr (subtype, *this );
2272
+ if (!size_expr_opt.has_value ())
2273
+ {
2274
+ error ().source_location = f_op.source_location ();
2275
+ error () << identifier << " was given object pointer without size"
2276
+ << eom;
2277
+ throw 0 ;
2278
+ }
2279
+
2280
+ size_expr = std::move (size_expr_opt.value ());
2281
+ }
2282
+
2283
+ irep_idt id = identifier == CPROVER_PREFIX " r_ok" ? ID_r_ok
2284
+ : identifier == CPROVER_PREFIX " w_ok" ? ID_w_ok
2285
+ : ID_rw_ok;
2286
+
2287
+ r_or_w_ok_exprt ok_expr (id, pointer_expr, size_expr);
2288
+ ok_expr.add_source_location () = expr.source_location ();
2289
+
2290
+ expr.swap (ok_expr);
2291
+ return ;
2292
+ }
2221
2293
else if (
2222
2294
auto gcc_polymorphic = typecheck_gcc_polymorphic_builtin (
2223
2295
identifier, expr.arguments (), f_op.source_location ()))
@@ -3145,70 +3217,6 @@ exprt c_typecheck_baset::do_special_functions(
3145
3217
3146
3218
return std::move (malloc_expr);
3147
3219
}
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
3220
else if (
3213
3221
(identifier == CPROVER_PREFIX " old" ) ||
3214
3222
(identifier == CPROVER_PREFIX " loop_entry" ))
0 commit comments