From e89ff446df48a43c632c316e64a5fbb1b95d227e Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 14 Jul 2014 01:25:37 -0400 Subject: [PATCH] re PR c++/58511 ([c++11] ICE using static const member variable in constexpr) PR c++/58511 * semantics.c (is_instantiation_of_constexpr): Return true for defaulted functions, too. (explain_invalid_constexpr_fn): Only use explain_implicit_non_constexpr if !DECL_DECLARED_CONSTEXPR_P. * method.c (explain_implicit_non_constexpr): Pass DECL_INHERITED_CTOR_BASE to explain_implicit_non_constexpr. From-SVN: r212507 --- gcc/cp/ChangeLog | 8 ++++++++ gcc/cp/method.c | 3 ++- gcc/cp/semantics.c | 11 +++++++---- gcc/testsuite/g++.dg/cpp0x/constexpr-inhctor1.C | 15 +++++++++++++++ gcc/testsuite/g++.dg/cpp0x/nsdmi3.C | 4 ++-- 5 files changed, 34 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/constexpr-inhctor1.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 2918318506c..3c35c104816 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,13 @@ 2014-07-13 Jason Merrill + PR c++/58511 + * semantics.c (is_instantiation_of_constexpr): Return true for + defaulted functions, too. + (explain_invalid_constexpr_fn): Only use + explain_implicit_non_constexpr if !DECL_DECLARED_CONSTEXPR_P. + * method.c (explain_implicit_non_constexpr): Pass + DECL_INHERITED_CTOR_BASE to explain_implicit_non_constexpr. + PR c++/58611 * decl.c (check_initializer): Don't finish_compound_literal on erroneous constexpr init. diff --git a/gcc/cp/method.c b/gcc/cp/method.c index 4d8aac1dfbb..1fa4be8d552 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -1575,7 +1575,8 @@ explain_implicit_non_constexpr (tree decl) synthesized_method_walk (DECL_CLASS_CONTEXT (decl), special_function_p (decl), const_p, NULL, NULL, NULL, &dummy, true, - NULL_TREE, NULL_TREE); + DECL_INHERITED_CTOR_BASE (decl), + FUNCTION_FIRST_USER_PARMTYPE (decl)); } /* DECL is an instantiation of an inheriting constructor template. Deduce diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index a6d941b5532..c87764d58d4 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -3949,13 +3949,16 @@ emit_associated_thunks (tree fn) } /* Returns true iff FUN is an instantiation of a constexpr function - template. */ + template or a defaulted constexpr function. */ static inline bool is_instantiation_of_constexpr (tree fun) { - return (DECL_TEMPLOID_INSTANTIATION (fun) - && DECL_DECLARED_CONSTEXPR_P (DECL_TI_TEMPLATE (fun))); + return ((DECL_TEMPLOID_INSTANTIATION (fun) + && DECL_DECLARED_CONSTEXPR_P (DECL_TI_TEMPLATE (fun))) + || (DECL_DEFAULTED_FN (fun) + && DECL_DECLARED_CONSTEXPR_P (fun))); + } /* Generate RTL for FN. */ @@ -8048,7 +8051,7 @@ explain_invalid_constexpr_fn (tree fun) if (is_valid_constexpr_fn (fun, true)) { /* Then if it's OK, the body. */ - if (DECL_DEFAULTED_FN (fun)) + if (!DECL_DECLARED_CONSTEXPR_P (fun)) explain_implicit_non_constexpr (fun); else { diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-inhctor1.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-inhctor1.C new file mode 100644 index 00000000000..ee8757f4dcf --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-inhctor1.C @@ -0,0 +1,15 @@ +// PR c++/58511 +// { dg-do compile { target c++11 } } + +struct A +{ + constexpr A(int, int = i) {} + static const int i; +}; + +struct B : A +{ + using A::A; // { dg-error "A::i" } +}; + +constexpr B b(0); // { dg-error "B::B" } diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi3.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi3.C index a8e8cdf2fef..6ac414b7437 100644 --- a/gcc/testsuite/g++.dg/cpp0x/nsdmi3.C +++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi3.C @@ -10,9 +10,9 @@ struct B { A a1 = 1; // { dg-error "" } A a2 { 2 }; - A a3 = { 3 }; // { dg-error "" } + A a3 = { 3 }; // { dg-error "explicit" } }; constexpr B b; // { dg-error "B::B" } -// { dg-message "a1. is invalid" "" { target *-*-* } 11 } +// { dg-prune-output "uninitialized member" }