This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH] Fix 22551 (changes c-common)
- From: Nathan Sidwell <nathan at codesourcery dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Cc: "Joseph S. Myers" <joseph at codesourcery dot com>
- Date: Fri, 14 Oct 2005 09:35:30 +0100
- Subject: [C++ PATCH] Fix 22551 (changes c-common)
Hi,
this patch fixes 22551 an ICE caused by constant overflow. The case label
values end up with an overflow flag set on them (cue rant about the way we deal
with constant overflow :) This seems like the best way to avoid the problem. I
couldn't come up with a C testcase that exhibited the same problem.
booted & tested on i686-pc-linux-gnu, ok?
nathan
--
Nathan Sidwell :: http://www.codesourcery.com :: CodeSourcery LLC
nathan@codesourcery.com :: http://www.planetfall.pwp.blueyonder.co.uk
2005-10-14 Nathan Sidwell <nathan@codesourcery.com>
PR c++/22551
* c-common.c (c_add_case_label): Clear LOW_VALUE and HIGH_VALUE's
overflow flags. Refactor some conditionals.
Index: c-common.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.c,v
retrieving revision 1.655
diff -c -3 -p -r1.655 c-common.c
*** c-common.c 12 Oct 2005 23:34:08 -0000 1.655
--- c-common.c 14 Oct 2005 08:30:04 -0000
*************** c_add_case_label (splay_tree cases, tree
*** 3588,3612 ****
{
low_value = check_case_value (low_value);
low_value = convert_and_check (type, low_value);
}
if (high_value)
{
high_value = check_case_value (high_value);
high_value = convert_and_check (type, high_value);
}
! /* If an error has occurred, bail out now. */
! if (low_value == error_mark_node || high_value == error_mark_node)
! goto error_out;
!
! /* If the LOW_VALUE and HIGH_VALUE are the same, then this isn't
! really a case range, even though it was written that way. Remove
! the HIGH_VALUE to simplify later processing. */
! if (tree_int_cst_equal (low_value, high_value))
! high_value = NULL_TREE;
! if (low_value && high_value
! && !tree_int_cst_lt (low_value, high_value))
! warning (0, "empty range specified");
/* See if the case is in range of the type of the original testing
expression. If both low_value and high_value are out of range,
--- 3588,3619 ----
{
low_value = check_case_value (low_value);
low_value = convert_and_check (type, low_value);
+ if (low_value == error_mark_node)
+ goto error_out;
+ /* Do not propagate any overflow information past this point.
+ It is safe to just clear the flags, as any constants with
+ them set will not be shared. */
+ TREE_CONSTANT_OVERFLOW (low_value) = TREE_OVERFLOW (low_value) = 0;
}
if (high_value)
{
high_value = check_case_value (high_value);
high_value = convert_and_check (type, high_value);
+ if (high_value == error_mark_node)
+ goto error_out;
+ TREE_CONSTANT_OVERFLOW (high_value) = TREE_OVERFLOW (high_value) = 0;
}
! if (low_value && high_value)
! {
! /* If the LOW_VALUE and HIGH_VALUE are the same, then this isn't
! really a case range, even though it was written that way.
! Remove the HIGH_VALUE to simplify later processing. */
! if (tree_int_cst_equal (low_value, high_value))
! high_value = NULL_TREE;
! else if (!tree_int_cst_lt (low_value, high_value))
! warning (0, "empty range specified");
! }
/* See if the case is in range of the type of the original testing
expression. If both low_value and high_value are out of range,
// Copyright (C) 2005 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 13 Oct 2005 <nathan@codesourcery.com>
// PR 22551:ICE
// Origin: Johnny Casey <emailwastefilter-bugzillagccorg@yahoo.com>
const int B = 0x80000000;
#define b(x) (B + x)
int Foo (int error)
{
switch (error)
{
case b (1): return 0; // { dg-error "overflow" "" }
case b (2): return 0; // { dg-error "overflow" "" }
case b (3): return 0; // { dg-error "overflow" "" }
case b (4): return 0; // { dg-error "overflow" "" }
case b (5): return 0; // { dg-error "overflow" "" }
}
}