diff --git a/README.md b/README.md index 84122d0..b485095 100644 --- a/README.md +++ b/README.md @@ -151,6 +151,8 @@ python Test/run_lifetime_negative_tests.py --exe .\TransPyV\output\TransPyV.exe > 默认跑 `EscapeTest` / `EscapeMethodTest` / `EscapeXmodTest`:断言**编译失败且输出含 `LifetimeError`**;编译成功 = 漏检(FAIL),报错但方向不符 = SKIP。 +负向项目在 `SequentialRegressionTest.py` 里是**反向判定**(`NEGATIVE_PROJECTS`):编译失败且输出含 `LifetimeError` 才算通过,且**不再进入运行阶段**;编译成功 = 漏检,直接终止。`regression_test.py --escape` 会**剔除**这些项目(该脚本要求"编译成功 + 能跑"),负向断言请用 `SequentialRegressionTest.py --escape` 或上面的 `run_lifetime_negative_tests.py`。 + --- ## 二、建议实现顺序(难度升序,共 68 步) diff --git a/SequentialRegressionTest.py b/SequentialRegressionTest.py index 066c6f6..ca10b68 100644 --- a/SequentialRegressionTest.py +++ b/SequentialRegressionTest.py @@ -40,6 +40,17 @@ OVERVIEW = os.path.join(TEST_DIR, "README.md") # Test/ 下:NewTest;仓库根下:EscapeTest/EscapeOkTest/EscapeMethodTest/EscapeXmodTest ESCAPE_PROJECTS = ["EscapeTest", "EscapeOkTest", "EscapeMethodTest", "EscapeXmodTest", "NewTest"] +# 负向项目:**期望编译失败**且输出含指定关键字(反向判定,且不运行可执行文件)。 +# 这些项目里的用例故意交出本帧栈地址(或跨模块摘要路径),必须被 M1–M2.3 的 +# 逃逸检查拒绝;编译成功 = 编译器漏检(判 FAIL 并终止)。 +# 注:EscapeMethodTest / EscapeXmodTest 内含多条互斥用例(编译在第一个错误处终止), +# 故只保证"至少触发一条"。 +NEGATIVE_PROJECTS = { + "EscapeTest": "LifetimeError", + "EscapeMethodTest": "LifetimeError", + "EscapeXmodTest": "LifetimeError", +} + def find_project_file(proj_dir): """项目目录下找 project.json(Test/ 约定)或 project.vpj(仓库根约定)""" @@ -270,6 +281,23 @@ def main(): print(f"\n在 {name} 编译异常,立即终止。") return 1 + # ---------- 负向项目:反向判定(期望失败),且不进入运行阶段 ---------- + if name in NEGATIVE_PROJECTS: + want_kw: str = NEGATIVE_PROJECTS[name] + if compile_ok: + print(f"漏检 ({elapsed:.1f}s):负向项目竟编译成功,应报 {want_kw}") + print_tail(output) + print(f"\n在 {name} 漏检(应拒绝却通过),立即终止。") + return 1 + if want_kw.lower() in output.lower(): + print(f"通过(已按预期拒绝: {want_kw}, {elapsed:.1f}s)") + passed += 1 + continue + print(f"失败(报错方向不符,未见 {want_kw})") + print_tail(output) + print(f"\n在 {name} 报错方向不符,立即终止。") + return 1 + if not compile_ok: print(f"失败 ({elapsed:.1f}s)") print_tail(output) diff --git a/regression_test.py b/regression_test.py index c6dad4d..e6cd0af 100644 --- a/regression_test.py +++ b/regression_test.py @@ -89,6 +89,11 @@ def find_test_projects(): # Test/ 下:NewTest;仓库根下:EscapeTest/EscapeOkTest/EscapeMethodTest/EscapeXmodTest ESCAPE_PROJECTS = ["EscapeTest", "EscapeOkTest", "EscapeMethodTest", "EscapeXmodTest", "NewTest"] +# 负向项目(**期望编译失败**,见 SequentialRegressionTest.NEGATIVE_PROJECTS): +# 本脚本按"编译必须成功 + 能跑"判定,纳入会误报,故 --escape 时剔除; +# 负向断言请用 SequentialRegressionTest(反向判定)或 run_lifetime_negative_tests.py。 +NEGATIVE_PROJECT_NAMES = {"EscapeTest", "EscapeMethodTest", "EscapeXmodTest"} + def find_project_file(proj_dir): """项目目录下找 project.json(Test/ 约定)或 project.vpj(仓库根约定)""" @@ -218,7 +223,8 @@ def main(): print() if args.escape: - projects = select_named_projects(ESCAPE_PROJECTS) + projects = [p for p in select_named_projects(ESCAPE_PROJECTS) if p[0] not in NEGATIVE_PROJECT_NAMES] + print("(负向项目已剔除;负向断言请用 SequentialRegressionTest 或 run_lifetime_negative_tests.py)") elif args.only: projects = select_named_projects([n.strip() for n in args.only.split(",") if n.strip()]) else: