Skip to content

C++: support for designated initializers #116

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

Merged
merged 8 commits into from
Aug 31, 2018

Conversation

nickrolfe
Copy link
Contributor

I've added new tuples to associate aggregate literals, their initializer expressions, and the field or element index being initialized.

This will need to be merged in sync with the internal extractor PR.

This PR also includes the comment-only dbscheme changes from #18, to avoid an extra upgrade script.

@nickrolfe nickrolfe added C++ depends on internal PR This PR should only be merged in sync with an internal Semmle PR labels Aug 29, 2018
@nickrolfe nickrolfe added this to the 1.18 milestone Aug 29, 2018
@rdmarsh2
Copy link
Contributor

Can we get a test with out-of-order designated initializers? Something like someStruct {.j = 1, .i = 2}. I'd also like to see a test of how this interacts with child ordering; before this PR, designated struct initializers led to creating two children for each initializer.

@nickrolfe
Copy link
Contributor Author

@rdmarsh2 for your first request, I think the initializers on lines 63-64 of aggregate_literals.c show the right output:

| aggregate_literals.c:62:13:65:7 | {...} | aggregate_literals.c:6:8:6:22 | someOtherStruct | aggregate_literals.c:7:9:7:9 | a | aggregate_literals.c:64:14:64:16 | ... / ... |
| aggregate_literals.c:62:13:65:7 | {...} | aggregate_literals.c:6:8:6:22 | someOtherStruct | aggregate_literals.c:8:9:8:9 | b | aggregate_literals.c:63:14:63:16 | ... * ... |

For your request about child ordering, can you expand on what sort of query you'd like to see? (I think I can explain the problem you saw, and it should now be fixed, but I'm happy to improve the test).

@rdmarsh2
Copy link
Contributor

rdmarsh2 commented Aug 29, 2018

Those initializers look right; missed it on my first read through.

The queries I was observing issues with were:

from ClassAggregateLiteral cal, int i
select cal, cal.getType().getUnspecifiedType(), i, cal.getChild(i)

and

from ClassAggregateLiteral cal, int i, Field f
where cal.getFieldExpr(f) = cal.getChild(i)
select cal, cal.getType().getUnspecifiedType(), i, cal.getChild(i), f

@jbj
Copy link
Contributor

jbj commented Aug 30, 2018

@dave-bartolomeo can you have a look to ensure that the extracted data is suitable for IR translation?

@nickrolfe
Copy link
Contributor Author

I've added some tests to show that the child expressions of an aggregate literal are in the correct order (and match the correct fields/array elements).

@@ -173,7 +173,7 @@ class ClassAggregateLiteral extends AggregateLiteral {
*/
Expr getFieldExpr(Field field) {
field = classType.getAField() and
result = getChild(field.getInitializationOrder())
aggregate_field_init(this, result, field)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be aggregate_field_init(underlyingElement(this), unresolveElement(result), unresolveElement(field))

@@ -230,7 +230,7 @@ class ArrayAggregateLiteral extends AggregateLiteral {
* element `elementIndex`, if present.
*/
Expr getElementExpr(int elementIndex) {
result = getChild(elementIndex)
aggregate_array_init(this, result, elementIndex)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly here

Copy link
Contributor

@dave-bartolomeo dave-bartolomeo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on your tests, it appears that for an initialization where the order of the designators in the source code does not match the declaration order of the fields, the order of the children in the AggregateLiteral will match the order of the init expression in the source code, not field declaration order, right? The C standard leaves the order of evaluation unspecified, and all three major compilers actually emit the initialization in field declaration order. Do we want the child order to match the source, or to match the order of evaluation?
My guess is that we should do whatever we do for constructor init lists, which have the same issue.

@ian-semmle
Copy link
Contributor

We already know the field declaration order, but the source code order is extra information that is potentially useful.

@nickrolfe
Copy link
Contributor Author

the order of the children in the AggregateLiteral will match the order of the init expression in the source code, not field declaration order, right?

Right.

I was going to make the same point as @ian.

Also, changing the order of the child exprs would be a largely orthogonal extractor change to the ones made to support designated initializers. I'm sure we could do it, but I'd like to get this PR merged first (especially since the 1.18 deadline is looming).

@dave-bartolomeo
Copy link
Contributor

LGTM

FWIW, constructor init lists seem to show up in field declaration order, regardless of init list order.

The IR currently ignores child order, and sorts initializers by field declaration order, so this change shouldn't impact the IR. Even if it did, the IR is easier to change after feature freeze than the extractor.

I assume I shouldn't approve this until the extractor change goes into the private repo?

@nickrolfe
Copy link
Contributor Author

Approval is harmless, but it should only be merged at the same time as the private PR.

BTW, should I add a release note?

@jbj
Copy link
Contributor

jbj commented Aug 30, 2018

Yes, definitely add a release note for this change and also other user-visible extractor features added for 1.18. #24 probably qualifies and maybe also the support for _FloatN and _FloatNx.

@ian-semmle ian-semmle merged commit 6c73964 into github:master Aug 31, 2018
@nickrolfe nickrolfe deleted the desig_init branch August 31, 2018 10:57
@jbj jbj mentioned this pull request Aug 31, 2018
aibaars added a commit that referenced this pull request Oct 14, 2021
CFG: make loop expressions post order
smowton added a commit to smowton/codeql that referenced this pull request Dec 6, 2021
erik-krogh pushed a commit to erik-krogh/ql that referenced this pull request Dec 15, 2021
erik-krogh pushed a commit to erik-krogh/ql that referenced this pull request Dec 15, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C++ depends on internal PR This PR should only be merged in sync with an internal Semmle PR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants