This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[c++] conditional expr abort
- To: gcc-patches at gcc dot gnu dot org, Jason Merrill <jason at redhat dot com>
- Subject: [c++] conditional expr abort
- From: Richard Henderson <rth at redhat dot com>
- Date: Sun, 8 Apr 2001 12:40:13 -0700
The following test case fails on (afaik) all versions:
extern int a1[];
extern int a2[];
void foo(int p)
{
int x = (p ? a1 : a2)[1];
}
/home/rth/zz.cc: In function `void foo(int)':
/home/rth/zz.cc:5: Internal compiler error in assign_stack_temp_for_type, at
function.c:663
After two attempts that created more problems than it solved
due to utterly strange c++ rules, I came up with the following
that did pass the test suite. Ok?
r~
* call.c (build_conditional_expr): Decompose same_type_p array
lvalues around the COND_EXPR.
Index: call.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/call.c,v
retrieving revision 1.265
diff -c -p -d -r1.265 call.c
*** call.c 2001/03/23 01:49:10 1.265
--- call.c 2001/04/08 19:32:06
*************** build_conditional_expr (arg1, arg2, arg3
*** 3001,3010 ****
If the second and third operands are lvalues and have the same
type, the result is of that type and is an lvalue. */
! if (real_lvalue_p (arg2) && real_lvalue_p (arg3) &&
! same_type_p (arg2_type, arg3_type))
{
result_type = arg2_type;
goto valid_operands;
}
--- 3001,3023 ----
If the second and third operands are lvalues and have the same
type, the result is of that type and is an lvalue. */
! if (real_lvalue_p (arg2) && real_lvalue_p (arg3)
! && same_type_p (arg2_type, arg3_type))
{
result_type = arg2_type;
+
+ /* ??? We can get into trouble with assign_stack_temp_for_type
+ vs incomplete arrays. Since C++ does not allow us to decay
+ the type here, play games. */
+ if (TREE_CODE (arg2_type) == ARRAY_TYPE)
+ {
+ arg2 = decay_conversion (arg2);
+ arg3 = decay_conversion (arg3);
+ result = fold (build (COND_EXPR, TREE_TYPE (arg2), arg1, arg2, arg3));
+ result = fold (build1 (INDIRECT_REF, result_type, result));
+ return result;
+ }
+
goto valid_operands;
}