diff options
author | Jason Merrill <jason@redhat.com> | 2017-10-10 14:03:22 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2017-10-10 14:03:22 -0400 |
commit | 4d612bfde8ac11bf00c7e52969c0b727cd08f733 (patch) | |
tree | af5aa8f43021030eed870a1424ecc1f95d43b121 /gcc | |
parent | 3652a4d24398b66ac96f2e08e9f36a9b791be79a (diff) | |
download | gcc-4d612bfde8ac11bf00c7e52969c0b727cd08f733.zip gcc-4d612bfde8ac11bf00c7e52969c0b727cd08f733.tar.gz gcc-4d612bfde8ac11bf00c7e52969c0b727cd08f733.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/constraint.cc | 7 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 18 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/concepts/req6.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.pt/crash3.C | 4 |
5 files changed, 30 insertions, 8 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 0d69bda..fe0315c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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 diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc index 64a8ea9..8b49455 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 c3310db..01647d0 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__, "%<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); diff --git a/gcc/testsuite/g++.dg/concepts/req6.C b/gcc/testsuite/g++.dg/concepts/req6.C index 670fd54..50fa3b4 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<typename T> - concept bool C1() { return X(); } + concept bool C1() { return X(); } // { dg-error "bool" } template<C1 T> 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 160cbe5..e5b3f25 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<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" } } }; |