diff options
Diffstat (limited to 'gcc/cp/decl.c')
-rw-r--r-- | gcc/cp/decl.c | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index b16ae26..6537c50 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -3967,13 +3967,16 @@ shadow_tag (cp_decl_specifier_seq *declspecs) tree groktypename (cp_decl_specifier_seq *type_specifiers, - const cp_declarator *declarator) + const cp_declarator *declarator, + bool is_template_arg) { tree attrs; tree type; + enum decl_context context + = is_template_arg ? TEMPLATE_TYPE_ARG : TYPENAME; attrs = type_specifiers->attributes; type_specifiers->attributes = NULL_TREE; - type = grokdeclarator (declarator, type_specifiers, TYPENAME, 0, &attrs); + type = grokdeclarator (declarator, type_specifiers, context, 0, &attrs); if (attrs && type != error_mark_node) { if (CLASS_TYPE_P (type)) @@ -7603,6 +7606,7 @@ grokdeclarator (const cp_declarator *declarator, bool type_was_error_mark_node = false; bool parameter_pack_p = declarator? declarator->parameter_pack_p : false; bool set_no_warning = false; + bool template_type_arg = false; signed_p = declspecs->specs[(int)ds_signed]; unsigned_p = declspecs->specs[(int)ds_unsigned]; @@ -7617,6 +7621,8 @@ grokdeclarator (const cp_declarator *declarator, funcdef_flag = true, decl_context = FIELD; else if (decl_context == BITFIELD) bitfield = 1, decl_context = FIELD; + else if (decl_context == TEMPLATE_TYPE_ARG) + template_type_arg = true, decl_context = TYPENAME; if (initialized > 1) funcdef_flag = true; @@ -8476,6 +8482,12 @@ grokdeclarator (const cp_declarator *declarator, memfn_quals = TYPE_UNQUALIFIED; } + if (TREE_CODE (type) == FUNCTION_TYPE + && cp_type_quals (type) != TYPE_UNQUALIFIED) + error ("cannot declare %s to qualified function type %qT", + declarator->kind == cdk_reference ? "reference" : "pointer", + type); + if (declarator->kind == cdk_reference) { /* In C++0x, the type we are creating a reference to might be @@ -8948,15 +8960,17 @@ grokdeclarator (const cp_declarator *declarator, } else if (memfn_quals) { - if (ctype == NULL_TREE) - { - if (TREE_CODE (type) != METHOD_TYPE) - error ("invalid qualifiers on non-member function type"); - else - ctype = TYPE_METHOD_BASETYPE (type); - } + if (ctype == NULL_TREE + && TREE_CODE (type) == METHOD_TYPE) + ctype = TYPE_METHOD_BASETYPE (type); + if (ctype) type = build_memfn_type (type, ctype, memfn_quals); + /* Core issue #547: need to allow this in template type args. */ + else if (template_type_arg && TREE_CODE (type) == FUNCTION_TYPE) + type = cp_build_qualified_type (type, memfn_quals); + else + error ("invalid qualifiers on non-member function type"); } return type; |