diff mbox

RFA (6): C++ PATCH for c++/70690, wrong code in tcmalloc

Message ID 57152E6B.80509@redhat.com
State New
Headers show

Commit Message

Jason Merrill April 18, 2016, 6:58 p.m. UTC
My change to type_has_constexpr_default_constructor broke 
build_vec_init, which asserts that it implies that 
default-initialization is the same as value-initialization, which is not 
the case for the "maybe constexpr" case.  So this patch reverts the 
change and adds a new "maybe constexpr" entry point when we don't need a 
firm answer.

Tested x86_64-pc-linux-gnu, applying to trunk.  OK for 6.1?

Comments

Jakub Jelinek April 18, 2016, 7:53 p.m. UTC | #1
On Mon, Apr 18, 2016 at 02:58:51PM -0400, Jason Merrill wrote:
> My change to type_has_constexpr_default_constructor broke build_vec_init,
> which asserts that it implies that default-initialization is the same as
> value-initialization, which is not the case for the "maybe constexpr" case.
> So this patch reverts the change and adds a new "maybe constexpr" entry
> point when we don't need a firm answer.
> 
> Tested x86_64-pc-linux-gnu, applying to trunk.  OK for 6.1?

Ok, thanks.

> commit 695043a6eb769f6510c4d495dacd5d70514c89ab
> Author: Jason Merrill <jason@redhat.com>
> Date:   Mon Apr 18 14:29:19 2016 -0400
> 
>     	PR c++/70690
>     
>     	PR c++/70528
>     	* class.c (type_maybe_constexpr_default_constructor): New.
>     	(type_has_constexpr_default_constructor): Revert.

	Jakub
diff mbox

Patch

commit 695043a6eb769f6510c4d495dacd5d70514c89ab
Author: Jason Merrill <jason@redhat.com>
Date:   Mon Apr 18 14:29:19 2016 -0400

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

diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index e6d5bb0..2c5ce73 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -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
index 0000000..e8ee181
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/array41.C
@@ -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();
+}