From efff2fb40e390e81780d92abbc388454c0b5280e Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Sun, 29 Jan 2012 21:41:54 +0000 Subject: [PATCH] re PR c++/51327 ([c++0x] [4.7 Regression] ICE with invalid constexpr parameter) /cp 2012-01-29 Paolo Carlini PR c++/51327 * class.c (explain_non_literal_class): Correctly handle implicitly deleted constructors. /testsuite 2012-01-29 Paolo Carlini PR c++/51327 * g++.dg/cpp0x/constexpr-ice6.C: New. From-SVN: r183684 --- gcc/cp/class.c | 22 ++++++++++++++++++++- gcc/testsuite/g++.dg/cpp0x/constexpr-ice6.C | 11 +++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/constexpr-ice6.C diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 35e0864e256..5d834d9ae5d 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -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 index 00000000000..1a494bb3236 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-ice6.C @@ -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" }