re PR c++/68006 ([C++14] Incorrect aggregate initialization from empty initializer list with NSDMI)

PR c++/68006

	* decl.c (implicit_default_ctor_p): New.
	(start_preparsed_function): Don't clobber on entry to one.

From-SVN: r228949
This commit is contained in:
Jason Merrill 2015-10-18 14:02:10 -04:00 committed by Jason Merrill
parent a70ba41f41
commit 49489608c0
3 changed files with 43 additions and 1 deletions

View File

@ -1,3 +1,9 @@
2015-10-17 Jason Merrill <jason@redhat.com>
PR c++/68006
* decl.c (implicit_default_ctor_p): New.
(start_preparsed_function): Don't clobber on entry to one.
2015-10-16 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/67926

View File

@ -13630,6 +13630,16 @@ check_function_type (tree decl, tree current_function_parms)
abstract_virtuals_error (decl, TREE_TYPE (fntype));
}
/* True iff FN is an implicitly-defined default constructor. */
static bool
implicit_default_ctor_p (tree fn)
{
return (DECL_CONSTRUCTOR_P (fn)
&& !user_provided_p (fn)
&& sufficient_parms_p (FUNCTION_FIRST_USER_PARMTYPE (fn)));
}
/* Create the FUNCTION_DECL for a function definition.
DECLSPECS and DECLARATOR are the parts of the declaration;
they describe the function's name and the type it returns,
@ -14036,7 +14046,11 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
store_parm_decls (current_function_parms);
if (!processing_template_decl
&& flag_lifetime_dse && DECL_CONSTRUCTOR_P (decl1))
&& flag_lifetime_dse && DECL_CONSTRUCTOR_P (decl1)
/* We can't clobber safely for an implicitly-defined default constructor
because part of the initialization might happen before we enter the
consructor, via AGGR_INIT_ZERO_FIRST (c++/68006). */
&& !implicit_default_ctor_p (decl1))
{
/* Insert a clobber to let the back end know that the object storage
is dead when we enter the constructor. */

View File

@ -0,0 +1,22 @@
// PR c++/68006
// { dg-do run { target c++11 } }
// { dg-options -O2 }
inline void* operator new(__SIZE_TYPE__, void* ptr)
{
return ptr;
}
struct X { int x; int y; int z = 42; };
void test_bar(void* p)
{
new(p) X{}; // Bad.
}
int main()
{
int ar[3] = { 1,2,3 };
test_bar (ar);
return (ar[0] != 0 || ar[1] != 0 || ar[2] != 42);
}