Skip to content

Commit e79d1aa

Browse files
committed
C++: Call functions for NSDMI initialization
Currently missing: side-effect information for the functions
1 parent 34ce890 commit e79d1aa

File tree

5 files changed

+372
-208
lines changed

5 files changed

+372
-208
lines changed

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -767,14 +767,22 @@ newtype TTranslatedElement =
767767
expr = initList.getFieldExpr(field, position).getFullyConverted()
768768
)
769769
or
770-
exists(ConstructorFieldInit init |
770+
exists(ConstructorDirectFieldInit init |
771771
not ignoreExpr(init) and
772772
ast = init and
773773
field = init.getTarget() and
774774
expr = init.getExpr().getFullyConverted() and
775775
position = -1
776776
)
777777
} or
778+
// The initialization of a field via a default member initializer.
779+
TTranslatedDefaultFieldInitialization(Expr ast, Field field) {
780+
exists(ConstructorDefaultFieldInit init |
781+
not ignoreExpr(init) and
782+
ast = init and
783+
field = init.getTarget()
784+
)
785+
} or
778786
// The value initialization of a field due to an omitted member of an
779787
// initializer list.
780788
TTranslatedFieldValueInitialization(Expr ast, Field field) {

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

Lines changed: 78 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -533,17 +533,28 @@ abstract class TranslatedFieldInitialization extends TranslatedElement {
533533
result = getEnclosingVariable(ast).(Field)
534534
}
535535

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

541538
/**
542539
* Gets the zero-based index describing the order in which this field is to be
543540
* initialized relative to the other fields in the class.
544541
*/
545542
final int getOrder() { result = field.getInitializationOrder() }
546543

544+
/** Gets the position in the initializer list, or `-1` if the initialization is implicit. */
545+
int getPosition() { result = -1 }
546+
}
547+
548+
/**
549+
* Represents the IR translation of the initialization of a field from an
550+
* element of an initializer list where default initialization is not used.
551+
*/
552+
abstract class TranslatedNonDefaultFieldInitialization extends TranslatedFieldInitialization {
553+
final override Instruction getFirstInstruction(EdgeKind kind) {
554+
result = this.getInstruction(this.getFieldAddressTag()) and
555+
kind instanceof GotoEdge
556+
}
557+
547558
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
548559
tag = this.getFieldAddressTag() and
549560
opcode instanceof Opcode::FieldAddress and
@@ -561,18 +572,13 @@ abstract class TranslatedFieldInitialization extends TranslatedElement {
561572
}
562573

563574
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 }
569575
}
570576

571577
/**
572578
* Represents the IR translation of the initialization of a field from an
573579
* explicit element in an initializer list.
574580
*/
575-
class TranslatedExplicitFieldInitialization extends TranslatedFieldInitialization,
581+
class TranslatedExplicitFieldInitialization extends TranslatedNonDefaultFieldInitialization,
576582
InitializationContext, TTranslatedExplicitFieldInitialization
577583
{
578584
Expr expr;
@@ -612,6 +618,61 @@ class TranslatedExplicitFieldInitialization extends TranslatedFieldInitializatio
612618
override int getPosition() { result = position }
613619
}
614620

621+
/**
622+
* Represents the IR translation of the initialization of a field from an
623+
* element of an initializer list where default initialization is used.
624+
*/
625+
class TranslatedDefaultFieldInitialization extends TranslatedFieldInitialization,
626+
TTranslatedDefaultFieldInitialization
627+
{
628+
TranslatedDefaultFieldInitialization() {
629+
this = TTranslatedDefaultFieldInitialization(ast, field)
630+
}
631+
632+
final override Instruction getFirstInstruction(EdgeKind kind) {
633+
result = this.getInstruction(CallTargetTag()) and
634+
kind instanceof GotoEdge
635+
}
636+
637+
override Instruction getALastInstructionInternal() { result = this.getInstruction(CallTag()) }
638+
639+
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
640+
tag = CallTargetTag() and
641+
result = this.getInstruction(CallTag())
642+
or
643+
tag = CallTag() and
644+
result = this.getParent().getChildSuccessor(this, kind)
645+
}
646+
647+
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
648+
tag = CallTargetTag() and
649+
opcode instanceof Opcode::FunctionAddress and
650+
resultType = getFunctionGLValueType()
651+
or
652+
tag = CallTag() and
653+
opcode instanceof Opcode::Call and
654+
resultType = getVoidType()
655+
}
656+
657+
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
658+
tag = CallTag() and
659+
(
660+
operandTag instanceof CallTargetOperandTag and
661+
result = this.getInstruction(CallTargetTag())
662+
or
663+
operandTag instanceof ThisArgumentOperandTag and
664+
result = getTranslatedFunction(this.getFunction()).getLoadThisInstruction()
665+
)
666+
}
667+
668+
override Declaration getInstructionFunction(InstructionTag tag) {
669+
tag = CallTargetTag() and
670+
result = field
671+
}
672+
673+
override TranslatedElement getChild(int id) { none() }
674+
}
675+
615676
private string getZeroValue(Type type) {
616677
if type instanceof FloatingPointType then result = "0.0" else result = "0"
617678
}
@@ -620,17 +681,19 @@ private string getZeroValue(Type type) {
620681
* Represents the IR translation of the initialization of a field without a
621682
* corresponding element in the initializer list.
622683
*/
623-
class TranslatedFieldValueInitialization extends TranslatedFieldInitialization,
684+
class TranslatedFieldValueInitialization extends TranslatedNonDefaultFieldInitialization,
624685
TTranslatedFieldValueInitialization
625686
{
626-
TranslatedFieldValueInitialization() { this = TTranslatedFieldValueInitialization(ast, field) }
687+
TranslatedFieldValueInitialization() {
688+
this = TTranslatedFieldValueInitialization(ast, field)
689+
}
627690

628691
override Instruction getALastInstructionInternal() {
629692
result = this.getInstruction(this.getFieldDefaultValueStoreTag())
630693
}
631694

632695
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
633-
TranslatedFieldInitialization.super.hasInstruction(opcode, tag, resultType)
696+
TranslatedNonDefaultFieldInitialization.super.hasInstruction(opcode, tag, resultType)
634697
or
635698
tag = this.getFieldDefaultValueTag() and
636699
opcode instanceof Opcode::Constant and
@@ -661,7 +724,8 @@ class TranslatedFieldValueInitialization extends TranslatedFieldInitialization,
661724
}
662725

663726
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
664-
result = TranslatedFieldInitialization.super.getInstructionRegisterOperand(tag, operandTag)
727+
result =
728+
TranslatedNonDefaultFieldInitialization.super.getInstructionRegisterOperand(tag, operandTag)
665729
or
666730
tag = this.getFieldDefaultValueStoreTag() and
667731
(

0 commit comments

Comments
 (0)