Skip to content

Commit d8222bb

Browse files
author
openharmony_ci
committed
!1050 merge fix-1030 into master
fix: 修复 switch 的 default 不在最后时,case 跳到错误的子句(#1030) Created-by: GuoLan_Fruket Commit-by: GuoLan Merged-by: openharmony_ci Description: ### 一、内容说明(相关的Issue) 把默认default在最后的写法换成了通过defaultBlock找到defaultIndex,兼容了default不在最后的情况。 See merge request: openharmony-sig/arkanalyzer!1050
2 parents 4675d63 + 9e9779b commit d8222bb

5 files changed

Lines changed: 169 additions & 2 deletions

File tree

‎src/core/graph/builder/SwitchBuilder.ts‎

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,17 @@ export class SwitchBuilder {
123123
const expectedSuccessorsOfCaseIfBlock: BasicBlock[] = [];
124124
const defaultStmtBuilder = switchStmtBuilder.default;
125125
if (defaultStmtBuilder && defaultStmtBuilder.block) {
126-
expectedSuccessorsOfCaseIfBlock.push(...successorsOfBlockContainSwitch.splice(-1, 1));
126+
// default may appear before later cases; identify by block identity, not list position
127+
if (!blockBuilderToCfgBlock.has(defaultStmtBuilder.block)) {
128+
logger.error(`can't find basicBlock corresponding to the default blockBuilder.`);
129+
return false;
130+
}
131+
const defaultBasicBlock = blockBuilderToCfgBlock.get(defaultStmtBuilder.block)!;
132+
const defaultIndex = successorsOfBlockContainSwitch.indexOf(defaultBasicBlock);
133+
if (defaultIndex !== -1) {
134+
successorsOfBlockContainSwitch.splice(defaultIndex, 1);
135+
}
136+
expectedSuccessorsOfCaseIfBlock.push(defaultBasicBlock);
127137
} else {
128138
const afterSwitchStmtBuilder = switchStmtBuilder.afterSwitch;
129139
const afterSwitchBlockBuilder = afterSwitchStmtBuilder?.block;

‎src/frontend/cppFrontend/graph/builder/SwitchBuilder.ts‎

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,17 @@ export class CxxSwitchBuilder {
123123
const expectedSuccessorsOfCaseIfBlock: BasicBlock[] = [];
124124
const defaultStmtBuilder = switchStmtBuilder.default;
125125
if (defaultStmtBuilder && defaultStmtBuilder.block) {
126-
expectedSuccessorsOfCaseIfBlock.push(...successorsOfBlockContainSwitch.splice(-1, 1));
126+
// default may appear before later cases; identify by block identity, not list position
127+
if (!blockBuilderToCfgBlock.has(defaultStmtBuilder.block)) {
128+
logger.error(`can't find basicBlock corresponding to the default blockBuilder.`);
129+
return false;
130+
}
131+
const defaultBasicBlock = blockBuilderToCfgBlock.get(defaultStmtBuilder.block)!;
132+
const defaultIndex = successorsOfBlockContainSwitch.indexOf(defaultBasicBlock);
133+
if (defaultIndex !== -1) {
134+
successorsOfBlockContainSwitch.splice(defaultIndex, 1);
135+
}
136+
expectedSuccessorsOfCaseIfBlock.push(defaultBasicBlock);
127137
} else {
128138
const afterSwitchStmtBuilder = switchStmtBuilder.afterSwitch;
129139
const afterSwitchBlockBuilder = afterSwitchStmtBuilder?.block;

‎tests/resources/cfg/switch/SwitchExpect.ts‎

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -930,4 +930,116 @@ export const SWITCH_EXPECT_CASE17 = {
930930
succes: [3],
931931
},
932932
],
933+
};
934+
935+
export const SWITCH_EXPECT_CASE18 = {
936+
blocks: [
937+
{
938+
id: 0,
939+
stmts: [
940+
'this = this: @switch/SwitchSample.ts: %dflt',
941+
'a = 0',
942+
'b = 1',
943+
'if a == 1',
944+
],
945+
preds: [],
946+
succes: [1, 5],
947+
},
948+
{
949+
id: 1,
950+
stmts: [
951+
'b = 11',
952+
],
953+
preds: [0],
954+
succes: [4],
955+
},
956+
{
957+
id: 2,
958+
stmts: [
959+
'b = 99',
960+
],
961+
preds: [5],
962+
succes: [4],
963+
},
964+
{
965+
id: 3,
966+
stmts: [
967+
'b = 22',
968+
],
969+
preds: [5],
970+
succes: [4],
971+
},
972+
{
973+
id: 4,
974+
stmts: [
975+
'return',
976+
],
977+
preds: [1, 2, 3],
978+
succes: [],
979+
},
980+
{
981+
id: 5,
982+
stmts: [
983+
'if a == 2',
984+
],
985+
preds: [0],
986+
succes: [3, 2],
987+
},
988+
],
989+
};
990+
991+
export const SWITCH_EXPECT_CASE19 = {
992+
blocks: [
993+
{
994+
id: 0,
995+
stmts: [
996+
'this = this: @switch/SwitchSample.ts: %dflt',
997+
'a = 0',
998+
'b = 1',
999+
'if a == 1',
1000+
],
1001+
preds: [],
1002+
succes: [1, 5],
1003+
},
1004+
{
1005+
id: 1,
1006+
stmts: [
1007+
'b = 11',
1008+
],
1009+
preds: [0],
1010+
succes: [2],
1011+
},
1012+
{
1013+
id: 2,
1014+
stmts: [
1015+
'b = 99',
1016+
],
1017+
preds: [1, 5],
1018+
succes: [4],
1019+
},
1020+
{
1021+
id: 3,
1022+
stmts: [
1023+
'b = 22',
1024+
],
1025+
preds: [5],
1026+
succes: [4],
1027+
},
1028+
{
1029+
id: 4,
1030+
stmts: [
1031+
'return',
1032+
],
1033+
preds: [2, 3],
1034+
succes: [],
1035+
},
1036+
{
1037+
id: 5,
1038+
stmts: [
1039+
'if a == 2',
1040+
],
1041+
preds: [0],
1042+
succes: [3, 2],
1043+
},
1044+
],
9331045
};

‎tests/resources/cfg/switch/SwitchSample.ts‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,4 +233,35 @@ function case17(): void {
233233
b = 3;
234234
break;
235235
}
236+
}
237+
238+
function case18(): void {
239+
let a = 0;
240+
let b = 1;
241+
switch (a) {
242+
case 1:
243+
b = 11;
244+
break;
245+
default:
246+
b = 99;
247+
break;
248+
case 2:
249+
b = 22;
250+
break;
251+
}
252+
}
253+
254+
function case19(): void {
255+
let a = 0;
256+
let b = 1;
257+
switch (a) {
258+
case 1:
259+
b = 11;
260+
default:
261+
b = 99;
262+
break;
263+
case 2:
264+
b = 22;
265+
break;
266+
}
236267
}

‎tests/unit/core/graph/Cfg.test.ts‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ import {
4949
SWITCH_EXPECT_CASE15,
5050
SWITCH_EXPECT_CASE16,
5151
SWITCH_EXPECT_CASE17,
52+
SWITCH_EXPECT_CASE18,
53+
SWITCH_EXPECT_CASE19,
5254
SWITCH_EXPECT_CASE2,
5355
SWITCH_EXPECT_CASE3,
5456
SWITCH_EXPECT_CASE4,
@@ -221,6 +223,8 @@ describe('CfgTest', () => {
221223
testBlocks(scene, 'SwitchSample.ts', 'case15', SWITCH_EXPECT_CASE15.blocks);
222224
testBlocks(scene, 'SwitchSample.ts', 'case16', SWITCH_EXPECT_CASE16.blocks);
223225
testBlocks(scene, 'SwitchSample.ts', 'case17', SWITCH_EXPECT_CASE17.blocks);
226+
testBlocks(scene, 'SwitchSample.ts', 'case18', SWITCH_EXPECT_CASE18.blocks);
227+
testBlocks(scene, 'SwitchSample.ts', 'case19', SWITCH_EXPECT_CASE19.blocks);
224228
});
225229

226230
it('case4: loop statement', () => {

0 commit comments

Comments
 (0)