Commit 4546865e by Mark Mitchell Committed by Mark Mitchell

call.c (build_op_delete_call): Do not forget the placement arguments when…

call.c (build_op_delete_call): Do not forget the placement arguments when iterating through mutiple delete...

	* call.c (build_op_delete_call): Do not forget the placement
	arguments when iterating through mutiple delete operators.

	* cp-tree.h (svaed_scope): Remove last_parms.
	(NEW_DELETE_OPNAME_P): New macro.
	(last_function_parms): Remove.
	(do_friend): Adjust prototype.
	* decl.c (grokparms): Return the PARM_DECLs directly, rather than
	using last_function_parms.
	(grokfndecl): Take the PARM_DECLs as an argument, rather than
	using last_function_parms.
	(grokdeclarator): Adjust accordingly.  Do not form METHOD_TYPEs
	for class-specific operator new and operator delete.
	(grok_op_properties): Do not look for allocation functions with
	METHOD_TYPEs.
	(start_function): Use DECL_ARGUMENTS instead of
	last_function_parms.
	* decl.h (last_function_parms): Do not declare.
	* decl2.c (grokclassfn): Do not use last_function_parms.
	* friend.c (do_friend): Remove parmdecls parameter.
	* name-lookup.c (push_to_top_level): Do not save last_function_parms.
	(pop_from_top_level): Do not restore it.
	* pt.c (check_explicit_specialization): Do not adjust
	last_function_parms.

	* name-lookup.c (do_local_using_decl): Create a local binding for
	types brought in via using declarations.

	* name-lookup.c (lookup_arg_dependent): Handle block-scope
	function declarations correctly.

	* semantics.c (finish_id_expression): Correct handling of
	conversion operators to dependent types.

	* typeck.c (lookup_destructor): Allow the use of destructors from
	base classes.

	* g++.dg/init/placement3.C: New test.

	* g++.dg/template/spec13.C: New test.

	* g++.dg/lookup/using11.C: New test.

	* g++.dg/lookup/koenig3.C: New test.

	* g++.dg/template/operator2.C: New test.

	* g++.dg/expr/dtor3.C: New test.
	* g++.old-deja/g++.brendan/crash15.C: Remove incorrect dg-error
	marker.
	* g++.old-deja/g++.law/visibility28.C: Likewise.

