Skip to content

Commit 9138e19

Browse files
committed
C++: Call functions for NSDMI initialization
Currently missing: side-effect information for the functions
1 parent 70db459 commit 9138e19

File tree

5 files changed

+382
-209
lines changed

5 files changed

+382
-209
lines changed

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -775,6 +775,17 @@ newtype TTranslatedElement =
775775
position = -1
776776
)
777777
} or
778+
// The initialization of a field via a default member initializer.
779+
TTranslatedDefaultFieldInitialization(Expr ast, Field field, int position) {
780+
exists(ConstructorFieldInit init |
781+
not ignoreExpr(init) and
782+
ast = init and
783+
field = init.getTarget() and
784+
not exists(init.getExpr()) and
785+
exists(field.getInitializer()) and
786+
position = -1
787+
)
788+
} or
778789
// The value initialization of a field due to an omitted member of an
779790
// initializer list.
780791
TTranslatedFieldValueInitialization(Expr ast, Field field) {

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

Lines changed: 86 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,11 @@ TranslatedFieldInitialization getTranslatedConstructorFieldInitialization(Constr
521521
abstract class TranslatedFieldInitialization extends TranslatedElement {
522522
Expr ast;
523523
Field field;
524+
int position;
525+
526+
// All subclass charpreds must bind the `position` field.
527+
bindingset[position]
528+
TranslatedFieldInitialization() { any() }
524529

525530
final override string toString() { result = ast.toString() + "." + field.toString() }
526531

@@ -533,17 +538,32 @@ abstract class TranslatedFieldInitialization extends TranslatedElement {
533538
result = getEnclosingVariable(ast).(Field)
534539
}
535540

536-
final override Instruction getFirstInstruction(EdgeKind kind) {
537-
result = this.getInstruction(this.getFieldAddressTag()) and
538-
kind instanceof GotoEdge
539-
}
541+
final Field getField() { result = field }
540542

541543
/**
542544
* Gets the zero-based index describing the order in which this field is to be
543545
* initialized relative to the other fields in the class.
544546
*/
545547
final int getOrder() { result = field.getInitializationOrder() }
546548

549+
/** Gets the position in the initializer list, or `-1` if the initialization is implicit. */
550+
final int getPosition() { result = position }
551+
}
552+
553+
/**
554+
* Represents the IR translation of the initialization of a field from an
555+
* element of an initializer list where default initialization is not used.
556+
*/
557+
abstract class TranslatedNonDefaultFieldInitialization extends TranslatedFieldInitialization {
558+
// All subclass charpreds must bind the `position` field.
559+
bindingset[position]
560+
TranslatedNonDefaultFieldInitialization() { any() }
561+
562+
final override Instruction getFirstInstruction(EdgeKind kind) {
563+
result = this.getInstruction(this.getFieldAddressTag()) and
564+
kind instanceof GotoEdge
565+
}
566+
547567
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
548568
tag = this.getFieldAddressTag() and
549569
opcode instanceof Opcode::FieldAddress and
@@ -561,22 +581,16 @@ abstract class TranslatedFieldInitialization extends TranslatedElement {
561581
}
562582

563583
final InstructionTag getFieldAddressTag() { result = InitializerFieldAddressTag() }
564-
565-
final Field getField() { result = field }
566-
567-
/** Gets the position in the initializer list, or `-1` if the initialization is implicit. */
568-
int getPosition() { result = -1 }
569584
}
570585

571586
/**
572587
* Represents the IR translation of the initialization of a field from an
573588
* explicit element in an initializer list.
574589
*/
575-
class TranslatedExplicitFieldInitialization extends TranslatedFieldInitialization,
590+
class TranslatedExplicitFieldInitialization extends TranslatedNonDefaultFieldInitialization,
576591
InitializationContext, TTranslatedExplicitFieldInitialization
577592
{
578593
Expr expr;
579-
int position;
580594

581595
TranslatedExplicitFieldInitialization() {
582596
this = TTranslatedExplicitFieldInitialization(ast, field, expr, position)
@@ -608,8 +622,61 @@ class TranslatedExplicitFieldInitialization extends TranslatedFieldInitializatio
608622
private TranslatedInitialization getInitialization() {
609623
result = getTranslatedInitialization(expr)
610624
}
625+
}
611626

612-
override int getPosition() { result = position }
627+
/**
628+
* Represents the IR translation of the initialization of a field from an
629+
* element of an initializer list where default initialization is used.
630+
*/
631+
class TranslatedDefaultFieldInitialization extends TranslatedFieldInitialization,
632+
TTranslatedDefaultFieldInitialization
633+
{
634+
TranslatedDefaultFieldInitialization() {
635+
this = TTranslatedDefaultFieldInitialization(ast, field, position)
636+
}
637+
638+
final override Instruction getFirstInstruction(EdgeKind kind) {
639+
result = this.getInstruction(CallTargetTag()) and
640+
kind instanceof GotoEdge
641+
}
642+
643+
override Instruction getALastInstructionInternal() { result = this.getInstruction(CallTag()) }
644+
645+
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
646+
tag = CallTargetTag() and
647+
result = this.getInstruction(CallTag())
648+
or
649+
tag = CallTag() and
650+
result = this.getParent().getChildSuccessor(this, kind)
651+
}
652+
653+
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
654+
tag = CallTargetTag() and
655+
opcode instanceof Opcode::FunctionAddress and
656+
resultType = getFunctionGLValueType()
657+
or
658+
tag = CallTag() and
659+
opcode instanceof Opcode::Call and
660+
resultType = getVoidType()
661+
}
662+
663+
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
664+
tag = CallTag() and
665+
(
666+
operandTag instanceof CallTargetOperandTag and
667+
result = this.getInstruction(CallTargetTag())
668+
or
669+
operandTag instanceof ThisArgumentOperandTag and
670+
result = getTranslatedFunction(this.getFunction()).getLoadThisInstruction()
671+
)
672+
}
673+
674+
override Declaration getInstructionFunction(InstructionTag tag) {
675+
tag = CallTargetTag() and
676+
result = field
677+
}
678+
679+
override TranslatedElement getChild(int id) { none() }
613680
}
614681

