mirror of git://gcc.gnu.org/git/gcc.git
PR c++/79118 - anon-members and constexpr
PR c++/79118 - anon-members and constexpr * constexpr.c (cx_check_missing_mem_inits): Caller passes type not ctor decl. Recursively check anonymous members. (register_constexpr_fundef): Adjust cx_check_missing_mem_inits call. (explain_invalid_constexpr_fn): Likewise. PR c++/79118 * g++.dg/cpp0x/pr79118.C: New. From-SVN: r244881
This commit is contained in:
parent
b20ba138ef
commit
3e4b91f275
|
|
@ -1,3 +1,12 @@
|
||||||
|
2017-01-24 Nathan Sidwell <nathan@acm.org>
|
||||||
|
|
||||||
|
PR c++/79118 - anon-members and constexpr
|
||||||
|
* constexpr.c (cx_check_missing_mem_inits): Caller passes type not
|
||||||
|
ctor decl. Recursively check anonymous members.
|
||||||
|
(register_constexpr_fundef): Adjust cx_check_missing_mem_inits
|
||||||
|
call.
|
||||||
|
(explain_invalid_constexpr_fn): Likewise.
|
||||||
|
|
||||||
2017-01-23 Nathan Sidwell <nathan@acm.org>
|
2017-01-23 Nathan Sidwell <nathan@acm.org>
|
||||||
|
|
||||||
PR c++/71710 - template using directive of field
|
PR c++/71710 - template using directive of field
|
||||||
|
|
|
||||||
|
|
@ -696,23 +696,21 @@ massage_constexpr_body (tree fun, tree body)
|
||||||
return body;
|
return body;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FUN is a constexpr constructor with massaged body BODY. Return true
|
/* CTYPE is a type constructed from BODY. Return true if some
|
||||||
if some bases/fields are uninitialized, and complain if COMPLAIN. */
|
bases/fields are uninitialized, and complain if COMPLAIN. */
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
cx_check_missing_mem_inits (tree fun, tree body, bool complain)
|
cx_check_missing_mem_inits (tree ctype, tree body, bool complain)
|
||||||
{
|
{
|
||||||
bool bad;
|
unsigned nelts = 0;
|
||||||
tree field;
|
|
||||||
unsigned i, nelts;
|
if (body)
|
||||||
tree ctype;
|
{
|
||||||
|
if (TREE_CODE (body) != CONSTRUCTOR)
|
||||||
if (TREE_CODE (body) != CONSTRUCTOR)
|
return false;
|
||||||
return false;
|
nelts = CONSTRUCTOR_NELTS (body);
|
||||||
|
}
|
||||||
nelts = CONSTRUCTOR_NELTS (body);
|
tree field = TYPE_FIELDS (ctype);
|
||||||
ctype = DECL_CONTEXT (fun);
|
|
||||||
field = TYPE_FIELDS (ctype);
|
|
||||||
|
|
||||||
if (TREE_CODE (ctype) == UNION_TYPE)
|
if (TREE_CODE (ctype) == UNION_TYPE)
|
||||||
{
|
{
|
||||||
|
|
@ -726,13 +724,13 @@ cx_check_missing_mem_inits (tree fun, tree body, bool complain)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bad = false;
|
/* Iterate over the CONSTRUCTOR, checking any missing fields don't
|
||||||
for (i = 0; i <= nelts; ++i)
|
need an explicit initialization. */
|
||||||
|
bool bad = false;
|
||||||
|
for (unsigned i = 0; i <= nelts; ++i)
|
||||||
{
|
{
|
||||||
tree index;
|
tree index = NULL_TREE;
|
||||||
if (i == nelts)
|
if (i < nelts)
|
||||||
index = NULL_TREE;
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
index = CONSTRUCTOR_ELT (body, i)->index;
|
index = CONSTRUCTOR_ELT (body, i)->index;
|
||||||
/* Skip base and vtable inits. */
|
/* Skip base and vtable inits. */
|
||||||
|
|
@ -740,13 +738,25 @@ cx_check_missing_mem_inits (tree fun, tree body, bool complain)
|
||||||
|| DECL_ARTIFICIAL (index))
|
|| DECL_ARTIFICIAL (index))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (; field != index; field = DECL_CHAIN (field))
|
for (; field != index; field = DECL_CHAIN (field))
|
||||||
{
|
{
|
||||||
tree ftype;
|
tree ftype;
|
||||||
if (TREE_CODE (field) != FIELD_DECL
|
if (TREE_CODE (field) != FIELD_DECL)
|
||||||
|| (DECL_C_BIT_FIELD (field) && !DECL_NAME (field))
|
|
||||||
|| DECL_ARTIFICIAL (field))
|
|
||||||
continue;
|
continue;
|
||||||
|
if (DECL_C_BIT_FIELD (field) && !DECL_NAME (field))
|
||||||
|
continue;
|
||||||
|
if (DECL_ARTIFICIAL (field))
|
||||||
|
continue;
|
||||||
|
if (ANON_AGGR_TYPE_P (TREE_TYPE (field)))
|
||||||
|
{
|
||||||
|
/* Recurse to check the anonummous aggregate member. */
|
||||||
|
bad |= cx_check_missing_mem_inits
|
||||||
|
(TREE_TYPE (field), NULL_TREE, complain);
|
||||||
|
if (bad && !complain)
|
||||||
|
return true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
ftype = strip_array_types (TREE_TYPE (field));
|
ftype = strip_array_types (TREE_TYPE (field));
|
||||||
if (type_has_constexpr_default_constructor (ftype))
|
if (type_has_constexpr_default_constructor (ftype))
|
||||||
{
|
{
|
||||||
|
|
@ -766,6 +776,15 @@ cx_check_missing_mem_inits (tree fun, tree body, bool complain)
|
||||||
}
|
}
|
||||||
if (field == NULL_TREE)
|
if (field == NULL_TREE)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
if (ANON_AGGR_TYPE_P (TREE_TYPE (index)))
|
||||||
|
{
|
||||||
|
/* Check the anonymous aggregate initializer is valid. */
|
||||||
|
bad |= cx_check_missing_mem_inits
|
||||||
|
(TREE_TYPE (index), CONSTRUCTOR_ELT (body, i)->value, complain);
|
||||||
|
if (bad && !complain)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
field = DECL_CHAIN (field);
|
field = DECL_CHAIN (field);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -803,7 +822,8 @@ register_constexpr_fundef (tree fun, tree body)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DECL_CONSTRUCTOR_P (fun)
|
if (DECL_CONSTRUCTOR_P (fun)
|
||||||
&& cx_check_missing_mem_inits (fun, massaged, !DECL_GENERATED_P (fun)))
|
&& cx_check_missing_mem_inits (DECL_CONTEXT (fun),
|
||||||
|
massaged, !DECL_GENERATED_P (fun)))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* Create the constexpr function table if necessary. */
|
/* Create the constexpr function table if necessary. */
|
||||||
|
|
@ -864,7 +884,7 @@ explain_invalid_constexpr_fn (tree fun)
|
||||||
body = massage_constexpr_body (fun, DECL_SAVED_TREE (fun));
|
body = massage_constexpr_body (fun, DECL_SAVED_TREE (fun));
|
||||||
require_potential_rvalue_constant_expression (body);
|
require_potential_rvalue_constant_expression (body);
|
||||||
if (DECL_CONSTRUCTOR_P (fun))
|
if (DECL_CONSTRUCTOR_P (fun))
|
||||||
cx_check_missing_mem_inits (fun, body, true);
|
cx_check_missing_mem_inits (DECL_CONTEXT (fun), body, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
input_location = save_loc;
|
input_location = save_loc;
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,8 @@
|
||||||
|
2017-01-24 Nathan Sidwell <nathan@acm.org>
|
||||||
|
|
||||||
|
PR c++/79118
|
||||||
|
* g++.dg/cpp0x/pr79118.C: New.
|
||||||
|
|
||||||
2017-01-24 Eric Botcazou <ebotcazou@adacore.com>
|
2017-01-24 Eric Botcazou <ebotcazou@adacore.com>
|
||||||
|
|
||||||
* gcc.target/arm/vfp-longcall-apcs.c: New test.
|
* gcc.target/arm/vfp-longcall-apcs.c: New test.
|
||||||
|
|
@ -305,7 +310,7 @@
|
||||||
|
|
||||||
2017-01-20 Nathan Sidwell <nathan@acm.org>
|
2017-01-20 Nathan Sidwell <nathan@acm.org>
|
||||||
|
|
||||||
PR c++/79495
|
PR c++/78495
|
||||||
* g++.dg/cpp1z/inh-ctor38.C: New.
|
* g++.dg/cpp1z/inh-ctor38.C: New.
|
||||||
|
|
||||||
2017-01-20 Marek Polacek <polacek@redhat.com>
|
2017-01-20 Marek Polacek <polacek@redhat.com>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
// { dg-do compile { target c++11 } }
|
||||||
|
// { dg-additional-options { -Wno-pedantic } }
|
||||||
|
// PR c++/79118 failure to check initialization of anonymous members.
|
||||||
|
|
||||||
|
struct One
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
int a;
|
||||||
|
int b;
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr One () : a(), b() {} // { dg-error "multiple" }
|
||||||
|
constexpr One (int) : a() {}
|
||||||
|
constexpr One (unsigned) : b () {}
|
||||||
|
constexpr One (void *) {} // { dg-error "exactly one" }
|
||||||
|
};
|
||||||
|
|
||||||
|
One a ();
|
||||||
|
One b (0);
|
||||||
|
One c (0u);
|
||||||
|
One d ((void *)0);
|
||||||
|
|
||||||
|
struct Two
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
int a;
|
||||||
|
int b;
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr Two () : a(), b() {}
|
||||||
|
constexpr Two (int) : a() {} // { dg-error "b' must be initialized" }
|
||||||
|
constexpr Two (unsigned) : b () {} // { dg-error "a' must be initialized" }
|
||||||
|
constexpr Two (void *) {} // { dg-error "a' must be initialized" }
|
||||||
|
// { dg-error "b' must be initialized" "" { target *-*-* } 35 }
|
||||||
|
};
|
||||||
|
|
||||||
|
Two e ();
|
||||||
|
Two f (0);
|
||||||
|
Two g (0u);
|
||||||
|
Two h ((void *)0);
|
||||||
Loading…
Reference in New Issue