Skip to content

Commit dec761b

Browse files
committed
[cc] ir: continue fixing ternary
1 parent 8a9b26c commit dec761b

File tree

2 files changed

+79
-2
lines changed

2 files changed

+79
-2
lines changed

cc/ir/linearize.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2501,8 +2501,11 @@ impl<'a> Linearizer<'a> {
25012501
self.is_pure_expr(left) && self.is_pure_expr(right)
25022502
}
25032503

2504-
// Unary ops are pure if operand is pure (no side-effect ops here)
2505-
ExprKind::Unary { operand, .. } => self.is_pure_expr(operand),
2504+
// Unary ops are pure if operand is pure, except for pre-inc/dec
2505+
ExprKind::Unary { op, operand, .. } => match op {
2506+
UnaryOp::PreInc | UnaryOp::PreDec => false,
2507+
_ => self.is_pure_expr(operand),
2508+
},
25062509

25072510
// Post-increment/decrement have side effects
25082511
ExprKind::PostInc(_) | ExprKind::PostDec(_) => false,

cc/tests/features/short_circuit.rs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,80 @@ int main(void) {
339339
assert_eq!(compile_and_run("ternary_types", code), 0);
340340
}
341341

342+
// ============================================================================
343+
// Pre-increment/pre-decrement in ternary (impure expressions)
344+
// ============================================================================
345+
346+
#[test]
347+
fn ternary_pre_inc_dec() {
348+
let code = r#"
349+
int main(void) {
350+
// Test 1: Pre-increment in ternary - only selected branch evaluated
351+
int x = 10, y = 20;
352+
int result = (1 ? ++x : ++y);
353+
if (result != 11) return 1;
354+
if (x != 11) return 2; // x was incremented
355+
if (y != 20) return 3; // y was NOT incremented
356+
357+
// Test 2: Pre-increment in false branch
358+
x = 10; y = 20;
359+
result = (0 ? ++x : ++y);
360+
if (result != 21) return 4;
361+
if (x != 10) return 5; // x was NOT incremented
362+
if (y != 21) return 6; // y was incremented
363+
364+
// Test 3: Pre-decrement in ternary
365+
x = 10; y = 20;
366+
result = (1 ? --x : --y);
367+
if (result != 9) return 7;
368+
if (x != 9) return 8; // x was decremented
369+
if (y != 20) return 9; // y was NOT decremented
370+
371+
// Test 4: Pre-decrement in false branch
372+
x = 10; y = 20;
373+
result = (0 ? --x : --y);
374+
if (result != 19) return 10;
375+
if (x != 10) return 11; // x was NOT decremented
376+
if (y != 19) return 12; // y was decremented
377+
378+
// Test 5: Variable condition with pre-increment
379+
int cond = 5;
380+
x = 100; y = 200;
381+
result = (cond ? ++x : ++y);
382+
if (result != 101) return 13;
383+
if (x != 101) return 14;
384+
if (y != 200) return 15;
385+
386+
// Test 6: Zero variable condition with pre-increment
387+
cond = 0;
388+
x = 100; y = 200;
389+
result = (cond ? ++x : ++y);
390+
if (result != 201) return 16;
391+
if (x != 100) return 17;
392+
if (y != 201) return 18;
393+
394+
// Test 7: Mixed pre-inc and pre-dec
395+
x = 50; y = 50;
396+
result = (1 ? ++x : --y);
397+
if (result != 51) return 19;
398+
if (x != 51) return 20;
399+
if (y != 50) return 21;
400+
401+
// Test 8: Pre-increment in nested ternary
402+
x = 0; y = 0;
403+
int z = 0;
404+
result = (1 ? (0 ? ++x : ++y) : ++z);
405+
if (result != 1) return 22;
406+
if (x != 0) return 23; // x NOT incremented
407+
if (y != 1) return 24; // y incremented (inner false branch)
408+
if (z != 0) return 25; // z NOT incremented (outer false branch)
409+
410+
return 0;
411+
}
412+
"#;
413+
assert_eq!(compile_and_run("ternary_pre_inc_dec", code), 0);
414+
}
415+
342416
// ============================================================================
343417
// Edge cases and complex scenarios
344418
// ============================================================================

0 commit comments

Comments
 (0)