diff options
author | Douglas Gregor <dgregor@cs.indiana.edu> | 2005-02-21 23:12:27 +0000 |
---|---|---|
committer | Paolo Carlini <paolo@gcc.gnu.org> | 2005-02-21 23:12:27 +0000 |
commit | 9804209d324be049840389053e370d5a1ce51550 (patch) | |
tree | 04879cd2510172e1979dedf06e8a47fcc01ae72a /gcc/cp/decl.c | |
parent | 89e4aa8109752fdf412a763afcb721acca852e96 (diff) | |
download | gcc-9804209d324be049840389053e370d5a1ce51550.zip gcc-9804209d324be049840389053e370d5a1ce51550.tar.gz gcc-9804209d324be049840389053e370d5a1ce51550.tar.bz2 |
re PR c++/19076 (Pointer to member function not matched to pointer to member template)
2005-02-21 Douglas Gregor <dgregor@cs.indiana.edu>
PR c++/19076
PR c++/6628
* cp-tree.h (cp_apply_type_quals_to_decl): Declared.
* decl.c (grokdeclarator): Pedwarn about qualifying a function
type.
Add qualifiers when declaring a typedef of a function type.
Member function pointers pick up the qualifiers of the typedef
used to declare them.
Don't complain about creating cv-qualified function types.
Complain about qualified function typedefs that are used to
declare non-static member functions or free functions.
Use cp_apply_type_quals_to_decl.
(start_preparsed_function): Use cp_apply_type_quals_to_decl.
(grokclassfn): Use cp_apply_type_quals_to_decl.
* error.c (dump_type_suffix): Print qualifiers for function
types.
* pt.c (tsubst_decl): Use cp_apply_type_quals_to_decl.
(tsubst): When substituting a function type into a member
pointer type, pass along the qualifiers.
(unify): Unify member pointers to member function pointers.
* tree.c (cp_build_qualified_type_real): Function types may be
qualified. This includes restrict qualifiers.
* typeck.c (cp_apply_type_quals_to_decl): New function to replace
use of c_apply_type_quals_to_decl. Drops qualifiers that are being
added to function types.
From-SVN: r95356
Diffstat (limited to 'gcc/cp/decl.c')
-rw-r--r-- | gcc/cp/decl.c | 55 |
1 files changed, 48 insertions, 7 deletions
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 2f6b98f..1613488 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -6939,6 +6939,20 @@ grokdeclarator (const cp_declarator *declarator, error ("qualifiers are not allowed on declaration of %<operator %T%>", ctor_return_type); + if (TREE_CODE (type) == FUNCTION_TYPE + && type_quals != TYPE_UNQUALIFIED) + { + /* This was an error in C++98 (cv-qualifiers cannot be added to + a function type), but DR 295 makes the code well-formed by + dropping the extra qualifiers. */ + if (pedantic) + { + tree bad_type = build_qualified_type (type, type_quals); + pedwarn ("ignoring %qV qualifiers added to function type %qT", + bad_type, type); + } + type_quals = TYPE_UNQUALIFIED; + } type_quals |= cp_type_quals (type); type = cp_build_qualified_type_real (type, type_quals, ((typedef_decl && !DECL_ARTIFICIAL (typedef_decl) @@ -7300,6 +7314,7 @@ grokdeclarator (const cp_declarator *declarator, } type = build_function_type (type, arg_types); + type = cp_build_qualified_type (type, quals); } break; @@ -7332,7 +7347,15 @@ grokdeclarator (const cp_declarator *declarator, && (TREE_CODE (type) == FUNCTION_TYPE || (quals && TREE_CODE (type) == METHOD_TYPE))) { - tree dummy = build_decl (TYPE_DECL, NULL_TREE, type); + tree dummy; + + /* If the type is a FUNCTION_TYPE, pick up the + qualifiers from that function type. No other + qualifiers may be supplied. */ + if (TREE_CODE (type) == FUNCTION_TYPE) + quals = cp_type_quals (type); + + dummy = build_decl (TYPE_DECL, NULL_TREE, type); grok_method_quals (declarator->u.pointer.class_type, dummy, quals); type = TREE_TYPE (dummy); @@ -7629,11 +7652,12 @@ grokdeclarator (const cp_declarator *declarator, { if (ctype == NULL_TREE) { - if (TREE_CODE (type) != METHOD_TYPE) - error ("%Jinvalid type qualifier for non-member function type", - decl); - else + if (TREE_CODE (type) == METHOD_TYPE) ctype = TYPE_METHOD_BASETYPE (type); + /* Any qualifiers on a function type typedef have + already been dealt with. */ + else if (TREE_CODE (type) == FUNCTION_TYPE) + quals = TYPE_UNQUALIFIED; } if (ctype != NULL_TREE) grok_method_quals (ctype, decl, quals); @@ -7676,6 +7700,23 @@ grokdeclarator (const cp_declarator *declarator, } parms = nreverse (decls); + + if (decl_context != TYPENAME) + { + /* A cv-qualifier-seq shall only be part of the function type + for a non-static member function. [8.3.5/4 dcl.fct] */ + if (cp_type_quals (type) != TYPE_UNQUALIFIED + && (current_class_type == NULL_TREE || staticp) ) + { + error ("qualified function types cannot be used to declare %s functions", + (staticp? "static member" : "free")); + type = TYPE_MAIN_VARIANT (type); + } + + /* The qualifiers on the function type become the qualifiers on + the non-static member function. */ + quals |= cp_type_quals (type); + } } /* If this is a type name (such as, in a cast or sizeof), @@ -8211,7 +8252,7 @@ grokdeclarator (const cp_declarator *declarator, when processing a template; we'll do this for the instantiated declaration based on the type of DECL. */ if (!processing_template_decl) - c_apply_type_quals_to_decl (type_quals, decl); + cp_apply_type_quals_to_decl (type_quals, decl); return decl; } @@ -9995,7 +10036,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags) DECL_IGNORED_P (resdecl) = 1; DECL_RESULT (decl1) = resdecl; - c_apply_type_quals_to_decl (cp_type_quals (restype), resdecl); + cp_apply_type_quals_to_decl (cp_type_quals (restype), resdecl); } /* Initialize RTL machinery. We cannot do this until |