This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH for c++/42370 (bogus return warning with lambda)
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches List <gcc-patches at gcc dot gnu dot org>
- Date: Tue, 09 Feb 2010 15:00:00 -0500
- Subject: C++ PATCH for c++/42370 (bogus return warning with lambda)
We can't just change the return type of a FUNCTION_TYPE, as it might be
shared; we need to build a new one.
Tested x86_64-pc-linux-gnu, applied to trunk as it only touches C++0x code.
commit 85ac13e865d4d0ec6eeb6ffc23fbbcbeb252b74e
Author: Jason Merrill <jason@redhat.com>
Date: Tue Feb 9 13:53:40 2010 -0500
PR c++/42370
* decl2.c (change_return_type): New fn.
* semantics.c (apply_lambda_return_type): Use it.
* cp-tree.h: Declare it.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 2f925e1..27c820b 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -4732,6 +4732,7 @@ extern tree cxx_maybe_build_cleanup (tree);
/* in decl2.c */
extern bool check_java_method (tree);
extern tree build_memfn_type (tree, tree, cp_cv_quals);
+extern tree change_return_type (tree, tree);
extern void maybe_retrofit_in_chrg (tree);
extern void maybe_make_one_only (tree);
extern bool vague_linkage_fn_p (tree);
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 2b284fb..c5b6e87 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -139,6 +139,33 @@ build_memfn_type (tree fntype, tree ctype, cp_cv_quals quals)
return fntype;
}
+/* Return a variant of FNTYPE, a FUNCTION_TYPE or METHOD_TYPE, with its
+ return type changed to NEW_RET. */
+
+tree
+change_return_type (tree new_ret, tree fntype)
+{
+ tree newtype;
+ tree args = TYPE_ARG_TYPES (fntype);
+ tree raises = TYPE_RAISES_EXCEPTIONS (fntype);
+ tree attrs = TYPE_ATTRIBUTES (fntype);
+
+ if (same_type_p (new_ret, TREE_TYPE (fntype)))
+ return fntype;
+
+ if (TREE_CODE (fntype) == FUNCTION_TYPE)
+ newtype = build_function_type (new_ret, args);
+ else
+ newtype = build_method_type_directly (TYPE_METHOD_BASETYPE (fntype),
+ new_ret, TREE_CHAIN (args));
+ if (raises)
+ newtype = build_exception_variant (newtype, raises);
+ if (attrs)
+ newtype = cp_build_type_attribute_variant (newtype, attrs);
+
+ return newtype;
+}
+
/* Build a PARM_DECL with NAME and TYPE, and set DECL_ARG_TYPE
appropriately. */
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 441081c..39085be 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -5584,7 +5584,7 @@ apply_lambda_return_type (tree lambda, tree return_type)
/* TREE_TYPE (FUNCTION_DECL) == METHOD_TYPE
TREE_TYPE (METHOD_TYPE) == return-type */
- TREE_TYPE (TREE_TYPE (fco)) = return_type;
+ TREE_TYPE (fco) = change_return_type (return_type, TREE_TYPE (fco));
result = DECL_RESULT (fco);
if (result == NULL_TREE)
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-warn2.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-warn2.C
new file mode 100644
index 0000000..ce5e7c4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-warn2.C
@@ -0,0 +1,7 @@
+// PR c++/42370
+// { dg-options "-std=c++0x -Wall" }
+
+void foo()
+{
+ []{ return 0; }();
+} // { dg-bogus "no return statement" }