aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/decl.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/decl.c')
-rw-r--r--gcc/cp/decl.c32
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;