Skip to content

Commit bef0a15

Browse files
committed
C++: IR generation for repeated initializers.
1 parent a0df7d2 commit bef0a15

File tree

3 files changed

+65
-18
lines changed

3 files changed

+65
-18
lines changed

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

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -190,10 +190,23 @@ class ClassAggregateLiteral extends AggregateLiteral {
190190
* Gets the expression within the aggregate literal that is used to initialize
191191
* field `field`, if present.
192192
*/
193-
Expr getFieldExpr(Field field) {
193+
Expr getFieldExpr(Field field) { result = this.getFieldExpr(field, _) }
194+
195+
/**
196+
* Gets the expression within the aggregate literal that is used to initialize
197+
* field `field` the `repitition`'th time in the initializer list, if present.
198+
*
199+
* For example, if `aggr` represents the initialization literal `{.x = 1234, .x = 5678}` in
200+
* ```cpp
201+
* struct Foo { int x; };
202+
* struct Foo foo = {.x = 1234, .x = 5678};
203+
* ```
204+
* then `aggr.getFieldExpr(x, 0)` gives `1234`, and `aggr.getFieldExpr(x, 1)` gives `5678`.
205+
*/
206+
Expr getFieldExpr(Field field, int repitition) {
194207
field = classType.getAField() and
195208
aggregate_field_init(underlyingElement(this), unresolveElement(result), unresolveElement(field),
196-
_)
209+
repitition)
197210
}
198211

199212
/**
@@ -264,8 +277,20 @@ class ArrayOrVectorAggregateLiteral extends AggregateLiteral {
264277
* Gets the expression within the aggregate literal that is used to initialize
265278
* element `elementIndex`, if present.
266279
*/
267-
Expr getElementExpr(int elementIndex) {
268-
aggregate_array_init(underlyingElement(this), unresolveElement(result), elementIndex, _)
280+
Expr getElementExpr(int elementIndex) { result = this.getElementExpr(elementIndex, _) }
281+
282+
/**
283+
* Gets the expression within the aggregate literal that is used to initialize
284+
* element `elementIndex` the `repitition`'th time in the initializer list, if present.
285+
*
286+
* For example, if `a` represents the initialization literal `{[0] = 1234, [0] = 5678}` in
287+
* ```cpp
288+
* int x[1] = {[0] = 1234, [0] = 5678};
289+
* ```
290+
* then `a.getElementExpr(0, 0)` gives `1234`, and `a.getElementExpr(0, 1)` gives `5678`.
291+
*/
292+
Expr getElementExpr(int elementIndex, int repitition) {
293+
aggregate_array_init(underlyingElement(this), unresolveElement(result), elementIndex, repitition)
269294
}
270295

271296
/**

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 repitition) {
623623
exists(ClassAggregateLiteral initList |
624624
not ignoreExpr(initList) and
625625
ast = initList and
626-
expr = initList.getFieldExpr(field).getFullyConverted()
626+
expr = initList.getFieldExpr(field, repitition).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+
repitition = 0
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 repitition
649+
) {
647650
not ignoreExpr(initList) and
648-
exists(initList.getElementExpr(elementIndex))
651+
exists(initList.getElementExpr(elementIndex, repitition))
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: 28 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.getRepetitionIndex()
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.getRepetitionIndex()
226228
)
227229
}
228230
}
@@ -522,6 +524,12 @@ abstract class TranslatedFieldInitialization extends TranslatedElement {
522524
final InstructionTag getFieldAddressTag() { result = InitializerFieldAddressTag() }
523525

524526
final Field getField() { result = field }
527+
528+
/**
529+
* Gets the index of this initialization, if the field is mentioned
530+
* multiple times in the initializer.
531+
*/
532+
int getRepetitionIndex() { result = 0 }
525533
}
526534

527535
/**
@@ -532,9 +540,10 @@ class TranslatedExplicitFieldInitialization extends TranslatedFieldInitializatio
532540
InitializationContext, TTranslatedExplicitFieldInitialization
533541
{
534542
Expr expr;
543+
int repitition;
535544

536545
TranslatedExplicitFieldInitialization() {
537-
this = TTranslatedExplicitFieldInitialization(ast, field, expr)
546+
this = TTranslatedExplicitFieldInitialization(ast, field, expr, repitition)
538547
}
539548

540549
override Instruction getTargetAddress() { result = getInstruction(getFieldAddressTag()) }
@@ -556,6 +565,8 @@ class TranslatedExplicitFieldInitialization extends TranslatedFieldInitializatio
556565
private TranslatedInitialization getInitialization() {
557566
result = getTranslatedInitialization(expr)
558567
}
568+
569+
override int getRepetitionIndex() { result = repitition }
559570
}
560571

561572
private string getZeroValue(Type type) {
@@ -689,6 +700,8 @@ abstract class TranslatedElementInitialization extends TranslatedElement {
689700

690701
abstract int getElementIndex();
691702

703+
int getRepetitionIndex() { result = 0 }
704+
692705
final InstructionTag getElementAddressTag() { result = InitializerElementAddressTag() }
693706

694707
final InstructionTag getElementIndexTag() { result = InitializerElementIndexTag() }
@@ -706,9 +719,10 @@ class TranslatedExplicitElementInitialization extends TranslatedElementInitializ
706719
TTranslatedExplicitElementInitialization, InitializationContext
707720
{
708721
int elementIndex;
722+
int repetition;
709723

710724
TranslatedExplicitElementInitialization() {
711-
this = TTranslatedExplicitElementInitialization(initList, elementIndex)
725+
this = TTranslatedExplicitElementInitialization(initList, elementIndex, repetition)
712726
}
713727

714728
override Instruction getTargetAddress() { result = getInstruction(getElementAddressTag()) }
@@ -731,8 +745,13 @@ class TranslatedExplicitElementInitialization extends TranslatedElementInitializ
731745

732746
override int getElementIndex() { result = elementIndex }
733747

748+
override int getRepetitionIndex() { result = repetition }
749+
734750
TranslatedInitialization getInitialization() {
735-
result = getTranslatedInitialization(initList.getElementExpr(elementIndex).getFullyConverted())
751+
result =
752+
getTranslatedInitialization(initList
753+
.getElementExpr(elementIndex, repetition)
754+
.getFullyConverted())
736755
}
737756
}
738757

0 commit comments

Comments
 (0)