From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 81409 invoked by alias); 16 Jan 2019 12:32:22 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 81392 invoked by uid 89); 16 Jan 2019 12:32:21 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=half X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 16 Jan 2019 12:32:19 +0000 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D2EE85F726 for ; Wed, 16 Jan 2019 12:32:17 +0000 (UTC) Received: from redhat.com (ovpn-120-189.rdu2.redhat.com [10.10.120.189]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 45FF660BEC; Wed, 16 Jan 2019 12:32:17 +0000 (UTC) Date: Wed, 16 Jan 2019 12:32:00 -0000 From: Marek Polacek To: Jason Merrill , GCC Patches Subject: C++ PATCH for c++/78244 - narrowing conversion in template not detected Message-ID: <20190116123222.GI19569@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.10.1 (2018-07-13) X-SW-Source: 2019-01/txt/msg00906.txt.bz2 While looking into 88815, a 9 regression, I realized we'll have to fix 78244 first. This patch fixes one half of 78244. The problem was that we never detected narrowing conversion in a template, because the IMPLICIT_CONV_EXPR template code doesn't have the information whether it was initialized by a braced-init-list. This patch adds such a bit, which works much like IMPLICIT_CONV_EXPR_DIRECT_INIT. Bootstrapped/regtested on x86_64-linux, ok for trunk? 2019-01-16 Marek Polacek PR c++/78244 - narrowing conversion in template not detected. * call.c (perform_implicit_conversion_flags): Set IMPLICIT_CONV_EXPR_BRACED_INIT. * cp-tree.h (IMPLICIT_CONV_EXPR_BRACED_INIT): New. * pt.c (tsubst_copy_and_build): Use it. * g++.dg/cpp0x/Wnarrowing13.C: New test. * g++.dg/cpp0x/Wnarrowing14.C: New test. diff --git gcc/cp/call.c gcc/cp/call.c index 8bc8566e8d6..4f04b610004 100644 --- gcc/cp/call.c +++ gcc/cp/call.c @@ -11018,6 +11018,8 @@ perform_implicit_conversion_flags (tree type, tree expr, expr = build1 (IMPLICIT_CONV_EXPR, type, expr); if (!(flags & LOOKUP_ONLYCONVERTING)) IMPLICIT_CONV_EXPR_DIRECT_INIT (expr) = true; + if (flags & LOOKUP_NO_NARROWING) + IMPLICIT_CONV_EXPR_BRACED_INIT (expr) = true; } else expr = convert_like (conv, expr, complain); diff --git gcc/cp/cp-tree.h gcc/cp/cp-tree.h index 6a2004330d2..1c85b37ba7f 100644 --- gcc/cp/cp-tree.h +++ gcc/cp/cp-tree.h @@ -442,6 +442,7 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX]; OVL_HIDDEN_P (in OVERLOAD) SWITCH_STMT_NO_BREAK_P (in SWITCH_STMT) LAMBDA_EXPR_CAPTURE_OPTIMIZED (in LAMBDA_EXPR) + IMPLICIT_CONV_EXPR_BRACED_INIT (in IMPLICIT_CONV_EXPR) 3: (TREE_REFERENCE_EXPR) (in NON_LVALUE_EXPR) (commented-out). ICS_BAD_FLAG (in _CONV) FN_TRY_BLOCK_P (in TRY_BLOCK) @@ -4229,6 +4230,11 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter) #define IMPLICIT_CONV_EXPR_NONTYPE_ARG(NODE) \ (TREE_LANG_FLAG_1 (IMPLICIT_CONV_EXPR_CHECK (NODE))) +/* True if NODE represents a conversion for braced-init-list in a + template. Set by perform_implicit_conversion_flags. */ +#define IMPLICIT_CONV_EXPR_BRACED_INIT(NODE) \ + (TREE_LANG_FLAG_2 (IMPLICIT_CONV_EXPR_CHECK (NODE))) + /* Nonzero means that an object of this type cannot be initialized using an initializer list. */ #define CLASSTYPE_NON_AGGREGATE(NODE) \ diff --git gcc/cp/pt.c gcc/cp/pt.c index c6fc1cfeffb..83bceb26474 100644 --- gcc/cp/pt.c +++ gcc/cp/pt.c @@ -18210,6 +18210,8 @@ tsubst_copy_and_build (tree t, int flags = LOOKUP_IMPLICIT; if (IMPLICIT_CONV_EXPR_DIRECT_INIT (t)) flags = LOOKUP_NORMAL; + if (IMPLICIT_CONV_EXPR_BRACED_INIT (t)) + flags |= LOOKUP_NO_NARROWING; RETURN (perform_implicit_conversion_flags (type, expr, complain, flags)); } diff --git gcc/testsuite/g++.dg/cpp0x/Wnarrowing13.C gcc/testsuite/g++.dg/cpp0x/Wnarrowing13.C new file mode 100644 index 00000000000..3750f293df3 --- /dev/null +++ gcc/testsuite/g++.dg/cpp0x/Wnarrowing13.C @@ -0,0 +1,8 @@ +// PR c++/78244 +// { dg-do compile { target c++11 } } + +template +struct S { + static const int i{1.1}; // { dg-error "narrowing conversion" } + static const int i2 = {1.1}; // { dg-error "narrowing conversion" } +}; diff --git gcc/testsuite/g++.dg/cpp0x/Wnarrowing14.C gcc/testsuite/g++.dg/cpp0x/Wnarrowing14.C new file mode 100644 index 00000000000..1aa22196f33 --- /dev/null +++ gcc/testsuite/g++.dg/cpp0x/Wnarrowing14.C @@ -0,0 +1,17 @@ +// PR c++/78244 +// { dg-do compile { target c++11 } } + +using Number = unsigned int; + +template +struct S { + S() { + const Number x = {-1}; // { dg-error "narrowing conversion" } + (void)x; + } +}; + +int main() +{ + S<1> s; +}