From patchwork Mon Oct 11 13:28:26 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 67423 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id B8AB0B70A7 for ; Tue, 12 Oct 2010 00:28:41 +1100 (EST) Received: (qmail 16707 invoked by alias); 11 Oct 2010 13:28:39 -0000 Received: (qmail 16697 invoked by uid 22791); 11 Oct 2010 13:28:37 -0000 X-SWARE-Spam-Status: No, hits=-6.1 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, SPF_HELO_PASS, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 11 Oct 2010 13:28:28 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o9BDSRhk013913 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Mon, 11 Oct 2010 09:28:27 -0400 Received: from [127.0.0.1] ([10.3.113.4]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id o9BDSQpl005074 for ; Mon, 11 Oct 2010 09:28:26 -0400 Message-ID: <4CB310FA.2040200@redhat.com> Date: Mon, 11 Oct 2010 09:28:26 -0400 From: Jason Merrill User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.14) Gecko/20101002 Lightning/1.0b1 Shredder/3.0.9pre MIME-Version: 1.0 To: gcc-patches List Subject: C++ PATCH for lto/45959 (trying to stream template_type_parm) Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org This bug turned out to be caused by an INTEGER_CST which still had dependent type because tsubst_copy was assuming that it didn't need any modification; the first patch fixes that. While I was doing that, I thought that the default to just return t was pretty fragile and might cause other problems, so I changed it to abort by default. After fixing various places that shouldn't have been calling tsubst_copy in the first place, I only needed to add two more cases: OVERLOAD and PTRMEM_CST. This is the second patch. Tested x86_64-pc-linux-gnu, applied to trunk. commit 33416fbf8614d0b4d71a85aa35403d2070fc4fc0 Author: Jason Merrill Date: Sun Oct 10 16:20:20 2010 -0400 * pt.c (tsubst_default_argument): Handle DEFAULT_ARG. (tsubst_default_arguments): Only do this once for cloned fns. (tsubst): Use typedef_variant_p. Handle LANG_TYPE. Don't handle expressions. (tsubst_expr): Avoid calling tsubst_expr for non-expressions. (tsubst_copy_and_build): Likewise. (tsubst_initializer_list): Likewise. (tsubst_copy): Change default to gcc_unreachable. Handle OVERLOAD and PTRMEM_CST. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index b84cc78..84901d3 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -8871,6 +8871,10 @@ tsubst_default_argument (tree fn, tree type, tree arg) tree saved_class_ptr = NULL_TREE; tree saved_class_ref = NULL_TREE; + /* This can happen in invalid code. */ + if (TREE_CODE (arg) == DEFAULT_ARG) + return arg; + /* This default argument came from a template. Instantiate the default argument here, not in tsubst. In the case of something like: @@ -8935,6 +8939,9 @@ tsubst_default_arguments (tree fn) its default arguments. */ if (uses_template_parms (tmpl_args)) return; + /* Don't do this again for clones. */ + if (DECL_CLONED_FUNCTION_P (fn)) + return; for (arg = TYPE_ARG_TYPES (TREE_TYPE (fn)); arg; @@ -10033,8 +10040,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) /* Reuse typedefs. We need to do this to handle dependent attributes, such as attribute aligned. */ if (TYPE_P (t) - && TYPE_NAME (t) - && TYPE_NAME (t) != TYPE_MAIN_DECL (t)) + && typedef_variant_p (t)) { tree decl = TYPE_NAME (t); @@ -10090,9 +10096,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) case COMPLEX_TYPE: case VECTOR_TYPE: case BOOLEAN_TYPE: - case INTEGER_CST: - case REAL_CST: - case STRING_CST: + case LANG_TYPE: return t; case INTEGER_TYPE: @@ -10541,29 +10545,6 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) return r; } - case PLUS_EXPR: - case MINUS_EXPR: - { - tree e1 = tsubst (TREE_OPERAND (t, 0), args, complain, in_decl); - tree e2 = tsubst (TREE_OPERAND (t, 1), args, complain, in_decl); - - if (e1 == error_mark_node || e2 == error_mark_node) - return error_mark_node; - - return fold_build2_loc (input_location, - code, TREE_TYPE (t), e1, e2); - } - - case NEGATE_EXPR: - case NOP_EXPR: - { - tree e = tsubst (TREE_OPERAND (t, 0), args, complain, in_decl); - if (e == error_mark_node) - return error_mark_node; - - return fold_build1_loc (input_location, code, TREE_TYPE (t), e); - } - case TYPENAME_TYPE: { tree ctx = tsubst_aggr_type (TYPE_CONTEXT (t), args, complain, @@ -10639,33 +10620,6 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) return make_unbound_class_template (ctx, name, parm_list, complain); } - case INDIRECT_REF: - case ADDR_EXPR: - case CALL_EXPR: - gcc_unreachable (); - - case ARRAY_REF: - { - tree e1 = tsubst (TREE_OPERAND (t, 0), args, complain, in_decl); - tree e2 = tsubst_expr (TREE_OPERAND (t, 1), args, complain, in_decl, - /*integral_constant_expression_p=*/false); - if (e1 == error_mark_node || e2 == error_mark_node) - return error_mark_node; - - return build_nt (ARRAY_REF, e1, e2, NULL_TREE, NULL_TREE); - } - - case SCOPE_REF: - { - tree e1 = tsubst (TREE_OPERAND (t, 0), args, complain, in_decl); - tree e2 = tsubst (TREE_OPERAND (t, 1), args, complain, in_decl); - if (e1 == error_mark_node || e2 == error_mark_node) - return error_mark_node; - - return build_qualified_name (/*type=*/NULL_TREE, - e1, e2, QUALIFIED_NAME_IS_TEMPLATE (t)); - } - case TYPEOF_TYPE: { tree type; @@ -10734,6 +10688,21 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) } break; + case INTEGER_CST: + case REAL_CST: + case STRING_CST: + case PLUS_EXPR: + case MINUS_EXPR: + case NEGATE_EXPR: + case NOP_EXPR: + case INDIRECT_REF: + case ADDR_EXPR: + case CALL_EXPR: + case ARRAY_REF: + case SCOPE_REF: + /* We should use one of the expression tsubsts for these codes. */ + gcc_unreachable (); + default: sorry ("use of %qs in template", tree_code_name [(int) code]); return error_mark_node; @@ -11047,6 +11016,13 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) mark_used (t); return t; + case OVERLOAD: + /* An OVERLOAD will always be a non-dependent overload set; an + overload set from function scope will just be represented with an + IDENTIFIER_NODE, and from class scope with a BASELINK. */ + gcc_assert (!uses_template_parms (t)); + return t; + case BASELINK: return tsubst_baselink (t, current_class_type, args, complain, in_decl); @@ -11384,8 +11360,14 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) return r; } - default: + case PTRMEM_CST: + /* These can sometimes show up in a partial instantiation, but never + involve template parms. */ + gcc_assert (!uses_template_parms (t)); return t; + + default: + gcc_unreachable (); } } @@ -11666,7 +11648,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, break; case USING_STMT: - do_using_directive (RECUR (USING_STMT_NAMESPACE (t))); + do_using_directive (USING_STMT_NAMESPACE (t)); break; case DECL_EXPR: @@ -11683,7 +11665,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, tree name = DECL_NAME (decl); tree decl; - scope = RECUR (scope); + scope = tsubst (scope, args, complain, in_decl); decl = lookup_qualified_name (scope, name, /*is_type_p=*/false, /*complain=*/false); @@ -12276,15 +12258,15 @@ tsubst_copy_and_build (tree t, case ADDR_EXPR: op1 = TREE_OPERAND (t, 0); + if (TREE_CODE (op1) == LABEL_DECL) + return finish_label_address_expr (DECL_NAME (op1), + EXPR_LOCATION (op1)); if (TREE_CODE (op1) == SCOPE_REF) op1 = tsubst_qualified_id (op1, args, complain, in_decl, /*done=*/true, /*address_p=*/true); else op1 = tsubst_non_call_postfix_expression (op1, args, complain, in_decl); - if (TREE_CODE (op1) == LABEL_DECL) - return finish_label_address_expr (DECL_NAME (op1), - EXPR_LOCATION (op1)); return build_x_unary_op (ADDR_EXPR, op1, complain); case PLUS_EXPR: @@ -12459,7 +12441,7 @@ tsubst_copy_and_build (tree t, } ret = build_new (&placement_vec, - RECUR (TREE_OPERAND (t, 1)), + tsubst (TREE_OPERAND (t, 1), args, complain, in_decl), RECUR (TREE_OPERAND (t, 2)), &init_vec, NEW_EXPR_USE_GLOBAL (t), @@ -12909,10 +12891,17 @@ tsubst_copy_and_build (tree t, case TYPEID_EXPR: { - tree operand_0 = RECUR (TREE_OPERAND (t, 0)); + tree operand_0 = TREE_OPERAND (t, 0); if (TYPE_P (operand_0)) - return get_typeid (operand_0); - return build_typeid (operand_0); + { + operand_0 = tsubst (operand_0, args, complain, in_decl); + return get_typeid (operand_0); + } + else + { + operand_0 = RECUR (operand_0); + return build_typeid (operand_0); + } } case VAR_DECL: @@ -17279,9 +17268,11 @@ tsubst_initializer_list (tree t, tree argvec) if (decl && !DECL_P (decl)) in_base_initializer = 1; - init = tsubst_expr (TREE_VALUE (t), argvec, - tf_warning_or_error, NULL_TREE, - /*integral_constant_expression_p=*/false); + init = TREE_VALUE (t); + if (init != void_type_node) + init = tsubst_expr (init, argvec, + tf_warning_or_error, NULL_TREE, + /*integral_constant_expression_p=*/false); in_base_initializer = 0; }