diff -p -r -U3 -N -X /home/gpc/p/script/gpcdiff.exclude orig/p/gpc-typeck.c p/gpc-typeck.c --- orig/p/gpc-typeck.c Sat Dec 8 03:43:35 2001 +++ p/gpc-typeck.c Fri Dec 14 03:03:42 2001 @@ -6829,7 +6829,7 @@ build_modify_expr (lhs, modifycode, rhs) * * This depends on how build_pascal_array_ref() works. */ - tree newlhs, temprhs, access = lhs; + tree newlhs, access = lhs; tree mask, shifted_mask, offset, eraser, brush; tree low_lhs, high_lhs, low_assignment, high_assignment; @@ -6842,11 +6842,19 @@ build_modify_expr (lhs, modifycode, rhs) while (TREE_CODE (access) == NOP_EXPR) access = TREE_OPERAND (access, 0); /* - * Now ACCESS must be an RSHIFT_EXPR; its arg0 must be a BIT_AND_EXPR. + * Now ACCESS must be an RSHIFT_EXPR (but might have been folded to a + * NON_LVALUE_EXPR if it was a shift by 0 (emil1.pas); its arg0 must + * be a BIT_AND_EXPR in both cases. */ - assert (TREE_CODE (access) == RSHIFT_EXPR - && TREE_CODE (TREE_OPERAND (access, 0)) == BIT_AND_EXPR); - offset = TREE_OPERAND (access, 1); + if (TREE_CODE (access) == NON_LVALUE_EXPR) + offset = integer_zero_node; + else + { + assert (TREE_CODE (access) == RSHIFT_EXPR); + offset = TREE_OPERAND (access, 1); + } + + assert (TREE_CODE (TREE_OPERAND (access, 0)) == BIT_AND_EXPR); newlhs = TREE_OPERAND (TREE_OPERAND (access, 0), 0); shifted_mask = TREE_OPERAND (TREE_OPERAND (access, 0), 1); @@ -6864,20 +6872,21 @@ build_modify_expr (lhs, modifycode, rhs) while (TREE_CODE (high_lhs) == NOP_EXPR) high_lhs = TREE_OPERAND (high_lhs, 0); - /* Dig out the non-shifted mask. - */ + /* Dig out the non-shifted mask. */ mask = shifted_mask; while (TREE_CODE (mask) == NOP_EXPR) mask = TREE_OPERAND (mask, 0); - assert (TREE_CODE (mask) == LSHIFT_EXPR - && TREE_CODE (TREE_OPERAND (mask, 0)) == INTEGER_CST); - mask = TREE_OPERAND (mask, 0); - /* NEWRHS will be accessed more than once, so use a temporary variable. - */ - temprhs = make_new_variable ("assign_packed", TREE_TYPE (newrhs)); - expand_expr_stmt (build_modify_expr (temprhs, NOP_EXPR, newrhs)); - newrhs = temprhs; + /* If the shift was optimized away, mask is an INTEGER_CST already. Fine. */ + if (TREE_CODE (mask) != INTEGER_CST) + { + assert ((TREE_CODE (mask) == LSHIFT_EXPR || TREE_CODE (mask) == NON_LVALUE_EXPR) + && TREE_CODE (TREE_OPERAND (mask, 0)) == INTEGER_CST); + mask = TREE_OPERAND (mask, 0); + } + + /* NEWRHS will be accessed more than once */ + newrhs = save_expr (newrhs); /* Do the modification. */ diff -p -r -U3 -N -X /home/gpc/p/script/gpcdiff.exclude orig/p/test/emil1.pas p/test/emil1.pas --- orig/p/test/emil1.pas Thu Jan 1 01:00:00 1970 +++ p/test/emil1.pas Fri Dec 14 02:49:26 2001 @@ -0,0 +1,13 @@ +program emil1; + +var + t : packed array[0..1]of 0..32768; {non-packed is OK, <=32767 is OK} + h : 0..1; {or integer or whatever} + +begin + t[0]:=2; + t[1]:=3; + h:=0; + t[h]:=0; {t[0]:=0 is OK} + if (t[0]=0) and (t[1]=3) then WriteLn ('OK') else WriteLn ('failed') +end.