Message ID | 20190823231833.30678-2-jason@redhat.com |
---|---|
State | New |
Headers | show |
Series | [C++,1/2] * parser.c (cp_parser_nested_name_specifier_opt): Avoid redundant error. | expand |
On Fri, Aug 23, 2019 at 4:18 PM Jason Merrill <jason@redhat.com> wrote: Apparently git send-email only spawns the editor once, so I need to edit both messages before exiting... This testcase comes from committee reflector discussion: 'fn' can't be dependent because it is not in the scope of any template parameters. Tested x86_64-pc-linux-gnu, applying to trunk. > * decl2.c (decl_dependent_p): New. > (mark_used): Check it instead of just processing_template_decl. > --- > gcc/cp/decl2.c | 24 ++++++++++++++++++++- > gcc/testsuite/g++.dg/cpp1z/constexpr-if30.C | 10 +++++++++ > gcc/cp/ChangeLog | 5 +++++ > 3 files changed, 38 insertions(+), 1 deletion(-) > create mode 100644 gcc/testsuite/g++.dg/cpp1z/constexpr-if30.C > > diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c > index a32108f9d16..134f6d6e3df 100644 > --- a/gcc/cp/decl2.c > +++ b/gcc/cp/decl2.c > @@ -5407,6 +5407,25 @@ cp_warn_deprecated_use (tree decl, tsubst_flags_t complain) > return warned; > } > > +/* True if DECL or its enclosing scope have unbound template parameters. */ > + > +bool > +decl_dependent_p (tree decl) > +{ > + if (DECL_FUNCTION_SCOPE_P (decl) > + || TREE_CODE (decl) == CONST_DECL > + || TREE_CODE (decl) == USING_DECL > + || TREE_CODE (decl) == FIELD_DECL) > + decl = CP_DECL_CONTEXT (decl); > + if (tree tinfo = get_template_info (decl)) > + if (any_dependent_template_arguments_p (TI_ARGS (tinfo))) > + return true; > + if (LAMBDA_FUNCTION_P (decl) > + && dependent_type_p (DECL_CONTEXT (decl))) > + return true; > + return false; > +} > + > /* Mark DECL (either a _DECL or a BASELINK) as "used" in the program. > If DECL is a specialization or implicitly declared class member, > generate the actual definition. Return false if something goes > @@ -5433,6 +5452,9 @@ mark_used (tree decl, tsubst_flags_t complain) > decl = OVL_FIRST (decl); > } > > + if (!DECL_P (decl)) > + return true; > + > /* Set TREE_USED for the benefit of -Wunused. */ > TREE_USED (decl) = 1; > /* And for structured bindings also the underlying decl. */ > @@ -5480,7 +5502,7 @@ mark_used (tree decl, tsubst_flags_t complain) > || DECL_LANG_SPECIFIC (decl) == NULL > || DECL_THUNK_P (decl)) > { > - if (!processing_template_decl > + if (!decl_dependent_p (decl) > && !require_deduced_type (decl, complain)) > return false; > return true; > diff --git a/gcc/testsuite/g++.dg/cpp1z/constexpr-if30.C b/gcc/testsuite/g++.dg/cpp1z/constexpr-if30.C > new file mode 100644 > index 00000000000..1e3d15dca1c > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp1z/constexpr-if30.C > @@ -0,0 +1,10 @@ > +// { dg-do compile { target c++17 } } > + > +auto fn = [](auto i) { > + if constexpr (sizeof(i) == 1) > + return fn(123); // { dg-error "auto" } > +}; > + > +int main() { > + fn('!'); > +} > diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog > index d07c0de82dd..e6c83b5338e 100644 > --- a/gcc/cp/ChangeLog > +++ b/gcc/cp/ChangeLog > @@ -1,3 +1,8 @@ > +2019-08-22 Jason Merrill <jason@redhat.com> > + > + * decl2.c (decl_dependent_p): New. > + (mark_used): Check it instead of just processing_template_decl. > + > 2019-08-22 Jason Merrill <jason@redhat.com> > > * parser.c (cp_parser_nested_name_specifier_opt): Avoid redundant > -- > 2.21.0 >
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index a32108f9d16..134f6d6e3df 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -5407,6 +5407,25 @@ cp_warn_deprecated_use (tree decl, tsubst_flags_t complain) return warned; } +/* True if DECL or its enclosing scope have unbound template parameters. */ + +bool +decl_dependent_p (tree decl) +{ + if (DECL_FUNCTION_SCOPE_P (decl) + || TREE_CODE (decl) == CONST_DECL + || TREE_CODE (decl) == USING_DECL + || TREE_CODE (decl) == FIELD_DECL) + decl = CP_DECL_CONTEXT (decl); + if (tree tinfo = get_template_info (decl)) + if (any_dependent_template_arguments_p (TI_ARGS (tinfo))) + return true; + if (LAMBDA_FUNCTION_P (decl) + && dependent_type_p (DECL_CONTEXT (decl))) + return true; + return false; +} + /* Mark DECL (either a _DECL or a BASELINK) as "used" in the program. If DECL is a specialization or implicitly declared class member, generate the actual definition. Return false if something goes @@ -5433,6 +5452,9 @@ mark_used (tree decl, tsubst_flags_t complain) decl = OVL_FIRST (decl); } + if (!DECL_P (decl)) + return true; + /* Set TREE_USED for the benefit of -Wunused. */ TREE_USED (decl) = 1; /* And for structured bindings also the underlying decl. */ @@ -5480,7 +5502,7 @@ mark_used (tree decl, tsubst_flags_t complain) || DECL_LANG_SPECIFIC (decl) == NULL || DECL_THUNK_P (decl)) { - if (!processing_template_decl + if (!decl_dependent_p (decl) && !require_deduced_type (decl, complain)) return false; return true; diff --git a/gcc/testsuite/g++.dg/cpp1z/constexpr-if30.C b/gcc/testsuite/g++.dg/cpp1z/constexpr-if30.C new file mode 100644 index 00000000000..1e3d15dca1c --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/constexpr-if30.C @@ -0,0 +1,10 @@ +// { dg-do compile { target c++17 } } + +auto fn = [](auto i) { + if constexpr (sizeof(i) == 1) + return fn(123); // { dg-error "auto" } +}; + +int main() { + fn('!'); +} diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d07c0de82dd..e6c83b5338e 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2019-08-22 Jason Merrill <jason@redhat.com> + + * decl2.c (decl_dependent_p): New. + (mark_used): Check it instead of just processing_template_decl. + 2019-08-22 Jason Merrill <jason@redhat.com> * parser.c (cp_parser_nested_name_specifier_opt): Avoid redundant