diff options
author | Jason Merrill <jason@yorick.cygnus.com> | 1998-06-16 02:51:01 +0000 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 1998-06-15 22:51:01 -0400 |
commit | 1c2c08a5531fb816f8da4599428d6a8223dd3d5a (patch) | |
tree | fa90bdc903bf55966857420c39e6ce0bdf3f83fc | |
parent | 8b45da67d0eaa8d7fec5913d9439d88865edfc55 (diff) | |
download | gcc-1c2c08a5531fb816f8da4599428d6a8223dd3d5a.zip gcc-1c2c08a5531fb816f8da4599428d6a8223dd3d5a.tar.gz gcc-1c2c08a5531fb816f8da4599428d6a8223dd3d5a.tar.bz2 |
method.c (hack_identifier): Don't let a class template out.
* method.c (hack_identifier): Don't let a class template out.
* call.c (check_dtor_name): Split out.
(build_scoped_method_call): Use it.
(build_method_call): Use it.
* init.c (build_offset_ref): Use it.
* typeck.c (build_static_cast): Fix handling of pointers to members.
* decl.c (finish_function): Just return nothing from a constructor.
* typeck.c (c_expand_return): Complain about returning a void
expression from a destructor.
From-SVN: r20521
-rw-r--r-- | gcc/cp/ChangeLog | 15 | ||||
-rw-r--r-- | gcc/cp/call.c | 85 | ||||
-rw-r--r-- | gcc/cp/decl.c | 6 | ||||
-rw-r--r-- | gcc/cp/init.c | 28 | ||||
-rw-r--r-- | gcc/cp/method.c | 5 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 32 |
6 files changed, 89 insertions, 82 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 897a1a1..ea7f271 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,18 @@ +1998-06-16 Jason Merrill <jason@yorick.cygnus.com> + + * method.c (hack_identifier): Don't let a class template out. + + * call.c (check_dtor_name): Split out. + (build_scoped_method_call): Use it. + (build_method_call): Use it. + * init.c (build_offset_ref): Use it. + + * typeck.c (build_static_cast): Fix handling of pointers to members. + + * decl.c (finish_function): Just return nothing from a constructor. + * typeck.c (c_expand_return): Complain about returning a void + expression from a destructor. + 1998-06-13 Mark Mitchell <mark@markmitchell.com> * class.c (alter_access): Accept a BINFO explaining how to get diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 429b4cf..8999897 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -340,6 +340,35 @@ resolve_scope_to_name (outer_type, inner_stuff) return tmp; } +/* Returns nonzero iff the destructor name specified in NAME + (a BIT_NOT_EXPR) matches BASETYPE. The operand of NAME can take many + forms... */ + +int +check_dtor_name (basetype, name) + tree basetype, name; +{ + name = TREE_OPERAND (name, 0); + + if (TREE_CODE (name) == TYPE_DECL) + name = TREE_TYPE (name); + else if (TREE_CODE_CLASS (TREE_CODE (name)) == 't') + /* OK */; + else if (TREE_CODE (name) == IDENTIFIER_NODE) + { + if (IS_AGGR_TYPE (basetype) && name == constructor_name (basetype)) + name = basetype; + else + name = get_type_value (name); + } + else + my_friendly_abort (980605); + + if (name && TYPE_MAIN_VARIANT (basetype) == TYPE_MAIN_VARIANT (name)) + return 1; + return 0; +} + /* Build a method call of the form `EXP->SCOPES::NAME (PARMS)'. This is how virtual function calls are avoided. */ @@ -386,31 +415,9 @@ build_scoped_method_call (exp, basetype, name, parms) binfo = NULL_TREE; /* Check the destructor call syntax. */ - if (TREE_CODE (name) == BIT_NOT_EXPR) - { - tmp = TREE_OPERAND (name, 0); - - if (TREE_CODE (tmp) == TYPE_DECL) - tmp = TREE_TYPE (tmp); - else if (TREE_CODE_CLASS (TREE_CODE (tmp)) == 't') - /* OK */; - else if (TREE_CODE (tmp) == IDENTIFIER_NODE) - { - if (IS_AGGR_TYPE (basetype) && tmp == constructor_name (basetype)) - tmp = basetype; - else - tmp = get_type_value (tmp); - } - else - my_friendly_abort (980605); - - if (! (tmp && TYPE_MAIN_VARIANT (basetype) == TYPE_MAIN_VARIANT (tmp))) - { - cp_error ("qualified type `%T' does not match destructor name `~%T'", - basetype, TREE_OPERAND (name, 0)); - return error_mark_node; - } - } + if (TREE_CODE (name) == BIT_NOT_EXPR && ! check_dtor_name (basetype, name)) + cp_error ("qualified type `%T' does not match destructor name `~%T'", + basetype, TREE_OPERAND (name, 0)); /* Destructors can be "called" for simple types; see 5.2.4 and 12.4 Note that explicit ~int is caught in the parser; this deals with typedefs @@ -645,36 +652,16 @@ build_method_call (instance, name, parms, basetype_path, flags) if (TREE_CODE (name) == BIT_NOT_EXPR) { - tree tmp; - - tmp = name = TREE_OPERAND (name, 0); - if (parms) error ("destructors take no parameters"); basetype = TREE_TYPE (instance); if (TREE_CODE (basetype) == REFERENCE_TYPE) basetype = TREE_TYPE (basetype); - if (TREE_CODE (tmp) == TYPE_DECL) - tmp = TREE_TYPE (tmp); - else if (TREE_CODE_CLASS (TREE_CODE (tmp)) == 't') - /* OK */; - else if (TREE_CODE (tmp) == IDENTIFIER_NODE) - { - if (IS_AGGR_TYPE (basetype) && tmp == constructor_name (basetype)) - tmp = basetype; - else - tmp = get_type_value (tmp); - } - else - my_friendly_abort (980605); - - if (! (tmp && TYPE_MAIN_VARIANT (basetype) == TYPE_MAIN_VARIANT (tmp))) - { - cp_error ("destructor name `~%T' does not match type `%T' of expression", - name, basetype); - return cp_convert (void_type_node, instance); - } + if (! check_dtor_name (basetype, name)) + cp_error + ("destructor name `~%T' does not match type `%T' of expression", + TREE_OPERAND (name, 0), basetype); if (! TYPE_HAS_DESTRUCTOR (complete_type (basetype))) return cp_convert (void_type_node, instance); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index e6c5fff..20dfdf7 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -12599,7 +12599,8 @@ finish_function (lineno, call_poplevel, nested) expand_end_bindings (decls, decls != NULL_TREE, 0); poplevel (decls != NULL_TREE, 0, 0); } - c_expand_return (current_class_ptr); + /* c_expand_return knows to return 'this' from a constructor. */ + c_expand_return (NULL_TREE); } else if (TREE_CODE (TREE_TYPE (DECL_RESULT (current_function_decl))) != VOID_TYPE && return_label != NULL_RTX) @@ -12666,7 +12667,8 @@ finish_function (lineno, call_poplevel, nested) poplevel (decls != NULL_TREE, 1, 0); } - c_expand_return (current_class_ptr); + /* c_expand_return knows to return 'this' from a constructor. */ + c_expand_return (NULL_TREE); current_function_assigns_this = 0; current_function_just_assigned_this = 0; diff --git a/gcc/cp/init.c b/gcc/cp/init.c index aa8fb0c..84015b0 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -1521,7 +1521,6 @@ build_offset_ref (type, name) { tree decl, fnfields, fields, t = error_mark_node; tree basebinfo = NULL_TREE; - int dtor = 0; tree orig_name = name; /* class templates can come in as TEMPLATE_DECLs here. */ @@ -1553,12 +1552,17 @@ build_offset_ref (type, name) if (TREE_CODE (name) == BIT_NOT_EXPR) { - dtor = 1; - name = TREE_OPERAND (name, 0); + if (! check_dtor_name (type, name)) + cp_error ("qualified type `%T' does not match destructor name `~%T'", + type, TREE_OPERAND (name, 0)); + name = dtor_identifier; } - - if (name == constructor_name_full (type)) - name = constructor_name (type); +#if 0 + /* I think this is wrong, but the draft is unclear. --jason 6/15/98 */ + else if (name == constructor_name_full (type) + || name == constructor_name (type)) + name = ctor_identifier; +#endif if (TYPE_SIZE (complete_type (type)) == 0) { @@ -1598,18 +1602,6 @@ build_offset_ref (type, name) else decl = current_class_ref; - if (constructor_name (BINFO_TYPE (basebinfo)) == name) - { - if (dtor) - name = dtor_identifier; - else - name = ctor_identifier; - } - else - if (dtor) - my_friendly_abort (999); - - fnfields = lookup_fnfields (basebinfo, name, 1); fields = lookup_field (basebinfo, name, 0, 0); diff --git a/gcc/cp/method.c b/gcc/cp/method.c index cc01371..1414870 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -1847,6 +1847,11 @@ hack_identifier (value, name) else if (TREE_CODE (value) == NAMESPACE_DECL) /* A namespace is not really expected here; this is likely illegal code. */ return value; + else if (DECL_CLASS_TEMPLATE_P (value)) + { + cp_error ("use of class template `%T' as expression", value); + value = error_mark_node; + } else mark_used (value); diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index b8a46d1..b038a86 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -4774,7 +4774,11 @@ unary_complex_lvalue (code, arg) /* Check all this code for right semantics. */ if (TREE_CODE (t) == FUNCTION_DECL) - return build_unary_op (ADDR_EXPR, t, 0); + { + if (DECL_DESTRUCTOR_P (t)) + cp_error ("taking address of destructor"); + return build_unary_op (ADDR_EXPR, t, 0); + } if (TREE_CODE (t) == VAR_DECL) return build_unary_op (ADDR_EXPR, t, 0); else @@ -5422,8 +5426,8 @@ build_static_cast (type, expr) >= TYPE_READONLY (TREE_TYPE (TREE_TYPE (intype)))) && (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (type))) >= TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (intype)))) - && (binfo = get_binfo (TYPE_OFFSET_BASETYPE (intype), - TYPE_OFFSET_BASETYPE (type), 0)) + && (binfo = get_binfo (TYPE_OFFSET_BASETYPE (TREE_TYPE (type)), + TYPE_OFFSET_BASETYPE (TREE_TYPE (intype)), 0)) && ! TREE_VIA_VIRTUAL (binfo)) ok = 1; } @@ -7206,16 +7210,19 @@ c_expand_return (retval) return; } - if (retval == NULL_TREE) + if (dtor_label) { - /* A non-named return value does not count. */ + if (retval) + error ("returning a value from a destructor"); /* Can't just return from a destructor. */ - if (dtor_label) - { - expand_goto (dtor_label); - return; - } + expand_goto (dtor_label); + return; + } + + if (retval == NULL_TREE) + { + /* A non-named return value does not count. */ if (DECL_CONSTRUCTOR_P (current_function_decl)) retval = current_class_ptr; @@ -7242,13 +7249,12 @@ c_expand_return (retval) return; } } - else if (DECL_CONSTRUCTOR_P (current_function_decl) - && retval != current_class_ptr) + else if (DECL_CONSTRUCTOR_P (current_function_decl)) { if (flag_this_is_variable) error ("return from a constructor: use `this = ...' instead"); else - error ("return from a constructor"); + error ("returning a value from a constructor"); retval = current_class_ptr; } |