From 046c58907ec85884042d9937ea9c25ef9fe57b1d Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 17 Mar 2020 22:32:34 +0100 Subject: c: Handle C_TYPE_INCOMPLETE_VARS even for ENUMERAL_TYPEs [PR94172] The following testcases ICE, because they contain extern variable declarations with incomplete enum types that is later completed and after that those variables are accessed. The ICEs are because the vars then may have incorrect DECL_MODE etc., e.g. in the first case the var has SImode DECL_MODE (the guessed mode for the enum), but the enum then actually has DImode because its enumerators don't fit into unsigned int. The following patch fixes it by using C_TYPE_INCOMPLETE_VARS not just on incomplete struct/union types, but also incomplete enum types. TYPE_VFIELD can't be used as it is TYPE_MIN_VALUE on ENUMERAL_TYPE, thankfully TYPE_LANG_SLOT_1 has been used in the C FE only on FUNCTION_TYPEs. 2020-03-17 Jakub Jelinek PR c/94172 * c-tree.h (C_TYPE_INCOMPLETE_VARS): Define to TYPE_LANG_SLOT_1 instead of TYPE_VFIELD, and support it on {RECORD,UNION,ENUMERAL}_TYPE. (TYPE_ACTUAL_ARG_TYPES): Check that it is only used on FUNCTION_TYPEs. * c-decl.c (pushdecl): Push C_TYPE_INCOMPLETE_VARS also to ENUMERAL_TYPEs. (finish_incomplete_vars): New function, moved from finish_struct. Use relayout_decl instead of layout_decl. (finish_struct): Remove obsolete comment about C_TYPE_INCOMPLETE_VARS being TYPE_VFIELD. Use finish_incomplete_vars. (finish_enum): Clear C_TYPE_INCOMPLETE_VARS. Call finish_incomplete_vars. * c-typeck.c (c_build_qualified_type): Clear C_TYPE_INCOMPLETE_VARS also on ENUMERAL_TYPEs. * gcc.dg/pr94172-1.c: New test. * gcc.dg/pr94172-2.c: New test. --- gcc/c/c-tree.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'gcc/c/c-tree.h') diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h index 7122992..364d7e0 100644 --- a/gcc/c/c-tree.h +++ b/gcc/c/c-tree.h @@ -38,9 +38,12 @@ along with GCC; see the file COPYING3. If not see nonzero if the definition of the type has already started. */ #define C_TYPE_BEING_DEFINED(TYPE) TYPE_LANG_FLAG_0 (TYPE) -/* In an incomplete RECORD_TYPE or UNION_TYPE, a list of variable - declarations whose type would be completed by completing that type. */ -#define C_TYPE_INCOMPLETE_VARS(TYPE) TYPE_VFIELD (TYPE) +/* In an incomplete RECORD_TYPE, UNION_TYPE or ENUMERAL_TYPE, a list of + variable declarations whose type would be completed by completing + that type. */ +#define C_TYPE_INCOMPLETE_VARS(TYPE) \ + TYPE_LANG_SLOT_1 (TREE_CHECK4 (TYPE, RECORD_TYPE, UNION_TYPE, \ + QUAL_UNION_TYPE, ENUMERAL_TYPE)) /* In an IDENTIFIER_NODE, nonzero if this identifier is actually a keyword. C_RID_CODE (node) is then the RID_* value of the keyword. */ @@ -108,7 +111,8 @@ along with GCC; see the file COPYING3. If not see /* For FUNCTION_TYPE, a hidden list of types of arguments. The same as TYPE_ARG_TYPES for functions with prototypes, but created for functions without prototypes. */ -#define TYPE_ACTUAL_ARG_TYPES(NODE) TYPE_LANG_SLOT_1 (NODE) +#define TYPE_ACTUAL_ARG_TYPES(NODE) \ + TYPE_LANG_SLOT_1 (FUNCTION_TYPE_CHECK (NODE)) /* For a CONSTRUCTOR, whether some initializer contains a subexpression meaning it is not a constant expression. */ -- cgit v1.1