Files
2026-10-17 21:57:03 +08:00

71 lines
2.4 KiB
Plaintext

# ProbeGen: minimal probe for cross-generation IR instability. Do not treat as a normal feature test.
# Translate the same source with two compiler generations, then diff the emitted IR per module
# (module file name = source SHA1, so both sides are comparable).
# Gen 1: ViperC\output\viperc.exe --project Test\ProbeGen\project.vpj --clean --run --build-dir Test\ProbeGen\__vpcbuild___g1
# Gen 2: ViperC\__vpcbuild__\output\viperc.exe --project Test\ProbeGen\project.vpj --clean --run --build-dir Test\ProbeGen\__vpcbuild___g2
# WARNING [P6] breaks compilation from generation 2 onward; comment out [P6] to get Gen-2 IR for P1..P5.
from stdint import *
import win32.win32console as win32console
# [P1] Nested union parameter: VOIDPTR (typedef of t.CPtr) unioned with t.CPtr gives i8** on one side, i8* on the other.
# Declared but never called, so no link reference is produced.
extern def ProbeNestedUnion(Context: VOIDPTR*) -> BOOL
# [P2] Struct by-value parameter: COORD without | t.CPtr gives %COORD on one side, %COORD* on the other.
extern def ProbeCoordByVal(dwSize: win32console.COORD) -> BOOL
# [P5] Sink for the local uint8 = 1 literal: store it into a global so the code is not dead-code eliminated.
U8Sink: uint8 = 0
# [P3] char -> int promotion: param char, int return. One side must emit zext i8 to i32, not ret i8.
def ProbeOrd(s: char) -> int:
return s
# [P4] double comparison: params/return double. One side must emit fcmp olt double, not icmp slt double.
def ProbeMin(a: double, b: double) -> double:
if a < b:
return a
return b
# [P5] Local uint8 = 1 assignment: literal typing must emit store i8 1, not store i32 1 or trunc+store.
def ProbeU8Literal() -> uint8:
global U8Sink
result: uint8 = 1
U8Sink = result
return result
# [P6] Class field union + subscript write: field is char | t.CPtr, must null-check before indexed write.
# Generations 2+ fail here with "SyntaxError: subscript ptr is None".
class Box:
p: char*
def __init__(self):
self.p = None
def Clear(self):
if self.p != None:
self.p[0] = 0
pass
# Entry: keep main minimal, referencing each construct above so it is really translated; return 0.
# P1/P2 are extern declarations and are not called, so their difference shows in this module's declares.
export def main() -> int:
Ch: char = 'A'
BoxInst: Box = Box()
BoxInst.Clear()
ProbeOrd(Ch)
ProbeMin(1.0, 2.0)
ProbeU8Literal()
return 0