From af18580616ce581d8d730b15b6e5cca76896f30b Mon Sep 17 00:00:00 2001 From: jason Date: Mon, 5 Sep 2011 04:33:40 +0000 Subject: [PATCH] * class.c (trivial_default_constructor_is_constexpr): Rename from synthesized_default_constructor_is_constexpr. (type_has_constexpr_default_constructor): Adjust. (add_implicitly_declared_members): Call it instead. (explain_non_literal_class): Explain about non-constexpr default ctor. * cp-tree.h: Adjust. * method.c (synthesized_method_walk): Adjust. * semantics.c (explain_invalid_constexpr_fn): Handle defaulted functions, too. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@178519 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 10 ++++++++ gcc/cp/class.c | 29 +++++++++++++++------- gcc/cp/cp-tree.h | 2 +- gcc/cp/method.c | 2 +- gcc/cp/semantics.c | 5 ++-- gcc/testsuite/ChangeLog | 2 ++ .../g++.dg/cpp0x/constexpr-default-ctor.C | 12 +++++++++ 7 files changed, 49 insertions(+), 13 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/constexpr-default-ctor.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index a83d19b..d61f5f7 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,15 @@ 2011-09-04 Jason Merrill + * class.c (trivial_default_constructor_is_constexpr): Rename from + synthesized_default_constructor_is_constexpr. + (type_has_constexpr_default_constructor): Adjust. + (add_implicitly_declared_members): Call it instead. + (explain_non_literal_class): Explain about non-constexpr default ctor. + * cp-tree.h: Adjust. + * method.c (synthesized_method_walk): Adjust. + * semantics.c (explain_invalid_constexpr_fn): Handle defaulted + functions, too. + PR c++/50248 Core 1358 * init.c (perform_member_init): Don't diagnose missing inits here. diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 2a4bc77..a4a7468 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -2726,7 +2726,8 @@ add_implicitly_declared_members (tree t, CLASSTYPE_LAZY_DEFAULT_CTOR (t) = 1; if (cxx_dialect >= cxx0x) TYPE_HAS_CONSTEXPR_CTOR (t) - = synthesized_default_constructor_is_constexpr (t); + /* This might force the declaration. */ + = type_has_constexpr_default_constructor (t); } /* [class.ctor] @@ -4355,15 +4356,15 @@ type_has_user_provided_default_constructor (tree t) return false; } -/* Returns true iff for class T, a synthesized default constructor +/* Returns true iff for class T, a trivial synthesized default constructor would be constexpr. */ bool -synthesized_default_constructor_is_constexpr (tree t) +trivial_default_constructor_is_constexpr (tree t) { - /* A defaulted default constructor is constexpr + /* A defaulted trivial default constructor is constexpr if there is nothing to initialize. */ - /* FIXME adjust for non-static data member initializers. */ + gcc_assert (!TYPE_HAS_COMPLEX_DFLT (t)); return is_really_empty_class (t); } @@ -4381,7 +4382,12 @@ type_has_constexpr_default_constructor (tree t) return false; } if (CLASSTYPE_LAZY_DEFAULT_CTOR (t)) - return synthesized_default_constructor_is_constexpr (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); + } fns = locate_ctor (t); return (fns && DECL_DECLARED_CONSTEXPR_P (fns)); } @@ -4608,9 +4614,14 @@ explain_non_literal_class (tree t) else if (CLASSTYPE_NON_AGGREGATE (t) && !TYPE_HAS_TRIVIAL_DFLT (t) && !TYPE_HAS_CONSTEXPR_CTOR (t)) - inform (0, " %q+T is not an aggregate, does not have a trivial " - "default constructor, and has no constexpr constructor that " - "is not a copy or move constructor", t); + { + inform (0, " %q+T is not an aggregate, does not have a trivial " + "default constructor, and has no constexpr constructor that " + "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)); + } else { tree binfo, base_binfo, field; int i; diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index d18599b..cf6c056 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4823,7 +4823,7 @@ extern tree in_class_defaulted_default_constructor (tree); extern bool user_provided_p (tree); extern bool type_has_user_provided_constructor (tree); extern bool type_has_user_provided_default_constructor (tree); -extern bool synthesized_default_constructor_is_constexpr (tree); +extern bool trivial_default_constructor_is_constexpr (tree); extern bool type_has_constexpr_default_constructor (tree); extern bool type_has_virtual_destructor (tree); extern bool type_has_move_constructor (tree); diff --git a/gcc/cp/method.c b/gcc/cp/method.c index 74a3bdb..5b24f8f 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -1187,7 +1187,7 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p, && (!copy_arg_p || cxx_dialect < cxx0x)) { if (constexpr_p && sfk == sfk_constructor) - *constexpr_p = synthesized_default_constructor_is_constexpr (ctype); + *constexpr_p = trivial_default_constructor_is_constexpr (ctype); return; } diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index fd96d70..bdc4cf2 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -5881,8 +5881,9 @@ explain_invalid_constexpr_fn (tree fun) static struct pointer_set_t *diagnosed; tree body; location_t save_loc; - /* Only diagnose instantiations of constexpr templates. */ - if (!is_instantiation_of_constexpr (fun)) + /* Only diagnose defaulted functions or instantiations. */ + if (!DECL_DEFAULTED_FN (fun) + && !is_instantiation_of_constexpr (fun)) return; if (diagnosed == NULL) diagnosed = pointer_set_create (); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 19441c4..2f149c4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,7 @@ 2011-09-04 Jason Merrill + * g++.dg/cpp0x/constexpr-default-ctor.C: New. + PR c++/50248 Core 1358 * g++.dg/cpp0x/constexpr-template1.C: New. diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-default-ctor.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-default-ctor.C new file mode 100644 index 0000000..d3868b5 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-default-ctor.C @@ -0,0 +1,12 @@ +// { dg-options -std=c++0x } + +struct A { + int i; + constexpr A():i(42) { }; +}; +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" } +constexpr int g(D d) { return 42; } // { dg-error "invalid type" } -- 2.7.4