This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Proposed fix for PR c/15224
- From: kenner at vlsi1 dot ultra dot nyu dot edu (Richard Kenner)
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 31 Aug 04 19:12:38 EDT
- Subject: Proposed fix for PR c/15224
I want to run this by some C-front-end folks. It looks right to me and
tests OK on x86-64-linux-gnu.
2004-08-31 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
PR c/15224
* c-common.c (handle_mode_attribute): Handle ENUMERAL_TYPE.
* c-decl.c (finish_enum): Check for user-specified precision too small.
*** c-common.c 28 Aug 2004 02:33:45 -0000 1.562
--- c-common.c 29 Aug 2004 21:32:32 -0000
*************** handle_mode_attribute (tree *node, tree
*** 4352,4355 ****
--- 4352,4356 ----
else
typefm = lang_hooks.types.type_for_mode (mode, TYPE_UNSIGNED (type));
+
if (typefm == NULL_TREE)
{
*************** handle_mode_attribute (tree *node, tree
*** 4357,4360 ****
--- 4358,4378 ----
return NULL_TREE;
}
+ else if (TREE_CODE (type) == ENUMERAL_TYPE)
+ {
+ /* For enumeral types, copy the precision from the integer
+ type returned above. If not an INTEGER_TYPE, we can't use
+ this mode for this type. */
+ if (TREE_CODE (typefm) != INTEGER_TYPE)
+ {
+ error ("cannot use mode '%s' for enumeral types",
+ GET_MODE_NAME (mode));
+ return NULL_TREE;
+ }
+
+ if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
+ type = build_variant_type_copy (type);
+ TYPE_PRECISION (type) = TYPE_PRECISION (typefm);
+ typefm = type;
+ }
*node = typefm;
*** c-decl.c 26 Aug 2004 21:30:15 -0000 1.564
--- c-decl.c 29 Aug 2004 21:32:37 -0000
*************** finish_enum (tree enumtype, tree values,
*** 5675,5678 ****
--- 5675,5679 ----
precision = MAX (min_precision (minnode, unsign),
min_precision (maxnode, unsign));
+
if (TYPE_PACKED (enumtype) || precision > TYPE_PRECISION (integer_type_node))
{
*************** finish_enum (tree enumtype, tree values,
*** 5689,5695 ****
TYPE_MIN_VALUE (enumtype) = TYPE_MIN_VALUE (tem);
TYPE_MAX_VALUE (enumtype) = TYPE_MAX_VALUE (tem);
- TYPE_PRECISION (enumtype) = TYPE_PRECISION (tem);
TYPE_UNSIGNED (enumtype) = TYPE_UNSIGNED (tem);
TYPE_SIZE (enumtype) = 0;
layout_type (enumtype);
--- 5690,5706 ----
TYPE_MIN_VALUE (enumtype) = TYPE_MIN_VALUE (tem);
TYPE_MAX_VALUE (enumtype) = TYPE_MAX_VALUE (tem);
TYPE_UNSIGNED (enumtype) = TYPE_UNSIGNED (tem);
TYPE_SIZE (enumtype) = 0;
+
+ /* If the precision of the type was specific with an attribute and it
+ was too small, give an error. Otherwise, use it. */
+ if (TYPE_PRECISION (enumtype))
+ {
+ if (precision > TYPE_PRECISION (enumtype))
+ error ("specified mode too small for enumeral values");
+ }
+ else
+ TYPE_PRECISION (enumtype) = TYPE_PRECISION (tem);
+
layout_type (enumtype);