C++: Handle C++17 switch initializers

This commit is contained in:
Jeroen Ketema
2022-04-29 16:18:25 +02:00
parent ebbd9c5b90
commit 71c019e126
11 changed files with 568 additions and 12 deletions

View File

@@ -679,6 +679,8 @@ private predicate namedStmtChildPredicates(Locatable s, Element e, string pred)
or
s.(IfStmt).getElse() = e and pred = "getElse()"
or
s.(SwitchStmt).getInitialization() = e and pred = "getInitialization()"
or
s.(SwitchStmt).getExpr() = e and pred = "getExpr()"
or
s.(SwitchStmt).getStmt() = e and pred = "getStmt()"

View File

@@ -708,30 +708,33 @@ private predicate straightLineSparse(Node scope, int i, Node ni, Spec spec) {
or
scope =
any(SwitchStmt s |
// SwitchStmt [-> init] -> expr
i = -1 and ni = s and spec.isAt()
or
i = 0 and ni = s.getExpr() and spec.isAround()
i = 0 and ni = s.getInitialization() and spec.isAround()
or
i = 1 and ni = s.getExpr() and spec.isAround()
or
// If the switch body is not a block then this step is skipped, and the
// expression jumps directly to the cases.
i = 1 and ni = s.getStmt().(BlockStmt) and spec.isAt()
i = 2 and ni = s.getStmt().(BlockStmt) and spec.isAt()
or
i = 2 and ni = s.getASwitchCase() and spec.isBefore()
i = 3 and ni = s.getASwitchCase() and spec.isBefore()
or
// If there is no default case, we can jump to after the block. Note: `i`
// is same value as above.
not s.getASwitchCase() instanceof DefaultCase and
i = 2 and
i = 3 and
ni = s.getStmt() and
spec.isAfter()
or
i = 3 and /* BARRIER */ ni = s and spec.isBarrier()
i = 4 and /* BARRIER */ ni = s and spec.isBarrier()
or
i = 4 and ni = s.getStmt() and spec.isAfter()
i = 5 and ni = s.getStmt() and spec.isAfter()
or
i = 5 and ni = s and spec.isAroundDestructors()
i = 6 and ni = s and spec.isAroundDestructors()
or
i = 6 and ni = s and spec.isAfter()
i = 7 and ni = s and spec.isAfter()
)
or
scope =

View File

@@ -717,14 +717,28 @@ class TranslatedSwitchStmt extends TranslatedStmt {
result = getTranslatedExpr(stmt.getExpr().getFullyConverted())
}
private Instruction getFirstExprInstruction() { result = getExpr().getFirstInstruction() }
private TranslatedStmt getBody() { result = getTranslatedStmt(stmt.getStmt()) }
override Instruction getFirstInstruction() { result = getExpr().getFirstInstruction() }
override Instruction getFirstInstruction() {
if hasInitialization()
then result = getInitialization().getFirstInstruction()
else result = getFirstExprInstruction()
}
override TranslatedElement getChild(int id) {
id = 0 and result = getExpr()
id = 0 and result = getInitialization()
or
id = 1 and result = getBody()
id = 1 and result = getExpr()
or
id = 2 and result = getBody()
}
private predicate hasInitialization() { exists(stmt.getInitialization()) }
private TranslatedStmt getInitialization() {
result = getTranslatedStmt(stmt.getInitialization())
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
@@ -754,6 +768,8 @@ class TranslatedSwitchStmt extends TranslatedStmt {
}
override Instruction getChildSuccessor(TranslatedElement child) {
child = getInitialization() and result = getFirstExprInstruction()
or
child = getExpr() and result = getInstruction(SwitchBranchTag())
or
child = getBody() and result = getParent().getChildSuccessor(this)

View File

@@ -1512,6 +1512,28 @@ class DefaultCase extends SwitchCase {
class SwitchStmt extends ConditionalStmt, @stmt_switch {
override string getAPrimaryQlClass() { result = "SwitchStmt" }
/**
* Gets the initialization statement of this 'switch' statement.
*
* For example, for
* ```
* switch (x = y; b) { }
* ```
* the result is `x = y;`.
*
* Does not hold if the initialization statement is missing or an empty statement, as in
* ```
* switch (b) { }
* ```
* or
* ```
* switch (; b) { }
* ```
*/
Stmt getInitialization() {
switch_initialization(underlyingElement(this), unresolveElement(result))
}
/**
* Gets the expression that this 'switch' statement switches on.
*
@@ -1527,7 +1549,7 @@ class SwitchStmt extends ConditionalStmt, @stmt_switch {
* ```
* the result is `i`.
*/
Expr getExpr() { result = this.getChild(0) }
Expr getExpr() { result = this.getChild(1) }
override Expr getControllingExpr() { result = this.getExpr() }

View File

@@ -1903,6 +1903,11 @@ do_body(
int body_id: @stmt ref
);
switch_initialization(
unique int switch_stmt: @stmt_switch ref,
int init_id: @stmt ref
);
#keyset[switch_stmt, index]
switch_case(
int switch_stmt: @stmt_switch ref,

View File

@@ -13776,6 +13776,205 @@ ir.cpp:
# 1781| Type = [IntType] int
# 1781| ValueCategory = prvalue(load)
# 1783| getStmt(8): [ReturnStmt] return ...
# 1785| [TopLevelFunction] void switch_initialization(int)
# 1785| <params>:
# 1785| getParameter(0): [Parameter] x
# 1785| Type = [IntType] int
# 1785| getEntryPoint(): [BlockStmt] { ... }
# 1786| getStmt(0): [SwitchStmt] switch (...) ...
# 1786| getInitialization(): [DeclStmt] declaration
# 1786| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y
# 1786| Type = [IntType] int
# 1786| getVariable().getInitializer(): [Initializer] initializer for y
# 1786| getExpr(): [VariableAccess] x
# 1786| Type = [IntType] int
# 1786| ValueCategory = prvalue(load)
# 1786| getExpr(): [AddExpr] ... + ...
# 1786| Type = [IntType] int
# 1786| ValueCategory = prvalue
# 1786| getLeftOperand(): [VariableAccess] x
# 1786| Type = [IntType] int
# 1786| ValueCategory = prvalue(load)
# 1786| getRightOperand(): [Literal] 1
# 1786| Type = [IntType] int
# 1786| Value = [Literal] 1
# 1786| ValueCategory = prvalue
# 1786| getStmt(): [BlockStmt] { ... }
# 1787| getStmt(0): [SwitchCase] default:
# 1788| getStmt(1): [ExprStmt] ExprStmt
# 1788| getExpr(): [AssignExpr] ... = ...
# 1788| Type = [IntType] int
# 1788| ValueCategory = lvalue
# 1788| getLValue(): [VariableAccess] x
# 1788| Type = [IntType] int
# 1788| ValueCategory = lvalue
# 1788| getRValue(): [AddExpr] ... + ...
# 1788| Type = [IntType] int
# 1788| ValueCategory = prvalue
# 1788| getLeftOperand(): [VariableAccess] x
# 1788| Type = [IntType] int
# 1788| ValueCategory = prvalue(load)
# 1788| getRightOperand(): [VariableAccess] y
# 1788| Type = [IntType] int
# 1788| ValueCategory = prvalue(load)
# 1791| getStmt(1): [DeclStmt] declaration
# 1791| getDeclarationEntry(0): [VariableDeclarationEntry] definition of w
# 1791| Type = [IntType] int
# 1792| getStmt(2): [SwitchStmt] switch (...) ...
# 1792| getInitialization(): [ExprStmt] ExprStmt
# 1792| getExpr(): [AssignExpr] ... = ...
# 1792| Type = [IntType] int
# 1792| ValueCategory = lvalue
# 1792| getLValue(): [VariableAccess] w
# 1792| Type = [IntType] int
# 1792| ValueCategory = lvalue
# 1792| getRValue(): [VariableAccess] x
# 1792| Type = [IntType] int
# 1792| ValueCategory = prvalue(load)
# 1792| getExpr(): [AddExpr] ... + ...
# 1792| Type = [IntType] int
# 1792| ValueCategory = prvalue
# 1792| getLeftOperand(): [VariableAccess] x
# 1792| Type = [IntType] int
# 1792| ValueCategory = prvalue(load)
# 1792| getRightOperand(): [Literal] 1
# 1792| Type = [IntType] int
# 1792| Value = [Literal] 1
# 1792| ValueCategory = prvalue
# 1792| getStmt(): [BlockStmt] { ... }
# 1793| getStmt(0): [SwitchCase] default:
# 1794| getStmt(1): [ExprStmt] ExprStmt
# 1794| getExpr(): [AssignExpr] ... = ...
# 1794| Type = [IntType] int
# 1794| ValueCategory = lvalue
# 1794| getLValue(): [VariableAccess] x
# 1794| Type = [IntType] int
# 1794| ValueCategory = lvalue
# 1794| getRValue(): [AddExpr] ... + ...
# 1794| Type = [IntType] int
# 1794| ValueCategory = prvalue
# 1794| getLeftOperand(): [VariableAccess] x
# 1794| Type = [IntType] int
# 1794| ValueCategory = prvalue(load)
# 1794| getRightOperand(): [VariableAccess] w
# 1794| Type = [IntType] int
# 1794| ValueCategory = prvalue(load)
# 1797| getStmt(3): [SwitchStmt] switch (...) ...
# 1797| getInitialization(): [ExprStmt] ExprStmt
# 1797| getExpr(): [AssignExpr] ... = ...
# 1797| Type = [IntType] int
# 1797| ValueCategory = lvalue
# 1797| getLValue(): [VariableAccess] w
# 1797| Type = [IntType] int
# 1797| ValueCategory = lvalue
# 1797| getRValue(): [VariableAccess] x
# 1797| Type = [IntType] int
# 1797| ValueCategory = prvalue(load)
# 1797| getExpr(): [ConditionDeclExpr] (condition decl)
# 1797| Type = [IntType] int
# 1797| ValueCategory = prvalue
# 1797| getVariableAccess(): [VariableAccess] w2
# 1797| Type = [IntType] int
# 1797| ValueCategory = prvalue(load)
# 1797| getStmt(): [BlockStmt] { ... }
# 1798| getStmt(0): [SwitchCase] default:
# 1799| getStmt(1): [ExprStmt] ExprStmt
# 1799| getExpr(): [AssignExpr] ... = ...
# 1799| Type = [IntType] int
# 1799| ValueCategory = lvalue
# 1799| getLValue(): [VariableAccess] x
# 1799| Type = [IntType] int
# 1799| ValueCategory = lvalue
# 1799| getRValue(): [AddExpr] ... + ...
# 1799| Type = [IntType] int
# 1799| ValueCategory = prvalue
# 1799| getLeftOperand(): [VariableAccess] x
# 1799| Type = [IntType] int
# 1799| ValueCategory = prvalue(load)
# 1799| getRightOperand(): [VariableAccess] w
# 1799| Type = [IntType] int
# 1799| ValueCategory = prvalue(load)
# 1802| getStmt(4): [SwitchStmt] switch (...) ...
# 1802| getInitialization(): [DeclStmt] declaration
# 1802| getDeclarationEntry(0): [VariableDeclarationEntry] definition of v
# 1802| Type = [IntType] int
# 1802| getVariable().getInitializer(): [Initializer] initializer for v
# 1802| getExpr(): [VariableAccess] x
# 1802| Type = [IntType] int
# 1802| ValueCategory = prvalue(load)
# 1802| getExpr(): [ConditionDeclExpr] (condition decl)
# 1802| Type = [IntType] int
# 1802| ValueCategory = prvalue
# 1802| getVariableAccess(): [VariableAccess] v2
# 1802| Type = [IntType] int
# 1802| ValueCategory = prvalue(load)
# 1802| getStmt(): [BlockStmt] { ... }
# 1803| getStmt(0): [SwitchCase] default:
# 1804| getStmt(1): [ExprStmt] ExprStmt
# 1804| getExpr(): [AssignExpr] ... = ...
# 1804| Type = [IntType] int
# 1804| ValueCategory = lvalue
# 1804| getLValue(): [VariableAccess] x
# 1804| Type = [IntType] int
# 1804| ValueCategory = lvalue
# 1804| getRValue(): [AddExpr] ... + ...
# 1804| Type = [IntType] int
# 1804| ValueCategory = prvalue
# 1804| getLeftOperand(): [VariableAccess] x
# 1804| Type = [IntType] int
# 1804| ValueCategory = prvalue(load)
# 1804| getRightOperand(): [VariableAccess] v
# 1804| Type = [IntType] int
# 1804| ValueCategory = prvalue(load)
# 1807| getStmt(5): [DeclStmt] declaration
# 1807| getDeclarationEntry(0): [VariableDeclarationEntry] definition of z
# 1807| Type = [IntType] int
# 1807| getVariable().getInitializer(): [Initializer] initializer for z
# 1807| getExpr(): [VariableAccess] x
# 1807| Type = [IntType] int
# 1807| ValueCategory = prvalue(load)
# 1808| getStmt(6): [SwitchStmt] switch (...) ...
# 1808| getExpr(): [VariableAccess] z
# 1808| Type = [IntType] int
# 1808| ValueCategory = prvalue(load)
# 1808| getStmt(): [BlockStmt] { ... }
# 1809| getStmt(0): [SwitchCase] default:
# 1810| getStmt(1): [ExprStmt] ExprStmt
# 1810| getExpr(): [AssignExpr] ... = ...
# 1810| Type = [IntType] int
# 1810| ValueCategory = lvalue
# 1810| getLValue(): [VariableAccess] x
# 1810| Type = [IntType] int
# 1810| ValueCategory = lvalue
# 1810| getRValue(): [AddExpr] ... + ...
# 1810| Type = [IntType] int
# 1810| ValueCategory = prvalue
# 1810| getLeftOperand(): [VariableAccess] x
# 1810| Type = [IntType] int
# 1810| ValueCategory = prvalue(load)
# 1810| getRightOperand(): [VariableAccess] z
# 1810| Type = [IntType] int
# 1810| ValueCategory = prvalue(load)
# 1813| getStmt(7): [SwitchStmt] switch (...) ...
# 1813| getExpr(): [ConditionDeclExpr] (condition decl)
# 1813| Type = [IntType] int
# 1813| ValueCategory = prvalue
# 1813| getVariableAccess(): [VariableAccess] z2
# 1813| Type = [IntType] int
# 1813| ValueCategory = prvalue(load)
# 1813| getStmt(): [BlockStmt] { ... }
# 1814| getStmt(0): [SwitchCase] default:
# 1815| getStmt(1): [ExprStmt] ExprStmt
# 1815| getExpr(): [AssignAddExpr] ... += ...
# 1815| Type = [IntType] int
# 1815| ValueCategory = lvalue
# 1815| getLValue(): [VariableAccess] x
# 1815| Type = [IntType] int
# 1815| ValueCategory = lvalue
# 1815| getRValue(): [VariableAccess] z2
# 1815| Type = [IntType] int
# 1815| ValueCategory = prvalue(load)
# 1817| getStmt(8): [ReturnStmt] return ...
perf-regression.cpp:
# 4| [CopyAssignmentOperator] Big& Big::operator=(Big const&)
# 4| <params>:

View File

@@ -1782,4 +1782,38 @@ void if_initialization(int x) {
}
}
void switch_initialization(int x) {
switch (int y = x; x + 1) {
default:
x = x + y;
}
int w;
switch (w = x; x + 1) {
default:
x = x + w;
}
switch (w = x; int w2 = w) {
default:
x = x + w;
}
switch (int v = x; int v2 = v) {
default:
x = x + v;
}
int z = x;
switch (z) {
default:
x = x + z;
}
switch (int z2 = z) {
default:
x += z2;
}
}
// semmle-extractor-options: -std=c++17 --clang

View File

@@ -8347,6 +8347,116 @@
| ir.cpp:1781:14:1781:15 | Address | &:r1781_1 |
| ir.cpp:1781:14:1781:15 | Load | m1780_5 |
| ir.cpp:1781:14:1781:15 | Right | r1781_2 |
| ir.cpp:1785:6:1785:26 | ChiPartial | partial:m1785_3 |
| ir.cpp:1785:6:1785:26 | ChiTotal | total:m1785_2 |
| ir.cpp:1785:6:1785:26 | SideEffect | m1785_3 |
| ir.cpp:1785:32:1785:32 | Address | &:r1785_5 |
| ir.cpp:1786:17:1786:17 | Address | &:r1786_1 |
| ir.cpp:1786:21:1786:21 | Address | &:r1786_2 |
| ir.cpp:1786:21:1786:21 | Load | m1785_6 |
| ir.cpp:1786:21:1786:21 | StoreValue | r1786_3 |
| ir.cpp:1786:24:1786:24 | Address | &:r1786_5 |
| ir.cpp:1786:24:1786:24 | Left | r1786_6 |
| ir.cpp:1786:24:1786:24 | Load | m1785_6 |
| ir.cpp:1786:24:1786:28 | Condition | r1786_8 |
| ir.cpp:1786:28:1786:28 | Right | r1786_7 |
| ir.cpp:1788:9:1788:9 | Address | &:r1788_6 |
| ir.cpp:1788:13:1788:13 | Address | &:r1788_1 |
| ir.cpp:1788:13:1788:13 | Left | r1788_2 |
| ir.cpp:1788:13:1788:13 | Load | m1785_6 |
| ir.cpp:1788:13:1788:17 | StoreValue | r1788_5 |
| ir.cpp:1788:17:1788:17 | Address | &:r1788_3 |
| ir.cpp:1788:17:1788:17 | Load | m1786_4 |
| ir.cpp:1788:17:1788:17 | Right | r1788_4 |
| ir.cpp:1791:9:1791:9 | Address | &:r1791_1 |
| ir.cpp:1792:13:1792:13 | Address | &:r1792_3 |
| ir.cpp:1792:17:1792:17 | Address | &:r1792_1 |
| ir.cpp:1792:17:1792:17 | Load | m1788_7 |
| ir.cpp:1792:17:1792:17 | StoreValue | r1792_2 |
| ir.cpp:1792:20:1792:20 | Address | &:r1792_5 |
| ir.cpp:1792:20:1792:20 | Left | r1792_6 |
| ir.cpp:1792:20:1792:20 | Load | m1788_7 |
| ir.cpp:1792:20:1792:24 | Condition | r1792_8 |
| ir.cpp:1792:24:1792:24 | Right | r1792_7 |
| ir.cpp:1794:9:1794:9 | Address | &:r1794_6 |
| ir.cpp:1794:13:1794:13 | Address | &:r1794_1 |
| ir.cpp:1794:13:1794:13 | Left | r1794_2 |
| ir.cpp:1794:13:1794:13 | Load | m1788_7 |
| ir.cpp:1794:13:1794:17 | StoreValue | r1794_5 |
| ir.cpp:1794:17:1794:17 | Address | &:r1794_3 |
| ir.cpp:1794:17:1794:17 | Load | m1792_4 |
| ir.cpp:1794:17:1794:17 | Right | r1794_4 |
| ir.cpp:1797:13:1797:13 | Address | &:r1797_3 |
| ir.cpp:1797:17:1797:17 | Address | &:r1797_1 |
| ir.cpp:1797:17:1797:17 | Load | m1794_7 |
| ir.cpp:1797:17:1797:17 | StoreValue | r1797_2 |
| ir.cpp:1797:18:1797:29 | Address | &:r1797_5 |
| ir.cpp:1797:18:1797:29 | Condition | r1797_11 |
| ir.cpp:1797:24:1797:25 | Address | &:r1797_9 |
| ir.cpp:1797:24:1797:25 | Load | m1797_8 |
| ir.cpp:1797:24:1797:25 | Unary | r1797_10 |
| ir.cpp:1797:29:1797:29 | Address | &:r1797_6 |
| ir.cpp:1797:29:1797:29 | Load | m1797_4 |
| ir.cpp:1797:29:1797:29 | StoreValue | r1797_7 |
| ir.cpp:1799:9:1799:9 | Address | &:r1799_6 |
| ir.cpp:1799:13:1799:13 | Address | &:r1799_1 |
| ir.cpp:1799:13:1799:13 | Left | r1799_2 |
| ir.cpp:1799:13:1799:13 | Load | m1794_7 |
| ir.cpp:1799:13:1799:17 | StoreValue | r1799_5 |
| ir.cpp:1799:17:1799:17 | Address | &:r1799_3 |
| ir.cpp:1799:17:1799:17 | Load | m1797_4 |
| ir.cpp:1799:17:1799:17 | Right | r1799_4 |
| ir.cpp:1802:13:1802:33 | Address | &:r1802_5 |
| ir.cpp:1802:13:1802:33 | Condition | r1802_11 |
| ir.cpp:1802:17:1802:17 | Address | &:r1802_1 |
| ir.cpp:1802:21:1802:21 | Address | &:r1802_2 |
| ir.cpp:1802:21:1802:21 | Load | m1799_7 |
| ir.cpp:1802:21:1802:21 | StoreValue | r1802_3 |
| ir.cpp:1802:28:1802:29 | Address | &:r1802_9 |
| ir.cpp:1802:28:1802:29 | Load | m1802_8 |
| ir.cpp:1802:28:1802:29 | Unary | r1802_10 |
| ir.cpp:1802:33:1802:33 | Address | &:r1802_6 |
| ir.cpp:1802:33:1802:33 | Load | m1802_4 |
| ir.cpp:1802:33:1802:33 | StoreValue | r1802_7 |
| ir.cpp:1804:9:1804:9 | Address | &:r1804_6 |
| ir.cpp:1804:13:1804:13 | Address | &:r1804_1 |
| ir.cpp:1804:13:1804:13 | Left | r1804_2 |
| ir.cpp:1804:13:1804:13 | Load | m1799_7 |
| ir.cpp:1804:13:1804:17 | StoreValue | r1804_5 |
| ir.cpp:1804:17:1804:17 | Address | &:r1804_3 |
| ir.cpp:1804:17:1804:17 | Load | m1802_4 |
| ir.cpp:1804:17:1804:17 | Right | r1804_4 |
| ir.cpp:1807:9:1807:9 | Address | &:r1807_1 |
| ir.cpp:1807:13:1807:13 | Address | &:r1807_2 |
| ir.cpp:1807:13:1807:13 | Load | m1804_7 |
| ir.cpp:1807:13:1807:13 | StoreValue | r1807_3 |
| ir.cpp:1808:13:1808:13 | Address | &:r1808_1 |
| ir.cpp:1808:13:1808:13 | Condition | r1808_2 |
| ir.cpp:1808:13:1808:13 | Load | m1807_4 |
| ir.cpp:1810:9:1810:9 | Address | &:r1810_6 |
| ir.cpp:1810:13:1810:13 | Address | &:r1810_1 |
| ir.cpp:1810:13:1810:13 | Left | r1810_2 |
| ir.cpp:1810:13:1810:13 | Load | m1804_7 |
| ir.cpp:1810:13:1810:17 | StoreValue | r1810_5 |
| ir.cpp:1810:17:1810:17 | Address | &:r1810_3 |
| ir.cpp:1810:17:1810:17 | Load | m1807_4 |
| ir.cpp:1810:17:1810:17 | Right | r1810_4 |
| ir.cpp:1813:13:1813:22 | Address | &:r1813_1 |
| ir.cpp:1813:13:1813:22 | Condition | r1813_7 |
| ir.cpp:1813:17:1813:18 | Address | &:r1813_5 |
| ir.cpp:1813:17:1813:18 | Load | m1813_4 |
| ir.cpp:1813:17:1813:18 | Unary | r1813_6 |
| ir.cpp:1813:22:1813:22 | Address | &:r1813_2 |
| ir.cpp:1813:22:1813:22 | Load | m1807_4 |
| ir.cpp:1813:22:1813:22 | StoreValue | r1813_3 |
| ir.cpp:1815:9:1815:9 | Address | &:r1815_3 |
| ir.cpp:1815:9:1815:9 | Address | &:r1815_3 |
| ir.cpp:1815:9:1815:9 | Left | r1815_4 |
| ir.cpp:1815:9:1815:9 | Load | m1810_7 |
| ir.cpp:1815:9:1815:15 | StoreValue | r1815_5 |
| ir.cpp:1815:14:1815:15 | Address | &:r1815_1 |
| ir.cpp:1815:14:1815:15 | Load | m1813_4 |
| ir.cpp:1815:14:1815:15 | Right | r1815_2 |
| perf-regression.cpp:6:3:6:5 | Address | &:r6_5 |
| perf-regression.cpp:6:3:6:5 | Address | &:r6_5 |
| perf-regression.cpp:6:3:6:5 | Address | &:r6_7 |

View File

@@ -9584,6 +9584,142 @@ ir.cpp:
# 1757| v1757_7(void) = AliasedUse : ~m?
# 1757| v1757_8(void) = ExitFunction :
# 1785| void switch_initialization(int)
# 1785| Block 0
# 1785| v1785_1(void) = EnterFunction :
# 1785| mu1785_2(unknown) = AliasedDefinition :
# 1785| mu1785_3(unknown) = InitializeNonLocal :
# 1785| r1785_4(glval<int>) = VariableAddress[x] :
# 1785| mu1785_5(int) = InitializeParameter[x] : &:r1785_4
# 1786| r1786_1(glval<int>) = VariableAddress[y] :
# 1786| r1786_2(glval<int>) = VariableAddress[x] :
# 1786| r1786_3(int) = Load[x] : &:r1786_2, ~m?
# 1786| mu1786_4(int) = Store[y] : &:r1786_1, r1786_3
# 1786| r1786_5(glval<int>) = VariableAddress[x] :
# 1786| r1786_6(int) = Load[x] : &:r1786_5, ~m?
# 1786| r1786_7(int) = Constant[1] :
# 1786| r1786_8(int) = Add : r1786_6, r1786_7
# 1786| v1786_9(void) = Switch : r1786_8
#-----| Default -> Block 1
# 1787| Block 1
# 1787| v1787_1(void) = NoOp :
# 1788| r1788_1(glval<int>) = VariableAddress[x] :
# 1788| r1788_2(int) = Load[x] : &:r1788_1, ~m?
# 1788| r1788_3(glval<int>) = VariableAddress[y] :
# 1788| r1788_4(int) = Load[y] : &:r1788_3, ~m?
# 1788| r1788_5(int) = Add : r1788_2, r1788_4
# 1788| r1788_6(glval<int>) = VariableAddress[x] :
# 1788| mu1788_7(int) = Store[x] : &:r1788_6, r1788_5
# 1791| r1791_1(glval<int>) = VariableAddress[w] :
# 1791| mu1791_2(int) = Uninitialized[w] : &:r1791_1
# 1792| r1792_1(glval<int>) = VariableAddress[x] :
# 1792| r1792_2(int) = Load[x] : &:r1792_1, ~m?
# 1792| r1792_3(glval<int>) = VariableAddress[w] :
# 1792| mu1792_4(int) = Store[w] : &:r1792_3, r1792_2
# 1792| r1792_5(glval<int>) = VariableAddress[x] :
# 1792| r1792_6(int) = Load[x] : &:r1792_5, ~m?
# 1792| r1792_7(int) = Constant[1] :
# 1792| r1792_8(int) = Add : r1792_6, r1792_7
# 1792| v1792_9(void) = Switch : r1792_8
#-----| Default -> Block 2
# 1793| Block 2
# 1793| v1793_1(void) = NoOp :
# 1794| r1794_1(glval<int>) = VariableAddress[x] :
# 1794| r1794_2(int) = Load[x] : &:r1794_1, ~m?
# 1794| r1794_3(glval<int>) = VariableAddress[w] :
# 1794| r1794_4(int) = Load[w] : &:r1794_3, ~m?
# 1794| r1794_5(int) = Add : r1794_2, r1794_4
# 1794| r1794_6(glval<int>) = VariableAddress[x] :
# 1794| mu1794_7(int) = Store[x] : &:r1794_6, r1794_5
# 1797| r1797_1(glval<int>) = VariableAddress[x] :
# 1797| r1797_2(int) = Load[x] : &:r1797_1, ~m?
# 1797| r1797_3(glval<int>) = VariableAddress[w] :
# 1797| mu1797_4(int) = Store[w] : &:r1797_3, r1797_2
# 1797| r1797_5(glval<int>) = VariableAddress[w2] :
# 1797| r1797_6(glval<int>) = VariableAddress[w] :
# 1797| r1797_7(int) = Load[w] : &:r1797_6, ~m?
# 1797| mu1797_8(int) = Store[w2] : &:r1797_5, r1797_7
# 1797| r1797_9(glval<int>) = VariableAddress[w2] :
# 1797| r1797_10(int) = Load[w2] : &:r1797_9, ~m?
# 1797| r1797_11(int) = CopyValue : r1797_10
# 1797| v1797_12(void) = Switch : r1797_11
#-----| Default -> Block 3
# 1798| Block 3
# 1798| v1798_1(void) = NoOp :
# 1799| r1799_1(glval<int>) = VariableAddress[x] :
# 1799| r1799_2(int) = Load[x] : &:r1799_1, ~m?
# 1799| r1799_3(glval<int>) = VariableAddress[w] :
# 1799| r1799_4(int) = Load[w] : &:r1799_3, ~m?
# 1799| r1799_5(int) = Add : r1799_2, r1799_4
# 1799| r1799_6(glval<int>) = VariableAddress[x] :
# 1799| mu1799_7(int) = Store[x] : &:r1799_6, r1799_5
# 1802| r1802_1(glval<int>) = VariableAddress[v] :
# 1802| r1802_2(glval<int>) = VariableAddress[x] :
# 1802| r1802_3(int) = Load[x] : &:r1802_2, ~m?
# 1802| mu1802_4(int) = Store[v] : &:r1802_1, r1802_3
# 1802| r1802_5(glval<int>) = VariableAddress[v2] :
# 1802| r1802_6(glval<int>) = VariableAddress[v] :
# 1802| r1802_7(int) = Load[v] : &:r1802_6, ~m?
# 1802| mu1802_8(int) = Store[v2] : &:r1802_5, r1802_7
# 1802| r1802_9(glval<int>) = VariableAddress[v2] :
# 1802| r1802_10(int) = Load[v2] : &:r1802_9, ~m?
# 1802| r1802_11(int) = CopyValue : r1802_10
# 1802| v1802_12(void) = Switch : r1802_11
#-----| Default -> Block 4
# 1803| Block 4
# 1803| v1803_1(void) = NoOp :
# 1804| r1804_1(glval<int>) = VariableAddress[x] :
# 1804| r1804_2(int) = Load[x] : &:r1804_1, ~m?
# 1804| r1804_3(glval<int>) = VariableAddress[v] :
# 1804| r1804_4(int) = Load[v] : &:r1804_3, ~m?
# 1804| r1804_5(int) = Add : r1804_2, r1804_4
# 1804| r1804_6(glval<int>) = VariableAddress[x] :
# 1804| mu1804_7(int) = Store[x] : &:r1804_6, r1804_5
# 1807| r1807_1(glval<int>) = VariableAddress[z] :
# 1807| r1807_2(glval<int>) = VariableAddress[x] :
# 1807| r1807_3(int) = Load[x] : &:r1807_2, ~m?
# 1807| mu1807_4(int) = Store[z] : &:r1807_1, r1807_3
# 1808| r1808_1(glval<int>) = VariableAddress[z] :
# 1808| r1808_2(int) = Load[z] : &:r1808_1, ~m?
# 1808| v1808_3(void) = Switch : r1808_2
#-----| Default -> Block 5
# 1809| Block 5
# 1809| v1809_1(void) = NoOp :
# 1810| r1810_1(glval<int>) = VariableAddress[x] :
# 1810| r1810_2(int) = Load[x] : &:r1810_1, ~m?
# 1810| r1810_3(glval<int>) = VariableAddress[z] :
# 1810| r1810_4(int) = Load[z] : &:r1810_3, ~m?
# 1810| r1810_5(int) = Add : r1810_2, r1810_4
# 1810| r1810_6(glval<int>) = VariableAddress[x] :
# 1810| mu1810_7(int) = Store[x] : &:r1810_6, r1810_5
# 1813| r1813_1(glval<int>) = VariableAddress[z2] :
# 1813| r1813_2(glval<int>) = VariableAddress[z] :
# 1813| r1813_3(int) = Load[z] : &:r1813_2, ~m?
# 1813| mu1813_4(int) = Store[z2] : &:r1813_1, r1813_3
# 1813| r1813_5(glval<int>) = VariableAddress[z2] :
# 1813| r1813_6(int) = Load[z2] : &:r1813_5, ~m?
# 1813| r1813_7(int) = CopyValue : r1813_6
# 1813| v1813_8(void) = Switch : r1813_7
#-----| Default -> Block 6
# 1814| Block 6
# 1814| v1814_1(void) = NoOp :
# 1815| r1815_1(glval<int>) = VariableAddress[z2] :
# 1815| r1815_2(int) = Load[z2] : &:r1815_1, ~m?
# 1815| r1815_3(glval<int>) = VariableAddress[x] :
# 1815| r1815_4(int) = Load[x] : &:r1815_3, ~m?
# 1815| r1815_5(int) = Add : r1815_4, r1815_2
# 1815| mu1815_6(int) = Store[x] : &:r1815_3, r1815_5
# 1817| v1817_1(void) = NoOp :
# 1785| v1785_6(void) = ReturnVoid :
# 1785| v1785_7(void) = AliasedUse : ~m?
# 1785| v1785_8(void) = ExitFunction :
perf-regression.cpp:
# 6| void Big::Big()
# 6| Block 0

View File

@@ -12,3 +12,20 @@
| switchstmt | switchstmt.c:1:6:1:6 | f | 7 | 8 | switchstmt.c:7:5:7:5 | switchstmt.c:7:5:7:5 | switchstmt.c:7:5:7:5 | ; | 8: return ... |
| switchstmt | switchstmt.c:1:6:1:6 | f | 8 | 9 | switchstmt.c:8:1:8:1 | switchstmt.c:8:1:8:1 | switchstmt.c:8:1:8:1 | return ... | 8: f |
| switchstmt | switchstmt.c:1:6:1:6 | f | 8 | 10 | switchstmt.c:1:6:1:6 | switchstmt.c:1:6:1:6 | switchstmt.c:1:6:1:6 | f | <none> |
| switchstmt | switchstmt.cpp:3:6:3:6 | g | 3 | 1 | switchstmt.cpp:3:15:12:1 | switchstmt.cpp:3:15:12:1 | switchstmt.cpp:3:15:12:1 | { ... } | 4: switch (...) ... |
| switchstmt | switchstmt.cpp:3:6:3:6 | g | 4 | 2 | switchstmt.cpp:4:6:10:5 | switchstmt.cpp:4:6:10:5 | switchstmt.cpp:4:6:10:5 | switch (...) ... | 5: declaration |
| switchstmt | switchstmt.cpp:3:6:3:6 | g | 5 | 3 | switchstmt.cpp:5:10:5:10 | switchstmt.cpp:5:10:5:10 | switchstmt.cpp:5:10:5:10 | declaration | 5: initializer for y |
| switchstmt | switchstmt.cpp:3:6:3:6 | g | 5 | 4 | switchstmt.cpp:5:17:5:18 | switchstmt.cpp:5:17:5:18 | switchstmt.cpp:5:17:5:18 | initializer for y | 5: x |
| switchstmt | switchstmt.cpp:3:6:3:6 | g | 5 | 5 | switchstmt.cpp:5:18:5:18 | switchstmt.cpp:5:18:5:18 | switchstmt.cpp:5:18:5:18 | x | 6: y |
| switchstmt | switchstmt.cpp:3:6:3:6 | g | 6 | 6 | switchstmt.cpp:6:10:6:10 | switchstmt.cpp:6:10:6:10 | switchstmt.cpp:6:10:6:10 | y | 6: { ... } |
| switchstmt | switchstmt.cpp:3:6:3:6 | g | 6 | 7 | switchstmt.cpp:6:13:10:5 | switchstmt.cpp:6:13:10:5 | switchstmt.cpp:6:13:10:5 | { ... } | 7: case ...: |
| switchstmt | switchstmt.cpp:3:6:3:6 | g | 6 | 7 | switchstmt.cpp:6:13:10:5 | switchstmt.cpp:6:13:10:5 | switchstmt.cpp:6:13:10:5 | { ... } | 8: case ...: |
| switchstmt | switchstmt.cpp:3:6:3:6 | g | 6 | 7 | switchstmt.cpp:6:13:10:5 | switchstmt.cpp:6:13:10:5 | switchstmt.cpp:6:13:10:5 | { ... } | 9: default: |
| switchstmt | switchstmt.cpp:3:6:3:6 | g | 7 | 1 | switchstmt.cpp:7:14:7:14 | switchstmt.cpp:7:14:7:14 | switchstmt.cpp:7:14:7:14 | 1 | <none> |
| switchstmt | switchstmt.cpp:3:6:3:6 | g | 7 | 8 | switchstmt.cpp:7:9:7:15 | switchstmt.cpp:7:9:7:15 | switchstmt.cpp:7:9:7:15 | case ...: | 8: case ...: |
| switchstmt | switchstmt.cpp:3:6:3:6 | g | 8 | 1 | switchstmt.cpp:8:14:8:14 | switchstmt.cpp:8:14:8:14 | switchstmt.cpp:8:14:8:14 | 2 | <none> |
| switchstmt | switchstmt.cpp:3:6:3:6 | g | 8 | 9 | switchstmt.cpp:8:9:8:15 | switchstmt.cpp:8:9:8:15 | switchstmt.cpp:8:9:8:15 | case ...: | 9: default: |
| switchstmt | switchstmt.cpp:3:6:3:6 | g | 9 | 10 | switchstmt.cpp:9:9:9:16 | switchstmt.cpp:9:9:9:16 | switchstmt.cpp:9:9:9:16 | default: | 11: ; |
| switchstmt | switchstmt.cpp:3:6:3:6 | g | 11 | 11 | switchstmt.cpp:11:5:11:5 | switchstmt.cpp:11:5:11:5 | switchstmt.cpp:11:5:11:5 | ; | 12: return ... |
| switchstmt | switchstmt.cpp:3:6:3:6 | g | 12 | 12 | switchstmt.cpp:12:1:12:1 | switchstmt.cpp:12:1:12:1 | switchstmt.cpp:12:1:12:1 | return ... | 12: g |
| switchstmt | switchstmt.cpp:3:6:3:6 | g | 12 | 13 | switchstmt.cpp:3:6:3:6 | switchstmt.cpp:3:6:3:6 | switchstmt.cpp:3:6:3:6 | g | <none> |

View File

@@ -0,0 +1,12 @@
// semmle-extractor-options: -std=c++17
void g(int x) {
switch (
int y = x;
y) {
case 1:
case 2:
default:
}
;
}