aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2003-06-27 21:21:08 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2003-06-27 21:21:08 +0000
commite455bc273ebd4e45e4383b9031f8c4d48a4728a8 (patch)
treeb9408cbb00f6506219f8eaca4f93ac88b1312eec /gcc
parentdc65c307c80fc0817b0452685f3e4b804f1d521e (diff)
downloadgcc-e455bc273ebd4e45e4383b9031f8c4d48a4728a8.zip
gcc-e455bc273ebd4e45e4383b9031f8c4d48a4728a8.tar.gz
gcc-e455bc273ebd4e45e4383b9031f8c4d48a4728a8.tar.bz2
re PR c++/10796 (ICE (segfault) when defining an enum with two values: -1 and MAX_INT_64BIT)
PR c++/10796 * decl.c (finish_enum): Implement DR377. * decl.c (cp_finish_decl): Don't make variables with reference type readonly while they are being initialized. PR c++/10796 * g++.dg/init/enum1.C: New test. From-SVN: r68610
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/decl.c39
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/init/enum1.C10
4 files changed, 49 insertions, 13 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index d0ecbdb..3e1fa5d 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,11 @@
+2003-06-27 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10796
+ * decl.c (finish_enum): Implement DR377.
+
+ * decl.c (cp_finish_decl): Don't make variables with reference
+ type readonly while they are being initialized.
+
2003-06-26 Mark Mitchell <mark@codesourcery.com>
PR c++/11332
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index b9c59af..66257c0 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -8101,7 +8101,8 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
ttype = target_type (type);
if (! DECL_EXTERNAL (decl) && TREE_READONLY (decl)
- && TYPE_NEEDS_CONSTRUCTING (type))
+ && (TYPE_NEEDS_CONSTRUCTING (type)
+ || TREE_CODE (type) == REFERENCE_TYPE))
{
/* Currently, GNU C++ puts constants in text space, making them
impossible to initialize. In the future, one would hope for
@@ -13106,24 +13107,36 @@ finish_enum (tree enumtype)
highprec = min_precision (maxnode, unsignedp);
precision = MAX (lowprec, highprec);
- /* Set TYPE_MIN_VALUE and TYPE_MAX_VALUE according to `precision'. */
- TYPE_SIZE (enumtype) = NULL_TREE;
+ /* DR 377
+
+ IF no integral type can represent all the enumerator values, the
+ enumeration is ill-formed. */
+ if (precision > TYPE_PRECISION (long_long_integer_type_node))
+ {
+ error ("no integral type can represent all of the enumerator values "
+ "for `%T'", enumtype);
+ precision = TYPE_PRECISION (long_long_integer_type_node);
+ }
+
+ /* Compute the minium and maximum values for the type, the size of
+ the type, and so forth. */
TYPE_PRECISION (enumtype) = precision;
+ TYPE_SIZE (enumtype) = NULL_TREE;
if (unsignedp)
fixup_unsigned_type (enumtype);
else
fixup_signed_type (enumtype);
- if (flag_short_enums || (precision > TYPE_PRECISION (integer_type_node)))
- /* Use the width of the narrowest normal C type which is wide
- enough. */
- TYPE_PRECISION (enumtype) = TYPE_PRECISION (c_common_type_for_size
- (precision, 1));
- else
- TYPE_PRECISION (enumtype) = TYPE_PRECISION (integer_type_node);
-
- TYPE_SIZE (enumtype) = NULL_TREE;
- layout_type (enumtype);
+ /* We use "int" or "unsigned int" as the underlying type, unless all
+ the values will not fit or the user has requested that we try to
+ use shorter types where possible. */
+ if (precision < TYPE_PRECISION (integer_type_node)
+ && !flag_short_enums)
+ {
+ TYPE_PRECISION (enumtype) = TYPE_PRECISION (integer_type_node);
+ TYPE_SIZE (enumtype) = NULL_TREE;
+ layout_type (enumtype);
+ }
/* Fix up all variant types of this enum type. */
for (t = TYPE_MAIN_VARIANT (enumtype); t; t = TYPE_NEXT_VARIANT (t))
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 930031b..b407402 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2003-06-27 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10796
+ * g++.dg/init/enum1.C: New test.
+
2003-06-27 Ulrich Weigand <uweigand@de.ibm.com>
* gcc.dg/20030627-1.c: New test.
diff --git a/gcc/testsuite/g++.dg/init/enum1.C b/gcc/testsuite/g++.dg/init/enum1.C
new file mode 100644
index 0000000..f74a5ad
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/enum1.C
@@ -0,0 +1,10 @@
+enum test {
+ acceptable = -1,
+ unacceptable = 0xffffffffffffffffLL
+}; // { dg-error "" }
+
+enum test t = acceptable, u = unacceptable;
+
+int main() {
+ return 0;
+}