This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


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?
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();
+}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]