From-SVN: r79722
parent b40bc279
2004-03-19 Mark Mitchell <mark@codesourcery.com>
* call.c (build_op_delete_call): Do not forget the placement
arguments when iterating through mutiple delete operators.
* cp-tree.h (svaed_scope): Remove last_parms.
(NEW_DELETE_OPNAME_P): New macro.
(last_function_parms): Remove.
(do_friend): Adjust prototype.
* decl.c (grokparms): Return the PARM_DECLs directly, rather than
using last_function_parms.
(grokfndecl): Take the PARM_DECLs as an argument, rather than
using last_function_parms.
(grokdeclarator): Adjust accordingly. Do not form METHOD_TYPEs
for class-specific operator new and operator delete.
(grok_op_properties): Do not look for allocation functions with
METHOD_TYPEs.
(start_function): Use DECL_ARGUMENTS instead of
last_function_parms.
* decl.h (last_function_parms): Do not declare.
* decl2.c (grokclassfn): Do not use last_function_parms.
* friend.c (do_friend): Remove parmdecls parameter.
* name-lookup.c (push_to_top_level): Do not save last_function_parms.
(pop_from_top_level): Do not restore it.
* pt.c (check_explicit_specialization): Do not adjust
last_function_parms.
* name-lookup.c (do_local_using_decl): Create a local binding for
types brought in via using declarations.
* name-lookup.c (lookup_arg_dependent): Handle block-scope
function declarations correctly.
* semantics.c (finish_id_expression): Correct handling of
conversion operators to dependent types.
* typeck.c (lookup_destructor): Allow the use of destructors from
base classes.
2004-03-19 Richard Kenner <kenner@vlsi1.ultra.nyu.edu> 2004-03-19 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* cxx-pretty-print.c (pp_cxx_unqualified_id): Use * cxx-pretty-print.c (pp_cxx_unqualified_id): Use
......
...@@ -3979,15 +3979,15 @@ build_op_delete_call (enum tree_code code, tree addr, tree size, ...@@ -3979,15 +3979,15 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
/* On the first pass, check the rest of the arguments. */ /* On the first pass, check the rest of the arguments. */
if (pass == 0) if (pass == 0)
{ {
while (argtypes && t) tree a = argtypes;
while (a && t)
{ {
if (!same_type_p (TREE_VALUE (argtypes), if (!same_type_p (TREE_VALUE (a), TREE_VALUE (t)))
TREE_VALUE (t)))
break; break;
argtypes = TREE_CHAIN (argtypes); a = TREE_CHAIN (a);
t = TREE_CHAIN (t); t = TREE_CHAIN (t);
} }
if (!argtypes && !t) if (!a && !t)
break; break;
} }
/* On the second pass, the second argument must be /* On the second pass, the second argument must be
......
...@@ -679,7 +679,6 @@ struct saved_scope GTY(()) ...@@ -679,7 +679,6 @@ struct saved_scope GTY(())
tree x_previous_class_type; tree x_previous_class_type;
tree x_previous_class_values; tree x_previous_class_values;
tree x_saved_tree; tree x_saved_tree;
tree last_parms;
HOST_WIDE_INT x_processing_template_decl; HOST_WIDE_INT x_processing_template_decl;
int x_processing_specialization; int x_processing_specialization;
...@@ -837,6 +836,14 @@ struct language_function GTY(()) ...@@ -837,6 +836,14 @@ struct language_function GTY(())
#define current_function_return_value \ #define current_function_return_value \
(cp_function_chain->x_return_value) (cp_function_chain->x_return_value)
/* True if NAME is the IDENTIFIER_NODE for an overloaded "operator
new" or "operator delete". */
#define NEW_DELETE_OPNAME_P(NAME) \
((NAME) == ansi_opname (NEW_EXPR) \
|| (NAME) == ansi_opname (VEC_NEW_EXPR) \
|| (NAME) == ansi_opname (DELETE_EXPR) \
|| (NAME) == ansi_opname (VEC_DELETE_EXPR))
#define ansi_opname(CODE) \ #define ansi_opname(CODE) \
(operator_name_info[(int) (CODE)].identifier) (operator_name_info[(int) (CODE)].identifier)
#define ansi_assopname(CODE) \ #define ansi_assopname(CODE) \
...@@ -3693,7 +3700,6 @@ extern tree check_elaborated_type_specifier (enum tag_types, tree, bool); ...@@ -3693,7 +3700,6 @@ extern tree check_elaborated_type_specifier (enum tag_types, tree, bool);
extern void warn_extern_redeclared_static (tree, tree); extern void warn_extern_redeclared_static (tree, tree);
extern bool have_extern_spec; extern bool have_extern_spec;
extern GTY(()) tree last_function_parms;
/* in decl2.c */ /* in decl2.c */
extern bool check_java_method (tree); extern bool check_java_method (tree);
...@@ -3774,7 +3780,7 @@ extern tree cplus_expand_constant (tree); ...@@ -3774,7 +3780,7 @@ extern tree cplus_expand_constant (tree);
extern int is_friend (tree, tree); extern int is_friend (tree, tree);
extern void make_friend_class (tree, tree, bool); extern void make_friend_class (tree, tree, bool);
extern void add_friend (tree, tree, bool); extern void add_friend (tree, tree, bool);
extern tree do_friend (tree, tree, tree, tree, tree, enum overload_flags, tree, int); extern tree do_friend (tree, tree, tree, tree, enum overload_flags, tree, int);
/* in init.c */ /* in init.c */
extern tree expand_member_init (tree); extern tree expand_member_init (tree);
......
...@@ -52,7 +52,7 @@ Boston, MA 02111-1307, USA. */ ...@@ -52,7 +52,7 @@ Boston, MA 02111-1307, USA. */
#include "debug.h" #include "debug.h"
#include "timevar.h" #include "timevar.h"
static tree grokparms (tree); static tree grokparms (tree, tree *);
static const char *redeclaration_error_message (tree, tree); static const char *redeclaration_error_message (tree, tree);
static int decl_jump_unsafe (tree); static int decl_jump_unsafe (tree);
...@@ -61,7 +61,7 @@ static int ambi_op_p (enum tree_code); ...@@ -61,7 +61,7 @@ static int ambi_op_p (enum tree_code);
static int unary_op_p (enum tree_code); static int unary_op_p (enum tree_code);
static void push_local_name (tree); static void push_local_name (tree);
static tree grok_reference_init (tree, tree, tree, tree *); static tree grok_reference_init (tree, tree, tree, tree *);
static tree grokfndecl (tree, tree, tree, tree, int, static tree grokfndecl (tree, tree, tree, tree, tree, int,
enum overload_flags, tree, enum overload_flags, tree,
tree, int, int, int, int, int, int, tree); tree, int, int, int, int, int, int, tree);
static tree grokvardecl (tree, tree, RID_BIT_TYPE *, int, int, tree); static tree grokvardecl (tree, tree, RID_BIT_TYPE *, int, int, tree);
...@@ -207,9 +207,6 @@ tree static_aggregates; ...@@ -207,9 +207,6 @@ tree static_aggregates;
tree integer_two_node, integer_three_node; tree integer_two_node, integer_three_node;
/* Similar, for last_function_parm_tags. */
tree last_function_parms;
/* A list of all LABEL_DECLs in the function that have names. Here so /* A list of all LABEL_DECLs in the function that have names. Here so
we can clear out their names' definitions at the end of the we can clear out their names' definitions at the end of the
function, and so we can check the validity of jumps to these labels. */ function, and so we can check the validity of jumps to these labels. */
...@@ -5419,6 +5416,7 @@ bad_specifiers (tree object, ...@@ -5419,6 +5416,7 @@ bad_specifiers (tree object,
TYPE is type this FUNCTION_DECL should have, either FUNCTION_TYPE TYPE is type this FUNCTION_DECL should have, either FUNCTION_TYPE
or METHOD_TYPE. or METHOD_TYPE.
DECLARATOR is the function's name. DECLARATOR is the function's name.
PARMS is a chain of PARM_DECLs for the function.
VIRTUALP is truthvalue of whether the function is virtual or not. VIRTUALP is truthvalue of whether the function is virtual or not.
FLAGS are to be passed through to `grokclassfn'. FLAGS are to be passed through to `grokclassfn'.
QUALS are qualifiers indicating whether the function is `const' QUALS are qualifiers indicating whether the function is `const'
...@@ -5434,6 +5432,7 @@ static tree ...@@ -5434,6 +5432,7 @@ static tree
grokfndecl (tree ctype, grokfndecl (tree ctype,
tree type, tree type,
tree declarator, tree declarator,
tree parms,
tree orig_declarator, tree orig_declarator,
int virtualp, int virtualp,
enum overload_flags flags, enum overload_flags flags,
...@@ -5456,6 +5455,7 @@ grokfndecl (tree ctype, ...@@ -5456,6 +5455,7 @@ grokfndecl (tree ctype,
type = build_exception_variant (type, raises); type = build_exception_variant (type, raises);
decl = build_lang_decl (FUNCTION_DECL, declarator, type); decl = build_lang_decl (FUNCTION_DECL, declarator, type);
DECL_ARGUMENTS (decl) = parms;
/* Propagate volatile out from type to decl. */ /* Propagate volatile out from type to decl. */
if (TYPE_VOLATILE (type)) if (TYPE_VOLATILE (type))
TREE_THIS_VOLATILE (decl) = 1; TREE_THIS_VOLATILE (decl) = 1;
...@@ -5680,12 +5680,9 @@ grokfndecl (tree ctype, ...@@ -5680,12 +5680,9 @@ grokfndecl (tree ctype,
if (old_decl && DECL_STATIC_FUNCTION_P (old_decl) if (old_decl && DECL_STATIC_FUNCTION_P (old_decl)
&& TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE) && TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE)
{ /* Remove the `this' parm added by grokclassfn.
/* Remove the `this' parm added by grokclassfn. XXX Isn't this done in start_function, too? */
XXX Isn't this done in start_function, too? */ revert_static_member_fn (decl);
revert_static_member_fn (decl);
last_function_parms = TREE_CHAIN (last_function_parms);
}
if (old_decl && DECL_ARTIFICIAL (old_decl)) if (old_decl && DECL_ARTIFICIAL (old_decl))
error ("definition of implicitly-declared `%D'", old_decl); error ("definition of implicitly-declared `%D'", old_decl);
...@@ -6339,6 +6336,7 @@ grokdeclarator (tree declarator, ...@@ -6339,6 +6336,7 @@ grokdeclarator (tree declarator,
tree in_namespace = NULL_TREE; tree in_namespace = NULL_TREE;
tree returned_attrs = NULL_TREE; tree returned_attrs = NULL_TREE;
tree scope = NULL_TREE; tree scope = NULL_TREE;
tree parms = NULL_TREE;
RIDBIT_RESET_ALL (specbits); RIDBIT_RESET_ALL (specbits);
if (decl_context == FUNCDEF) if (decl_context == FUNCDEF)
...@@ -7411,7 +7409,7 @@ grokdeclarator (tree declarator, ...@@ -7411,7 +7409,7 @@ grokdeclarator (tree declarator,
declarator = TREE_OPERAND (declarator, 0); declarator = TREE_OPERAND (declarator, 0);
arg_types = grokparms (inner_parms); arg_types = grokparms (inner_parms, &parms);
if (declarator && flags == DTOR_FLAG) if (declarator && flags == DTOR_FLAG)
{ {
...@@ -7425,7 +7423,7 @@ grokdeclarator (tree declarator, ...@@ -7425,7 +7423,7 @@ grokdeclarator (tree declarator,
{ {
error ("destructors may not have parameters"); error ("destructors may not have parameters");
arg_types = void_list_node; arg_types = void_list_node;
last_function_parms = NULL_TREE; parms = NULL_TREE;
} }
} }
...@@ -7592,7 +7590,11 @@ grokdeclarator (tree declarator, ...@@ -7592,7 +7590,11 @@ grokdeclarator (tree declarator,
} }
else if (TREE_CODE (type) == FUNCTION_TYPE) else if (TREE_CODE (type) == FUNCTION_TYPE)
{ {
if (current_class_type == NULL_TREE || friendp) if (NEW_DELETE_OPNAME_P (sname))
/* Overloaded operator new and operator delete
are always static functions. */
;
else if (current_class_type == NULL_TREE || friendp)
type type
= build_method_type_directly (ctype, = build_method_type_directly (ctype,
TREE_TYPE (type), TREE_TYPE (type),
...@@ -7851,8 +7853,7 @@ grokdeclarator (tree declarator, ...@@ -7851,8 +7853,7 @@ grokdeclarator (tree declarator,
type = build_cplus_array_type (TREE_TYPE (type), NULL_TREE); type = build_cplus_array_type (TREE_TYPE (type), NULL_TREE);
/* Detect where we're using a typedef of function type to declare a /* Detect where we're using a typedef of function type to declare a
function. last_function_parms will not be set, so we must create function. PARMS will not be set, so we must create it now. */
it now. */
if (type == typedef_type && TREE_CODE (type) == FUNCTION_TYPE) if (type == typedef_type && TREE_CODE (type) == FUNCTION_TYPE)
{ {
...@@ -7867,7 +7868,7 @@ grokdeclarator (tree declarator, ...@@ -7867,7 +7868,7 @@ grokdeclarator (tree declarator,
decls = decl; decls = decl;
} }
last_function_parms = nreverse (decls); parms = nreverse (decls);
} }
/* If this is a type name (such as, in a cast or sizeof), /* If this is a type name (such as, in a cast or sizeof),
...@@ -8061,10 +8062,7 @@ grokdeclarator (tree declarator, ...@@ -8061,10 +8062,7 @@ grokdeclarator (tree declarator,
return void_type_node; return void_type_node;
} }
if (declarator == ansi_opname (NEW_EXPR) if (NEW_DELETE_OPNAME_P (declarator))
|| declarator == ansi_opname (VEC_NEW_EXPR)
|| declarator == ansi_opname (DELETE_EXPR)
|| declarator == ansi_opname (VEC_DELETE_EXPR))
{ {
if (virtualp) if (virtualp)
{ {
...@@ -8087,6 +8085,7 @@ grokdeclarator (tree declarator, ...@@ -8087,6 +8085,7 @@ grokdeclarator (tree declarator,
decl = grokfndecl (ctype, type, decl = grokfndecl (ctype, type,
TREE_CODE (declarator) != TEMPLATE_ID_EXPR TREE_CODE (declarator) != TEMPLATE_ID_EXPR
? declarator : dname, ? declarator : dname,
parms,
declarator, declarator,
virtualp, flags, quals, raises, virtualp, flags, quals, raises,
friendp ? -1 : 0, friendp, publicp, inlinep, friendp ? -1 : 0, friendp, publicp, inlinep,
...@@ -8133,6 +8132,7 @@ grokdeclarator (tree declarator, ...@@ -8133,6 +8132,7 @@ grokdeclarator (tree declarator,
decl = grokfndecl (ctype, type, decl = grokfndecl (ctype, type,
TREE_CODE (declarator) != TEMPLATE_ID_EXPR TREE_CODE (declarator) != TEMPLATE_ID_EXPR
? declarator : dname, ? declarator : dname,
parms,
declarator, declarator,
virtualp, flags, quals, raises, virtualp, flags, quals, raises,
friendp ? -1 : 0, friendp, 1, 0, funcdef_flag, friendp ? -1 : 0, friendp, 1, 0, funcdef_flag,
...@@ -8190,8 +8190,7 @@ grokdeclarator (tree declarator, ...@@ -8190,8 +8190,7 @@ grokdeclarator (tree declarator,
} }
decl = do_friend (ctype, declarator, decl, decl = do_friend (ctype, declarator, decl,
last_function_parms, *attrlist, *attrlist, flags, quals, funcdef_flag);
flags, quals, funcdef_flag);
return decl; return decl;
} }
else else
...@@ -8304,7 +8303,8 @@ grokdeclarator (tree declarator, ...@@ -8304,7 +8303,8 @@ grokdeclarator (tree declarator,
virtualp = 0; virtualp = 0;
} }
} }
else if (TREE_CODE (type) == FUNCTION_TYPE && staticp < 2) else if (TREE_CODE (type) == FUNCTION_TYPE && staticp < 2
&& !NEW_DELETE_OPNAME_P (original_name))
type = build_method_type_directly (ctype, type = build_method_type_directly (ctype,
TREE_TYPE (type), TREE_TYPE (type),
TYPE_ARG_TYPES (type)); TYPE_ARG_TYPES (type));
...@@ -8314,7 +8314,7 @@ grokdeclarator (tree declarator, ...@@ -8314,7 +8314,7 @@ grokdeclarator (tree declarator,
|| RIDBIT_SETP (RID_EXTERN, specbits) || RIDBIT_SETP (RID_EXTERN, specbits)
|| !RIDBIT_SETP (RID_STATIC, specbits)); || !RIDBIT_SETP (RID_STATIC, specbits));
decl = grokfndecl (ctype, type, original_name, declarator, decl = grokfndecl (ctype, type, original_name, parms, declarator,
virtualp, flags, quals, raises, virtualp, flags, quals, raises,
1, friendp, 1, friendp,
publicp, inlinep, funcdef_flag, publicp, inlinep, funcdef_flag,
...@@ -8552,10 +8552,10 @@ check_default_argument (tree decl, tree arg) ...@@ -8552,10 +8552,10 @@ check_default_argument (tree decl, tree arg)
flag. If unset, we append void_list_node. A parmlist declared flag. If unset, we append void_list_node. A parmlist declared
as `(void)' is accepted as the empty parmlist. as `(void)' is accepted as the empty parmlist.
Also set last_function_parms to the chain of PARM_DECLs. */ *PARMS is set to the chain of PARM_DECLs created. */
static tree static tree
grokparms (tree first_parm) grokparms (tree first_parm, tree *parms)
{ {
tree result = NULL_TREE; tree result = NULL_TREE;
tree decls = NULL_TREE; tree decls = NULL_TREE;
...@@ -8661,7 +8661,7 @@ grokparms (tree first_parm) ...@@ -8661,7 +8661,7 @@ grokparms (tree first_parm)
result = nreverse (result); result = nreverse (result);
if (!ellipsis) if (!ellipsis)
result = chainon (result, void_list_node); result = chainon (result, void_list_node);
last_function_parms = decls; *parms = decls;
return result; return result;
} }
...@@ -8914,21 +8914,9 @@ grok_op_properties (tree decl, int friendp, bool complain) ...@@ -8914,21 +8914,9 @@ grok_op_properties (tree decl, int friendp, bool complain)
} }
if (operator_code == NEW_EXPR || operator_code == VEC_NEW_EXPR) if (operator_code == NEW_EXPR || operator_code == VEC_NEW_EXPR)
{ TREE_TYPE (decl) = coerce_new_type (TREE_TYPE (decl));
/* When the compiler encounters the definition of A::operator new, it
doesn't look at the class declaration to find out if it's static. */
if (methodp)
revert_static_member_fn (decl);
TREE_TYPE (decl) = coerce_new_type (TREE_TYPE (decl));
}
else if (operator_code == DELETE_EXPR || operator_code == VEC_DELETE_EXPR) else if (operator_code == DELETE_EXPR || operator_code == VEC_DELETE_EXPR)
{ TREE_TYPE (decl) = coerce_delete_type (TREE_TYPE (decl));
if (methodp)
revert_static_member_fn (decl);
TREE_TYPE (decl) = coerce_delete_type (TREE_TYPE (decl));
}
else else
{ {
/* An operator function must either be a non-static member function /* An operator function must either be a non-static member function
...@@ -10039,8 +10027,6 @@ start_function (tree declspecs, tree declarator, tree attrs, int flags) ...@@ -10039,8 +10027,6 @@ start_function (tree declspecs, tree declarator, tree attrs, int flags)
else else
doing_friend = 1; doing_friend = 1;
} }
last_function_parms = DECL_ARGUMENTS (decl1);
} }
else else
{ {
...@@ -10091,7 +10077,6 @@ start_function (tree declspecs, tree declarator, tree attrs, int flags) ...@@ -10091,7 +10077,6 @@ start_function (tree declspecs, tree declarator, tree attrs, int flags)
&& TREE_CODE (TREE_TYPE (decl1)) == METHOD_TYPE) && TREE_CODE (TREE_TYPE (decl1)) == METHOD_TYPE)
{ {
revert_static_member_fn (decl1); revert_static_member_fn (decl1);
last_function_parms = TREE_CHAIN (last_function_parms);
ctype = NULL_TREE; ctype = NULL_TREE;
} }
...@@ -10138,7 +10123,7 @@ start_function (tree declspecs, tree declarator, tree attrs, int flags) ...@@ -10138,7 +10123,7 @@ start_function (tree declspecs, tree declarator, tree attrs, int flags)
/* Save the parm names or decls from this function's declarator /* Save the parm names or decls from this function's declarator
where store_parm_decls will find them. */ where store_parm_decls will find them. */
current_function_parms = last_function_parms; current_function_parms = DECL_ARGUMENTS (decl1);
/* Make sure the parameter and return types are reasonable. When /* Make sure the parameter and return types are reasonable. When
you declare a function, these types can be incomplete, but they you declare a function, these types can be incomplete, but they
......
...@@ -33,10 +33,6 @@ enum decl_context ...@@ -33,10 +33,6 @@ enum decl_context
/* We need this in here to get the decl_context definition. */ /* We need this in here to get the decl_context definition. */
extern tree grokdeclarator (tree, tree, enum decl_context, int, tree*); extern tree grokdeclarator (tree, tree, enum decl_context, int, tree*);
/* Parsing a function declarator leaves a list of parameter names
or a chain or parameter decls here. */
extern GTY(()) tree last_function_parms;
#ifdef DEBUG_CP_BINDING_LEVELS #ifdef DEBUG_CP_BINDING_LEVELS
/* Purely for debugging purposes. */ /* Purely for debugging purposes. */
extern int debug_bindings_indentation; extern int debug_bindings_indentation;
......
...@@ -336,11 +336,10 @@ grokclassfn (tree ctype, tree function, enum overload_flags flags, tree quals) ...@@ -336,11 +336,10 @@ grokclassfn (tree ctype, tree function, enum overload_flags flags, tree quals)
qual_type = cp_build_qualified_type (type, this_quals); qual_type = cp_build_qualified_type (type, this_quals);
parm = build_artificial_parm (this_identifier, qual_type); parm = build_artificial_parm (this_identifier, qual_type);
c_apply_type_quals_to_decl (this_quals, parm); c_apply_type_quals_to_decl (this_quals, parm);
TREE_CHAIN (parm) = last_function_parms; TREE_CHAIN (parm) = DECL_ARGUMENTS (function);
last_function_parms = parm; DECL_ARGUMENTS (function) = parm;
} }
DECL_ARGUMENTS (function) = last_function_parms;
DECL_CONTEXT (function) = ctype; DECL_CONTEXT (function) = ctype;
if (flags == DTOR_FLAG) if (flags == DTOR_FLAG)
......
...@@ -314,17 +314,13 @@ make_friend_class (tree type, tree friend_type, bool complain) ...@@ -314,17 +314,13 @@ make_friend_class (tree type, tree friend_type, bool complain)
DECL is the FUNCTION_DECL that the friend is. DECL is the FUNCTION_DECL that the friend is.
In case we are parsing a friend which is part of an inline
definition, we will need to store PARM_DECL chain that comes
with it into the DECL_ARGUMENTS slot of the FUNCTION_DECL.
FLAGS is just used for `grokclassfn'. FLAGS is just used for `grokclassfn'.
QUALS say what special qualifies should apply to the object QUALS say what special qualifies should apply to the object
pointed to by `this'. */ pointed to by `this'. */
tree tree
do_friend (tree ctype, tree declarator, tree decl, tree parmdecls, do_friend (tree ctype, tree declarator, tree decl,
tree attrlist, enum overload_flags flags, tree quals, tree attrlist, enum overload_flags flags, tree quals,
int funcdef_flag) int funcdef_flag)
{ {
...@@ -424,7 +420,6 @@ do_friend (tree ctype, tree declarator, tree decl, tree parmdecls, ...@@ -424,7 +420,6 @@ do_friend (tree ctype, tree declarator, tree decl, tree parmdecls,
Note that because classes all wind up being top-level Note that because classes all wind up being top-level
in their scope, their friend wind up in top-level scope as well. */ in their scope, their friend wind up in top-level scope as well. */
DECL_ARGUMENTS (decl) = parmdecls;
if (funcdef_flag) if (funcdef_flag)
SET_DECL_FRIEND_CONTEXT (decl, current_class_type); SET_DECL_FRIEND_CONTEXT (decl, current_class_type);
......
...@@ -2272,7 +2272,10 @@ do_local_using_decl (tree decl, tree scope, tree name) ...@@ -2272,7 +2272,10 @@ do_local_using_decl (tree decl, tree scope, tree name)
push_local_binding (name, newval, PUSH_USING); push_local_binding (name, newval, PUSH_USING);
} }
if (newtype) if (newtype)
set_identifier_type_value (name, newtype); {
push_local_binding (name, newtype, PUSH_USING);
set_identifier_type_value (name, newtype);
}
/* Emit debug info. */ /* Emit debug info. */
if (!processing_template_decl) if (!processing_template_decl)
...@@ -4474,11 +4477,15 @@ lookup_arg_dependent (tree name, tree fns, tree args) ...@@ -4474,11 +4477,15 @@ lookup_arg_dependent (tree name, tree fns, tree args)
we found were brought into the current namespace via a using we found were brought into the current namespace via a using
declaration, we have not really checked the namespace from which declaration, we have not really checked the namespace from which
they came. Therefore, we check all namespaces here -- unless the they came. Therefore, we check all namespaces here -- unless the
function we have is from the current namespace. */ function we have is from the current namespace. Even then, we
must check all namespaces if the function is a local
declaration; any other declarations present at namespace scope
should be visible during argument-dependent lookup. */
if (fns) if (fns)
fn = OVL_CURRENT (fns); fn = OVL_CURRENT (fns);
if (fn && TREE_CODE (fn) == FUNCTION_DECL if (fn && TREE_CODE (fn) == FUNCTION_DECL
&& CP_DECL_CONTEXT (fn) != current_decl_namespace ()) && (CP_DECL_CONTEXT (fn) != current_decl_namespace ()
|| DECL_LOCAL_FUNCTION_P (fn)))
k.namespaces = NULL_TREE; k.namespaces = NULL_TREE;
else else
/* Setting NAMESPACES is purely an optimization; it prevents /* Setting NAMESPACES is purely an optimization; it prevents
...@@ -4835,7 +4842,6 @@ push_to_top_level (void) ...@@ -4835,7 +4842,6 @@ push_to_top_level (void)
s->bindings = b; s->bindings = b;
s->need_pop_function_context = need_pop; s->need_pop_function_context = need_pop;
s->function_decl = current_function_decl; s->function_decl = current_function_decl;
s->last_parms = last_function_parms;
scope_chain = s; scope_chain = s;
current_function_decl = NULL_TREE; current_function_decl = NULL_TREE;
...@@ -4873,7 +4879,6 @@ pop_from_top_level (void) ...@@ -4873,7 +4879,6 @@ pop_from_top_level (void)
if (s->need_pop_function_context) if (s->need_pop_function_context)
pop_function_context_from (NULL_TREE); pop_function_context_from (NULL_TREE);
current_function_decl = s->function_decl; current_function_decl = s->function_decl;
last_function_parms = s->last_parms;
timevar_pop (TV_NAME_LOOKUP); timevar_pop (TV_NAME_LOOKUP);
} }
......
...@@ -1910,15 +1910,10 @@ check_explicit_specialization (tree declarator, ...@@ -1910,15 +1910,10 @@ check_explicit_specialization (tree declarator,
/* If we thought that the DECL was a member function, but it /* If we thought that the DECL was a member function, but it
turns out to be specializing a static member function, turns out to be specializing a static member function,
make DECL a static member function as well. We also have make DECL a static member function as well. */
to adjust last_function_parms to avoid confusing
start_function later. */
if (DECL_STATIC_FUNCTION_P (tmpl) if (DECL_STATIC_FUNCTION_P (tmpl)
&& DECL_NONSTATIC_MEMBER_FUNCTION_P (decl)) && DECL_NONSTATIC_MEMBER_FUNCTION_P (decl))
{ revert_static_member_fn (decl);
revert_static_member_fn (decl);
last_function_parms = TREE_CHAIN (last_function_parms);
}
/* If this is a specialization of a member template of a /* If this is a specialization of a member template of a
template class. In we want to return the TEMPLATE_DECL, template class. In we want to return the TEMPLATE_DECL,
......
...@@ -2364,11 +2364,16 @@ finish_id_expression (tree id_expression, ...@@ -2364,11 +2364,16 @@ finish_id_expression (tree id_expression,
if (decl == error_mark_node) if (decl == error_mark_node)
{ {
/* Name lookup failed. */ /* Name lookup failed. */
if (scope && (!TYPE_P (scope) || !dependent_type_p (scope))) if (scope
&& (!TYPE_P (scope)
|| (!dependent_type_p (scope)
&& !(TREE_CODE (id_expression) == IDENTIFIER_NODE
&& IDENTIFIER_TYPENAME_P (id_expression)
&& dependent_type_p (TREE_TYPE (id_expression))))))
{ {
/* Qualified name lookup failed, and the qualifying name /* If the qualifying type is non-dependent (and the name
was not a dependent type. That is always an does not name a conversion operator to a dependent
error. */ type), issue an error. */
qualified_name_lookup_error (scope, id_expression); qualified_name_lookup_error (scope, id_expression);
return error_mark_node; return error_mark_node;
} }
...@@ -2378,6 +2383,8 @@ finish_id_expression (tree id_expression, ...@@ -2378,6 +2383,8 @@ finish_id_expression (tree id_expression,
*idk = CP_ID_KIND_UNQUALIFIED; *idk = CP_ID_KIND_UNQUALIFIED;
return id_expression; return id_expression;
} }
else
decl = id_expression;
} }
/* If DECL is a variable that would be out of scope under /* If DECL is a variable that would be out of scope under
ANSI/ISO rules, but in scope in the ARM, name lookup ANSI/ISO rules, but in scope in the ARM, name lookup
......
...@@ -1788,6 +1788,7 @@ lookup_destructor (tree object, tree scope, tree dtor_name) ...@@ -1788,6 +1788,7 @@ lookup_destructor (tree object, tree scope, tree dtor_name)
{ {
tree object_type = TREE_TYPE (object); tree object_type = TREE_TYPE (object);
tree dtor_type = TREE_OPERAND (dtor_name, 0); tree dtor_type = TREE_OPERAND (dtor_name, 0);
tree expr;
if (scope && !check_dtor_name (scope, dtor_name)) if (scope && !check_dtor_name (scope, dtor_name))
{ {
...@@ -1795,17 +1796,20 @@ lookup_destructor (tree object, tree scope, tree dtor_name) ...@@ -1795,17 +1796,20 @@ lookup_destructor (tree object, tree scope, tree dtor_name)
scope, dtor_type); scope, dtor_type);
return error_mark_node; return error_mark_node;
} }
if (!same_type_p (dtor_type, TYPE_MAIN_VARIANT (object_type))) if (!DERIVED_FROM_P (dtor_type, TYPE_MAIN_VARIANT (object_type)))
{ {
error ("the type being destroyed is `%T', but the destructor refers to `%T'", error ("the type being destroyed is `%T', but the destructor refers to `%T'",
TYPE_MAIN_VARIANT (object_type), dtor_type); TYPE_MAIN_VARIANT (object_type), dtor_type);
return error_mark_node; return error_mark_node;
} }
if (!TYPE_HAS_DESTRUCTOR (object_type)) if (!TYPE_HAS_DESTRUCTOR (dtor_type))
return build (PSEUDO_DTOR_EXPR, void_type_node, object, scope, return build (PSEUDO_DTOR_EXPR, void_type_node, object, scope,
dtor_type); dtor_type);
return lookup_member (object_type, complete_dtor_identifier, expr = lookup_member (dtor_type, complete_dtor_identifier,
/*protect=*/1, /*want_type=*/false); /*protect=*/1, /*want_type=*/false);
expr = (adjust_result_of_qualified_name_lookup
(expr, dtor_type, object_type));
return expr;
} }
/* This function is called by the parser to process a class member /* This function is called by the parser to process a class member
......
2004-03-19 Mark Mitchell <mark@codesourcery.com>
* g++.dg/init/placement3.C: New test.
* g++.dg/template/spec13.C: New test.
* g++.dg/lookup/using11.C: New test.
* g++.dg/lookup/koenig3.C: New test.
* g++.dg/template/operator2.C: New test.
* g++.dg/expr/dtor3.C: New test.
* g++.old-deja/g++.brendan/crash15.C: Remove incorrect dg-error
marker.
* g++.old-deja/g++.law/visibility28.C: Likewise.
2004-03-19 Paolo Bonzini <bonzini@gnu.org> 2004-03-19 Paolo Bonzini <bonzini@gnu.org>
* gcc.dg/altivec-6.c: Use vector_size attribute, not mode. * gcc.dg/altivec-6.c: Use vector_size attribute, not mode.
......
struct B {
~B();
};
struct D : public B {
~D();
};
void f(D d) {
d.B::~B();
}
typedef __SIZE_TYPE__ size_t;
extern "C" void *malloc (size_t);
int i;
struct S {
S(int) {
throw 3;
}
void *operator new(size_t s, int) {
++i;
return malloc (s);
}
void operator delete(void *, int) {
--i;
}
void operator delete(void *, int, int) ;
};
int main () {
try {
new (7) S (12);
} catch (int) {
if (i)
return 1;
}
}
extern "C" void abort ();
struct S {
};
void f(S, int) { abort(); }
void f(S, double) {}
S s;
int main() {
extern void f(S, int);
f(s, 3.0);
}
namespace N1 {
enum e { a };
void e(char);
}
void f() {
using N1::e;
enum e x;
}
template <typename T> struct A {};
struct B {
operator A<B>();
};
template <typename T>
void f() { B::operator A<T>; }
// { dg-options "-w" }
template <typename T>
struct S {
int i;
template <typename U> void f(U) {}
};
template<>
template <typename U>
void S<int>::f(U) { i; }
void f() {
S<int> s;
s.f<int>(3);
}
...@@ -16,7 +16,7 @@ int ...@@ -16,7 +16,7 @@ int
main() { main() {
std::cout << "starting\n"; std::cout << "starting\n";
B b; B b;
b.~A();// { dg-error "" } destructor b.~A();
std::cout << "done\n"; std::cout << "done\n";
} }
...@@ -11,7 +11,7 @@ public: ...@@ -11,7 +11,7 @@ public:
class D : public B { class D : public B {
public: public:
virtual ~D() { printf( "D::~D\n"); } virtual ~D() { printf( "D::~D\n"); }
void operator = ( int i) { this->~B(); }// { dg-error "" } D has no ~B part to it void operator = ( int i) { this->~B(); }
}; };
int int
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment