aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2015-10-18 14:02:10 -0400
committerJason Merrill <jason@gcc.gnu.org>2015-10-18 14:02:10 -0400
commit49489608c05a33a41bd1f2b5d277819a70f45807 (patch)
treec0b9f59698bc719baa768613cd3cdcae9370728c /gcc
parenta70ba41f41bca6d1965e617686ab02fc6eb42c5f (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--gcc/cp/decl.c16
-rw-r--r--gcc/testsuite/g++.dg/opt/flifetime-dse3.C22
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);
+}