aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/decl.c
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2009-03-31 14:31:17 -0400
committerJason Merrill <jason@gcc.gnu.org>2009-03-31 14:31:17 -0400
commit0d9c089222329e55fb3d372e3c8029f5a18a080f (patch)
tree155b10aa3c254e87c8ef3b1be4137739cf355dfb /gcc/cp/decl.c
parenta3c497526740202a565d78c77d29f2b93c92f1ee (diff)
downloadgcc-0d9c089222329e55fb3d372e3c8029f5a18a080f.zip
gcc-0d9c089222329e55fb3d372e3c8029f5a18a080f.tar.gz
gcc-0d9c089222329e55fb3d372e3c8029f5a18a080f.tar.bz2
re PR c++/37806 (CV-qualifiers on function typedef's are inconsistently accepted depending on typedef scope)
PR c++/37806 * typeck.c (cp_apply_type_quals_to_decl): Don't apply any quals to a typedef. * tree.c (cp_build_qualified_type_real): Don't apply restrict to a function type. * decl.h (enum decl_context): Add TEMPLATE_TYPE_ARG. * decl.c (groktypename): Add is_template_arg parameter. (grokdeclarator): Allow function cv-quals on a template type arg. * parser.c (cp_parser_new_type_id, cp_parser_type_id): Add is_template_arg argument in calls to groktypename. * cp-tree.h: Adjust prototype. * error.c (dump_type_prefix, dump_type_suffix): Fix plain FUNCTION_TYPE printing. PR libstdc++/39310 * include/tr1_impl/type_traits (is_function): Add partial specializations with function cv-quals. (__is_function_helper): Remove. (is_member_pointer): Don't define in terms of is_member_*_pointer. From-SVN: r145365
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;