aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2017-10-10 14:03:22 -0400
committerJason Merrill <jason@gcc.gnu.org>2017-10-10 14:03:22 -0400
commit4d612bfde8ac11bf00c7e52969c0b727cd08f733 (patch)
treeaf5aa8f43021030eed870a1424ecc1f95d43b121 /gcc
parent3652a4d24398b66ac96f2e08e9f36a9b791be79a (diff)
downloadgcc-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/ChangeLog7
-rw-r--r--gcc/cp/constraint.cc7
-rw-r--r--gcc/cp/typeck.c18
-rw-r--r--gcc/testsuite/g++.dg/concepts/req6.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/crash3.C4
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" }
}
};