diff options
author | Patrick Palka <ppalka@gcc.gnu.org> | 2015-12-17 04:01:47 +0000 |
---|---|---|
committer | Patrick Palka <ppalka@gcc.gnu.org> | 2015-12-17 04:01:47 +0000 |
commit | f85e1317f8ea933f5c615680353bd646f480f7d3 (patch) | |
tree | 5e30c38f716a0c0974f3789b148f2648e1ce888e | |
parent | 5fdfa03e795034058a66f641eb9d1f4499052639 (diff) | |
download | gcc-f85e1317f8ea933f5c615680353bd646f480f7d3.zip gcc-f85e1317f8ea933f5c615680353bd646f480f7d3.tar.gz gcc-f85e1317f8ea933f5c615680353bd646f480f7d3.tar.bz2 |
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
-rw-r--r-- | gcc/cp/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 16 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/conversion/pr16333.C | 10 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/conversion/pr41426.C | 40 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/conversion/pr59878.C | 25 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/conversion/pr66895.C | 16 |
7 files changed, 120 insertions, 7 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 91bc456..14292e9 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,14 @@ 2015-12-16 Patrick Palka <ppalka@gcc.gnu.org> + 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 <ppalka@gcc.gnu.org> + * tree.c (cp_tree_operand_length): Define in terms of cp_tree_code_length. diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 39c1af2..a06ecf0 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 0a87230..697fd06 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,14 @@ +2015-12-16 Patrick Palka <ppalka@gcc.gnu.org> + + 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 <msebor@redhat.com> 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 0000000..810c12a --- /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 0000000..78ec5fb --- /dev/null +++ b/gcc/testsuite/g++.dg/conversion/pr41426.C @@ -0,0 +1,40 @@ +// PR c++/41426 + +template <typename _T> +struct A +{ + template <int _N> + A(_T (&V)[_N]); + A(); +}; + +A<float> g1() +{ + float f[] = {1.1f, 2.3f}; + return f; +} + +const A<float> &g3() +{ + float f[] = {1.1f, 2.3f}; + return f; // { dg-warning "returning reference to temporary" } +} + +A<float> &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 0000000..ed567fe --- /dev/null +++ b/gcc/testsuite/g++.dg/conversion/pr59878.C @@ -0,0 +1,25 @@ +// PR c++/59878 + +struct Test { + template <int N> + Test(const char (&array)[N]) {} +}; + +Test test() { + return "test1"; +} + +void test2(Test arg = "test12") {} + +template <typename T> +void test3(T arg = "test123") {} + +template <typename T> +void test4(const T &arg = "test123") {} + +int main() { + test(); + test2(); + test3<Test>(); + test4<Test>(); +} diff --git a/gcc/testsuite/g++.dg/conversion/pr66895.C b/gcc/testsuite/g++.dg/conversion/pr66895.C new file mode 100644 index 0000000..14203bd --- /dev/null +++ b/gcc/testsuite/g++.dg/conversion/pr66895.C @@ -0,0 +1,16 @@ +// PR c++/66895 +// { dg-do compile { target c++11 } } + +#include <cstddef> +#include <initializer_list> + +struct S { + template<std::size_t N> S(char const (&)[N]); +}; +struct T1 { S s; }; +void f1(std::initializer_list<T1>); +void g1() { f1({{""}}); } + +struct T2 { const S& s; }; +void f2(std::initializer_list<T2>); +void g2() { f2({{""}}); } |