Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 2.1k
C++: Handle field initialization via NSDMI in IR generation#21391
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
5aabd9007603a859c27a268039ec09f930f9e60e12b91a52ae986d8922eda4ef3fc80ab554d7d4a637cb0f44d6a49c5cc0db7c619dad517f346ab9def780c1ab1f0c1File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| category: feature | ||
| --- | ||
| * Added a class `ConstructorDirectFieldInit` to represent field initializations that occur in member initializer lists. | ||
| * Added a class `ConstructorDefaultFieldInit` to represent default field initializations. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -495,7 +495,7 @@ class FieldInstruction extends Instruction { | ||
| * `FunctionAddress` instruction. | ||
| */ | ||
| class FunctionInstruction extends Instruction { | ||
| Language::Function funcSymbol; | ||
| Language::Declaration funcSymbol; | ||
| FunctionInstruction() { funcSymbol = Raw::getInstructionFunction(this) } | ||
| @@ -504,7 +504,7 @@ class FunctionInstruction extends Instruction { | ||
| /** | ||
| * Gets the function that this instruction references. | ||
jketema marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| */ | ||
| final Language::Function getFunctionSymbol() { result = funcSymbol } | ||
| final Language::Declaration getFunctionSymbol() { result = funcSymbol } | ||
| } | ||
| /** | ||
| @@ -1678,7 +1678,7 @@ class CallInstruction extends Instruction { | ||
| /** | ||
| * Gets the `Function` that the call targets, if this is statically known. | ||
| */ | ||
| final Language::Function getStaticCallTarget() { | ||
| final Language::Declaration getStaticCallTarget() { | ||
| result = this.getCallTarget().(FunctionAddressInstruction).getFunctionSymbol() | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -9,12 +9,13 @@ | ||
| private import semmle.code.cpp.ir.internal.TempVariableTag | ||
| private import InstructionTag | ||
| private import TranslatedCondition | ||
| private import TranslatedElement | ||
Check warningCode scanning / CodeQL Redundant import Warning
Redundant import, the module is already imported inside TranslatedGlobalVar Error loading related location LoadingUh oh!There was an error while loading. Please reload this page. Redundant import, the module is already imported inside TranslatedNonStaticDataMember Error loading related location LoadingUh oh!There was an error while loading. Please reload this page. | ||
| private import TranslatedExpr | ||
| private import TranslatedCall | ||
| private import TranslatedStmt | ||
| private import TranslatedFunction | ||
| private import TranslatedGlobalVar | ||
| private import TranslatedNonStaticDataMember | ||
| private import TranslatedInitialization | ||
| TranslatedElement getInstructionTranslatedElement(Instruction instruction) { | ||
| @@ -45,6 +46,9 @@ | ||
| or | ||
| not var.isFromUninstantiatedTemplate(_) and | ||
| var instanceof StaticInitializedStaticLocalVariable | ||
| or | ||
| not var.isFromUninstantiatedTemplate(_) and | ||
| var instanceof Field | ||
| ) and | ||
| var.hasInitializer() and | ||
| ( | ||
| @@ -64,6 +68,8 @@ | ||
| getTranslatedFunction(decl).hasUserVariable(var, type) | ||
| or | ||
| getTranslatedVarInit(decl).hasUserVariable(var, type) | ||
| or | ||
| getTranslatedFieldInit(decl).hasUserVariable(var, type) | ||
| } | ||
| cached | ||
| @@ -110,7 +116,7 @@ | ||
| } | ||
| cached | ||
| Function getInstructionFunction(Instruction instruction) { | ||
| Declaration getInstructionFunction(Instruction instruction) { | ||
| result = | ||
| getInstructionTranslatedElement(instruction) | ||
| .getInstructionFunction(getInstructionTag(instruction)) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -130,35 +130,39 @@ private predicate hasDefaultSideEffect(Call call, ParameterIndex i, boolean buff | ||
| } | ||
| /** | ||
| * A `Call` or `NewOrNewArrayExpr` or `DeleteOrDeleteArrayExpr`. | ||
| * An expression that can have call side effects. | ||
IdrissRio marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| * | ||
| * 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 expressions similarly, and to get the invoked `Declaration`. | ||
| */ | ||
| class CallOrAllocationExpr extends Expr { | ||
| CallOrAllocationExpr() { | ||
| class ExprWithCallSideEffects extends Expr { | ||
| ExprWithCallSideEffects() { | ||
| this instanceof Call | ||
| or | ||
| this instanceof NewOrNewArrayExpr | ||
| or | ||
| this instanceof DeleteOrDeleteArrayExpr | ||
| or | ||
| this instanceof ConstructorDefaultFieldInit | ||
| } | ||
| /** Gets the `Function` invoked by this expression, if known. */ | ||
| final Function getTarget() { | ||
| /** Gets the `Declaration` invoked by this expression, if known. */ | ||
| final Declaration getTarget() { | ||
| result = this.(Call).getTarget() | ||
| or | ||
| result = this.(NewOrNewArrayExpr).getAllocator() | ||
| or | ||
| result = this.(DeleteOrDeleteArrayExpr).getDeallocator() | ||
| or | ||
| result = this.(ConstructorDefaultFieldInit).getTarget() | ||
| } | ||
| } | ||
| /** | ||
| * 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(ExprWithCallSideEffects expr) { | ||
| not exists(expr.getTarget().(SideEffectFunction)) and result instanceof Opcode::CallSideEffect | ||
| or | ||
| exists(SideEffectFunction sideEffectFunction | | ||
| @@ -175,7 +179,7 @@ Opcode getCallSideEffectOpcode(CallOrAllocationExpr expr) { | ||
| /** | ||
| * Returns a side effect opcode for parameter index `i` of the specified call. | ||
| * | ||
| * This predicate will return at most two results: one read side effect, and one write side effect. | ||
| * This predicate will yield at most two results: one read side effect, and one write side effect. | ||
| */ | ||
| Opcode getASideEffectOpcode(Call call, ParameterIndex i) { | ||
| exists(boolean buffer | | ||
| @@ -228,3 +232,14 @@ Opcode getASideEffectOpcode(Call call, ParameterIndex i) { | ||
| ) | ||
| ) | ||
| } | ||
| /** | ||
| * Returns a side effect opcode for a default field initialization. | ||
| * | ||
| * This predicate will yield two results: one read side effect, and one write side effect. | ||
| */ | ||
| Opcode getDefaultFieldInitSideEffectOpcode() { | ||
| result instanceof Opcode::IndirectReadSideEffect | ||
| or | ||
| result instanceof Opcode::IndirectMayWriteSideEffect | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 Doesn't have to be now, though, of course! ContributorAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe 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() } | ||
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.