-
Notifications
You must be signed in to change notification settings - Fork 2.1k
C++: Implement MaD support for flow through perfect-forwarding functions #22521
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
Changes from all commits
0be3663
8c8ce60
ecd3cae
8560e34
5251c65
70be52a
232b29e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,6 +15,8 @@ | |
| * `namespace; type; subtypes; name; signature; ext; output; kind; provenance` | ||
| * - BarrierGuards: | ||
| * `namespace; type; subtypes; name; signature; ext; input; acceptingValue; kind; provenance` | ||
| * - Forwards: | ||
| * `namespace; type; subtypes; name; signature; ext; start; constructor; provenance` | ||
| * | ||
| * The interpretation of a row is similar to API-graphs with a left-to-right | ||
| * reading. | ||
|
|
@@ -160,6 +162,20 @@ predicate summaryModel( | |
| ) | ||
| } | ||
|
|
||
| /** | ||
| * Holds if a forward model exists for the given parameters. | ||
| */ | ||
| predicate forwardsModel( | ||
| string namespace, string type, boolean subtypes, string name, string signature, string ext, | ||
| string start, string constructor, string provenance, string model | ||
| ) { | ||
| exists(QlBuiltins::ExtensionId madId | | ||
| Extensions::forwardsModel(namespace, type, subtypes, name, signature, ext, start, constructor, | ||
| provenance, madId) and | ||
| model = madId.toString() | ||
| ) | ||
| } | ||
|
|
||
| /** Provides a query predicate to check the data for validation errors. */ | ||
| module ModelValidation { | ||
| private string getInvalidModelInput() { | ||
|
|
@@ -259,7 +275,8 @@ private predicate elementSpec( | |
| sinkModel(namespace, type, subtypes, name, signature, ext, _, _, _, _) or | ||
| barrierModel(namespace, type, subtypes, name, signature, ext, _, _, _, _) or | ||
| barrierGuardModel(namespace, type, subtypes, name, signature, ext, _, _, _, _, _) or | ||
| summaryModel(namespace, type, subtypes, name, signature, ext, _, _, _, _, _) | ||
| summaryModel(namespace, type, subtypes, name, signature, ext, _, _, _, _, _) or | ||
| forwardsModel(namespace, type, subtypes, name, signature, ext, _, _, _, _) | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -596,6 +613,14 @@ private string getAtIndex(string s, int i) { | |
| not (s = "" and i = 0) | ||
| } | ||
|
|
||
| /** Gets the number of comma-separated arguments in `s`. */ | ||
| bindingset[s] | ||
| private int getNumberOfArguments(string s) { | ||
| s = "" and result = 0 | ||
| or | ||
| s != "" and result = count(s.indexOf(",")) + 1 | ||
| } | ||
|
|
||
| /** | ||
| * Normalizes `partiallyNormalizedSignature` by replacing the `remaining` | ||
| * number of template arguments in `partiallyNormalizedSignature` with their | ||
|
|
@@ -605,7 +630,7 @@ private string getSignatureWithoutClassTemplateNames( | |
| string partiallyNormalizedSignature, string typeArgs, string nameArgs, int remaining | ||
| ) { | ||
| elementSpecWithArguments0(_, _, _, partiallyNormalizedSignature, typeArgs, nameArgs) and | ||
| remaining = count(partiallyNormalizedSignature.indexOf(",")) + 1 and | ||
| remaining = getNumberOfArguments(typeArgs) and | ||
| result = partiallyNormalizedSignature | ||
| or | ||
| exists(string mid | | ||
|
|
@@ -619,7 +644,7 @@ private string getSignatureWithoutClassTemplateNames( | |
| ) | ||
| or | ||
| // Make sure `remaining` is properly bound | ||
| remaining = [0 .. count(partiallyNormalizedSignature.indexOf(",")) + 1] and | ||
| remaining = [0 .. getNumberOfArguments(typeArgs)] and | ||
| not exists(getAtIndex(typeArgs, remaining)) and | ||
| result = mid | ||
| ) | ||
|
|
@@ -636,7 +661,7 @@ pragma[nomagic] | |
| private string getSignatureWithoutFunctionTemplateNames( | ||
| string partiallyNormalizedSignature, string typeArgs, string nameArgs, int remaining | ||
| ) { | ||
| remaining = count(partiallyNormalizedSignature.indexOf(",")) + 1 and | ||
| remaining = getNumberOfArguments(nameArgs) and | ||
| result = | ||
| getSignatureWithoutClassTemplateNames(partiallyNormalizedSignature, typeArgs, nameArgs, 0) | ||
| or | ||
|
|
@@ -651,7 +676,7 @@ private string getSignatureWithoutFunctionTemplateNames( | |
| ) | ||
| or | ||
| // Make sure `remaining` is properly bound | ||
| remaining = [0 .. count(partiallyNormalizedSignature.indexOf(",")) + 1] and | ||
| remaining = [0 .. getNumberOfArguments(nameArgs)] and | ||
| not exists(getAtIndex(nameArgs, remaining)) and | ||
| result = mid | ||
| ) | ||
|
|
@@ -1046,6 +1071,46 @@ private module Cached { | |
|
|
||
| import Cached | ||
|
|
||
| /** Gets the constructor type selected by `constructorType` in a forwarding model. */ | ||
| bindingset[forwarder, type, name, constructorType] | ||
| private Type getForwardedConstructorType( | ||
| Function forwarder, string type, string name, string constructorType | ||
| ) { | ||
| exists(string typeArguments, int index | | ||
| parseAngles(type, _, typeArguments, "") and | ||
| constructorType = getAtIndex(typeArguments, index) and | ||
| result = forwarder.getDeclaringType().getTemplateArgument(index) | ||
| ) | ||
| or | ||
| exists(string nameArguments, int index | | ||
| parseAngles(name, _, nameArguments, "") and | ||
| constructorType = getAtIndex(nameArguments, index) and | ||
| result = forwarder.getTemplateArgument(index) | ||
| ) | ||
| } | ||
|
|
||
| /** Holds if `forwarder` forwards its arguments starting at `start` to `constructor`. */ | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks! Copy/pasted into f381119 |
||
| predicate forwards(Function forwarder, Constructor constructor, int start) { | ||
| exists( | ||
| string namespace, string type, boolean subtypes, string name, string signature, string ext, | ||
| string startString, string constructorType | ||
| | | ||
| forwardsModel(namespace, type, subtypes, name, signature, ext, startString, constructorType, _, | ||
| _) and | ||
| forwarder = interpretElement(namespace, type, subtypes, name, signature, ext) and | ||
| start = startString.toInt() | ||
| | | ||
| // Either the row specifies forwarding to a type given by the type or | ||
| // function template, in which case we need to resolve that from the type | ||
| // or function name. | ||
| constructor.getDeclaringType() = | ||
| getForwardedConstructorType(forwarder, type, name, constructorType).getUnspecifiedType() | ||
| or | ||
| // Or the row specifies forwarding to a specific type. | ||
| classHasQualifiedName(constructor.getDeclaringType(), namespace, constructorType) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. AFAICT, there is currently no test case for this?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Uh, good point. Added in dcda06a |
||
| ) | ||
| } | ||
|
|
||
| /** | ||
| * Holds if `node` is specified as a source with the given kind in a MaD flow | ||
| * model. | ||
|
|
||
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 also think this branch is not covered by tests?
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.
Fixed in 8149caa