From: Jason Merrill Date: Tue, 10 Oct 2017 18:03:22 +0000 (-0400) Subject: Check non-dependent conversion in return from template fn. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=4d612bfde8ac11bf00c7e52969c0b727cd08f733;p=gcc.git Check non-dependent conversion in return from template fn. * typeck.c (check_return_expr): Check non-dependent conversion in templates. * constraint.cc (check_function_concept): Don't complain about an empty concept if seen_error. From-SVN: r253599 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 0d69bda285d..fe0315c88e0 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2017-10-10 Jason Merrill + + * typeck.c (check_return_expr): Check non-dependent conversion in + templates. + * constraint.cc (check_function_concept): Don't complain about an + empty concept if seen_error. + 2017-10-10 Richard Sandiford * cvt.c (ignore_overflows): Use wi::to_wide when diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc index 64a8ea926d2..8b49455a526 100644 --- a/gcc/cp/constraint.cc +++ b/gcc/cp/constraint.cc @@ -2504,7 +2504,12 @@ check_function_concept (tree fn) { location_t loc = DECL_SOURCE_LOCATION (fn); if (TREE_CODE (body) == STATEMENT_LIST && !STATEMENT_LIST_HEAD (body)) - error_at (loc, "definition of concept %qD is empty", fn); + { + if (seen_error ()) + /* The definition was probably erroneous, not empty. */; + else + error_at (loc, "definition of concept %qD is empty", fn); + } else error_at (loc, "definition of concept %qD has multiple statements", fn); } diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index c3310db7b3b..01647d04bc8 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -8957,10 +8957,14 @@ check_return_expr (tree retval, bool *no_warning) if (check_for_bare_parameter_packs (retval)) return error_mark_node; - if (WILDCARD_TYPE_P (TREE_TYPE (DECL_RESULT (current_function_decl))) + /* If one of the types might be void, we can't tell whether we're + returning a value. */ + if ((WILDCARD_TYPE_P (TREE_TYPE (DECL_RESULT (current_function_decl))) + && !current_function_auto_return_pattern) || (retval != NULL_TREE - && type_dependent_expression_p (retval))) - return retval; + && (TREE_TYPE (retval) == NULL_TREE + || WILDCARD_TYPE_P (TREE_TYPE (retval))))) + goto dependent; } functype = TREE_TYPE (TREE_TYPE (current_function_decl)); @@ -9098,8 +9102,10 @@ check_return_expr (tree retval, bool *no_warning) warning (OPT_Weffc__, "% should return a reference to %<*this%>"); } - if (processing_template_decl) + if (dependent_type_p (functype) + || type_dependent_expression_p (retval)) { + dependent: /* We should not have changed the return value. */ gcc_assert (retval == saved_retval); return retval; @@ -9126,6 +9132,7 @@ check_return_expr (tree retval, bool *no_warning) named_return_value_okay_p = (retval != NULL_TREE + && !processing_template_decl /* Must be a local, automatic variable. */ && VAR_P (retval) && DECL_CONTEXT (retval) == current_function_decl @@ -9222,6 +9229,9 @@ check_return_expr (tree retval, bool *no_warning) build_zero_cst (TREE_TYPE (retval))); } + if (processing_template_decl) + return saved_retval; + /* Actually copy the value returned into the appropriate location. */ if (retval && retval != result) retval = build2 (INIT_EXPR, TREE_TYPE (result), result, retval); diff --git a/gcc/testsuite/g++.dg/concepts/req6.C b/gcc/testsuite/g++.dg/concepts/req6.C index 670fd542f6f..50fa3b4dadd 100644 --- a/gcc/testsuite/g++.dg/concepts/req6.C +++ b/gcc/testsuite/g++.dg/concepts/req6.C @@ -4,7 +4,7 @@ struct X { }; int operator==(X, X) { return 0; } template - concept bool C1() { return X(); } + concept bool C1() { return X(); } // { dg-error "bool" } template void h(T) { } // OK until used. diff --git a/gcc/testsuite/g++.old-deja/g++.pt/crash3.C b/gcc/testsuite/g++.old-deja/g++.pt/crash3.C index 160cbe541a1..e5b3f25b530 100644 --- a/gcc/testsuite/g++.old-deja/g++.pt/crash3.C +++ b/gcc/testsuite/g++.old-deja/g++.pt/crash3.C @@ -6,11 +6,11 @@ public: CVector f() const { CVector v(); - return v; + return v; // { dg-error "convert" } } CVector g() const { CVector v(); - return v; + return v; // { dg-error "convert" } } };