615682
private string getZeroValue(Type type) {
@@ -620,17 +687,19 @@ private string getZeroValue(Type type) {
620687
* Represents the IR translation of the initialization of a field without a
621688
* corresponding element in the initializer list.
622689
*/
623-
class TranslatedFieldValueInitialization extends TranslatedFieldInitialization,
690+
class TranslatedFieldValueInitialization extends TranslatedNonDefaultFieldInitialization,
624691
TTranslatedFieldValueInitialization
625692
{
626-
TranslatedFieldValueInitialization() { this = TTranslatedFieldValueInitialization(ast, field) }
693+
TranslatedFieldValueInitialization() {
694+
this = TTranslatedFieldValueInitialization(ast, field) and position = -1
695+
}
627696

628697
override Instruction getALastInstructionInternal() {
629698
result = this.getInstruction(this.getFieldDefaultValueStoreTag())
630699
}
631700

632701
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
633-
TranslatedFieldInitialization.super.hasInstruction(opcode, tag, resultType)
702+
TranslatedNonDefaultFieldInitialization.super.hasInstruction(opcode, tag, resultType)
634703
or
635704
tag = this.getFieldDefaultValueTag() and
636705
opcode instanceof Opcode::Constant and
@@ -661,7 +730,8 @@ class TranslatedFieldValueInitialization extends TranslatedFieldInitialization,
661730
}
662731

663732
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
664-
result = TranslatedFieldInitialization.super.getInstructionRegisterOperand(tag, operandTag)
733+
result =
734+
TranslatedNonDefaultFieldInitialization.super.getInstructionRegisterOperand(tag, operandTag)
665735
or
666736
tag = this.getFieldDefaultValueStoreTag() and
667737
(

0 commit comments

Comments
 (0)