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
Swift: collection/tuple content for dictionary flow #13947
base: main
Are you sure you want to change the base?
Swift: collection/tuple content for dictionary flow #13947
Conversation
FTR, this is also how it's done in C# 👍 (though instead of |
|
That's good to know. Swift has had first-class tuples from the start, so they just alias |
| subscript.getArgument(0).getExpr() = node1.asExpr() and | ||
| node2.(DictionarySubscriptNode).getExpr() = subscript and | ||
| c.isSingleton(any(Content::TupleContent tc | tc.getIndex() = 1)) | ||
| or | ||
| assign.getSource() = node1.asExpr() and | ||
| node2.(DictionarySubscriptNode).getExpr() = subscript and | ||
| c.isSingleton(any(Content::TupleContent tc | tc.getIndex() = 1)) | ||
| or | ||
| node1.(DictionarySubscriptNode) = node1 and | ||
| node2.asExpr() = subscript and | ||
| c.isSingleton(any(Content::CollectionContent cc)) |
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.
So now we do:
source -> TupleContent -> CollectionContent
in two steps (which makes sense), and I gather that the last of these three cases is the CollectionContent step. But why do we need two cases to cover the first step? I would have thought that only the middle cases was needed, and the first case would happen through reverse reads?
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.
I think there are two steps to assemble the tuple because one is for the key and one is for the value.
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.
The first case is the step from the key in dict[key] = value - I typoed and it should be tc.getIndex() = 0 there.
swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll
Outdated
Show resolved
Hide resolved
swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll
Outdated
Show resolved
Hide resolved
| subscript.getArgument(0).getExpr() = node1.asExpr() and | ||
| node2.(DictionarySubscriptNode).getExpr() = subscript and | ||
| c.isSingleton(any(Content::TupleContent tc | tc.getIndex() = 1)) | ||
| or | ||
| assign.getSource() = node1.asExpr() and | ||
| node2.(DictionarySubscriptNode).getExpr() = subscript and | ||
| c.isSingleton(any(Content::TupleContent tc | tc.getIndex() = 1)) | ||
| or | ||
| node1.(DictionarySubscriptNode) = node1 and | ||
| node2.asExpr() = subscript and | ||
| c.isSingleton(any(Content::CollectionContent cc)) |
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.
I think there are two steps to assemble the tuple because one is for the key and one is for the value.
| ( | ||
| c.isSingleton(any(Content::FieldContent fc)) or | ||
| c.isSingleton(any(Content::TupleContent tc)) | ||
| ) |
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.
Why this restriction? Do we not want to clear CollectionContent and ArrayContent?
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.
... or EnumContent?
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 don't want to clear CollectionContent and ArrayContent at a post-update node because they may have been only partially overwritten - consider the case here. It shouldn't clear the content from line 779.
I think we do want to clear EnumContent, though. Good catch.
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.
My concerns have been addressed, how about you @MathiasVP
I think so, yes. I'd still like to see a DCA run on this PR, though 🙏. In addition, it would be nice if we could have a testcase that demonstrated the impact of 3ee3eab (although this can be done in a future PR if you prefer). |
This PR models dictionary content as being
TupleContentnested withinCollectionContent, and adds a newDictionarySubscriptNodeto represent the intermediate step, where only theTupleContenthas been stored, or only theCollectionContenthas been read. This means models for the genericCollectionprotocol will work for dictionaries without modification.