From 0d8e0057ef5bbf9f2fb85cb80b76054a96feefd3 Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Tue, 25 Jan 2022 15:20:44 +0000 Subject: [PATCH 1/3] Function pointer restrictions: refactor pointer-name parsing No changes in behaviour: this commit just moves the pointer-name parsing introduced in 771a153b2187b08 to a function of its own. This is to prepare for a fix of #6609: the same name parsing also needs to be added to function-pointer-restriction parsing from JSON files. To enable this code move, the exception class is moved to the global scope. --- .../restrict_function_pointers.cpp | 115 ++++++++++-------- .../restrict_function_pointers.h | 26 ++-- .../restrict_function_pointers.cpp | 12 +- 3 files changed, 85 insertions(+), 68 deletions(-) diff --git a/src/goto-programs/restrict_function_pointers.cpp b/src/goto-programs/restrict_function_pointers.cpp index dceecb4fbff..1f48834b911 100644 --- a/src/goto-programs/restrict_function_pointers.cpp +++ b/src/goto-programs/restrict_function_pointers.cpp @@ -84,14 +84,14 @@ static void restrict_function_pointer( } } // namespace -function_pointer_restrictionst::invalid_restriction_exceptiont:: - invalid_restriction_exceptiont(std::string reason, std::string correct_format) +invalid_restriction_exceptiont::invalid_restriction_exceptiont( + std::string reason, + std::string correct_format) : reason(std::move(reason)), correct_format(std::move(correct_format)) { } -std::string -function_pointer_restrictionst::invalid_restriction_exceptiont::what() const +std::string invalid_restriction_exceptiont::what() const { std::string res; @@ -291,6 +291,66 @@ function_pointer_restrictionst::parse_function_pointer_restrictions_from_file( return merged_restrictions; } +/// Parse \p candidate to distinguish whether it refers to a function pointer +/// symbol directly (as produced by \ref label_function_pointer_call_sites), or +/// a source location via its statement label. In the latter case, resolve the +/// name to the underlying function pointer symbol. +static std::string resolve_pointer_name( + const std::string &candidate, + const goto_modelt &goto_model) +{ + const auto last_dot = candidate.rfind('.'); + if( + last_dot == std::string::npos || last_dot + 1 == candidate.size() || + isdigit(candidate[last_dot + 1])) + { + return candidate; + } + + std::string pointer_name = candidate; + + const auto function_id = pointer_name.substr(0, last_dot); + const auto label = pointer_name.substr(last_dot + 1); + + bool found = false; + const auto it = goto_model.goto_functions.function_map.find(function_id); + if(it != goto_model.goto_functions.function_map.end()) + { + optionalt location; + for(const auto &instruction : it->second.body.instructions) + { + if( + std::find( + instruction.labels.begin(), instruction.labels.end(), label) != + instruction.labels.end()) + { + location = instruction.source_location(); + } + + if( + instruction.is_function_call() && + instruction.call_function().id() == ID_dereference && + location.has_value() && instruction.source_location() == *location) + { + auto const &called_function_pointer = + to_dereference_expr(instruction.call_function()).pointer(); + pointer_name = + id2string(to_symbol_expr(called_function_pointer).get_identifier()); + found = true; + break; + } + } + } + if(!found) + { + throw invalid_restriction_exceptiont{ + "non-existent pointer name " + pointer_name, + "pointers should be identifiers or .