Improve function pointer optimization for constant pointers#8771
Open
tautschnig wants to merge 1 commit intodiffblue:developfrom
Open
Improve function pointer optimization for constant pointers#8771tautschnig wants to merge 1 commit intodiffblue:developfrom
tautschnig wants to merge 1 commit intodiffblue:developfrom
Conversation
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>
6f8103a to
bc278c4
Compare
There was a problem hiding this comment.
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.cppto handle more “constant-like” access patterns. - Adjusts constness propagation rules when resolving member accesses and dereferences.
- Adds two new
goto-instrumentregression 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}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes: #476