re PR c++/70528 (bogus error: constructor required before non-static data member)
authorJason Merrill <jason@redhat.com>
Fri, 15 Apr 2016 02:23:05 +0000 (22:23 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Fri, 15 Apr 2016 02:23:05 +0000 (22:23 -0400)
PR c++/70528

* class.c (type_has_constexpr_default_constructor): Return true
for an implicitly declared constructor.

From-SVN: r235002

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/testsuite/g++.dg/cpp0x/constexpr-ctor12.C
gcc/testsuite/g++.dg/cpp0x/constexpr-default-ctor.C
gcc/testsuite/g++.dg/cpp0x/constexpr-ice6.C
gcc/testsuite/g++.dg/cpp0x/inh-ctor19.C
gcc/testsuite/g++.dg/cpp0x/pr70528.C [new file with mode: 0644]

index 6384ab890374b432b0e7b3034b187480ed099b35..12900d3cd45b3d03b2638bc388fc6489b1cb605e 100644 (file)
@@ -1,5 +1,9 @@
 2016-04-14  Jason Merrill  <jason@redhat.com>
 
+       PR c++/70528
+       * class.c (type_has_constexpr_default_constructor): Return true
+       for an implicitly declared constructor.
+
        PR c++/70622
        * parser.c (cp_parser_init_declarator): Add auto_result parm.
        (cp_parser_simple_declaration): Pass it.
index 02a992fa518525410c80397acd1344c29712eb0d..e6d5bb0fe9c1f1d101d5b9686d33f09bb3a4ca18 100644 (file)
@@ -3346,7 +3346,6 @@ add_implicitly_declared_members (tree t, tree* access_decls,
       CLASSTYPE_LAZY_DEFAULT_CTOR (t) = 1;
       if (cxx_dialect >= cxx11)
        TYPE_HAS_CONSTEXPR_CTOR (t)
-         /* This might force the declaration.  */
          = type_has_constexpr_default_constructor (t);
     }
 
@@ -5349,8 +5348,11 @@ type_has_constexpr_default_constructor (tree t)
     {
       if (!TYPE_HAS_COMPLEX_DFLT (t))
        return trivial_default_constructor_is_constexpr (t);
-      /* Non-trivial, we need to check subobject constructors.  */
-      lazily_declare_fn (sfk_constructor, 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;
     }
   fns = locate_ctor (t);
   return (fns && DECL_DECLARED_CONSTEXPR_P (fns));
index 45e1ed27faee175c7ba9c42d2a8dd895483530c3..42ca30a38ce10b11720312db3e6175e2c6136b93 100644 (file)
@@ -3,6 +3,7 @@
 
 template <typename Tp>
 struct C {
+  C() = default;
   constexpr C(const Tp& r) { }
 };
 
index a67505d749bbdded0161ad16426ed5557232269a..8d352d0bb99d25cd8ad3cf4bb6dbb8bcff28b805 100644 (file)
@@ -7,6 +7,6 @@ struct A {
 struct B: A { };
 constexpr int f(B b) { return b.i; }
 
-struct C { C(); };            // { dg-message "calls non-constexpr" }
-struct D: C { };              // { dg-message "no constexpr constructor" }
+struct C { C(); };            // { dg-message "" }
+struct D: C { };              // { dg-message "" }
 constexpr int g(D d) { return 42; } // { dg-error "invalid type" }
index 30e0a643bcb135c4f33d4f8a501df4683ca28276..bf95b2443c79e83a6cc08dd1eb8fa9d9990051cf 100644 (file)
@@ -6,6 +6,6 @@ struct A
   A(int);
 };
 
-struct B : A {};                   // { dg-error "no matching" }
+struct B : A {};                   // { dg-message "" }
 
 constexpr int foo(B) { return 0; } // { dg-error "invalid type" }
index 7a22f8830ecdf46f0b9ba6eaf2ed0a2e83f0b152..7e2d58b422efc245652eb0b7c97ee52fb701d5da 100644 (file)
@@ -8,7 +8,7 @@ struct A
 
 struct B : A
 {
-  using A::A;   // { dg-error "inherited" }
+  using A::A;
 };
 
 constexpr B b;  // { dg-error "literal" }
diff --git a/gcc/testsuite/g++.dg/cpp0x/pr70528.C b/gcc/testsuite/g++.dg/cpp0x/pr70528.C
new file mode 100644 (file)
index 0000000..af1c84e
--- /dev/null
@@ -0,0 +1,16 @@
+// PR c++/70258
+// { dg-do compile { target c++11 } }
+
+template <class T>
+struct H
+{
+  template <typename A = T, typename = decltype (A())>
+  H ();
+};
+
+struct J {
+  struct K {
+    int First = 0;
+  };
+  H<K> FunctionMDInfo;
+};