File tree Expand file tree Collapse file tree 9 files changed +138
-2
lines changed
src/semmle/code/cpp/ir/implementation Expand file tree Collapse file tree 9 files changed +138
-2
lines changed Original file line number Diff line number Diff line change 11private newtype TOpcode =
22 TNoOp ( ) or
33 TUninitialized ( ) or
4+ TError ( ) or
45 TInitializeParameter ( ) or
56 TInitializeThis ( ) or
67 TEnterFunction ( ) or
@@ -147,6 +148,7 @@ abstract class BufferAccessOpcode extends MemoryAccessOpcode {}
147148module Opcode {
148149 class NoOp extends Opcode , TNoOp { override final string toString ( ) { result = "NoOp" } }
149150 class Uninitialized extends MemoryAccessOpcode , TUninitialized { override final string toString ( ) { result = "Uninitialized" } }
151+ class Error extends Opcode , TError { override final string toString ( ) { result = "Error" } }
150152 class InitializeParameter extends MemoryAccessOpcode , TInitializeParameter { override final string toString ( ) { result = "InitializeParameter" } }
151153 class InitializeThis extends Opcode , TInitializeThis { override final string toString ( ) { result = "InitializeThis" } }
152154 class EnterFunction extends Opcode , TEnterFunction { override final string toString ( ) { result = "EnterFunction" } }
Original file line number Diff line number Diff line change @@ -702,6 +702,22 @@ class FieldAddressInstruction extends FieldInstruction {
702702 }
703703}
704704
705+ /**
706+ * An instruction that produces a well-defined but unknown result and has
707+ * unknown side effects, including side effects that are not conservatively
708+ * modeled in the SSA graph.
709+ *
710+ * This type of instruction appears when there is an `ErrorExpr` in the AST,
711+ * meaning that the extractor could not understand the expression and therefore
712+ * produced a partial AST. Queries that give alerts when some action is _not_
713+ * taken may want to ignore any function that contains an `ErrorInstruction`.
714+ */
715+ class ErrorInstruction extends Instruction {
716+ ErrorInstruction ( ) {
717+ getOpcode ( ) instanceof Opcode:: Error
718+ }
719+ }
720+
705721class UninitializedInstruction extends VariableInstruction {
706722 UninitializedInstruction ( ) {
707723 getOpcode ( ) instanceof Opcode:: Uninitialized
Original file line number Diff line number Diff line change @@ -702,6 +702,22 @@ class FieldAddressInstruction extends FieldInstruction {
702702 }
703703}
704704
705+ /**
706+ * An instruction that produces a well-defined but unknown result and has
707+ * unknown side effects, including side effects that are not conservatively
708+ * modeled in the SSA graph.
709+ *
710+ * This type of instruction appears when there is an `ErrorExpr` in the AST,
711+ * meaning that the extractor could not understand the expression and therefore
712+ * produced a partial AST. Queries that give alerts when some action is _not_
713+ * taken may want to ignore any function that contains an `ErrorInstruction`.
714+ */
715+ class ErrorInstruction extends Instruction {
716+ ErrorInstruction ( ) {
717+ getOpcode ( ) instanceof Opcode:: Error
718+ }
719+ }
720+
705721class UninitializedInstruction extends VariableInstruction {
706722 UninitializedInstruction ( ) {
707723 getOpcode ( ) instanceof Opcode:: Uninitialized
Original file line number Diff line number Diff line change @@ -84,7 +84,13 @@ private predicate ignoreExprOnly(Expr expr) {
8484 // Ignore the allocator call, because we always synthesize it. Don't ignore
8585 // its arguments, though, because we use them as part of the synthesis.
8686 newExpr .getAllocatorCall ( ) = expr
87- ) or
87+ )
88+ or
89+ // The extractor deliberately emits an `ErrorExpr` as the first argument to
90+ // the allocator call, if any, of a `NewOrNewArrayExpr`. That `ErrorExpr`
91+ // should not be translated.
92+ exists ( NewOrNewArrayExpr new | expr = new .getAllocatorCall ( ) .getArgument ( 0 ) )
93+ or
8894 not translateFunction ( expr .getEnclosingFunction ( ) )
8995 or
9096 // We do not yet translate destructors properly, so for now we ignore the
Original file line number Diff line number Diff line change @@ -2862,3 +2862,29 @@ class TranslatedStmtExpr extends TranslatedNonConstantExpr {
28622862 result = getTranslatedStmt ( expr .getStmt ( ) )
28632863 }
28642864}
2865+
2866+ class TranslatedErrorExpr extends TranslatedSingleInstructionExpr {
2867+ override ErrorExpr expr ;
2868+
2869+ override final Instruction getFirstInstruction ( ) {
2870+ result = getInstruction ( OnlyInstructionTag ( ) )
2871+ }
2872+
2873+ override final TranslatedElement getChild ( int id ) { none ( ) }
2874+
2875+ override final Instruction getInstructionSuccessor ( InstructionTag tag , EdgeKind kind ) {
2876+ tag = OnlyInstructionTag ( ) and
2877+ result = getParent ( ) .getChildSuccessor ( this ) and
2878+ kind instanceof GotoEdge
2879+ }
2880+
2881+ override final Instruction getChildSuccessor ( TranslatedElement child ) { none ( ) }
2882+
2883+ override final Instruction getInstructionOperand ( InstructionTag tag , OperandTag operandTag ) {
2884+ none ( )
2885+ }
2886+
2887+ override final Opcode getOpcode ( ) {
2888+ result instanceof Opcode:: Error
2889+ }
2890+ }
Original file line number Diff line number Diff line change @@ -702,6 +702,22 @@ class FieldAddressInstruction extends FieldInstruction {
702702 }
703703}
704704
705+ /**
706+ * An instruction that produces a well-defined but unknown result and has
707+ * unknown side effects, including side effects that are not conservatively
708+ * modeled in the SSA graph.
709+ *
710+ * This type of instruction appears when there is an `ErrorExpr` in the AST,
711+ * meaning that the extractor could not understand the expression and therefore
712+ * produced a partial AST. Queries that give alerts when some action is _not_
713+ * taken may want to ignore any function that contains an `ErrorInstruction`.
714+ */
715+ class ErrorInstruction extends Instruction {
716+ ErrorInstruction ( ) {
717+ getOpcode ( ) instanceof Opcode:: Error
718+ }
719+ }
720+
705721class UninitializedInstruction extends VariableInstruction {
706722 UninitializedInstruction ( ) {
707723 getOpcode ( ) instanceof Opcode:: Uninitialized
Original file line number Diff line number Diff line change @@ -190,6 +190,34 @@ bad_asts.cpp:
190190# 27| Type = const Point &
191191# 27| ValueCategory = prvalue(load)
192192# 28| 1: return ...
193+ # 30| void Bad::errorExpr()
194+ # 30| params:
195+ # 30| body: { ... }
196+ # 31| 0: declaration
197+ # 31| 0: definition of intref
198+ # 31| Type = int &
199+ # 31| init: initializer for intref
200+ # 31| expr: <error expr>
201+ # 31| Type = error
202+ # 31| ValueCategory = prvalue
203+ # 32| 1: declaration
204+ # 32| 0: definition of x
205+ # 32| Type = int
206+ # 32| init: initializer for x
207+ # 32| expr: <error expr>
208+ # 32| Type = error
209+ # 32| ValueCategory = prvalue
210+ # 33| 2: ExprStmt
211+ # 33| 0: ... = ...
212+ # 33| Type = int
213+ # 33| ValueCategory = lvalue
214+ # 33| 0: x
215+ # 33| Type = int
216+ # 33| ValueCategory = lvalue
217+ #-----| 1: <error expr>
218+ #-----| Type = error
219+ #-----| ValueCategory = prvalue(load)
220+ # 34| 3: return ...
193221clang.cpp:
194222# 5| int* globalIntAddress()
195223# 5| params:
Original file line number Diff line number Diff line change 1- // semmle-extractor-options: -std=c++17
1+ // semmle-extractor-options: -std=c++17 --expect_errors
22
33// Test cases that illustrate known bad ASTs that we have to work around in IR generation.
44namespace Bad {
@@ -26,4 +26,10 @@ namespace Bad {
2626 void CallCopyConstructor (const Point& a) {
2727 Point b = a; // Copy constructor contains literal expressions with no values.
2828 }
29+
30+ void errorExpr () {
31+ int &intref = 0 ;
32+ int x = 0 [0 ];
33+ x = 1 [1 ];
34+ }
2935}
Original file line number Diff line number Diff line change @@ -48,6 +48,26 @@ bad_asts.cpp:
4848# 26| v0_13(void) = UnmodeledUse : mu*
4949# 26| v0_14(void) = ExitFunction :
5050
51+ # 30| void Bad::errorExpr()
52+ # 30| Block 0
53+ # 30| v0_0(void) = EnterFunction :
54+ # 30| mu0_1(unknown) = AliasedDefinition :
55+ # 30| mu0_2(unknown) = UnmodeledDefinition :
56+ # 31| r0_3(glval<int &>) = VariableAddress[intref] :
57+ # 31| r0_4(error) = Error :
58+ # 31| mu0_5(int &) = Store : &:r0_3, r0_4
59+ # 32| r0_6(glval<int>) = VariableAddress[x] :
60+ # 32| r0_7(error) = Error :
61+ # 32| mu0_8(int) = Store : &:r0_6, r0_7
62+ #-----| r0_9(glval<error>) = Error :
63+ #-----| r0_10(error) = Load : &:r0_9, ~mu0_2
64+ # 33| r0_11(glval<int>) = VariableAddress[x] :
65+ # 33| mu0_12(int) = Store : &:r0_11, r0_10
66+ # 34| v0_13(void) = NoOp :
67+ # 30| v0_14(void) = ReturnVoid :
68+ # 30| v0_15(void) = UnmodeledUse : mu*
69+ # 30| v0_16(void) = ExitFunction :
70+
5171clang.cpp:
5272# 5| int* globalIntAddress()
5373# 5| Block 0
You can’t perform that action at this time.
0 commit comments