Commit e2537f2c by Mark Mitchell Committed by Mark Mitchell

re PR c++/26912 (friend const member function specialization fails to compile)

	PR c++/26912
	* cp-tree.h (build_this_parm): Declare.
	(grok_method_quals): Remove.
	(build_memfn_type): Declare.
	(build_artificial_parm): Declare.
	(do_friend): Remove quals parameter.
	* decl.c (build_this_parm): New function.
	(grokfndecl): Use it.  Do not pass quals to grokclassfn.
	(grokdeclarator): Rename quals to memfn_quals.  Avoid allocating
	unnecessary TYPE_DECLs.  Correct qualification of member function
	types.  Tidy.
	* method.c (implicitly_declare_fn): Use build_this_parm.
	* friend.c (do_friend): Remove quals parameter.
	* decl2.c (grok_method_quals): Remove.
	(build_memfn_type): New function.
	(build_artificial_parm): Give it external linkage.
	(grokclassfn): Remove quals parameter.  Do not build "this"
	PARM_DECL here.
	PR c++/26912
	* g++.dg/template/friend41.C: New test.

From-SVN: r113213
parent d24b23bb
2006-04-23 Mark Mitchell <mark@codesourcery.com> 2006-04-23 Mark Mitchell <mark@codesourcery.com>
PR c++/26912
* cp-tree.h (build_this_parm): Declare.
(grok_method_quals): Remove.
(build_memfn_type): Declare.
(build_artificial_parm): Declare.
(do_friend): Remove quals parameter.
* decl.c (build_this_parm): New function.
(grokfndecl): Use it. Do not pass quals to grokclassfn.
(grokdeclarator): Rename quals to memfn_quals. Avoid allocating
unnecessary TYPE_DECLs. Correct qualification of member function
types. Tidy.
* method.c (implicitly_declare_fn): Use build_this_parm.
* friend.c (do_friend): Remove quals parameter.
* decl2.c (grok_method_quals): Remove.
(build_memfn_type): New function.
(build_artificial_parm): Give it external linkage.
(grokclassfn): Remove quals parameter. Do not build "this"
PARM_DECL here.
PR c++/26534 PR c++/26534
* cp-tree.h (is_bitfield_expr_with_lowered_type): New function. * cp-tree.h (is_bitfield_expr_with_lowered_type): New function.
* typeck.c (is_bitfield_expr_with_lowered_type): New function. * typeck.c (is_bitfield_expr_with_lowered_type): New function.
......
...@@ -3842,6 +3842,7 @@ extern int cp_complete_array_type (tree *, tree, bool); ...@@ -3842,6 +3842,7 @@ extern int cp_complete_array_type (tree *, tree, bool);
extern tree build_ptrmemfunc_type (tree); extern tree build_ptrmemfunc_type (tree);
extern tree build_ptrmem_type (tree, tree); extern tree build_ptrmem_type (tree, tree);
/* the grokdeclarator prototype is in decl.h */ /* the grokdeclarator prototype is in decl.h */
extern tree build_this_parm (tree, cp_cv_quals);
extern int copy_fn_p (tree); extern int copy_fn_p (tree);
extern tree get_scope_of_declarator (const cp_declarator *); extern tree get_scope_of_declarator (const cp_declarator *);
extern void grok_special_member_properties (tree); extern void grok_special_member_properties (tree);
...@@ -3899,12 +3900,11 @@ extern bool have_extern_spec; ...@@ -3899,12 +3900,11 @@ extern bool have_extern_spec;
/* in decl2.c */ /* in decl2.c */
extern bool check_java_method (tree); extern bool check_java_method (tree);
extern cp_cv_quals grok_method_quals (tree, tree, cp_cv_quals); extern tree build_memfn_type (tree, tree, cp_cv_quals);
extern void maybe_retrofit_in_chrg (tree); extern void maybe_retrofit_in_chrg (tree);
extern void maybe_make_one_only (tree); extern void maybe_make_one_only (tree);
extern void grokclassfn (tree, tree, extern void grokclassfn (tree, tree,
enum overload_flags, enum overload_flags);
cp_cv_quals);
extern tree grok_array_decl (tree, tree); extern tree grok_array_decl (tree, tree);
extern tree delete_sanity (tree, tree, bool, int); extern tree delete_sanity (tree, tree, bool, int);
extern tree check_classfn (tree, tree, tree); extern tree check_classfn (tree, tree, tree);
...@@ -3934,6 +3934,7 @@ extern tree cxx_callgraph_analyze_expr (tree *, int *, tree); ...@@ -3934,6 +3934,7 @@ extern tree cxx_callgraph_analyze_expr (tree *, int *, tree);
extern void mark_needed (tree); extern void mark_needed (tree);
extern bool decl_needed_p (tree); extern bool decl_needed_p (tree);
extern void note_vague_linkage_fn (tree); extern void note_vague_linkage_fn (tree);
extern tree build_artificial_parm (tree, tree);
/* in error.c */ /* in error.c */
extern void init_error (void); extern void init_error (void);
...@@ -3966,7 +3967,7 @@ extern tree cplus_expand_constant (tree); ...@@ -3966,7 +3967,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, enum overload_flags, cp_cv_quals, bool); extern tree do_friend (tree, tree, tree, tree, enum overload_flags, bool);
/* in init.c */ /* in init.c */
extern tree expand_member_init (tree); extern tree expand_member_init (tree);
......
...@@ -103,33 +103,28 @@ tree static_ctors; ...@@ -103,33 +103,28 @@ tree static_ctors;
tree static_dtors; tree static_dtors;
/* Incorporate `const' and `volatile' qualifiers for member functions.
FUNCTION is a TYPE_DECL or a FUNCTION_DECL. /* Return a member function type (a METHOD_TYPE), given FNTYPE (a
QUALS is a list of qualifiers. Returns any explicit FUNCTION_TYPE), CTYPE (class type), and QUALS (the cv-qualifiers
top-level qualifiers of the method's this pointer, anything other than that apply to the function). */
TYPE_UNQUALIFIED will be an extension. */
tree
int build_memfn_type (tree fntype, tree ctype, cp_cv_quals quals)
grok_method_quals (tree ctype, tree function, cp_cv_quals quals)
{ {
tree fntype = TREE_TYPE (function); tree raises;
tree raises = TYPE_RAISES_EXCEPTIONS (fntype); int type_quals;
int type_quals = TYPE_UNQUALIFIED;
int this_quals = TYPE_UNQUALIFIED;
type_quals = quals & ~TYPE_QUAL_RESTRICT; type_quals = quals & ~TYPE_QUAL_RESTRICT;
this_quals = quals & TYPE_QUAL_RESTRICT;
ctype = cp_build_qualified_type (ctype, type_quals); ctype = cp_build_qualified_type (ctype, type_quals);
fntype = build_method_type_directly (ctype, TREE_TYPE (fntype), fntype = build_method_type_directly (ctype, TREE_TYPE (fntype),
(TREE_CODE (fntype) == METHOD_TYPE (TREE_CODE (fntype) == METHOD_TYPE
? TREE_CHAIN (TYPE_ARG_TYPES (fntype)) ? TREE_CHAIN (TYPE_ARG_TYPES (fntype))
: TYPE_ARG_TYPES (fntype))); : TYPE_ARG_TYPES (fntype)));
raises = TYPE_RAISES_EXCEPTIONS (fntype);
if (raises) if (raises)
fntype = build_exception_variant (fntype, raises); fntype = build_exception_variant (fntype, raises);
TREE_TYPE (function) = fntype; return fntype;
return this_quals;
} }
/* Build a PARM_DECL with NAME and TYPE, and set DECL_ARG_TYPE /* Build a PARM_DECL with NAME and TYPE, and set DECL_ARG_TYPE
...@@ -149,7 +144,7 @@ cp_build_parm_decl (tree name, tree type) ...@@ -149,7 +144,7 @@ cp_build_parm_decl (tree name, tree type)
/* Returns a PARM_DECL for a parameter of the indicated TYPE, with the /* Returns a PARM_DECL for a parameter of the indicated TYPE, with the
indicated NAME. */ indicated NAME. */
static tree tree
build_artificial_parm (tree name, tree type) build_artificial_parm (tree name, tree type)
{ {
tree parm = cp_build_parm_decl (name, type); tree parm = cp_build_parm_decl (name, type);
...@@ -257,11 +252,9 @@ maybe_retrofit_in_chrg (tree fn) ...@@ -257,11 +252,9 @@ maybe_retrofit_in_chrg (tree fn)
QUALS are the qualifiers for the this pointer. */ QUALS are the qualifiers for the this pointer. */
void void
grokclassfn (tree ctype, tree function, enum overload_flags flags, grokclassfn (tree ctype, tree function, enum overload_flags flags)
cp_cv_quals quals)
{ {
tree fn_name = DECL_NAME (function); tree fn_name = DECL_NAME (function);
cp_cv_quals this_quals = TYPE_UNQUALIFIED;
/* Even within an `extern "C"' block, members get C++ linkage. See /* Even within an `extern "C"' block, members get C++ linkage. See
[dcl.link] for details. */ [dcl.link] for details. */
...@@ -274,28 +267,6 @@ grokclassfn (tree ctype, tree function, enum overload_flags flags, ...@@ -274,28 +267,6 @@ grokclassfn (tree ctype, tree function, enum overload_flags flags,
DECL_NAME (function) = fn_name; DECL_NAME (function) = fn_name;
} }
if (quals)
this_quals = grok_method_quals (ctype, function, quals);
if (TREE_CODE (TREE_TYPE (function)) == METHOD_TYPE)
{
/* Must add the class instance variable up front. */
/* Right now we just make this a pointer. But later
we may wish to make it special. */
tree type = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (function)));
tree qual_type;
tree parm;
/* The `this' parameter is implicitly `const'; it cannot be
assigned to. */
this_quals |= TYPE_QUAL_CONST;
qual_type = cp_build_qualified_type (type, this_quals);
parm = build_artificial_parm (this_identifier, qual_type);
cp_apply_type_quals_to_decl (this_quals, parm);
TREE_CHAIN (parm) = DECL_ARGUMENTS (function);
DECL_ARGUMENTS (function) = parm;
}
DECL_CONTEXT (function) = ctype; DECL_CONTEXT (function) = ctype;
if (flags == DTOR_FLAG) if (flags == DTOR_FLAG)
......
...@@ -399,15 +399,11 @@ make_friend_class (tree type, tree friend_type, bool complain) ...@@ -399,15 +399,11 @@ 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.
FLAGS is just used for `grokclassfn'. FLAGS is just used for `grokclassfn'. */
QUALS say what special qualifies should apply to the object
pointed to by `this'. */
tree tree
do_friend (tree ctype, tree declarator, tree decl, do_friend (tree ctype, tree declarator, tree decl,
tree attrlist, enum overload_flags flags, tree attrlist, enum overload_flags flags,
cp_cv_quals quals,
bool funcdef_flag) bool funcdef_flag)
{ {
/* Every decl that gets here is a friend of something. */ /* Every decl that gets here is a friend of something. */
...@@ -456,8 +452,7 @@ do_friend (tree ctype, tree declarator, tree decl, ...@@ -456,8 +452,7 @@ do_friend (tree ctype, tree declarator, tree decl,
if (flags == NO_SPECIAL && declarator == cname) if (flags == NO_SPECIAL && declarator == cname)
DECL_CONSTRUCTOR_P (decl) = 1; DECL_CONSTRUCTOR_P (decl) = 1;
/* This will set up DECL_ARGUMENTS for us. */ grokclassfn (ctype, decl, flags);
grokclassfn (ctype, decl, flags, quals);
if (friend_depth) if (friend_depth)
{ {
......
...@@ -978,6 +978,7 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p) ...@@ -978,6 +978,7 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
tree fn_type; tree fn_type;
tree raises = empty_except_spec; tree raises = empty_except_spec;
tree rhs_parm_type = NULL_TREE; tree rhs_parm_type = NULL_TREE;
tree this_parm;
tree name; tree name;
HOST_WIDE_INT saved_processing_template_decl; HOST_WIDE_INT saved_processing_template_decl;
...@@ -1067,8 +1068,7 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p) ...@@ -1067,8 +1068,7 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
DECL_ASSIGNMENT_OPERATOR_P (fn) = 1; DECL_ASSIGNMENT_OPERATOR_P (fn) = 1;
SET_OVERLOADED_OPERATOR_CODE (fn, NOP_EXPR); SET_OVERLOADED_OPERATOR_CODE (fn, NOP_EXPR);
} }
/* Create the argument list. The call to "grokclassfn" will add the /* Create the explicit arguments. */
"this" parameter and any other implicit parameters. */
if (rhs_parm_type) if (rhs_parm_type)
{ {
/* Note that this parameter is *not* marked DECL_ARTIFICIAL; we /* Note that this parameter is *not* marked DECL_ARTIFICIAL; we
...@@ -1077,9 +1077,12 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p) ...@@ -1077,9 +1077,12 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
DECL_ARGUMENTS (fn) = cp_build_parm_decl (NULL_TREE, rhs_parm_type); DECL_ARGUMENTS (fn) = cp_build_parm_decl (NULL_TREE, rhs_parm_type);
TREE_READONLY (DECL_ARGUMENTS (fn)) = 1; TREE_READONLY (DECL_ARGUMENTS (fn)) = 1;
} }
/* Add the "this" parameter. */
this_parm = build_this_parm (fn_type, TYPE_UNQUALIFIED);
TREE_CHAIN (this_parm) = DECL_ARGUMENTS (fn);
DECL_ARGUMENTS (fn) = this_parm;
grokclassfn (type, fn, kind == sfk_destructor ? DTOR_FLAG : NO_SPECIAL, grokclassfn (type, fn, kind == sfk_destructor ? DTOR_FLAG : NO_SPECIAL);
TYPE_UNQUALIFIED);
grok_special_member_properties (fn); grok_special_member_properties (fn);
set_linkage_according_to_type (type, fn); set_linkage_according_to_type (type, fn);
rest_of_decl_compilation (fn, toplevel_bindings_p (), at_eof); rest_of_decl_compilation (fn, toplevel_bindings_p (), at_eof);
......
2006-04-23 Mark Mitchell <mark@codesourcery.com>
PR c++/26912
* g++.dg/template/friend41.C: New test.
2006-04-23 David Edelsohn <edelsohn@gnu.org> 2006-04-23 David Edelsohn <edelsohn@gnu.org>
* g++.dg/opt/pr15551.C: Include cstdio. * g++.dg/opt/pr15551.C: Include cstdio.
// PR c++/26912
struct Foo {
template<class T> int func() const;
};
class Bar {
friend int Foo::func<int>() const;
};
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