-
Notifications
You must be signed in to change notification settings - Fork 273
Base-type-eq: check pointer types really match [blocks: #4023] #4020
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Base-type-eq: check pointer types really match [blocks: #4023] #4020
Conversation
Generally base-type-eq's task is to ensure that types match up to substitution of a type's body for a symbol referring to that type. However now that derivatives of pointers exist with named subexpressions (e.g. java_generic_parametert), it is now possible for types not involving symbols to be `base_type_eq` but not `==`. This resolves that particular case by checking that the names subexpressions match exactly.
const auto &named_subs1 = type1.get_named_sub(); | ||
const auto &named_subs2 = type2.get_named_sub(); | ||
|
||
for(const auto &name_and_sub : named_subs1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use two iterators over the two collections, just like irept::operator==
does. Using find
is expensive and unnecessary as you can do this with a linear algorithm.
Before it would unintentionally erase SomeClass.field from A<B> to just the unqualified A type.
… just to compare This makes the invariant pass, but this surely warrants more attention -- type consistency is difficult to achieve when pointers are qualified and dereferencing and then taking the address again doesn't retain that information (but I don't know the logic behind the design decision in enough detail to change it)
Haven't done that yet, but did notice a problem with this check exposing two other inconsistency problems, which I've pushed commits to fix. One is easy (static fields in the Java frontend) and the other is hard (symex-dereference assuming that you can strip a pointer type and add it back with a plain I have a feeling my "fix" is really just weakening the test and actual inconsistency will still occur, but I'm not sure what to do about it yet. It looks an awful lot like encoding generics on the pointer rather than the struct type is the root of the problem, but I don't understand enough about the original design decision to try to change that (yet). @thk123 @allredj do you have any comment? |
@smowton the problem with putting in the struct is the struct/struct_tag_type, most of the time we have the latter, but then you end up in the weird situation where:
Intuitively (to me at least), it is the pointer that has the generic info because you can do: ArrayList<Foo> f = new ArrayList<>();
ArrayList b = f; Let's discuss in person on Monday - my view remains that the pointer is the Right Place(tm) for this information, but perhaps not. |
Having thought about this a bit more the following three comments may be worth considering:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We really want to get rid of base_type_eq
(and replace it by ==
). Echoing @tautschnig , if this is something that happens in the Java-front end only, then add ID_frontend_reference
and a local function?
@kroening @tautschnig @thk123 summary of an in-person discussion with @thk123 just now: Definition: a decorated pointer is a pointer with additional non-comment attributes beyond its subtype. Desired invariants:
Desired functionality: Java parameter and return-value types with generic signatures should be available both before and after running the goto-convert -> symex -> solving pipeline, to generate better method stubs / harnesses and to generate better tests respectively. Currently this is done by examining the types of symbols observed in a Current plan: ensure that any code dealing with decorated pointers preserves their type. This has proven easy in the Java frontend, but doing this to symex-dereference and the various ways of querying Proposed replacement plan: store generic information in the symbol table as comments, so that decorated types are Advantages:
Disadvantages:
Both disadvantages would go away if there was somewhere to store the decorated type that wasn't Thoughts? |
Thanks a lot for the detailed write-up! IMHO we do already have decorated types: these are now tags (struct/union/enum tags). Essentially a named pointer to another symbol that holds a lot more information. With tags there is no risk of |
Interesting. We do already have |
Replaced by #4114 |
Generally base-type-eq's task is to ensure that types match up to substitution of a type's body for a symbol referring to that type. However now that derivatives of pointers exist with named subexpressions (e.g. java_generic_parametert), it is now possible for types not involving symbols to be
base_type_eq
but not==
. This resolves that particular case by checking that the names subexpressions match exactly.