* 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 <ja...@redhat.com> + + * decl2.c (decl_dependent_p): New. + (mark_used): Check it instead of just processing_template_decl. + 2019-08-22 Jason Merrill <ja...@redhat.com> * parser.c (cp_parser_nested_name_specifier_opt): Avoid redundant -- 2.21.0