Skip to content

Commit f28cf25

Browse files
authored
Merge pull request github#12755 from MathiasVP/aggregate-initialization-ir
C++: IR generation for repeated initializers
2 parents 00fd23d + 6c26ad7 commit f28cf25

File tree

9 files changed

+875
-19
lines changed

9 files changed

+875
-19
lines changed

cpp/ql/lib/semmle/code/cpp/exprs/Literal.qll

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -187,13 +187,44 @@ class ClassAggregateLiteral extends AggregateLiteral {
187187
override string getAPrimaryQlClass() { result = "ClassAggregateLiteral" }
188188

189189
/**
190+
* Gets an expression within the aggregate literal that is used to initialize
191+
* field `field`, if present.
192+
*
193+
* This predicate may have multiple results since a field can be initialized
194+
* multiple times in the same initializer.
195+
*/
196+
Expr getAFieldExpr(Field field) { result = this.getFieldExpr(field, _) }
197+
198+
/**
199+
* DEPRECATED: Use `getAFieldExpr` instead.
200+
*
190201
* Gets the expression within the aggregate literal that is used to initialize
191202
* field `field`, if present.
203+
*
204+
* This predicate may have multiple results since a field can be initialized
205+
* multiple times in the same initializer.
206+
*/
207+
Expr getFieldExpr(Field field) { result = this.getFieldExpr(field, _) }
208+
209+
/**
210+
* Gets the expression within the aggregate literal that is used to initialize
211+
* field `field`, if present. The expression is the `position`'th entry in the
212+
* aggregate literal.
213+
*
214+
* For example, if `aggr` represents the initialization literal `{.x = 123, .y = 456 .x = 789}` in
215+
* ```cpp
216+
* struct Foo { int x; int y; };
217+
* struct Foo foo = {.x = 123, .y = 456 .x = 789};
218+
* ```
219+
* then:
220+
* - `aggr.getFieldExpr(x, 0)` gives `123`.
221+
* - `aggr.getFieldExpr(y, 1)` gives `456`.
222+
* - `aggr.getFieldExpr(x, 2)` gives `789`.
192223
*/
193-
Expr getFieldExpr(Field field) {
224+
Expr getFieldExpr(Field field, int position) {
194225
field = classType.getAField() and
195226
aggregate_field_init(underlyingElement(this), unresolveElement(result), unresolveElement(field),
196-
_)
227+
position)
197228
}
198229

199230
/**
@@ -261,11 +292,41 @@ class ArrayOrVectorAggregateLiteral extends AggregateLiteral {
261292
Type getElementType() { none() }
262293

263294
/**
295+
* Gets an expression within the aggregate literal that is used to initialize
296+
* element `elementIndex`, if present.
297+
*
298+
* This predicate may have multiple results since an element can be initialized
299+
* multiple times in the same initializer.
300+
*/
301+
Expr getAnElementExpr(int elementIndex) { result = this.getElementExpr(elementIndex, _) }
302+
303+
/**
304+
* DEPRECATED: Use `getAnElementExpr` instead.
305+
*
264306
* Gets the expression within the aggregate literal that is used to initialize
265307
* element `elementIndex`, if present.
308+
*
309+
* This predicate may have multiple results since an element can be initialized
310+
* multiple times in the same initializer.
311+
*/
312+
Expr getElementExpr(int elementIndex) { result = this.getElementExpr(elementIndex, _) }
313+
314+
/**
315+
* Gets the expression within the aggregate literal that is used to initialize
316+
* element `elementIndex`, if present. The expression is the `position`'th entry
317+
* in the aggregate literal.
318+
*
319+
* For example, if `a` represents the initialization literal `{[0] = 123, [1] = 456, [0] = 789 }` in
320+
* ```cpp
321+
* int x[2] = {[0] = 123, [1] = 456, [0] = 789 };
322+
* ```
323+
* then:
324+
* - `a.getElementExpr(0, 0)` gives `123`.
325+
* - `a.getElementExpr(1, 1)` gives `456`.
326+
* - `a.getElementExpr(0, 2)` gives `789`.
266327
*/
267-
Expr getElementExpr(int elementIndex) {
268-
aggregate_array_init(underlyingElement(this), unresolveElement(result), elementIndex, _)
328+
Expr getElementExpr(int elementIndex, int position) {
329+
aggregate_array_init(underlyingElement(this), unresolveElement(result), elementIndex, position)
269330
}
270331

271332
/**

cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -619,18 +619,19 @@ newtype TTranslatedElement =
619619
)
620620
} or
621621
// The initialization of a field via a member of an initializer list.
622-
TTranslatedExplicitFieldInitialization(Expr ast, Field field, Expr expr) {
622+
TTranslatedExplicitFieldInitialization(Expr ast, Field field, Expr expr, int position) {
623623
exists(ClassAggregateLiteral initList |
624624
not ignoreExpr(initList) and
625625
ast = initList and
626-
expr = initList.getFieldExpr(field).getFullyConverted()
626+
expr = initList.getFieldExpr(field, position).getFullyConverted()
627627
)
628628
or
629629
exists(ConstructorFieldInit init |
630630
not ignoreExpr(init) and
631631
ast = init and
632632
field = init.getTarget() and
633-
expr = init.getExpr().getFullyConverted()
633+
expr = init.getExpr().getFullyConverted() and
634+
position = -1
634635
)
635636
} or
636637
// The value initialization of a field due to an omitted member of an
@@ -643,9 +644,11 @@ newtype TTranslatedElement =
643644
)
644645
} or
645646
// The initialization of an array element via a member of an initializer list.
646-
TTranslatedExplicitElementInitialization(ArrayOrVectorAggregateLiteral initList, int elementIndex) {
647+
TTranslatedExplicitElementInitialization(
648+
ArrayOrVectorAggregateLiteral initList, int elementIndex, int position
649+
) {
647650
not ignoreExpr(initList) and
648-
exists(initList.getElementExpr(elementIndex))
651+
exists(initList.getElementExpr(elementIndex, position))
649652
} or
650653
// The value initialization of a range of array elements that were omitted
651654
// from an initializer list.

cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedInitialization.qll

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -201,11 +201,13 @@ class TranslatedClassListInitialization extends TranslatedListInitialization {
201201
override ClassAggregateLiteral expr;
202202

203203
override TranslatedElement getChild(int id) {
204-
exists(TranslatedFieldInitialization fieldInit |
205-
result = fieldInit and
206-
fieldInit = getTranslatedFieldInitialization(expr, _) and
207-
fieldInit.getOrder() = id
208-
)
204+
result =
205+
rank[id + 1](TranslatedFieldInitialization fieldInit, int ord |
206+
fieldInit = getTranslatedFieldInitialization(expr, _) and
207+
fieldInit.getOrder() = ord
208+
|
209+
fieldInit order by ord, fieldInit.getPosition()
210+
)
209211
}
210212
}
211213

@@ -222,7 +224,7 @@ class TranslatedArrayListInitialization extends TranslatedListInitialization {
222224
rank[id + 1](TranslatedElementInitialization init |
223225
init.getInitList() = expr
224226
|
225-
init order by init.getElementIndex()
227+
init order by init.getElementIndex(), init.getPosition()
226228
)
227229
}
228230
}
@@ -522,6 +524,9 @@ abstract class TranslatedFieldInitialization extends TranslatedElement {
522524
final InstructionTag getFieldAddressTag() { result = InitializerFieldAddressTag() }
523525

524526
final Field getField() { result = field }
527+
528+
/** Gets the position in the initializer list, or `-1` if the initialization is implicit. */
529+
int getPosition() { result = -1 }
525530
}
526531

527532
/**
@@ -532,9 +537,10 @@ class TranslatedExplicitFieldInitialization extends TranslatedFieldInitializatio
532537
InitializationContext, TTranslatedExplicitFieldInitialization
533538
{
534539
Expr expr;
540+
int position;
535541

536542
TranslatedExplicitFieldInitialization() {
537-
this = TTranslatedExplicitFieldInitialization(ast, field, expr)
543+
this = TTranslatedExplicitFieldInitialization(ast, field, expr, position)
538544
}
539545

540546
override Instruction getTargetAddress() { result = getInstruction(getFieldAddressTag()) }
@@ -556,6 +562,8 @@ class TranslatedExplicitFieldInitialization extends TranslatedFieldInitializatio
556562
private TranslatedInitialization getInitialization() {
557563
result = getTranslatedInitialization(expr)
558564
}
565+
566+
override int getPosition() { result = position }
559567
}
560568

561569
private string getZeroValue(Type type) {
@@ -689,6 +697,8 @@ abstract class TranslatedElementInitialization extends TranslatedElement {
689697

690698
abstract int getElementIndex();
691699

700+
int getPosition() { result = -1 }
701+
692702
final InstructionTag getElementAddressTag() { result = InitializerElementAddressTag() }
693703

694704
final InstructionTag getElementIndexTag() { result = InitializerElementIndexTag() }
@@ -706,9 +716,10 @@ class TranslatedExplicitElementInitialization extends TranslatedElementInitializ
706716
TTranslatedExplicitElementInitialization, InitializationContext
707717
{
708718
int elementIndex;
719+
int position;
709720

710721
TranslatedExplicitElementInitialization() {
711-
this = TTranslatedExplicitElementInitialization(initList, elementIndex)
722+
this = TTranslatedExplicitElementInitialization(initList, elementIndex, position)
712723
}
713724

714725
override Instruction getTargetAddress() { result = getInstruction(getElementAddressTag()) }
@@ -731,8 +742,13 @@ class TranslatedExplicitElementInitialization extends TranslatedElementInitializ
731742

732743
override int getElementIndex() { result = elementIndex }
733744

745+
override int getPosition() { result = position }
746+
734747
TranslatedInitialization getInitialization() {
735-
result = getTranslatedInitialization(initList.getElementExpr(elementIndex).getFullyConverted())
748+
result =
749+
getTranslatedInitialization(initList
750+
.getElementExpr(elementIndex, position)
751+
.getFullyConverted())
736752
}
737753
}
738754

0 commit comments

Comments
 (0)