Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 27 additions & 2 deletions cpp/ql/lib/semmle/code/cpp/exprs/Call.qll
Original file line number Diff line number Diff line change
Expand Up @@ -585,12 +585,15 @@ class ConstructorDelegationInit extends ConstructorBaseInit, @ctordelegatinginit

/**
* An initialization of a member variable performed as part of a
* constructor's explicit initializer list or implicit actions.
* constructor's initializer list or by default initialization.
*
* In the example below, member variable `b` is being initialized by
* constructor parameter `a`:
* constructor parameter `a`, and `c` is initialized by default
* initialization:
* ```
* struct S {
* int b;
* int c = 3;
* S(int a): b(a) {}
* } s(2);
* ```
Expand All @@ -616,6 +619,28 @@ class ConstructorFieldInit extends ConstructorInit, @ctorfieldinit {
override predicate mayBeGloballyImpure() { this.getExpr().mayBeGloballyImpure() }
}

/**
* An initialization of a member variable performed as part of a
* constructor's explicit initializer list.
*/
class ConstructorDirectFieldInit extends ConstructorFieldInit {
ConstructorDirectFieldInit() { exists(this.getChild(0)) }

override string getAPrimaryQlClass() { result = "ConstructorDirectFieldInit" }
}

/**
* An initialization of a member variable performed by default
* initialization.
*/
class ConstructorDefaultFieldInit extends ConstructorFieldInit {
ConstructorDefaultFieldInit() {
not exists(this.getChild(0)) and exists(this.getTarget().getInitializer())
}

override string getAPrimaryQlClass() { result = "ConstructorDefaultFieldInit" }
}

