diff options
author | Jason Merrill <jason@redhat.com> | 2017-05-09 16:37:44 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2017-05-09 16:37:44 -0400 |
commit | 54069e595976eb556b22c231951cb2703e523a22 (patch) | |
tree | b327c9852bc468cfe651509559b443ca822580d2 /gcc | |
parent | 8ef2b9a7b59418d9f5e644badbc0aade7f83414f (diff) | |
download | gcc-54069e595976eb556b22c231951cb2703e523a22.zip gcc-54069e595976eb556b22c231951cb2703e523a22.tar.gz gcc-54069e595976eb556b22c231951cb2703e523a22.tar.bz2 |
PR c++/66297, DR 1684 - literal class and constexpr member fns
* constexpr.c (is_valid_constexpr_fn): Only complain about
non-literal enclosing class in C++11.
* class.c (finalize_literal_type_property): Likewise.
From-SVN: r247813
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/class.c | 15 | ||||
-rw-r--r-- | gcc/cp/constexpr.c | 15 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/constexpr-data1.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/constexpr-diag1.C | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/constexpr-diag3.C | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/constexpr-memfn1.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/constexpr-neg1.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1y/constexpr-dr1684.C | 7 |
9 files changed, 37 insertions, 21 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6b899d1..521b7d9 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2017-05-09 Jason Merrill <jason@redhat.com> + + PR c++/66297, DR 1684 - literal class and constexpr member fns + * constexpr.c (is_valid_constexpr_fn): Only complain about + non-literal enclosing class in C++11. + * class.c (finalize_literal_type_property): Likewise. + 2017-05-09 Paolo Carlini <paolo.carlini@oracle.com> PR c++/80186 diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 9b996e3..89fa822 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -5757,7 +5757,9 @@ finalize_literal_type_property (tree t) && !TYPE_HAS_CONSTEXPR_CTOR (t)) CLASSTYPE_LITERAL_P (t) = false; - if (!CLASSTYPE_LITERAL_P (t)) + /* C++14 DR 1684 removed this restriction. */ + if (cxx_dialect < cxx14 + && !CLASSTYPE_LITERAL_P (t) && !LAMBDA_TYPE_P (t)) for (fn = TYPE_METHODS (t); fn; fn = DECL_CHAIN (fn)) if (DECL_DECLARED_CONSTEXPR_P (fn) && TREE_CODE (fn) != TEMPLATE_DECL @@ -5765,12 +5767,11 @@ finalize_literal_type_property (tree t) && !DECL_CONSTRUCTOR_P (fn)) { DECL_DECLARED_CONSTEXPR_P (fn) = false; - if (!DECL_GENERATED_P (fn) && !LAMBDA_TYPE_P (t)) - { - error ("enclosing class of constexpr non-static member " - "function %q+#D is not a literal type", fn); - explain_non_literal_class (t); - } + if (!DECL_GENERATED_P (fn) + && pedwarn (DECL_SOURCE_LOCATION (fn), OPT_Wpedantic, + "enclosing class of constexpr non-static member " + "function %q+#D is not a literal type", fn)) + explain_non_literal_class (t); } } diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 34d25ba..157b20d 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -210,16 +210,17 @@ is_valid_constexpr_fn (tree fun, bool complain) } } - if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fun) + /* C++14 DR 1684 removed this restriction. */ + if (cxx_dialect < cxx14 + && DECL_NONSTATIC_MEMBER_FUNCTION_P (fun) && !CLASSTYPE_LITERAL_P (DECL_CONTEXT (fun))) { ret = false; - if (complain) - { - error ("enclosing class of constexpr non-static member " - "function %q+#D is not a literal type", fun); - explain_non_literal_class (DECL_CONTEXT (fun)); - } + if (complain + && pedwarn (DECL_SOURCE_LOCATION (fun), OPT_Wpedantic, + "enclosing class of constexpr non-static member " + "function %q+#D is not a literal type", fun)) + explain_non_literal_class (DECL_CONTEXT (fun)); } } else if (CLASSTYPE_VBASECLASSES (DECL_CONTEXT (fun))) diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-data1.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-data1.C index f49c56a..9078533 100644 --- a/gcc/testsuite/g++.dg/cpp0x/constexpr-data1.C +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-data1.C @@ -36,7 +36,7 @@ class debug_flag { public: explicit debug_flag(bool); - constexpr bool is_on(); // { dg-error "enclosing class .* not a literal type" } + constexpr bool is_on(); // { dg-error "enclosing class .* not a literal type" "" { target c++11_only } } private: bool flag; }; diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-diag1.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-diag1.C index 6b908b6..450a0b5 100644 --- a/gcc/testsuite/g++.dg/cpp0x/constexpr-diag1.C +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-diag1.C @@ -5,7 +5,7 @@ template <class T> struct A { T t; - constexpr int f() const { return 42; } // { dg-error "enclosing class" } + constexpr int f() const { return 42; } // { dg-error "enclosing class" "" { target c++11_only } } }; struct B { B(); operator int(); }; @@ -13,7 +13,7 @@ struct B { B(); operator int(); }; constexpr A<int> ai = { 42 }; constexpr int i = ai.f(); -constexpr int b = A<B>().f(); // { dg-error "non-constexpr function" } +constexpr int b = A<B>().f(); // { dg-error "" } template <class T> constexpr int f (T t) { return 42; } // { dg-error "parameter" } diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-diag3.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-diag3.C index 580fceb..27aad93 100644 --- a/gcc/testsuite/g++.dg/cpp0x/constexpr-diag3.C +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-diag3.C @@ -16,7 +16,7 @@ int main() struct complex // { dg-message "no constexpr constructor" } { complex(double r, double i) : re(r), im(i) { } - constexpr double real() const { return re; } // { dg-error "not a literal type" } + constexpr double real() const { return re; } // { dg-error "not a literal type" "" { target c++11_only } } double imag() const { return im; } private: @@ -25,7 +25,7 @@ private: }; constexpr complex co1(0, 1); // { dg-error "not literal" } -constexpr double dd2 = co1.real(); // { dg-error "non-constexpr function" } +constexpr double dd2 = co1.real(); // { dg-error "" } // -------------------- diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-memfn1.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-memfn1.C index 775c103..d59f465 100644 --- a/gcc/testsuite/g++.dg/cpp0x/constexpr-memfn1.C +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-memfn1.C @@ -13,6 +13,6 @@ constexpr X X::g(X x) { return x; } struct Y { Y() { } - constexpr Y f(Y y); // { dg-error "not a literal type" } + constexpr Y f(Y y) {} // { dg-error "constexpr" } static constexpr Y g(Y y) {} // { dg-error "constexpr" } }; diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-neg1.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-neg1.C index 58b5d32..9c832b1 100644 --- a/gcc/testsuite/g++.dg/cpp0x/constexpr-neg1.C +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-neg1.C @@ -45,7 +45,7 @@ constexpr int g(int x, int n) { class debug_flag { public: explicit debug_flag(bool); - constexpr bool is_on(); // { dg-error "not a literal type" } debug_flag not literal type + constexpr bool is_on(); // { dg-error "not a literal type" "" { target c++11_only } } debug_flag not literal type private: bool flag; }; diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-dr1684.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-dr1684.C new file mode 100644 index 0000000..04ffcfd --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-dr1684.C @@ -0,0 +1,7 @@ +// DR 1684 +// { dg-do compile { target c++11 } } + +struct A { + A(int); + constexpr int foo() { return 0; } // { dg-error "literal" "" { target c++11_only } } +}; |