re PR c++/51327 ([c++0x] [4.7 Regression] ICE with invalid constexpr parameter)
authorPaolo Carlini <paolo@gcc.gnu.org>
Sun, 29 Jan 2012 21:41:54 +0000 (21:41 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Sun, 29 Jan 2012 21:41:54 +0000 (21:41 +0000)
/cp
2012-01-29  Paolo Carlini  <paolo.carlini@oracle.com>

PR c++/51327
* class.c (explain_non_literal_class): Correctly handle implicitly
deleted constructors.

/testsuite
2012-01-29  Paolo Carlini  <paolo.carlini@oracle.com>

PR c++/51327
* g++.dg/cpp0x/constexpr-ice6.C: New.

From-SVN: r183684

gcc/cp/class.c
gcc/testsuite/g++.dg/cpp0x/constexpr-ice6.C [new file with mode: 0644]

index 35e0864e2567fa91e804381594a4f547abe8d1a8..5d834d9ae5d4ee03a2f9d0e78ac449269c2898d7 100644 (file)
@@ -4910,7 +4910,27 @@ explain_non_literal_class (tree t)
              "is not a copy or move constructor", t);
       if (TYPE_HAS_DEFAULT_CONSTRUCTOR (t)
          && !type_has_user_provided_default_constructor (t))
-       explain_invalid_constexpr_fn (locate_ctor (t));
+       {
+         /* Note that we can't simply call locate_ctor because when the
+            constructor is deleted it just returns NULL_TREE.  */
+         tree fns;
+         for (fns = CLASSTYPE_CONSTRUCTORS (t); fns; fns = OVL_NEXT (fns))
+           {
+             tree fn = OVL_CURRENT (fns);
+             tree parms = TYPE_ARG_TYPES (TREE_TYPE (fn));
+
+             parms = skip_artificial_parms_for (fn, parms);
+
+             if (sufficient_parms_p (parms))
+               {
+                 if (DECL_DELETED_FN (fn))
+                   maybe_explain_implicit_delete (fn);
+                 else
+                   explain_invalid_constexpr_fn (fn);
+                 break;
+               }
+           }
+       }
     }
   else
     {
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-ice6.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-ice6.C
new file mode 100644 (file)
index 0000000..1a494bb
--- /dev/null
@@ -0,0 +1,11 @@
+// PR c++/51327
+// { dg-options -std=c++0x }
+
+struct A
+{
+  A(int);
+};
+
+struct B : A {};                   // { dg-error "no matching" }
+
+constexpr int foo(B) { return 0; } // { dg-error "invalid type" }