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