juha@tds.kth.se (Juha Sarlin) (06/16/89)
gcc 1.35 gives an error message: "case label does not reduce to an integer constant" for the following code: #define CTRL(c) (#c[0]&037) foo(c) { switch (c) { case CTRL(z): break; } } Below is my fix. Note that I didn't bother to handle similar cases, like *"foo" for example. *** /tmp/,RCSt1a00595 Thu Jun 16 14:03:59 1989 --- fold-const.c Wed Jun 15 18:40:33 1989 *************** *** 981,986 **** --- 981,1001 ---- #endif } #endif /* not REAL_IS_NOT_DOUBLE, or REAL_ARITHMETIC */ + else if (TREE_CODE (arg1) == ARRAY_REF) + { + tree array = TREE_OPERAND (arg1, 0); + tree index = TREE_OPERAND (arg1, 1); + int i; + + /* Fold an expression like: "foo"[2] */ + if (TREE_CODE (array) == STRING_CST + && TREE_CODE (index) == INTEGER_CST + && !TREE_INT_CST_HIGH (index) + && (i = TREE_INT_CST_LOW (index)) < TREE_STRING_LENGTH (array)) + t = build_int_2 (TREE_STRING_POINTER (array)[i], 0); + else /* Cannot fold this ARRAY_REF; return original expression */ + return t; + } TREE_TYPE (t) = type; } else if (TREE_CODE (type) == REAL_TYPE) *************** *** 1090,1095 **** --- 1105,1113 ---- #if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC) && TREE_CODE (TREE_OPERAND (t, i)) != REAL_CST #endif /* not REAL_IS_NOT_DOUBLE, or REAL_ARITHMETIC */ + && !(TREE_CODE (TREE_OPERAND (t, i)) == ARRAY_REF + && TREE_LITERAL (TREE_OPERAND (TREE_OPERAND (t, i), 0)) + && TREE_LITERAL (TREE_OPERAND (TREE_OPERAND (t, i), 1))) ) /* Note that TREE_LITERAL isn't enough: static var addresses are constant but we can't -- Juha Sarlin juha@tds.kth.se