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
This commit is contained in:
Jason Merrill 2017-10-10 14:03:22 -04:00 committed by Jason Merrill
parent 3652a4d243
commit 4d612bfde8
5 changed files with 30 additions and 8 deletions

View file

@ -1,3 +1,10 @@
2017-10-10 Jason Merrill <jason@redhat.com>
* 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 <richard.sandiford@linaro.org>
* cvt.c (ignore_overflows): Use wi::to_wide when

View file

@ -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);
}

View file

@ -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__, "%<operator=%> 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);

View file

@ -4,7 +4,7 @@ struct X { };
int operator==(X, X) { return 0; }
template<typename T>
concept bool C1() { return X(); }
concept bool C1() { return X(); } // { dg-error "bool" }
template<C1 T>
void h(T) { } // OK until used.

View file

@ -6,11 +6,11 @@ public:
CVector<int> f() const
{
CVector<int> v();
return v;
return v; // { dg-error "convert" }
}
CVector<long> g() const
{
CVector<long> v();
return v;
return v; // { dg-error "convert" }
}
};