-------------------------------------------------------------- specifically select a pointer to be dereferenced
| 1231 | // -------------------------------------------------------------- |
| 1232 | // specifically select a pointer to be dereferenced |
| 1233 | Variable * |
| 1234 | VariableSelector::select_deref_pointer(Effect::Access access, const CGContext &cg_context, const Type* type, const CVQualifiers* qfer, const vector<const Variable*>& invalid_vars) |
| 1235 | { |
| 1236 | assert(qfer && qfer->sanity_check(type)); |
| 1237 | vector<Variable*> vars; |
| 1238 | // add globals |
| 1239 | vars.insert(vars.end(), GlobalNonvolatilesList.begin(), GlobalNonvolatilesList.end()); |
| 1240 | // add parent locals |
| 1241 | const Block* b = cg_context.get_current_block(); |
| 1242 | while (b) { |
| 1243 | vars.insert(vars.end(), b->local_vars.begin(), b->local_vars.end()); |
| 1244 | b = b->parent; |
| 1245 | } |
| 1246 | // add function parameters |
| 1247 | const Function* f = cg_context.get_current_func(); |
| 1248 | vars.insert(vars.end(), f->param.begin(), f->param.end()); |
| 1249 | |
| 1250 | Variable* var = choose_var(vars, access, cg_context, type, qfer, eDereference, invalid_vars); |
| 1251 | if (var == 0) { |
| 1252 | Type* ptr_type = 0; |
| 1253 | if (type->get_indirect_level() < CGOptions::max_indirect_level()) { |
| 1254 | ptr_type = Type::find_pointer_type(type, true); |
| 1255 | } |
| 1256 | if (!ptr_type) { |
| 1257 | return 0; |
| 1258 | } |
| 1259 | CVQualifiers ptr_qfer = (!qfer || qfer->wildcard || !CGOptions::global_variables()) |
| 1260 | ? CVQualifiers::random_qualifiers(ptr_type, access, cg_context, true) |
| 1261 | //: qfer->indirect_qualifiers(-1); |
| 1262 | : qfer->random_add_qualifiers(!cg_context.get_effect_context().is_side_effect_free()); |
| 1263 | ERROR_GUARD(NULL); |
| 1264 | ptr_qfer.accept_stricter = false; |
| 1265 | if (access == Effect::WRITE) { |
| 1266 | ptr_qfer.set_const(false, 1); |
| 1267 | } |
| 1268 | if (ptr_qfer.is_volatile()) { |
| 1269 | if (CGOptions::expand_struct()) { |
| 1270 | var = VariableSelector::eager_create_global_struct(access, cg_context, ptr_type, |
| 1271 | &ptr_qfer, eDereference, invalid_vars); |
| 1272 | ERROR_GUARD(NULL); |
| 1273 | if (var) |
| 1274 | return var; |
| 1275 | else { |
| 1276 | Error::set_error(ERROR); |
| 1277 | return NULL; |
| 1278 | } |
| 1279 | } |
| 1280 | var = GenerateNewGlobal(access, cg_context, ptr_type, &ptr_qfer); |
| 1281 | } |
| 1282 | else { |
| 1283 | Block *block = cg_context.get_current_block(); |
| 1284 | if (CGOptions::expand_struct()) { |
| 1285 | Variable *var = VariableSelector::eager_create_local_struct(*block, access, |
| 1286 | cg_context, ptr_type, &ptr_qfer, eDereference, invalid_vars); |
| 1287 | ERROR_GUARD(NULL); |
| 1288 | if (var) |
| 1289 | return var; |
| 1290 | else { |
nothing calls this directly
no test coverage detected