PR c++/89083, c++/80864 - ICE with list initialization in template.
* constexpr.c (adjust_temp_type): Use copy_node and change the type instead of using build_constructor. * decl.c (reshape_init_r): Don't reshape a digested initializer. Return the initializer for COMPOUND_LITERAL_P. * g++.dg/cpp0x/initlist107.C: New test. * g++.dg/cpp0x/initlist108.C: New test. * g++.dg/cpp0x/initlist109.C: New test. * g++.dg/cpp0x/initlist110.C: New test. * g++.dg/cpp0x/initlist111.C: New test. * g++.dg/cpp0x/initlist112.C: New test. * g++.dg/init/ptrfn4.C: New test. From-SVN: r268428
This commit is contained in:
parent
1d4b4f4979
commit
b27f74e777
|
@ -1,3 +1,11 @@
|
||||||
|
2019-01-31 Marek Polacek <polacek@redhat.com>
|
||||||
|
|
||||||
|
PR c++/89083, c++/80864 - ICE with list initialization in template.
|
||||||
|
* constexpr.c (adjust_temp_type): Use copy_node and change the type
|
||||||
|
instead of using build_constructor.
|
||||||
|
* decl.c (reshape_init_r): Don't reshape a digested initializer.
|
||||||
|
Return the initializer for COMPOUND_LITERAL_P.
|
||||||
|
|
||||||
2019-01-30 Jason Merrill <jason@redhat.com>
|
2019-01-30 Jason Merrill <jason@redhat.com>
|
||||||
|
|
||||||
PR c++/88752 - ICE with lambda and constexpr if.
|
PR c++/88752 - ICE with lambda and constexpr if.
|
||||||
|
|
|
@ -1291,7 +1291,12 @@ adjust_temp_type (tree type, tree temp)
|
||||||
return temp;
|
return temp;
|
||||||
/* Avoid wrapping an aggregate value in a NOP_EXPR. */
|
/* Avoid wrapping an aggregate value in a NOP_EXPR. */
|
||||||
if (TREE_CODE (temp) == CONSTRUCTOR)
|
if (TREE_CODE (temp) == CONSTRUCTOR)
|
||||||
return build_constructor (type, CONSTRUCTOR_ELTS (temp));
|
{
|
||||||
|
/* build_constructor wouldn't retain various CONSTRUCTOR flags. */
|
||||||
|
tree t = copy_node (temp);
|
||||||
|
TREE_TYPE (t) = type;
|
||||||
|
return t;
|
||||||
|
}
|
||||||
if (TREE_CODE (temp) == EMPTY_CLASS_EXPR)
|
if (TREE_CODE (temp) == EMPTY_CLASS_EXPR)
|
||||||
return build0 (EMPTY_CLASS_EXPR, type);
|
return build0 (EMPTY_CLASS_EXPR, type);
|
||||||
gcc_assert (scalarish_type_p (type));
|
gcc_assert (scalarish_type_p (type));
|
||||||
|
|
|
@ -6154,20 +6154,29 @@ reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p,
|
||||||
{
|
{
|
||||||
if (TREE_CODE (stripped_init) == CONSTRUCTOR)
|
if (TREE_CODE (stripped_init) == CONSTRUCTOR)
|
||||||
{
|
{
|
||||||
if (TREE_TYPE (init) && TYPE_PTRMEMFUNC_P (TREE_TYPE (init)))
|
tree init_type = TREE_TYPE (init);
|
||||||
/* There is no need to reshape pointer-to-member function
|
if (init_type && TYPE_PTRMEMFUNC_P (init_type))
|
||||||
initializers, as they are always constructed correctly
|
/* There is no need to call reshape_init for pointer-to-member
|
||||||
by the front end. */
|
function initializers, as they are always constructed correctly
|
||||||
;
|
by the front end. Here we have e.g. {.__pfn=0B, .__delta=0},
|
||||||
else if (COMPOUND_LITERAL_P (stripped_init))
|
which is missing outermost braces. We should warn below, and
|
||||||
|
one of the routines below will wrap it in additional { }. */;
|
||||||
/* For a nested compound literal, there is no need to reshape since
|
/* For a nested compound literal, there is no need to reshape since
|
||||||
brace elision is not allowed. Even if we decided to allow it,
|
we called reshape_init in finish_compound_literal, before calling
|
||||||
we should add a call to reshape_init in finish_compound_literal,
|
digest_init. */
|
||||||
before calling digest_init, so changing this code would still
|
else if (COMPOUND_LITERAL_P (stripped_init)
|
||||||
not be necessary. */
|
/* Similarly, a CONSTRUCTOR of the target's type is a
|
||||||
gcc_assert (!BRACE_ENCLOSED_INITIALIZER_P (stripped_init));
|
previously digested initializer. */
|
||||||
|
|| same_type_ignoring_top_level_qualifiers_p (type,
|
||||||
|
init_type))
|
||||||
|
{
|
||||||
|
++d->cur;
|
||||||
|
gcc_assert (!BRACE_ENCLOSED_INITIALIZER_P (stripped_init));
|
||||||
|
return init;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* Something that hasn't been reshaped yet. */
|
||||||
++d->cur;
|
++d->cur;
|
||||||
gcc_assert (BRACE_ENCLOSED_INITIALIZER_P (stripped_init));
|
gcc_assert (BRACE_ENCLOSED_INITIALIZER_P (stripped_init));
|
||||||
return reshape_init (type, init, complain);
|
return reshape_init (type, init, complain);
|
||||||
|
|
|
@ -1,3 +1,14 @@
|
||||||
|
2019-01-31 Marek Polacek <polacek@redhat.com>
|
||||||
|
|
||||||
|
PR c++/89083, c++/80864 - ICE with list initialization in template.
|
||||||
|
* g++.dg/cpp0x/initlist107.C: New test.
|
||||||
|
* g++.dg/cpp0x/initlist108.C: New test.
|
||||||
|
* g++.dg/cpp0x/initlist109.C: New test.
|
||||||
|
* g++.dg/cpp0x/initlist110.C: New test.
|
||||||
|
* g++.dg/cpp0x/initlist111.C: New test.
|
||||||
|
* g++.dg/cpp0x/initlist112.C: New test.
|
||||||
|
* g++.dg/init/ptrfn4.C: New test.
|
||||||
|
|
||||||
2019-01-31 David Malcolm <dmalcolm@redhat.com>
|
2019-01-31 David Malcolm <dmalcolm@redhat.com>
|
||||||
|
|
||||||
PR c/89122
|
PR c/89122
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
// PR c++/89083
|
||||||
|
// { dg-do compile { target c++11 } }
|
||||||
|
// { dg-options "-Wmissing-braces" }
|
||||||
|
|
||||||
|
struct A { int x[3]; };
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
decltype(A{1, 2}, T()) fn1(T t) // { dg-warning "missing braces" }
|
||||||
|
{
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
decltype(A{{1, 2}}, T()) fn2(T t)
|
||||||
|
{
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
f()
|
||||||
|
{
|
||||||
|
fn1(1);
|
||||||
|
fn2(1);
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
// PR c++/80864
|
||||||
|
// { dg-do compile { target c++11 } }
|
||||||
|
// { dg-options "-Wmissing-braces" }
|
||||||
|
|
||||||
|
struct S {
|
||||||
|
char c[1];
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void
|
||||||
|
fn ()
|
||||||
|
{
|
||||||
|
constexpr S s1 = S{};
|
||||||
|
constexpr S s2 = S{{}};
|
||||||
|
constexpr S s3 = S{{{}}};
|
||||||
|
constexpr S s4 = {};
|
||||||
|
constexpr S s5 = {{}};
|
||||||
|
constexpr S s6 = {{{}}};
|
||||||
|
constexpr S s7{{}};
|
||||||
|
constexpr S s8{S{}};
|
||||||
|
constexpr S s9{S{{}}};
|
||||||
|
constexpr S s10{S{{{}}}};
|
||||||
|
constexpr S s11 = S();
|
||||||
|
constexpr S s12 = S({});
|
||||||
|
constexpr S s13 = S({{}});
|
||||||
|
constexpr S s14 = {{}};
|
||||||
|
constexpr S s15 = {{{}}};
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
foo ()
|
||||||
|
{
|
||||||
|
fn<int>();
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
// PR c++/80864
|
||||||
|
// { dg-do compile { target c++11 } }
|
||||||
|
// { dg-options "-Wmissing-braces" }
|
||||||
|
|
||||||
|
struct S {};
|
||||||
|
struct A { S s[1]; };
|
||||||
|
|
||||||
|
template <typename>
|
||||||
|
struct R { static constexpr auto h = A{S{}}; }; // { dg-warning "missing braces" }
|
||||||
|
|
||||||
|
template <typename>
|
||||||
|
struct R2 { static constexpr auto h = A{{S{}}}; };
|
||||||
|
|
||||||
|
A foo = R<int>::h;
|
||||||
|
A foo2 = R2<int>::h;
|
|
@ -0,0 +1,32 @@
|
||||||
|
// PR c++/89083
|
||||||
|
// { dg-do compile { target c++11 } }
|
||||||
|
|
||||||
|
struct C { int a[3]; int i; };
|
||||||
|
struct B { C c[3]; };
|
||||||
|
struct A { B b[3]; };
|
||||||
|
|
||||||
|
template<class T, int N>
|
||||||
|
decltype(A{N, N}, T()) fn1(T t)
|
||||||
|
{
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, int N>
|
||||||
|
decltype(A{{{N, N, N}, {N + 1}}}, T()) fn2(T t)
|
||||||
|
{
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, int N, int M>
|
||||||
|
decltype(A{{N + M}}, T()) fn3(T t)
|
||||||
|
{
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
f()
|
||||||
|
{
|
||||||
|
fn1<int, 10>(1);
|
||||||
|
fn2<int, 10>(1);
|
||||||
|
fn3<int, 10, 20>(1);
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
// PR c++/80864
|
||||||
|
// { dg-do compile { target c++11 } }
|
||||||
|
|
||||||
|
struct S {
|
||||||
|
int c[3];
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, int N>
|
||||||
|
void
|
||||||
|
fn ()
|
||||||
|
{
|
||||||
|
constexpr S s1 = S{N};
|
||||||
|
constexpr S s2 = S{{N, N}};
|
||||||
|
constexpr S s3 = S{N, N};
|
||||||
|
constexpr S s4 = {N};
|
||||||
|
constexpr S s5 = {{N}};
|
||||||
|
constexpr S s6 = {N, N};
|
||||||
|
constexpr S s7{{N}};
|
||||||
|
constexpr S s8{S{N}};
|
||||||
|
constexpr S s9{S{{N}}};
|
||||||
|
constexpr S s10{S{{N}}};
|
||||||
|
constexpr S s11 = S({N});
|
||||||
|
constexpr S s12 = S({{N}});
|
||||||
|
constexpr S s13 = {{N}};
|
||||||
|
constexpr S s14 = {{N, N, N}};
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
foo ()
|
||||||
|
{
|
||||||
|
fn<int, 10>();
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
// PR c++/80864
|
||||||
|
// { dg-do compile { target c++11 } }
|
||||||
|
|
||||||
|
struct S {int a[2]; };
|
||||||
|
struct A { S s[1]; };
|
||||||
|
|
||||||
|
template <typename, int N>
|
||||||
|
struct R { static constexpr auto h = A{S{N}}; };
|
||||||
|
|
||||||
|
template <typename, int N>
|
||||||
|
struct R2 { static constexpr auto h = A{S{{N, N}}}; };
|
||||||
|
|
||||||
|
A foo = R<int, 10>::h;
|
||||||
|
A foo2 = R2<int, 10>::h;
|
|
@ -0,0 +1,19 @@
|
||||||
|
// { dg-do compile }
|
||||||
|
// { dg-options "-Wmissing-braces" }
|
||||||
|
|
||||||
|
struct S { };
|
||||||
|
typedef void (S::*fptr1) (int);
|
||||||
|
|
||||||
|
struct A {
|
||||||
|
fptr1 f;
|
||||||
|
};
|
||||||
|
|
||||||
|
A a[] =
|
||||||
|
{
|
||||||
|
(fptr1) 0,
|
||||||
|
}; // { dg-warning "missing braces around initializer" }
|
||||||
|
|
||||||
|
A a2[] =
|
||||||
|
{
|
||||||
|
{ (fptr1) 0 }
|
||||||
|
};
|
Loading…
Reference in New Issue