From 162bc98d096a61193b3cb490a5430fb852d059eb Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Fri, 16 Oct 1998 03:37:43 +0000 Subject: [PATCH] typeck.c (build_indirect_ref): Complain about a pointer to data member, too. * typeck.c (build_indirect_ref): Complain about a pointer to data member, too. * typeck2.c (build_m_component_ref): Don't indirect a pointer to data member. * init.c (resolve_offset_ref): Don't undo the above. * cp-tree.h (DECL_C_BIT_FIELD, SET_DECL_C_BIT_FIELD): New macros. (struct lang_decl_flags): Add `bitfield'. * class.c (finish_struct_1): Use DECL_C_BIT_FIELD instead of DECL_BIT_FIELD. * decl2.c (grokbitfield, grok_alignof): Likewise. * init.c (build_offset_ref): Likewise. * typeck.c (build_component_addr, expr_sizeof): Likewise. * cvt.c (build_up_reference): Don't crash if taking the address returns error_mark_node. From-SVN: r23124 --- gcc/cp/ChangeLog | 16 ++++++++++++++++ gcc/cp/class.c | 12 +++++------- gcc/cp/cp-tree.h | 9 ++++++++- gcc/cp/cvt.c | 3 +++ gcc/cp/decl2.c | 4 ++-- gcc/cp/init.c | 12 ++++++------ gcc/cp/typeck.c | 10 +++++----- gcc/cp/typeck2.c | 3 +-- 8 files changed, 46 insertions(+), 23 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 2a830ee..1b93d02 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,21 @@ 1998-10-16 Jason Merrill + * typeck.c (build_indirect_ref): Complain about a pointer to data + member, too. + * typeck2.c (build_m_component_ref): Don't indirect a pointer to + data member. + * init.c (resolve_offset_ref): Don't undo the above. + + * cp-tree.h (DECL_C_BIT_FIELD, SET_DECL_C_BIT_FIELD): New macros. + (struct lang_decl_flags): Add `bitfield'. + * class.c (finish_struct_1): Use DECL_C_BIT_FIELD instead of + DECL_BIT_FIELD. + * decl2.c (grokbitfield, grok_alignof): Likewise. + * init.c (build_offset_ref): Likewise. + * typeck.c (build_component_addr, expr_sizeof): Likewise. + * cvt.c (build_up_reference): Don't crash if taking the address + returns error_mark_node. + * decl.c (grokfndecl): Also check ctype when checking for ::main(). 1998-10-15 Jason Merrill diff --git a/gcc/cp/class.c b/gcc/cp/class.c index d440e7c..d503296 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -3541,12 +3541,10 @@ finish_struct_1 (t, warn_anon) } } - /* We set DECL_BIT_FIELD tentatively in grokbitfield. - If the type and width are valid, we'll keep it set. - Otherwise, the flag is cleared. */ - if (DECL_BIT_FIELD (x)) + /* We set DECL_C_BIT_FIELD in grokbitfield. + If the type and width are valid, we'll also set DECL_BIT_FIELD. */ + if (DECL_C_BIT_FIELD (x)) { - DECL_BIT_FIELD (x) = 0; /* Invalid bit-field size done by grokfield. */ /* Detect invalid bit-field type. */ if (DECL_INITIAL (x) @@ -3844,13 +3842,13 @@ finish_struct_1 (t, warn_anon) C++: maybe we will support default field initialization some day... */ /* Delete all zero-width bit-fields from the front of the fieldlist */ - while (fields && DECL_BIT_FIELD (fields) + while (fields && DECL_C_BIT_FIELD (fields) && DECL_INITIAL (fields)) fields = TREE_CHAIN (fields); /* Delete all such fields from the rest of the fields. */ for (x = fields; x;) { - if (TREE_CHAIN (x) && DECL_BIT_FIELD (TREE_CHAIN (x)) + if (TREE_CHAIN (x) && DECL_C_BIT_FIELD (TREE_CHAIN (x)) && DECL_INITIAL (TREE_CHAIN (x))) TREE_CHAIN (x) = TREE_CHAIN (TREE_CHAIN (x)); else diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 76ba93e..a7ab145 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -1065,7 +1065,8 @@ struct lang_decl_flags unsigned not_really_extern : 1; unsigned comdat : 1; unsigned needs_final_overrider : 1; - unsigned dummy : 3; + unsigned bitfield : 1; + unsigned dummy : 2; tree access; tree context; @@ -1398,6 +1399,12 @@ extern int flag_new_for_scope; /* Record whether a typedef for type `int' was actually `signed int'. */ #define C_TYPEDEF_EXPLICITLY_SIGNED(exp) DECL_LANG_FLAG_1 ((exp)) +/* In a FIELD_DECL, nonzero if the decl was originally a bitfield. */ +#define DECL_C_BIT_FIELD(NODE) \ + (DECL_LANG_SPECIFIC (NODE) && DECL_LANG_SPECIFIC (NODE)->decl_flags.bitfield) +#define SET_DECL_C_BIT_FIELD(NODE) \ + (DECL_LANG_SPECIFIC (NODE)->decl_flags.bitfield = 1) + /* Nonzero if the type T promotes to itself. ANSI C states explicitly the list of types that promote; in particular, short promotes to int even if they have the same width. */ diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index 50c4fc5..a228e27 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -377,6 +377,9 @@ build_up_reference (type, arg, flags) address, transform all occurrences of the register, into a memory reference we could win better. */ rval = build_unary_op (ADDR_EXPR, arg, 1); + if (rval == error_mark_node) + return error_mark_node; + if ((flags & LOOKUP_PROTECT) && TYPE_MAIN_VARIANT (argtype) != TYPE_MAIN_VARIANT (target_type) && IS_AGGR_TYPE (argtype) diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 1f80473..92e01fe 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -1046,7 +1046,7 @@ grok_alignof (expr) return build_min (ALIGNOF_EXPR, sizetype, expr); if (TREE_CODE (expr) == COMPONENT_REF - && DECL_BIT_FIELD (TREE_OPERAND (expr, 1))) + && DECL_C_BIT_FIELD (TREE_OPERAND (expr, 1))) error ("`__alignof__' applied to a bit-field"); if (TREE_CODE (expr) == INDIRECT_REF) @@ -1809,7 +1809,7 @@ grokbitfield (declarator, declspecs, width) { constant_expression_warning (width); DECL_INITIAL (value) = width; - DECL_BIT_FIELD (value) = 1; + SET_DECL_C_BIT_FIELD (value); } DECL_IN_AGGR_P (value) = 1; diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 2386215..985718c 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -1686,7 +1686,7 @@ build_offset_ref (type, name) return convert_from_reference (t); } - if (TREE_CODE (t) == FIELD_DECL && DECL_BIT_FIELD (t)) + if (TREE_CODE (t) == FIELD_DECL && DECL_C_BIT_FIELD (t)) { cp_error ("illegal pointer to bit field `%D'", t); return error_mark_node; @@ -1740,7 +1740,8 @@ resolve_offset_ref (exp) } if ((TREE_CODE (member) == VAR_DECL - && ! TYPE_PTRMEMFUNC_P (TREE_TYPE (member))) + && ! TYPE_PTRMEMFUNC_P (TREE_TYPE (member)) + && ! TYPE_PTRMEM_P (TREE_TYPE (member))) || TREE_CODE (TREE_TYPE (member)) == FUNCTION_TYPE || TREE_CODE (TREE_TYPE (member)) == METHOD_TYPE) { @@ -1824,7 +1825,7 @@ resolve_offset_ref (exp) for the dereferenced pointer-to-member construct. */ addr = build_unary_op (ADDR_EXPR, base, 0); - if (TREE_CODE (TREE_TYPE (member)) == OFFSET_TYPE) + if (TYPE_PTRMEM_P (TREE_TYPE (member))) { if (addr == error_mark_node) { @@ -1832,10 +1833,9 @@ resolve_offset_ref (exp) return error_mark_node; } - basetype = TYPE_OFFSET_BASETYPE (TREE_TYPE (member)); + basetype = TYPE_OFFSET_BASETYPE (TREE_TYPE (TREE_TYPE (member))); addr = convert_pointer_to (basetype, addr); - member = cp_convert (ptrdiff_type_node, - build_unary_op (ADDR_EXPR, member, 0)); + member = cp_convert (ptrdiff_type_node, member); /* Pointer to data members are offset by one, so that a null pointer with a real value of 0 is distinguishable from an diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 3579176..c2f6eba 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -1538,7 +1538,7 @@ expr_sizeof (e) return build_min (SIZEOF_EXPR, sizetype, e); if (TREE_CODE (e) == COMPONENT_REF - && DECL_BIT_FIELD (TREE_OPERAND (e, 1))) + && DECL_C_BIT_FIELD (TREE_OPERAND (e, 1))) error ("sizeof applied to a bit-field"); /* ANSI says arrays and functions are converted inside comma. But we can't really convert them in build_compound_expr @@ -2291,7 +2291,7 @@ build_indirect_ref (ptr, errorstring) if (ptr == current_class_ptr) return current_class_ref; - if (TREE_CODE (type) == POINTER_TYPE || TREE_CODE (type) == REFERENCE_TYPE) + if (TYPE_PTR_P (type) || TREE_CODE (type) == REFERENCE_TYPE) { /* [expr.unary.op] @@ -2326,8 +2326,8 @@ build_indirect_ref (ptr, errorstring) } /* `pointer' won't be an error_mark_node if we were given a pointer to member, so it's cool to check for this here. */ - else if (TYPE_PTRMEMFUNC_P (type)) - error ("invalid use of `%s' on pointer to member function", errorstring); + else if (TYPE_PTRMEM_P (type) || TYPE_PTRMEMFUNC_P (type)) + error ("invalid use of `%s' on pointer to member", errorstring); else if (TREE_CODE (type) == RECORD_TYPE && (IS_SIGNATURE_POINTER (type) || IS_SIGNATURE_REFERENCE (type))) error ("cannot dereference signature pointer/reference"); @@ -4248,7 +4248,7 @@ build_component_addr (arg, argtype, msg) tree basetype = decl_type_context (field); tree rval = build_unary_op (ADDR_EXPR, TREE_OPERAND (arg, 0), 0); - if (DECL_BIT_FIELD (field)) + if (DECL_C_BIT_FIELD (field)) { error (msg, IDENTIFIER_POINTER (DECL_NAME (field))); return error_mark_node; diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index f5193cc..14e7ae2 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -1393,8 +1393,7 @@ build_m_component_ref (datum, component) } else { - component = build_indirect_ref (component, NULL_PTR); - type = TREE_TYPE (component); + type = TREE_TYPE (TREE_TYPE (component)); rettype = TREE_TYPE (type); } -- 2.7.4