From f85e1317f8ea933f5c615680353bd646f480f7d3 Mon Sep 17 00:00:00 2001 From: Patrick Palka Date: Thu, 17 Dec 2015 04:01:47 +0000 Subject: [PATCH] Fix some blockers of PR c++/24666 (arrays decay to pointers too early) 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. From-SVN: r231736 --- gcc/cp/ChangeLog | 9 +++++ gcc/cp/typeck.c | 16 +++++---- gcc/testsuite/ChangeLog | 11 +++++++ gcc/testsuite/g++.dg/conversion/pr16333.C | 10 ++++++ gcc/testsuite/g++.dg/conversion/pr41426.C | 40 +++++++++++++++++++++++ gcc/testsuite/g++.dg/conversion/pr59878.C | 25 ++++++++++++++ gcc/testsuite/g++.dg/conversion/pr66895.C | 16 +++++++++ 7 files changed, 120 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/ChangeLog b/gcc/cp/ChangeLog index 91bc456399f..14292e9fab3 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2015-12-16 Patrick Palka + + 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. + 2015-12-16 Patrick Palka * tree.c (cp_tree_operand_length): Define in terms of diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 39c1af2f257..a06ecf0732a 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 (non_reference (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/ChangeLog b/gcc/testsuite/ChangeLog index 0a8723080fd..697fd0667b8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,14 @@ +2015-12-16 Patrick Palka + + 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. + 2015-12-16 Martin Sebor PR c/68868 diff --git a/gcc/testsuite/g++.dg/conversion/pr16333.C b/gcc/testsuite/g++.dg/conversion/pr16333.C new file mode 100644 index 00000000000..810c12a9acb --- /dev/null +++ b/gcc/testsuite/g++.dg/conversion/pr16333.C @@ -0,0 +1,10 @@ +// PR c++/16333 + +struct X { + X (const int (&)[3]); +}; + +int a[3]; +X foo1 () { return a; } +const X &foo2 () { return a; } // { dg-warning "returning reference to temporary" } +X &foo3 () { return a; } // { dg-error "invalid initialization" } diff --git a/gcc/testsuite/g++.dg/conversion/pr41426.C b/gcc/testsuite/g++.dg/conversion/pr41426.C new file mode 100644 index 00000000000..78ec5fbdfbf --- /dev/null +++ b/gcc/testsuite/g++.dg/conversion/pr41426.C @@ -0,0 +1,40 @@ +// PR c++/41426 + +template +struct A +{ + template + A(_T (&V)[_N]); + A(); +}; + +A g1() +{ + float f[] = {1.1f, 2.3f}; + return f; +} + +const A &g3() +{ + float f[] = {1.1f, 2.3f}; + return f; // { dg-warning "returning reference to temporary" } +} + +A &g4() +{ + float f[] = {1.1f, 2.3f}; + return f; // { dg-error "invalid initialization" } +} + +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 00000000000..ed567fe6f24 --- /dev/null +++ b/gcc/testsuite/g++.dg/conversion/pr59878.C @@ -0,0 +1,25 @@ +// PR c++/59878 + +struct Test { + template + Test(const char (&array)[N]) {} +}; + +Test test() { + return "test1"; +} + +void test2(Test arg = "test12") {} + +template +void test3(T arg = "test123") {} + +template +void test4(const T &arg = "test123") {} + +int main() { + test(); + test2(); + test3(); + test4(); +} diff --git a/gcc/testsuite/g++.dg/conversion/pr66895.C b/gcc/testsuite/g++.dg/conversion/pr66895.C new file mode 100644 index 00000000000..14203bdab50 --- /dev/null +++ b/gcc/testsuite/g++.dg/conversion/pr66895.C @@ -0,0 +1,16 @@ +// PR c++/66895 +// { dg-do compile { target c++11 } } + +#include +#include + +struct S { + template S(char const (&)[N]); +}; +struct T1 { S s; }; +void f1(std::initializer_list); +void g1() { f1({{""}}); } + +struct T2 { const S& s; }; +void f2(std::initializer_list); +void g2() { f2({{""}}); } -- 2.30.2