From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 46876 invoked by alias); 18 Jan 2019 14:12:15 -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 44115 invoked by uid 89); 18 Jan 2019 14:12:13 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-25.4 required=5.0 tests=BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KAM_LAZY_DOMAIN_SECURITY,KAM_NUMSUBJECT,SPF_HELO_PASS autolearn=ham version=3.3.2 spammy= 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; Fri, 18 Jan 2019 14:12:10 +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 8DB7C9E63F for ; Fri, 18 Jan 2019 14:12:09 +0000 (UTC) Received: from redhat.com (ovpn-121-44.rdu2.redhat.com [10.10.121.44]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 11C9460BF1; Fri, 18 Jan 2019 14:12:08 +0000 (UTC) Date: Fri, 18 Jan 2019 14:12:00 -0000 From: Marek Polacek To: Jason Merrill Cc: GCC Patches Subject: Re: C++ PATCH for c++/78244 - narrowing conversion in template not detected, part 2 Message-ID: <20190118141207.GN19569@redhat.com> References: <20190117190921.GM19569@redhat.com> <4958169a-e8c8-4ca0-6f99-ce360b4834d5@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <4958169a-e8c8-4ca0-6f99-ce360b4834d5@redhat.com> User-Agent: Mutt/1.10.1 (2018-07-13) X-SW-Source: 2019-01/txt/msg01072.txt.bz2 On Thu, Jan 17, 2019 at 04:17:29PM -0500, Jason Merrill wrote: > On 1/17/19 2:09 PM, Marek Polacek wrote: > > This patch ought to fix the rest of 78244, a missing narrowing warning in > > decltype. > > > > As I explained in Bugzilla, there can be three scenarios: > > > > 1) decltype is in a template and it has no dependent expressions, which > > is the problematical case. finish_compound_literal just returns the > > compound literal without checking narrowing if processing_template_decl. > > This is the sort of thing that we've been gradually fixing: if the compound > literal isn't dependent at all, we want to do the normal processing. And > then usually return a result based on the original trees rather than the > result of processing. For instance, finish_call_expr. Something like that > ought to work here, too, and be more generally applicable; this shouldn't be > limited to casting to a scalar type, casting to a known class type can also > involve narrowing. Great, that works just fine. I also had to check if the type is type-dependent, otherwise complete_type could fail. > The check in the other patch that changes instantiation_dependent_r should > be more similar to the one in finish_compound_literal. Or perhaps you could > set a flag here in finish_compound_literal to indicate that it's > instantiation-dependent, and just check that in instantiation_dependent_r. Done, but I feel bad about adding another flag. But I guess it's cheaper this way. Thanks! Bootstrapped/regtested on x86_64-linux, ok for trunk? 2019-01-18 Marek Polacek PR c++/88815 - narrowing conversion lost in decltype. PR c++/78244 - narrowing conversion in template not detected. * cp-tree.h (CONSTRUCTOR_IS_DEPENDENT): New. * pt.c (instantiation_dependent_r): Consider a CONSTRUCTOR with CONSTRUCTOR_IS_DEPENDENT instantiation-dependent. * semantics.c (finish_compound_literal): When the compound literal isn't instantiation-dependent and the type isn't type-dependent, fall back to the normal processing. Don't only call check_narrowing for scalar types. Set CONSTRUCTOR_IS_DEPENDENT. * g++.dg/cpp0x/Wnarrowing15.C: New test. * g++.dg/cpp0x/constexpr-decltype3.C: New test. * g++.dg/cpp1y/Wnarrowing1.C: New test. diff --git gcc/cp/cp-tree.h gcc/cp/cp-tree.h index 5cc8f88d522..778874cccd6 100644 --- gcc/cp/cp-tree.h +++ gcc/cp/cp-tree.h @@ -424,6 +424,7 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX]; DECL_FINAL_P (in FUNCTION_DECL) QUALIFIED_NAME_IS_TEMPLATE (in SCOPE_REF) DECLTYPE_FOR_INIT_CAPTURE (in DECLTYPE_TYPE) + CONSTRUCTOR_IS_DEPENDENT (in CONSTRUCTOR) TINFO_USED_TEMPLATE_ID (in TEMPLATE_INFO) PACK_EXPANSION_SIZEOF_P (in *_PACK_EXPANSION) OVL_USING_P (in OVERLOAD) @@ -4202,6 +4203,11 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter) B b{1,2}, not B b({1,2}) or B b = {1,2}. */ #define CONSTRUCTOR_IS_DIRECT_INIT(NODE) (TREE_LANG_FLAG_0 (CONSTRUCTOR_CHECK (NODE))) +/* True if this CONSTRUCTOR is instantiation-dependent and needs to be + substituted. */ +#define CONSTRUCTOR_IS_DEPENDENT(NODE) \ + (TREE_LANG_FLAG_1 (CONSTRUCTOR_CHECK (NODE))) + /* True if this CONSTRUCTOR should not be used as a variable initializer because it was loaded from a constexpr variable with mutable fields. */ #define CONSTRUCTOR_MUTABLE_POISON(NODE) \ diff --git gcc/cp/pt.c gcc/cp/pt.c index e4f76478f54..ae77bae6b29 100644 --- gcc/cp/pt.c +++ gcc/cp/pt.c @@ -25800,6 +25800,11 @@ instantiation_dependent_r (tree *tp, int *walk_subtrees, return *tp; break; + case CONSTRUCTOR: + if (CONSTRUCTOR_IS_DEPENDENT (*tp)) + return *tp; + break; + default: break; } diff --git gcc/cp/semantics.c gcc/cp/semantics.c index e654750d249..4ff09ad3fb7 100644 --- gcc/cp/semantics.c +++ gcc/cp/semantics.c @@ -2795,11 +2795,14 @@ finish_compound_literal (tree type, tree compound_literal, return error_mark_node; } - if (processing_template_decl) + if (instantiation_dependent_expression_p (compound_literal) + || dependent_type_p (type)) { TREE_TYPE (compound_literal) = type; /* Mark the expression as a compound literal. */ TREE_HAS_CONSTRUCTOR (compound_literal) = 1; + /* And as instantiation-dependent. */ + CONSTRUCTOR_IS_DEPENDENT (compound_literal) = true; if (fcl_context == fcl_c99) CONSTRUCTOR_C99_COMPOUND_LITERAL (compound_literal) = 1; return compound_literal; @@ -2822,8 +2825,7 @@ finish_compound_literal (tree type, tree compound_literal, && check_array_initializer (NULL_TREE, type, compound_literal)) return error_mark_node; compound_literal = reshape_init (type, compound_literal, complain); - if (SCALAR_TYPE_P (type) - && !BRACE_ENCLOSED_INITIALIZER_P (compound_literal) + if (!BRACE_ENCLOSED_INITIALIZER_P (compound_literal) && !check_narrowing (type, compound_literal, complain)) return error_mark_node; if (TREE_CODE (type) == ARRAY_TYPE diff --git gcc/testsuite/g++.dg/cpp0x/Wnarrowing15.C gcc/testsuite/g++.dg/cpp0x/Wnarrowing15.C new file mode 100644 index 00000000000..4e7c17dcfca --- /dev/null +++ gcc/testsuite/g++.dg/cpp0x/Wnarrowing15.C @@ -0,0 +1,14 @@ +// PR c++/78244 +// { dg-do compile { target c++11 } } + +template +auto f1() -> decltype(int{2.0}, void()) { } // { dg-error "narrowing conversion" } + +template +auto f2() -> decltype(int{2.0}) { return 1; } // { dg-error "narrowing conversion" } + +template +auto f3() -> decltype(void(), int{2.0}) { return 1; } // { dg-error "narrowing conversion" } + +template +auto f4() -> decltype((int{2.0})) { return 1; } // { dg-error "narrowing conversion" } diff --git gcc/testsuite/g++.dg/cpp0x/constexpr-decltype3.C gcc/testsuite/g++.dg/cpp0x/constexpr-decltype3.C new file mode 100644 index 00000000000..fd05366de50 --- /dev/null +++ gcc/testsuite/g++.dg/cpp0x/constexpr-decltype3.C @@ -0,0 +1,25 @@ +// PR c++/88815 +// { dg-do compile { target c++11 } } + +struct true_type { + constexpr operator bool() const { return true; } +}; + +struct false_type { + constexpr operator bool() const { return false; } +}; + +template +true_type is_constexpr_impl(decltype(int{(p(), 0U)})); + +template +false_type is_constexpr_impl(...); + +template +using is_constexpr = decltype(is_constexpr_impl

(0)); + +constexpr int f() { return 0; } +int g() { return 0; } + +static_assert(is_constexpr(), ""); +static_assert(!is_constexpr(), ""); diff --git gcc/testsuite/g++.dg/cpp1y/Wnarrowing1.C gcc/testsuite/g++.dg/cpp1y/Wnarrowing1.C new file mode 100644 index 00000000000..e1e499542f0 --- /dev/null +++ gcc/testsuite/g++.dg/cpp1y/Wnarrowing1.C @@ -0,0 +1,5 @@ +// PR c++/78244 +// { dg-do compile { target c++14 } } + +template +decltype(int{1.1}) v; // { dg-error "narrowing conversion" }