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:
parent
3652a4d243
commit
4d612bfde8
5 changed files with 30 additions and 8 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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" }
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue