From patchwork Tue Dec 15 21:16:32 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Palka X-Patchwork-Id: 557083 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]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id D535D1402D6 for ; Wed, 16 Dec 2015 08:16:50 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=w6mI0sMZ; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id; q=dns; s=default; b=f7ffhkIA8k68 ZuhtT6Vj3CwyLvxIW8VOSMsbOGELuBk5YBRlO3qqf56C7nMT4yLEdFbpxlluyMDa D2EH02oGgjZzqQLy9K9nK0HTQ6zEY9DlgWVX0+Gv1aFS+PXzI5q8kBzhEWYzjR80 9AqSdHOCnUQSDeX6AdYc28ej2GBnYWc= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id; s=default; bh=FzUI8ipYMocFSJAqjV GzEM3ksX8=; b=w6mI0sMZWmmeRQxchDDakMwYEx6Vj+lq1gpLjcHhvA4xCATLM6 uOKmQYL1RHMk6HZV8RD8YF9KVC1rQ83gpE+lJ6C31x4jSmobDK5PPtg5AJ+d60vg frhv8Esy4J3q0YnGGIjwCrvpmH+TecN6n7mkvfYROeGNdmAVQtJEV5QHI= Received: (qmail 53832 invoked by alias); 15 Dec 2015 21:16:43 -0000 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 Received: (qmail 53804 invoked by uid 89); 15 Dec 2015 21:16:42 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.0 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.2 X-HELO: mail-qg0-f45.google.com Received: from mail-qg0-f45.google.com (HELO mail-qg0-f45.google.com) (209.85.192.45) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Tue, 15 Dec 2015 21:16:40 +0000 Received: by mail-qg0-f45.google.com with SMTP id 103so18562283qgi.3 for ; Tue, 15 Dec 2015 13:16:40 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=7pMstJKh4Rnp/Hsw5A1/wt+81Z6NZOXpPoqLcuANUj0=; b=mRkD1Rhn6mSI+01n2fnP3+XheNBuvbQWQIReyAx1MC+JjNIsMPiezIIBUd8BxzQTGD bg1sIsa0mQ/t3dAdGZDVU8r0jm+plwHEuuEpBgBQ1HxmX485HzMPuwxegsLHrAzJUbLe wVHht6BBF47gwrBZliiuP5gVoyx2802EAwanyje+abBjjWGN/nmwtW4nFaOGl6HaseGT i0ucSEjflDIWIAlt4ByksrBBiimylxZ4TwI2SH9J56D8yFI9wntxQhx1s+88Qg2IvGrQ yHak4+PXFLyOLZbh0cTseaEbLKYC5y2qijH45IvMI18d2dya6FEWIJ4KOgKyz21x62qr yQPg== X-Gm-Message-State: ALoCoQmJ1wXyBR5hyyJfwvGIKJIA751RzigxUuImrQ9ct6s1zl2sMZMrKfQ/KqwgoVuSvRHMu1C3GAYLanfg3yXUE4JB91BO8w== X-Received: by 10.140.145.15 with SMTP id 15mr8341110qhr.82.1450214198059; Tue, 15 Dec 2015 13:16:38 -0800 (PST) Received: from localhost.localdomain (ool-4353a8be.dyn.optonline.net. [67.83.168.190]) by smtp.gmail.com with ESMTPSA id 138sm1259729qhi.37.2015.12.15.13.16.37 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 15 Dec 2015 13:16:37 -0800 (PST) From: Patrick Palka To: gcc-patches@gcc.gnu.org Cc: jason@redhat.com, Patrick Palka Subject: [PATCH] Fix some blockers of PR c++/24666 (arrays decay to pointers too early) Date: Tue, 15 Dec 2015 16:16:32 -0500 Message-Id: <1450214192-23542-1-git-send-email-patrick@parcs.ath.cx> This patch just makes convert_for_initialization() to avoid eagerly decaying an array, function, etc if the type we're converting to is a class type, so that the correct conversion constructor could be later be selected in perform_implicit_conversion_flags(). Bootstrap + regtest in progress on x86_64-pc-linux-gnu, OK to commit if no new regressions? gcc/cp/ChangeLog: PR c++/16333 PR c++/41426 PR c++/59878 PR c++/66895 * typeck.c (convert_for_initialization): Don't perform an early decaying conversion if converting to a class type. gcc/testsuite/ChangeLog: PR c++/16333 PR c++/41426 PR c++/59878 PR c++/66895 * g++.dg/conversion/pr16333.C: New test. * g++.dg/conversion/pr41426.C: New test. * g++.dg/conversion/pr59878.C: New test. * g++.dg/conversion/pr66895.C: New test. --- gcc/cp/typeck.c | 16 +++++++++------- gcc/testsuite/g++.dg/conversion/pr16333.C | 8 ++++++++ gcc/testsuite/g++.dg/conversion/pr41426.C | 28 ++++++++++++++++++++++++++++ gcc/testsuite/g++.dg/conversion/pr59878.C | 19 +++++++++++++++++++ gcc/testsuite/g++.dg/conversion/pr66895.C | 11 +++++++++++ 5 files changed, 75 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/g++.dg/conversion/pr16333.C create mode 100644 gcc/testsuite/g++.dg/conversion/pr41426.C create mode 100644 gcc/testsuite/g++.dg/conversion/pr59878.C create mode 100644 gcc/testsuite/g++.dg/conversion/pr66895.C diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 39c1af2..1059b26 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -8479,13 +8479,15 @@ convert_for_initialization (tree exp, tree type, tree rhs, int flags, || (TREE_CODE (rhs) == TREE_LIST && TREE_VALUE (rhs) == error_mark_node)) return error_mark_node; - if ((TREE_CODE (TREE_TYPE (rhs)) == ARRAY_TYPE - && TREE_CODE (type) != ARRAY_TYPE - && (TREE_CODE (type) != REFERENCE_TYPE - || TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE)) - || (TREE_CODE (TREE_TYPE (rhs)) == FUNCTION_TYPE - && !TYPE_REFFN_P (type)) - || TREE_CODE (TREE_TYPE (rhs)) == METHOD_TYPE) + if (MAYBE_CLASS_TYPE_P (type)) + ; + else if ((TREE_CODE (TREE_TYPE (rhs)) == ARRAY_TYPE + && TREE_CODE (type) != ARRAY_TYPE + && (TREE_CODE (type) != REFERENCE_TYPE + || TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE)) + || (TREE_CODE (TREE_TYPE (rhs)) == FUNCTION_TYPE + && !TYPE_REFFN_P (type)) + || TREE_CODE (TREE_TYPE (rhs)) == METHOD_TYPE) rhs = decay_conversion (rhs, complain); rhstype = TREE_TYPE (rhs); diff --git a/gcc/testsuite/g++.dg/conversion/pr16333.C b/gcc/testsuite/g++.dg/conversion/pr16333.C new file mode 100644 index 0000000..979e0ac --- /dev/null +++ b/gcc/testsuite/g++.dg/conversion/pr16333.C @@ -0,0 +1,8 @@ +// PR c++/16333 + +struct X { + X (const int (&)[3]); +}; + +int a[3]; +X foo () { return a; } diff --git a/gcc/testsuite/g++.dg/conversion/pr41426.C b/gcc/testsuite/g++.dg/conversion/pr41426.C new file mode 100644 index 0000000..cc86dd5 --- /dev/null +++ b/gcc/testsuite/g++.dg/conversion/pr41426.C @@ -0,0 +1,28 @@ +// PR c++/41426 + +template +struct A +{ + template + A(_T (&V)[_N]); + A(); +}; + +A g1() +{ + float f[] = {1.1f, 2.3f}; + return f; +} + +struct B +{ + B (int (&v)[10]); + B(); +}; + +B g2() +{ + int c[10]; + return c; +} + diff --git a/gcc/testsuite/g++.dg/conversion/pr59878.C b/gcc/testsuite/g++.dg/conversion/pr59878.C new file mode 100644 index 0000000..15f3a37 --- /dev/null +++ b/gcc/testsuite/g++.dg/conversion/pr59878.C @@ -0,0 +1,19 @@ +struct Test { + template + Test(const char (&array)[N]) {} +}; + +Test test() { + return "test1"; +} + +void test2(Test arg = "test12") {} + +template +void test3(T arg = "test123") {} + +int main() { + test(); + test2(); + test3(); +} diff --git a/gcc/testsuite/g++.dg/conversion/pr66895.C b/gcc/testsuite/g++.dg/conversion/pr66895.C new file mode 100644 index 0000000..a4bf651 --- /dev/null +++ b/gcc/testsuite/g++.dg/conversion/pr66895.C @@ -0,0 +1,11 @@ +// { dg-do compile { target c++11 } } + +#include +#include + +struct S { + template S(char const (&)[N]); +}; +struct T { S s; }; +void f(std::initializer_list); +void g() { f({{""}}); }