Skip to content

Improve function pointer optimization for constant pointers#8771

Open
tautschnig wants to merge 1 commit intodiffblue:developfrom
tautschnig:fix-476-const-function-ptr
Open

Improve function pointer optimization for constant pointers#8771
tautschnig wants to merge 1 commit intodiffblue:developfrom
tautschnig:fix-476-const-function-ptr

Conversation

@tautschnig
Copy link
Collaborator

  • Enhanced constant function pointer detection and resolution
  • Added support for constant pointers to function pointers
  • Added support for constant structs containing function pointers
  • Added regression tests for new functionality

Fixes: #476

  • Each commit message has a non-empty body, explaining why the change was made.
  • Methods or procedures I have added are documented, following the guidelines provided in CODING_STANDARD.md.
  • n/a The feature or user visible behaviour I have added or modified has been documented in the User Guide in doc/cprover-manual/
  • Regression or unit tests are included, or existing tests cover the modified code (in this case I have detailed which ones those are in the commit message).
  • n/a My commit message includes data points confirming performance improvements (if claimed).
  • My PR is restricted to a single feature or bugfix.
  • n/a White-space or formatting changes outside the feature-related changed lines are in commits of their own.

@tautschnig tautschnig self-assigned this Feb 24, 2026
Enhance the constant function pointer optimization to handle:

1. Const struct members: when a struct member has the const qualifier,
   treat the member access as const even if the struct itself is not
   const. This resolves calls like:
     struct S { fp_t const handler; };
     struct S s = {f1}; s.handler(); // resolves to f1

2. Const pointers to structs: when a const pointer to a struct is
   dereferenced and simplified to the underlying symbol, look up the
   symbol's initial value from the symbol table. Combined with the
   pointee-type-is-const check in try_resolve_dereference, this
   resolves calls like:
     const struct S *const ptr = &s;
     ptr->handler(); // resolves to the function from s's initializer

The key changes:
- try_resolve_expression: when encountering a symbol, look up its
  initial value from the symbol table instead of immediately failing.
  Return it with is_const based on the symbol's type qualifier.
- try_resolve_dereference: when the pointer's base type is const,
  treat the dereferenced value as const regardless of the underlying
  object's constness.
- try_resolve_member: a member access is const if either the struct
  is const or the member itself is const.

Fixes: diffblue#476

Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
@tautschnig tautschnig force-pushed the fix-476-const-function-ptr branch from 6f8103a to bc278c4 Compare March 18, 2026 10:59
@tautschnig tautschnig marked this pull request as ready for review March 18, 2026 11:36
Copilot AI review requested due to automatic review settings March 18, 2026 11:36
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR enhances the --remove-const-function-pointers optimization so it can resolve more indirect-call targets, including cases involving pointers to function pointers and structs containing function pointers, and adds regression tests to cover the new scenarios.

Changes:

  • Extends expression/dereference/member resolution logic in remove_const_function_pointers.cpp to handle more “constant-like” access patterns.
  • Adjusts constness propagation rules when resolving member accesses and dereferences.
  • Adds two new goto-instrument regression tests covering const structs with function-pointer members and const pointers involving function pointers.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/goto-programs/remove_const_function_pointers.cpp Expands resolution logic for dereferences/symbols/members to enable more function-pointer target narrowing.
regression/goto-instrument/const-struct-with-function-ptr/test.desc New regression expectations for resolving a call via a const struct member.
regression/goto-instrument/const-struct-with-function-ptr/main.c New test program exercising a const struct containing a function pointer.
regression/goto-instrument/const-ptr-to-function-ptr/test.desc New regression expectations for resolving a call via a const pointer scenario.
regression/goto-instrument/const-ptr-to-function-ptr/main.c New test program exercising a const pointer to a struct with a function-pointer member.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +464 to +478
// Try to look up the symbol's initial value from the symbol table.
// Return it with is_const=false; callers that need constness
// (e.g., try_resolve_dereference with a const-qualified pointee type)
// can override this based on context.
const symbolt *sym = ns.get_symbol_table().lookup(
to_symbol_expr(simplified_expr).get_identifier());
if(sym != nullptr && sym->value.is_not_nil())
{
resolved_expressions.push_back(sym->value);
is_resolved_expression_const = is_const_expression(simplified_expr);
resolved = true;
}
else
{
LOG("Non const symbol will not be squashed", simplified_expr);
Comment on lines +749 to +753
const typet &ptr_type = deref_expr.pointer().type();
if(
ptr_type.id() == ID_pointer &&
to_pointer_type(ptr_type).base_type().get_bool(ID_C_constant))
{
}
}
out_is_const=all_objects_const;
out_is_const = all_objects_const || pointee_type_is_const;
Comment on lines +672 to +674
// Also check if the specific member being accessed is const
bool member_is_const = is_const_type(member_expr.type());


void test_const_ptr_to_struct(void)
{
struct ops s = {f2, 10};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Further improvements to function pointer optimisation

2 participants