/**
* A call to a destructor of a base class or field as part of a destructor's
* compiler-generated actions.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ private import TranslatedCall
private import TranslatedStmt
private import TranslatedFunction
private import TranslatedGlobalVar
private import TranslatedNonStaticDataMember
private import TranslatedInitialization

TranslatedElement getInstructionTranslatedElement(Instruction instruction) {
Expand Down Expand Up @@ -45,6 +46,8 @@ module Raw {
or
not var.isFromUninstantiatedTemplate(_) and
var instanceof StaticInitializedStaticLocalVariable
or
var instanceof Field
) and
var.hasInitializer() and
(
Expand All @@ -64,6 +67,8 @@ module Raw {
getTranslatedFunction(decl).hasUserVariable(var, type)
or
getTranslatedVarInit(decl).hasUserVariable(var, type)
or
getTranslatedFieldInit(decl).hasUserVariable(var, type)
}

cached
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,13 +130,13 @@ private predicate hasDefaultSideEffect(Call call, ParameterIndex i, boolean buff
}

/**
* A `Call` or `NewOrNewArrayExpr` or `DeleteOrDeleteArrayExpr`.
* An expression that can have call side effects.
*
* All kinds of expression invoke a function as part of their evaluation. This class provides a
* way to treat both kinds of function similarly, and to get the invoked `Function`.
* All kinds of expressions invoke a function as part of their evaluation. This class provides a
* way to treat those functions similarly, and to get the invoked `Function`.
*/
class CallOrAllocationExpr extends Expr {
CallOrAllocationExpr() {
class ExprWithCallSizeEffects extends Expr {
ExprWithCallSizeEffects() {
this instanceof Call
or
this instanceof NewOrNewArrayExpr
Expand All @@ -158,7 +158,7 @@ class CallOrAllocationExpr extends Expr {
* Returns the side effect opcode, if any, that represents any side effects not specifically modeled
* by an argument side effect.
*/
Opcode getCallSideEffectOpcode(CallOrAllocationExpr expr) {
Opcode getCallSideEffectOpcode(ExprWithCallSizeEffects expr) {
not exists(expr.getTarget().(SideEffectFunction)) and result instanceof Opcode::CallSideEffect
or
exists(SideEffectFunction sideEffectFunction |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ abstract class TranslatedCondition extends TranslatedElement {
final override Declaration getFunction() {
result = getEnclosingFunction(expr) or
result = getEnclosingVariable(expr).(GlobalOrNamespaceVariable) or
result = getEnclosingVariable(expr).(StaticInitializedStaticLocalVariable)
result = getEnclosingVariable(expr).(StaticInitializedStaticLocalVariable) or
result = getEnclosingVariable(expr).(Field)
Comment on lines 37 to +40
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

At some point we should probably have some kind of abstract class thingie instead of having to enumerate all the possible Elements for which we generate IRFunctions. I think this enumeration happens in quite a few places at this point.

Doesn't have to be now, though, of course!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Agreed. I like leaving that as a follow-up.

}

final Type getResultType() { result = expr.getUnspecifiedType() }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ abstract class TranslatedDeclarationEntry extends TranslatedElement, TTranslated
or
not entry.getDeclaration() instanceof StaticInitializedStaticLocalVariable and
not entry.getDeclaration() instanceof GlobalOrNamespaceVariable and
not entry.getDeclaration() instanceof Field and
result = stmt.getEnclosingFunction()
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -871,7 +871,7 @@ newtype TTranslatedElement =
// The declaration/initialization part of a `ConditionDeclExpr`
TTranslatedConditionDecl(ConditionDeclExpr expr) { not ignoreExpr(expr) } or
// The side effects of a `Call`
TTranslatedCallSideEffects(CallOrAllocationExpr expr) {
TTranslatedCallSideEffects(ExprWithCallSizeEffects expr) {
not ignoreExpr(expr) and
not ignoreSideEffects(expr)
} or
Expand Down Expand Up @@ -918,7 +918,10 @@ newtype TTranslatedElement =
} or
// The side effect that initializes newly-allocated memory.
TTranslatedAllocationSideEffect(AllocationExpr expr) { not ignoreSideEffects(expr) } or
TTranslatedStaticStorageDurationVarInit(Variable var) { Raw::varHasIRFunc(var) } or
TTranslatedStaticStorageDurationVarInit(Variable var) {
Raw::varHasIRFunc(var) and not var instanceof Field
} or
TTranslatedNonStaticDataMemberVarInit(Field var) { Raw::varHasIRFunc(var) } or
TTranslatedAssertionOperand(MacroInvocation mi, int index) { hasAssertionOperand(mi, index) }

/**
Expand Down Expand Up @@ -1297,5 +1300,7 @@ abstract class TranslatedRootElement extends TranslatedElement {
this instanceof TTranslatedFunction
or
this instanceof TTranslatedStaticStorageDurationVarInit
or
this instanceof TTranslatedNonStaticDataMemberVarInit
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ private import TranslatedFunction
private import TranslatedInitialization
private import TranslatedStmt
private import TranslatedGlobalVar
private import TranslatedNonStaticDataMember
private import IRConstruction
import TranslatedCall

Expand Down Expand Up @@ -138,6 +139,8 @@ abstract class TranslatedExpr extends TranslatedElement {
result = getTranslatedFunction(getEnclosingFunction(expr))
or
result = getTranslatedVarInit(getEnclosingVariable(expr))
or
result = getTranslatedFieldInit(getEnclosingVariable(expr))
}
}

Expand All @@ -153,7 +156,10 @@ Declaration getEnclosingDeclaration0(Expr e) {
i.getExpr().getFullyConverted() = e and
v = i.getDeclaration()
|
if v instanceof StaticInitializedStaticLocalVariable or v instanceof GlobalOrNamespaceVariable
if
v instanceof StaticInitializedStaticLocalVariable or
v instanceof GlobalOrNamespaceVariable or
v instanceof Field
then result = v
else result = e.getEnclosingDeclaration()
)
Expand All @@ -173,7 +179,10 @@ Variable getEnclosingVariable0(Expr e) {
i.getExpr().getFullyConverted() = e and
v = i.getDeclaration()
|
if v instanceof StaticInitializedStaticLocalVariable or v instanceof GlobalOrNamespaceVariable
if
v instanceof StaticInitializedStaticLocalVariable or
v instanceof GlobalOrNamespaceVariable or
v instanceof Field
then result = v
else result = e.getEnclosingVariable()
)
Expand Down Expand Up @@ -826,6 +835,46 @@ class TranslatedPostfixCrementOperation extends TranslatedCrementOperation {
override Instruction getResult() { result = this.getLoadedOperand().getResult() }
}

class TranslatedParamAccessForType extends TranslatedNonConstantExpr {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The name here feels too broad if it only handles this. Would it make sense to rename it to something like TranslatedThisParameterAccess?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Leaving as-is, as this matches the rest of the code.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think it would help the reader and whoever will have to touch the code in the future very much, but that's just my opinion 😄

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

From my perspective it will make it more difficult to find the place when we need to change things if we would ever need to expand on this.

override ParamAccessForType expr;

TranslatedParamAccessForType() {
// Currently only needed for this parameter accesses.
expr.isThisAccess()
}

final override Instruction getFirstInstruction(EdgeKind kind) {
result = this.getInstruction(OnlyInstructionTag()) and
kind instanceof GotoEdge
}

override Instruction getALastInstructionInternal() {
result = this.getInstruction(OnlyInstructionTag())
}

final override TranslatedElement getChildInternal(int id) { none() }

override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
tag = OnlyInstructionTag() and
result = this.getParent().getChildSuccessor(this, kind)
}

override Instruction getResult() { result = this.getInstruction(OnlyInstructionTag()) }

override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
tag = OnlyInstructionTag() and
opcode instanceof Opcode::CopyValue and
resultType = getTypeForPRValue(expr.getType())
}

override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = OnlyInstructionTag() and
operandTag instanceof UnaryOperandTag and
result =
this.getEnclosingFunction().(TranslatedNonStaticDataMemberVarInit).getLoadThisInstruction()
}
}

/**
* IR translation of an array access expression (e.g. `a[i]`). The array being accessed will either
* be a prvalue of pointer type (possibly due to an implicit array-to-pointer conversion), or a
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,8 @@ abstract class TranslatedInitialization extends TranslatedElement, TTranslatedIn
final override Declaration getFunction() {
result = getEnclosingFunction(expr) or
result = getEnclosingVariable(expr).(GlobalOrNamespaceVariable) or
result = getEnclosingVariable(expr).(StaticInitializedStaticLocalVariable)
result = getEnclosingVariable(expr).(StaticInitializedStaticLocalVariable) or
result = getEnclosingVariable(expr).(Field)
}

final override Locatable getAst() { result = expr }
Expand Down Expand Up @@ -528,7 +529,8 @@ abstract class TranslatedFieldInitialization extends TranslatedElement {
final override Declaration getFunction() {
result = getEnclosingFunction(ast) or
result = getEnclosingVariable(ast).(GlobalOrNamespaceVariable) or
result = getEnclosingVariable(ast).(StaticInitializedStaticLocalVariable)
result = getEnclosingVariable(ast).(StaticInitializedStaticLocalVariable) or
result = getEnclosingVariable(ast).(Field)
}

final override Instruction getFirstInstruction(EdgeKind kind) {
Expand Down Expand Up @@ -701,6 +703,8 @@ abstract class TranslatedElementInitialization extends TranslatedElement {
result = getEnclosingVariable(initList).(GlobalOrNamespaceVariable)
or
result = getEnclosingVariable(initList).(StaticInitializedStaticLocalVariable)
or
result = getEnclosingVariable(initList).(Field)
}

final override Instruction getFirstInstruction(EdgeKind kind) {
Expand Down
Loading