From patchwork Tue Aug 4 16:32:05 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathan Sidwell X-Patchwork-Id: 1340919 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=acm.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=vCoAyiwT; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BLgJb1JJ7z9sTC for ; Wed, 5 Aug 2020 02:32:14 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id E4F3B384402B; Tue, 4 Aug 2020 16:32:11 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-qk1-x731.google.com (mail-qk1-x731.google.com [IPv6:2607:f8b0:4864:20::731]) by sourceware.org (Postfix) with ESMTPS id 1C333385041D for ; Tue, 4 Aug 2020 16:32:09 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 1C333385041D Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=acm.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=nathanmsidwell@gmail.com Received: by mail-qk1-x731.google.com with SMTP id d14so38921095qke.13 for ; Tue, 04 Aug 2020 09:32:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:to:from:subject:message-id:date:user-agent:mime-version :content-language; bh=RJZQ5FMJUhTWO9vhuWVqcg7fHyUWSirSMMroqxT5wkI=; b=vCoAyiwTycHZ6V3WMhVQwQvssLNJPv4otOp+Q/UHb8GhYh/6/mMte+nXqljyVfQwTY TQFoRx8/47yi7j9UvBftfmZUHqUN2Wejb69HG8l3c5neAavjgAOgwbY42O96UbeR3ddA ehogzJpEzpqMfKWNigXYUsb+er4MXaZnGIu812BZM9lrzpY0kU6oBbRffGA5FdNKqUHL IRJfdkg8EdryXO9YSKVWFF/Co0Z+haEaaFrKdZka052EmE/quNc5plfPG+d7KG7he0Ya MaxACQauW28FvdGumCQxBY87YL9K9H6B3/P4D1DZQ23DsBfMt6/mvuWicdh5QArl3D5Q hDwQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:to:from:subject:message-id:date :user-agent:mime-version:content-language; bh=RJZQ5FMJUhTWO9vhuWVqcg7fHyUWSirSMMroqxT5wkI=; b=kyaLFaL4y8RYjhPGhGliYWC5R1xZD/RguuY106BV3rKxpTnWBnyWgxfNXzA3OTzx5X XSsMkpneoFjRcjqHTCj5sz+1WcVBoh+GCMao8AbPJKRBkM7lBfEU1vgPPsb4DHqeEmYp VMIxeoO7QFXhtoJeaTxkB9w4a5YG9YJL8Bo4++PixZb+3u9uEvfVyq40fUC0w1o4eF1F OpL4xsy7cxTnrKaDN4uwYNdsLdqCYwxL4ouQtjOPlqfMRJc+hjUsSUfugy+W5QxLDL57 MWKHY7HkWsZUd8XjT7tI+mnMwQxVlCJrsmXZYWhzo/FiVXUFnKQFLl69ieg+as11ABIK DPLw== X-Gm-Message-State: AOAM531WQ0UriKxrvpBJqMZVsHbuwCETjlEGVUuHyqHrCFLHbZwBksKU I4MLuJFV2EuGldXBzXKi8l4= X-Google-Smtp-Source: ABdhPJyPELLtkVVF9C3xc+/opg2TIIdk2EkCLIQEBaUA963/A5G8Ga+00ws1bDxSAytefzxVsF8jIA== X-Received: by 2002:a05:620a:5a7:: with SMTP id q7mr21897533qkq.298.1596558728316; Tue, 04 Aug 2020 09:32:08 -0700 (PDT) Received: from ?IPv6:2620:10d:c0a8:1102:e451:2397:1925:7e0d? ([2620:10d:c091:480::1:39eb]) by smtp.googlemail.com with ESMTPSA id p202sm20957396qke.97.2020.08.04.09.32.06 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 04 Aug 2020 09:32:06 -0700 (PDT) To: GCC Patches From: Nathan Sidwell Subject: c++: fix template parm count leak Message-ID: <679c10ee-ba72-b1e0-190a-d221afd79b47@acm.org> Date: Tue, 4 Aug 2020 12:32:05 -0400 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.5.0 MIME-Version: 1.0 Content-Language: en-US X-Spam-Status: No, score=-10.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_EF, FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM, GIT_PATCH_0, HEADER_FROM_DIFFERENT_DOMAINS, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" I noticed that we could leak parser->num_template_parameter_lists with erroneous specializations. We'd increment, notice a problem and then bail out. This refactors cp_parser_explicit_specialization to avoid that code path. A couple of tests get different diagnostics because of the fix. pr39425 then goes to unbounded template instantiation and exceeds the implementation limit. gcc/cp/ * parser.c (cp_parser_explicit_specialization): Refactor to avoid leak of num_template_parameter_lists value. gcc/testsuite/ * g++.dg/template/pr39425.C: Adjust errors, (unbounded template recursion). * g++.old-deja/g++.pt/spec20.C: Remove fallout diagnostics. pushed, nathan diff --git i/gcc/cp/parser.c w/gcc/cp/parser.c index ab088874ba7..9946acdb42f 100644 --- i/gcc/cp/parser.c +++ w/gcc/cp/parser.c @@ -17640,7 +17640,6 @@ cp_parser_explicit_instantiation (cp_parser* parser) static void cp_parser_explicit_specialization (cp_parser* parser) { - bool need_lang_pop; cp_token *token = cp_lexer_peek_token (parser->lexer); /* Look for the `template' keyword. */ @@ -17651,52 +17650,54 @@ cp_parser_explicit_specialization (cp_parser* parser) cp_parser_require (parser, CPP_GREATER, RT_GREATER); /* We have processed another parameter list. */ ++parser->num_template_parameter_lists; + /* [temp] A template ... explicit specialization ... shall not have C linkage. */ - if (current_lang_name == lang_name_c) + bool need_lang_pop = current_lang_name == lang_name_c; + if (need_lang_pop) { error_at (token->location, "template specialization with C linkage"); maybe_show_extern_c_location (); + /* Give it C++ linkage to avoid confusing other parts of the front end. */ push_lang_context (lang_name_cplusplus); need_lang_pop = true; } - else - need_lang_pop = false; - /* Let the front end know that we are beginning a specialization. */ - if (!begin_specialization ()) - { - end_specialization (); - return; - } - /* If the next keyword is `template', we need to figure out whether - or not we're looking a template-declaration. */ - if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TEMPLATE)) + /* Let the front end know that we are beginning a specialization. */ + if (begin_specialization ()) { - if (cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_LESS - && cp_lexer_peek_nth_token (parser->lexer, 3)->type != CPP_GREATER) - cp_parser_template_declaration_after_export (parser, - /*member_p=*/false); + /* If the next keyword is `template', we need to figure out + whether or not we're looking a template-declaration. */ + if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TEMPLATE)) + { + if (cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_LESS + && cp_lexer_peek_nth_token (parser->lexer, 3)->type != CPP_GREATER) + cp_parser_template_declaration_after_export (parser, + /*member_p=*/false); + else + cp_parser_explicit_specialization (parser); + } else - cp_parser_explicit_specialization (parser); + /* Parse the dependent declaration. */ + cp_parser_single_declaration (parser, + /*checks=*/NULL, + /*member_p=*/false, + /*explicit_specialization_p=*/true, + /*friend_p=*/NULL); } - else - /* Parse the dependent declaration. */ - cp_parser_single_declaration (parser, - /*checks=*/NULL, - /*member_p=*/false, - /*explicit_specialization_p=*/true, - /*friend_p=*/NULL); + /* We're done with the specialization. */ end_specialization (); + /* For the erroneous case of a template with C linkage, we pushed an implicit C++ linkage scope; exit that scope now. */ if (need_lang_pop) pop_lang_context (); + /* We're done with this parameter list. */ --parser->num_template_parameter_lists; } diff --git i/gcc/testsuite/g++.dg/template/pr39425.C w/gcc/testsuite/g++.dg/template/pr39425.C index d55f547e253..cd304896a61 100644 --- i/gcc/testsuite/g++.dg/template/pr39425.C +++ w/gcc/testsuite/g++.dg/template/pr39425.C @@ -5,14 +5,16 @@ class a { template struct _rec { - static const char size = _rec< (s >> 1) >::size; + static const char size = _rec< (s >> 1) >::size; // { dg-error "depth" } }; template<> // { dg-error "explicit" } - struct _rec <0> { + struct _rec <0> { // { dg-error "too few" } static const char size = 0; }; static const unsigned int value = _rec < 1 >::size; -} // { dg-error "after class definition" } +}; + +// { dg-prune-output "compilation terminated" } diff --git i/gcc/testsuite/g++.old-deja/g++.pt/spec20.C w/gcc/testsuite/g++.old-deja/g++.pt/spec20.C index 610e6c73371..51bc26906eb 100644 --- i/gcc/testsuite/g++.old-deja/g++.pt/spec20.C +++ w/gcc/testsuite/g++.old-deja/g++.pt/spec20.C @@ -10,7 +10,8 @@ struct S { template void f(U); template <> void f(int); // { dg-error "20:template-id .f. in declaration|explicit specialization" } - template struct I {}; // { dg-error "template" } - template struct I {}; // { dg-error "template" } + template struct I {}; + template struct I {}; + template <> struct I; // { dg-error "" } invalid specialization };