std::string array_name( const namespacet &ns, const exprt &expr) { if(expr.id()==ID_index) { if(expr.operands().size()!=2) throw "index takes two operands"; return array_name(ns, expr.op0())+"[]"; } else if(is_ssa_expr(expr)) { const symbolt &symbol= ns.lookup(to_ssa_expr(expr).get_object_name()); return "array `"+id2string(symbol.base_name)+"'"; } else if(expr.id()==ID_symbol) { const symbolt &symbol=ns.lookup(expr); return "array `"+id2string(symbol.base_name)+"'"; } else if(expr.id()==ID_string_constant) { return "string constant"; } else if(expr.id()==ID_member) { assert(expr.operands().size()==1); return array_name(ns, expr.op0())+"."+ expr.get_string(ID_component_name); } return "array"; }
void value_set_dereferencet::valid_check( const exprt &object, const guardt &guard, const modet mode) { if(!options.get_bool_option("pointer-check")) return; const exprt &symbol_expr=get_symbol(object); if(symbol_expr.id()==ID_string_constant) { // always valid, but can't write if(mode==modet::WRITE) { dereference_callback.dereference_failure( "pointer dereference", "write access to string constant", guard); } } else if(symbol_expr.is_nil() || symbol_expr.get_bool(ID_C_invalid_object)) { // always "valid", shut up return; } else if(symbol_expr.id()==ID_symbol) { const irep_idt identifier= is_ssa_expr(symbol_expr)? to_ssa_expr(symbol_expr).get_object_name(): to_symbol_expr(symbol_expr).get_identifier(); const symbolt &symbol=ns.lookup(identifier); if(symbol.type.get_bool(ID_C_is_failed_symbol)) { dereference_callback.dereference_failure( "pointer dereference", "invalid pointer", guard); } #if 0 if(dereference_callback.is_valid_object(identifier)) return; // always ok #endif } }