From e6267549228960d1a5422dc073a0026081e39130 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 23 Nov 1998 23:57:32 +0000 Subject: [PATCH] typeck2.c (process_init_constructor): If there are elements that don't have initializers and they need to have... * typeck2.c (process_init_constructor): If there are elements that don't have initializers and they need to have constructors run, supply them with initializers. Fixes Sec12/6_1/P12176.C. * class.c (finish_struct_1): A class with a 0-width bitfield is still empty. Fixes Sec9/6/R09387.r0. Really this time. From-SVN: r23819 --- gcc/cp/ChangeLog | 9 +++ gcc/cp/class.c | 10 ++- gcc/cp/typeck2.c | 185 +++++++++++++++++++++++++++-------------------- 3 files changed, 123 insertions(+), 81 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ff7f5630c56..6e403361efe 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +1998-11-23 Jason Merrill + + * typeck2.c (process_init_constructor): If there are elements + that don't have initializers and they need to have constructors + run, supply them with initializers. + + * class.c (finish_struct_1): A class with a 0-width bitfield is + still empty. + 1998-11-23 Mark Mitchell * pt.c (instantiate_class_template): Don't try to figure out what diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 1c2ec6bf8a3..de283eae2dd 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -1235,7 +1235,9 @@ add_method (type, fields, method) } } - if (DECL_CONV_FN_P (method)) + if (TREE_VEC_ELT (method_vec, i)) + /* We found a match. */; + else if (DECL_CONV_FN_P (method)) { /* Type conversion operators have to come before ordinary methods; add_conversions depends on this to @@ -3453,7 +3455,11 @@ finish_struct_1 (t, warn_anon) if (TREE_CODE (x) == FIELD_DECL) { DECL_PACKED (x) |= TYPE_PACKED (t); - empty = 0; + + if (DECL_C_BIT_FIELD (x) && integer_zerop (DECL_INITIAL (x))) + /* A zero-width bitfield doesn't do the trick. */; + else + empty = 0; } if (TREE_CODE (x) == USING_DECL) diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index 4e490bfd23b..e11bde2d3b2 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -703,6 +703,9 @@ digest_init (type, init, tail) if (TREE_CODE (init) == NON_LVALUE_EXPR) init = TREE_OPERAND (init, 0); + if (TREE_CODE (init) == CONSTRUCTOR && TREE_TYPE (init) == type) + return init; + raw_constructor = TREE_CODE (init) == CONSTRUCTOR && TREE_TYPE (init) == 0; if (raw_constructor @@ -873,6 +876,7 @@ process_init_constructor (type, init, elts) /* List of the elements of the result constructor, in reverse order. */ register tree members = NULL; + register tree next1; tree result; int allconstant = 1; int allsimple = 1; @@ -907,42 +911,59 @@ process_init_constructor (type, init, elts) else len = -1; /* Take as many as there are */ - for (i = 0; (len < 0 || i < len) && tail != 0; i++) + for (i = 0; len < 0 || i < len; i++) { - register tree next1; - - if (TREE_PURPOSE (tail) - && (TREE_CODE (TREE_PURPOSE (tail)) != INTEGER_CST - || TREE_INT_CST_LOW (TREE_PURPOSE (tail)) != i)) - sorry ("non-trivial labeled initializers"); - - if (TREE_VALUE (tail) != 0) + if (tail) { - tree tail1 = tail; - next1 = digest_init (TREE_TYPE (type), - TREE_VALUE (tail), &tail1); - if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (type)) - && TYPE_MAIN_VARIANT (TREE_TYPE (type)) != TYPE_MAIN_VARIANT (TREE_TYPE (next1))) + if (TREE_PURPOSE (tail) + && (TREE_CODE (TREE_PURPOSE (tail)) != INTEGER_CST + || TREE_INT_CST_LOW (TREE_PURPOSE (tail)) != i)) + sorry ("non-trivial labeled initializers"); + + if (TREE_VALUE (tail) != 0) { - /* The fact this needs to be done suggests this code needs - to be totally rewritten. */ - next1 = convert_for_initialization (NULL_TREE, TREE_TYPE (type), next1, LOOKUP_NORMAL, "initialization", NULL_TREE, 0); + tree tail1 = tail; + next1 = digest_init (TREE_TYPE (type), + TREE_VALUE (tail), &tail1); + my_friendly_assert (TYPE_MAIN_VARIANT (TREE_TYPE (type)) + == TYPE_MAIN_VARIANT (TREE_TYPE (next1)), + 981123); + my_friendly_assert (tail1 == 0 + || TREE_CODE (tail1) == TREE_LIST, 319); + if (tail == tail1 && len < 0) + { + error ("non-empty initializer for array of empty elements"); + /* Just ignore what we were supposed to use. */ + tail1 = NULL_TREE; + } + tail = tail1; } - my_friendly_assert (tail1 == 0 - || TREE_CODE (tail1) == TREE_LIST, 319); - if (tail == tail1 && len < 0) + else { - error ("non-empty initializer for array of empty elements"); - /* Just ignore what we were supposed to use. */ - tail1 = NULL_TREE; + next1 = error_mark_node; + tail = TREE_CHAIN (tail); } - tail = tail1; } - else + else if (len < 0) + /* We're done. */ + break; + else if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (type))) { - next1 = error_mark_node; - tail = TREE_CHAIN (tail); + /* If this type needs constructors run for + default-initialization, we can't rely on the backend to do it + for us, so build up TARGET_EXPRs. If the type in question is + a class, just build one up; if it's an array, recurse. */ + + if (IS_AGGR_TYPE (TREE_TYPE (type))) + next1 = build_functional_cast (TREE_TYPE (type), NULL_TREE); + else + next1 = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, NULL_TREE); + next1 = digest_init (TREE_TYPE (type), next1, 0); } + else + /* The default zero-initialization is fine for us; don't + add anything to the CONSTRUCTOR. */ + break; if (next1 == error_mark_node) erroneous = 1; @@ -978,11 +999,9 @@ process_init_constructor (type, init, elts) } } - for (field = TYPE_FIELDS (type); field && tail; + for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) { - register tree next1; - if (! DECL_NAME (field) && DECL_C_BIT_FIELD (field)) { members = expr_tree_cons (field, integer_zero_node, members); @@ -992,25 +1011,67 @@ process_init_constructor (type, init, elts) if (TREE_CODE (field) != FIELD_DECL) continue; - if (TREE_PURPOSE (tail) - && TREE_PURPOSE (tail) != field - && TREE_PURPOSE (tail) != DECL_NAME (field)) - sorry ("non-trivial labeled initializers"); + if (tail) + { + if (TREE_PURPOSE (tail) + && TREE_PURPOSE (tail) != field + && TREE_PURPOSE (tail) != DECL_NAME (field)) + sorry ("non-trivial labeled initializers"); + + if (TREE_VALUE (tail) != 0) + { + tree tail1 = tail; - if (TREE_VALUE (tail) != 0) + next1 = digest_init (TREE_TYPE (field), + TREE_VALUE (tail), &tail1); + my_friendly_assert (tail1 == 0 + || TREE_CODE (tail1) == TREE_LIST, 320); + tail = tail1; + } + else + { + next1 = error_mark_node; + tail = TREE_CHAIN (tail); + } + } + else if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (field))) { - tree tail1 = tail; + /* If this type needs constructors run for + default-initialization, we can't rely on the backend to do it + for us, so build up TARGET_EXPRs. If the type in question is + a class, just build one up; if it's an array, recurse. */ + + if (IS_AGGR_TYPE (TREE_TYPE (field))) + next1 = build_functional_cast (TREE_TYPE (field), + NULL_TREE); + else + next1 = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, + NULL_TREE); + next1 = digest_init (TREE_TYPE (field), next1, 0); - next1 = digest_init (TREE_TYPE (field), - TREE_VALUE (tail), &tail1); - my_friendly_assert (tail1 == 0 - || TREE_CODE (tail1) == TREE_LIST, 320); - tail = tail1; + /* Warn when some struct elements are implicitly initialized. */ + if (extra_warnings) + cp_warning ("missing initializer for member `%D'", field); } else { - next1 = error_mark_node; - tail = TREE_CHAIN (tail); + if (TREE_READONLY (field)) + cp_error ("uninitialized const member `%D'", field); + else if (TYPE_LANG_SPECIFIC (TREE_TYPE (field)) + && CLASSTYPE_READONLY_FIELDS_NEED_INIT (TREE_TYPE (field))) + cp_error ("member `%D' with uninitialized const fields", + field); + else if (TREE_CODE (TREE_TYPE (field)) == REFERENCE_TYPE) + cp_error ("member `%D' is uninitialized reference", field); + + /* Warn when some struct elements are implicitly initialized + to zero. */ + if (extra_warnings) + cp_warning ("missing initializer for member `%D'", field); + + /* The default zero-initialization is fine for us; don't + add anything to the CONSTRUCTOR. */ + continue; } if (next1 == error_mark_node) @@ -1021,44 +1082,10 @@ process_init_constructor (type, init, elts) allsimple = 0; members = expr_tree_cons (field, next1, members); } - for (; field; field = TREE_CHAIN (field)) - { - if (TREE_CODE (field) != FIELD_DECL) - continue; - - /* Does this field have a default initialization? */ - if (DECL_INITIAL (field)) - { - register tree next1 = DECL_INITIAL (field); - if (TREE_CODE (next1) == ERROR_MARK) - erroneous = 1; - else if (!TREE_CONSTANT (next1)) - allconstant = 0; - else if (! initializer_constant_valid_p (next1, TREE_TYPE (next1))) - allsimple = 0; - members = expr_tree_cons (field, next1, members); - } - else if (TREE_READONLY (field)) - error ("uninitialized const member `%s'", - IDENTIFIER_POINTER (DECL_NAME (field))); - else if (TYPE_LANG_SPECIFIC (TREE_TYPE (field)) - && CLASSTYPE_READONLY_FIELDS_NEED_INIT (TREE_TYPE (field))) - error ("member `%s' with uninitialized const fields", - IDENTIFIER_POINTER (DECL_NAME (field))); - else if (TREE_CODE (TREE_TYPE (field)) == REFERENCE_TYPE) - error ("member `%s' is uninitialized reference", - IDENTIFIER_POINTER (DECL_NAME (field))); - /* Warn when some struct elements are implicitly initialized - to zero. */ - else if (extra_warnings) - warning ("missing initializer for member `%s'", - IDENTIFIER_POINTER (DECL_NAME (field))); - } } else if (TREE_CODE (type) == UNION_TYPE) { register tree field = TYPE_FIELDS (type); - register tree next1; /* Find the first named field. ANSI decided in September 1990 that only named fields count here. */ @@ -1087,8 +1114,8 @@ process_init_constructor (type, init, elts) if (temp) field = temp, win = 1; else - error ("no field `%s' in union being initialized", - IDENTIFIER_POINTER (TREE_PURPOSE (tail))); + cp_error ("no field `%D' in union being initialized", + TREE_PURPOSE (tail)); } if (!win) TREE_VALUE (tail) = error_mark_node; -- 2.30.2