Skip to content
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

It is easy to break IR::IndexedVector using its iterators #5083

Open
vlstill opened this issue Jan 2, 2025 · 4 comments
Open

It is easy to break IR::IndexedVector using its iterators #5083

vlstill opened this issue Jan 2, 2025 · 4 comments
Labels
bug This behavior is unintended and should be fixed. core Topics concerning the core segments of the compiler (frontend, midend, parser) duplicate This issue or pull request is a duplicate.

Comments

@vlstill
Copy link
Contributor

vlstill commented Jan 2, 2025

So the IR::IndexedVector does not do a good job of keeping its invariants, namely that it is properly indexed. This is (in part) because it exposed modifiable iterators. Therefore, it is possible to modify the objects by iterators (e.g. exchange them), without modifying the map. Example could be using std::remove_if on an indexed vector.

I think the best solution would be to not expose modifiable iterators at all. Of course, that could be a breaking change, but presumably it would only break code which is already buggy. Alternatively, we could offer a "heavyweight" modifiable iterator that actually causes the map to be updated on assignments, but I am not very keen on that.

@vlstill vlstill added the core Topics concerning the core segments of the compiler (frontend, midend, parser) label Jan 2, 2025
@ChrisDodd
Copy link
Contributor

ChrisDodd commented Jan 2, 2025

. Therefore, it is possible to modify the objects by iterators (e.g. exchange them), without modifying the map. Example could be using std::remove_if on an indexed vector.

Is that actually incorrect, though? If you exchange two objects in the same Vector via iterators, they're both still in the vector (so the internal map does not need to be changed). So remove_if is actually correct since it doesn't actually remove objects (despite its name), it moves them to the end where they can easily be removed by an erase (which does remove them from the map).

The incorrect thing that might be of concern is if iterators are used to move/copy/swap objects between two different vectors.

@vlstill
Copy link
Contributor Author

vlstill commented Jan 3, 2025

. Therefore, it is possible to modify the objects by iterators (e.g. exchange them), without modifying the map. Example could be using std::remove_if on an indexed vector.

Is that actually incorrect, though? If you exchange two objects in the same Vector via iterators, they're both still in the vector (so the internal map does not need to be changed). So remove_if is actually correct since it doesn't actually remove objects (despite its name), it moves them to the end where they can easily be removed by an erase (which does remove them from the map).

The incorrect thing that might be of concern is if iterators are used to move/copy/swap objects between two different vectors.

That would hold if std::remove/remove_if did swap on the elements, however, that is not the case:

Explanation

Removing is done by shifting the elements in the range in such a way that the elements that are not to be removed appear in the beginning of the range.

... https://en.cppreference.com/w/cpp/algorithm/remove

So a latter element is moved "over" the "to-be-removed" element, which therefore ceases to exist. But in IndexedVector it is in the map still.

However, this is just an example, the point is that IndexedVector exposes seemingly simple & safe API that can very easily break it.

@fruffy
Copy link
Collaborator

fruffy commented Jan 3, 2025

Related IR::IndexVector issues:
#4117
#43 One of the oldest issues still open.

@vlstill vlstill added bug This behavior is unintended and should be fixed. duplicate This issue or pull request is a duplicate. labels Jan 3, 2025
@vlstill
Copy link
Contributor Author

vlstill commented Jan 3, 2025

Related IR::IndexVector issues: #4117 #43 One of the oldest issues still open.

Yep, seems like this is a duplicate of #43.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug This behavior is unintended and should be fixed. core Topics concerning the core segments of the compiler (frontend, midend, parser) duplicate This issue or pull request is a duplicate.
Projects
None yet
Development

No branches or pull requests

3 participants