From 856216bbe352e0ebe97e8928e6a41906518ecccd Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Mon, 17 May 1999 16:07:39 +0000 Subject: [PATCH] cp-tree.def (TEMPLATE_ID_EXPR): Update documentation. * cp-tree.def (TEMPLATE_ID_EXPR): Update documentation. * decl.c (grokfndecl): Don't allow inline declarations of friend template specializations, or friend template specializations with default arguments. * pt.c (tsubst): Handle substitution into array types that does not yield a fixed upper bound, even when not processing a template. (tsubst_copy): Deal with the fact that the second operand to a TEMPLATE_ID_EXPR may be NULL_TREE, a TREE_LIST, or a TREE_VEC. * search.c (marked_pushdecls_p): Don't descend into TEMPLATE_TYPE_PARMs and the like. (unmarked_pushdecls_p): Likewise. From-SVN: r26975 --- gcc/cp/ChangeLog | 13 +++++++++++ gcc/cp/cp-tree.def | 8 +++---- gcc/cp/decl.c | 21 ++++++++++++++++- gcc/cp/pt.c | 24 ++++++++++++++++---- gcc/cp/search.c | 6 +++-- gcc/testsuite/g++.old-deja/g++.pt/friend37.C | 5 ++-- 6 files changed, 63 insertions(+), 14 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index a43deddfdb1..bd03f2c6e5b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,18 @@ 1999-05-17 Mark Mitchell + * cp-tree.def (TEMPLATE_ID_EXPR): Update documentation. + * decl.c (grokfndecl): Don't allow inline declarations of friend + template specializations, or friend template specializations with + default arguments. + * pt.c (tsubst): Handle substitution into array types that does + not yield a fixed upper bound, even when not processing a + template. + (tsubst_copy): Deal with the fact that the second operand to a + TEMPLATE_ID_EXPR may be NULL_TREE, a TREE_LIST, or a TREE_VEC. + * search.c (marked_pushdecls_p): Don't descend into + TEMPLATE_TYPE_PARMs and the like. + (unmarked_pushdecls_p): Likewise. + * call.c (build_over_call): Don't throw away initializations/copies of empty classes; use MODIFY_EXPR and INIT_EXPR as for non-empty classes. diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def index da0f1642fd8..70801fc9563 100644 --- a/gcc/cp/cp-tree.def +++ b/gcc/cp/cp-tree.def @@ -173,10 +173,10 @@ DEFTREECODE (USING_DECL, "using_decl", 'd', 0) DEFTREECODE (DEFAULT_ARG, "default_arg", 'c', 2) /* A template-id, like foo. The first operand is the template. - The second is the list of explicitly specified arguments. The - template will be a FUNCTION_DECL, TEMPLATE_DECL, or an OVERLOAD. - If the template-id refers to a member template, the template may be - an IDENTIFIER_NODE. */ + The second is the TREE_LIST or TREE_VEC of explicitly specified + arguments. The template will be a FUNCTION_DECL, TEMPLATE_DECL, or + an OVERLOAD. If the template-id refers to a member template, the + template may be an IDENTIFIER_NODE. */ DEFTREECODE (TEMPLATE_ID_EXPR, "template_id_expr", 'e', 2) /* An association between name and entity. Parameters are the scope diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 9df5474c1e4..05a0340b0d4 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -8710,6 +8710,7 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals, { tree cname, decl; int staticp = ctype && TREE_CODE (type) == FUNCTION_TYPE; + int has_default_arg = 0; tree t; if (ctype) @@ -8826,7 +8827,7 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals, if (TREE_PURPOSE (t) && TREE_CODE (TREE_PURPOSE (t)) == DEFAULT_ARG) { - add_defarg_fn (decl); + has_default_arg = 1; break; } @@ -8847,6 +8848,7 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals, return NULL_TREE; } + /* A friend declaration of the form friend void f<>(). Record the information in the TEMPLATE_ID_EXPR. */ SET_DECL_IMPLICIT_INSTANTIATION (decl); @@ -8854,9 +8856,26 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals, = perm_tree_cons (TREE_OPERAND (orig_declarator, 0), TREE_OPERAND (orig_declarator, 1), NULL_TREE); + + if (has_default_arg) + { + cp_error ("default arguments are not allowed in declaration of friend template specialization `%D'", + decl); + return NULL_TREE; + } + + if (inlinep) + { + cp_error ("`inline' is not allowed in declaration of friend template specialization `%D'", + decl); + return NULL_TREE; + } } } + if (has_default_arg) + add_defarg_fn (decl); + /* Plain overloading: will not be grok'd by grokclassfn. */ if (! ctype && ! processing_template_decl && DECL_LANGUAGE (decl) != lang_c diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 442f1b04953..59543ca0dfa 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -6128,7 +6128,12 @@ tsubst (t, args, complain, in_decl) if (max == error_mark_node) return error_mark_node; - if (processing_template_decl) + if (processing_template_decl + /* When providing explicit arguments to a template + function, but leaving some arguments for subsequent + deduction, MAX may be template-dependent even if we're + not PROCESSING_TEMPLATE_DECL. */ + || TREE_CODE (max) != INTEGER_CST) { tree itype = make_node (INTEGER_TYPE); TYPE_MIN_VALUE (itype) = size_zero_node; @@ -6908,9 +6913,20 @@ tsubst_copy (t, args, complain, in_decl) /* Substituted template arguments */ tree targs = tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl); - tree chain; - for (chain = targs; chain; chain = TREE_CHAIN (chain)) - TREE_VALUE (chain) = maybe_fold_nontype_arg (TREE_VALUE (chain)); + + if (targs && TREE_CODE (targs) == TREE_LIST) + { + tree chain; + for (chain = targs; chain; chain = TREE_CHAIN (chain)) + TREE_VALUE (chain) = maybe_fold_nontype_arg (TREE_VALUE (chain)); + } + else if (targs) + { + int i; + for (i = 0; i < TREE_VEC_LENGTH (targs); ++i) + TREE_VEC_ELT (targs, i) + = maybe_fold_nontype_arg (TREE_VEC_ELT (targs, i)); + } return lookup_template_function (tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl), targs); diff --git a/gcc/cp/search.c b/gcc/cp/search.c index 33873a0a305..12133589871 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -2122,7 +2122,8 @@ marked_pushdecls_p (binfo, data) tree binfo; void *data ATTRIBUTE_UNUSED; { - return BINFO_PUSHDECLS_MARKED (binfo) ? binfo : NULL_TREE; + return (CLASS_TYPE_P (BINFO_TYPE (binfo)) + && BINFO_PUSHDECLS_MARKED (binfo)) ? binfo : NULL_TREE; } static tree @@ -2130,7 +2131,8 @@ unmarked_pushdecls_p (binfo, data) tree binfo; void *data ATTRIBUTE_UNUSED; { - return !BINFO_PUSHDECLS_MARKED (binfo) ? binfo : NULL_TREE; + return (CLASS_TYPE_P (BINFO_TYPE (binfo)) + && !BINFO_PUSHDECLS_MARKED (binfo)) ? binfo : NULL_TREE; } #if 0 diff --git a/gcc/testsuite/g++.old-deja/g++.pt/friend37.C b/gcc/testsuite/g++.old-deja/g++.pt/friend37.C index 2379d5f1da7..c3ee4c7aaef 100644 --- a/gcc/testsuite/g++.old-deja/g++.pt/friend37.C +++ b/gcc/testsuite/g++.old-deja/g++.pt/friend37.C @@ -1,8 +1,7 @@ // Build don't link: // Simplified from report by Volker Dobler -// crash test - XFAIL *-*-* - template class A { - friend int ice<>( int k=0 ); // ERROR - undeclared + friend int ice<>( int k=0 ); // ERROR - default argument + friend inline int f<>(double); // ERROR - inline };