From bc61048a143b10d8efdc50195f2fc949d036ca92 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Sat, 11 Feb 2017 12:29:45 -0500 Subject: [PATCH] PR c++/77790 - ICE with auto function in C++11 mode * decl.c (undeduced_auto_decl): Remove C++14 limitation. (require_deduced_type): Add complain parm, return bool. * cp-tree.h: Adjust. * decl2.c (mark_used): Use require_deduced_type. From-SVN: r245358 --- gcc/cp/ChangeLog | 8 ++++++++ gcc/cp/cp-tree.h | 2 +- gcc/cp/decl.c | 15 ++++++++++----- gcc/cp/decl2.c | 17 +++++------------ gcc/testsuite/g++.dg/cpp0x/auto41.C | 2 +- gcc/testsuite/g++.dg/cpp1y/auto-fn35.C | 11 +++++++++++ 6 files changed, 36 insertions(+), 19 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp1y/auto-fn35.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 4523d128ccc..553db8a126b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2017-02-11 Jason Merrill + + PR c++/77790 - ICE with auto function in C++11 mode + * decl.c (undeduced_auto_decl): Remove C++14 limitation. + (require_deduced_type): Add complain parm, return bool. + * cp-tree.h: Adjust. + * decl2.c (mark_used): Use require_deduced_type. + 2017-02-10 Jason Merrill PR c++/78908 - template ops and bitfields diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index a4109261d48..0146332181c 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5909,7 +5909,7 @@ extern tree reshape_init (tree, tree, tsubst_flags_t); extern tree next_initializable_field (tree); extern tree fndecl_declared_return_type (tree); extern bool undeduced_auto_decl (tree); -extern void require_deduced_type (tree); +extern bool require_deduced_type (tree, tsubst_flags_t = tf_warning_or_error); extern tree finish_case_label (location_t, tree, tree); extern tree cxx_maybe_build_cleanup (tree, tsubst_flags_t); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 734a6c751d0..2292a3a2ac9 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -16138,24 +16138,29 @@ fndecl_declared_return_type (tree fn) return TREE_TYPE (TREE_TYPE (fn)); } -/* Returns true iff DECL was declared with an auto return type and it has +/* Returns true iff DECL was declared with an auto type and it has not yet been deduced to a real type. */ bool undeduced_auto_decl (tree decl) { - if (cxx_dialect < cxx14) + if (cxx_dialect < cxx11) return false; return type_uses_auto (TREE_TYPE (decl)); } /* Complain if DECL has an undeduced return type. */ -void -require_deduced_type (tree decl) +bool +require_deduced_type (tree decl, tsubst_flags_t complain) { if (undeduced_auto_decl (decl)) - error ("use of %qD before deduction of %", decl); + { + if (complain & tf_error) + error ("use of %qD before deduction of %", decl); + return false; + } + return true; } #include "gt-cp-decl.h" diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index cecb6a145b7..efc0b0e6974 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -5084,12 +5084,9 @@ mark_used (tree decl, tsubst_flags_t complain) || DECL_LANG_SPECIFIC (decl) == NULL || DECL_THUNK_P (decl)) { - if (!processing_template_decl && type_uses_auto (TREE_TYPE (decl))) - { - if (complain & tf_error) - error ("use of %qD before deduction of %", decl); - return false; - } + if (!processing_template_decl + && !require_deduced_type (decl, complain)) + return false; return true; } @@ -5117,12 +5114,8 @@ mark_used (tree decl, tsubst_flags_t complain) && uses_template_parms (DECL_TI_ARGS (decl))) return true; - if (undeduced_auto_decl (decl)) - { - if (complain & tf_error) - error ("use of %qD before deduction of %", decl); - return false; - } + if (!require_deduced_type (decl, complain)) + return false; /* If we don't need a value, then we don't need to synthesize DECL. */ if (cp_unevaluated_operand || in_discarded_stmt) diff --git a/gcc/testsuite/g++.dg/cpp0x/auto41.C b/gcc/testsuite/g++.dg/cpp0x/auto41.C index b1551e2e580..a1065af0741 100644 --- a/gcc/testsuite/g++.dg/cpp0x/auto41.C +++ b/gcc/testsuite/g++.dg/cpp0x/auto41.C @@ -2,4 +2,4 @@ // { dg-do compile { target c++11 } } auto foo(); // { dg-error "auto" "" { target { ! c++14 } } } -auto fp = foo; // { dg-error "auto" "" { target c++14 } } +auto fp = foo; // { dg-error "auto" } diff --git a/gcc/testsuite/g++.dg/cpp1y/auto-fn35.C b/gcc/testsuite/g++.dg/cpp1y/auto-fn35.C new file mode 100644 index 00000000000..a40817442d7 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/auto-fn35.C @@ -0,0 +1,11 @@ +// PR c++/77790 +// { dg-do compile { target c++11 } } + +template < typename S > struct A +{ + // { dg-error "" "" { target c++11_only } .+1 } + template < typename T > static auto f () { return 0; } + template < class U = decltype (f < S > ()) > int g () { return 0; } +}; + +auto a = A < int > {}.g ();