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
This commit is contained in:
Patrick Palka 2015-12-17 04:01:47 +00:00
parent 5fdfa03e79
commit f85e1317f8
7 changed files with 120 additions and 7 deletions

View file

@ -1,3 +1,12 @@
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

View file

@ -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);

View file

@ -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

View file

@ -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" }

View file

@ -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;
}

View file

@ -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>();
}

View file

@ -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({{""}}); }