re PR c++/70690 (r235002 miscompiles tcmalloc)
authorJason Merrill <jason@redhat.com>
Mon, 18 Apr 2016 19:00:00 +0000 (15:00 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 18 Apr 2016 19:00:00 +0000 (15:00 -0400)
PR c++/70690

PR c++/70528
* class.c (type_maybe_constexpr_default_constructor): New.
(type_has_constexpr_default_constructor): Revert.

From-SVN: r235165

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/testsuite/g++.dg/init/array41.C [new file with mode: 0644]

index 1dd48b6de81d200b46ba0c9c9432187536762281..104da7b58d2fda22f9d84ece4cd5fa6da3eab5ea 100644 (file)
@@ -1,3 +1,10 @@
+2016-04-18  Jason Merrill  <jason@redhat.com>
+
+       PR c++/70690
+       PR c++/70528
+       * class.c (type_maybe_constexpr_default_constructor): New.
+       (type_has_constexpr_default_constructor): Revert.
+
 2016-04-16  Sandra Loosemore  <sandra@codesourcery.com>
 
        PR target/1078
index e6d5bb0fe9c1f1d101d5b9686d33f09bb3a4ca18..2c5ce7384dac3ce14a64dc07753c10348a8441fe 100644 (file)
@@ -214,6 +214,7 @@ static bool base_derived_from (tree, tree);
 static int empty_base_at_nonzero_offset_p (tree, tree, splay_tree);
 static tree end_of_base (tree);
 static tree get_vcall_index (tree, tree);
+static bool type_maybe_constexpr_default_constructor (tree);
 
 /* Variables shared between class.c and call.c.  */
 
@@ -3346,7 +3347,11 @@ add_implicitly_declared_members (tree t, tree* access_decls,
       CLASSTYPE_LAZY_DEFAULT_CTOR (t) = 1;
       if (cxx_dialect >= cxx11)
        TYPE_HAS_CONSTEXPR_CTOR (t)
-         = type_has_constexpr_default_constructor (t);
+         /* Don't force the declaration to get a hard answer; if the
+            definition would have made the class non-literal, it will still be
+            non-literal because of the base or member in question, and that
+            gives a better diagnostic.  */
+         = type_maybe_constexpr_default_constructor (t);
     }
 
   /* [class.ctor]
@@ -5348,16 +5353,28 @@ type_has_constexpr_default_constructor (tree t)
     {
       if (!TYPE_HAS_COMPLEX_DFLT (t))
        return trivial_default_constructor_is_constexpr (t);
-      /* Assume it's constexpr to avoid unnecessary instantiation; if the
-        definition would have made the class non-literal, it will still be
-        non-literal because of the base or member in question, and that
-        gives a better diagnostic.  */
-      return true;
+      /* Non-trivial, we need to check subobject constructors.  */
+      lazily_declare_fn (sfk_constructor, t);
     }
   fns = locate_ctor (t);
   return (fns && DECL_DECLARED_CONSTEXPR_P (fns));
 }
 
+/* Returns true iff class T has a constexpr default constructor or has an
+   implicitly declared default constructor that we can't tell if it's constexpr
+   without forcing a lazy declaration (which might cause undesired
+   instantiations).  */
+
+bool
+type_maybe_constexpr_default_constructor (tree t)
+{
+  if (CLASS_TYPE_P (t) && CLASSTYPE_LAZY_DEFAULT_CTOR (t)
+      && TYPE_HAS_COMPLEX_DFLT (t))
+    /* Assume it's constexpr.  */
+    return true;
+  return type_has_constexpr_default_constructor (t);
+}
+
 /* Returns true iff class TYPE has a virtual destructor.  */
 
 bool
diff --git a/gcc/testsuite/g++.dg/init/array41.C b/gcc/testsuite/g++.dg/init/array41.C
new file mode 100644 (file)
index 0000000..e8ee181
--- /dev/null
@@ -0,0 +1,27 @@
+// PR c++/70690
+// { dg-do run }
+
+struct A {
+  A() {}
+};
+
+struct APadded : public A {
+  char pad[63];
+};
+
+int f();
+int i = f();
+APadded cache[50];
+APadded *p = cache;
+
+int f()
+{
+  cache[0].pad[0] = 42;
+  return 1;
+}
+
+int main()
+{
+  if (cache[0].pad[0] != 42)
+    __builtin_abort();
+}