diff options
author | Jason Merrill <jason@redhat.com> | 2015-10-18 14:02:10 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2015-10-18 14:02:10 -0400 |
commit | 49489608c05a33a41bd1f2b5d277819a70f45807 (patch) | |
tree | c0b9f59698bc719baa768613cd3cdcae9370728c /gcc | |
parent | a70ba41f41bca6d1965e617686ab02fc6eb42c5f (diff) | |
download | gcc-49489608c05a33a41bd1f2b5d277819a70f45807.zip gcc-49489608c05a33a41bd1f2b5d277819a70f45807.tar.gz gcc-49489608c05a33a41bd1f2b5d277819a70f45807.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/decl.c | 16 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/opt/flifetime-dse3.C | 22 |
3 files changed, 43 insertions, 1 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6664cf9..93ffc73 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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 diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 8eb9cc2..8036fb7 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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. */ diff --git a/gcc/testsuite/g++.dg/opt/flifetime-dse3.C b/gcc/testsuite/g++.dg/opt/flifetime-dse3.C new file mode 100644 index 0000000..7a03acc --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/flifetime-dse3.C @@ -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); +} |