aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorDodji Seketeli <dodji@redhat.com>2009-11-28 22:55:52 +0000
committerDodji Seketeli <dodji@gcc.gnu.org>2009-11-28 23:55:52 +0100
commit9af66ed16ec2971c40c5aa77f708d6e632cfb7f4 (patch)
tree51b5fc9ae82f2b8773076c0364709413c0897090 /gcc
parent288d6a77c3fc3d7f2dcc879f10c460f95236688a (diff)
downloadgcc-9af66ed16ec2971c40c5aa77f708d6e632cfb7f4.zip
gcc-9af66ed16ec2971c40c5aa77f708d6e632cfb7f4.tar.gz
gcc-9af66ed16ec2971c40c5aa77f708d6e632cfb7f4.tar.bz2
re PR c++/36408 (ICE with statement expression in template)
Fix PR c++/36408 gcc/cp/ChangeLog: PR c++/36408 * cp-tree.h (empty_expr_stmt_p): Declare ... * semantics.c (empty_expr_stmt_p): ... this. * pt.c (tsubst_copy_and_build) <STMT_EXPR>: Use it. gcc/testsuite/ChangeLog: PR c++/36408 * g++.dg/template/stmtexpr2.C: New test. From-SVN: r154731
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/pt.c5
-rw-r--r--gcc/cp/semantics.c26
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/template/stmtexpr2.C26
6 files changed, 70 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index e804913..4f58453 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2009-11-28 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/36408
+ * cp-tree.h (empty_expr_stmt_p): Declare ...
+ * semantics.c (empty_expr_stmt_p): ... this.
+ * pt.c (tsubst_copy_and_build) <STMT_EXPR>: Use it.
+
2009-11-27 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/38656
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index c6de2b4..2d8f409 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5074,6 +5074,7 @@ extern tree begin_stmt_expr (void);
extern tree finish_stmt_expr_expr (tree, tree);
extern tree finish_stmt_expr (tree, bool);
extern tree stmt_expr_value_expr (tree);
+bool empty_expr_stmt_p (tree);
extern tree perform_koenig_lookup (tree, VEC(tree,gc) *);
extern tree finish_call_expr (tree, VEC(tree,gc) **, bool,
bool, tsubst_flags_t);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index db3956b..eb1cdd3 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -12544,6 +12544,11 @@ tsubst_copy_and_build (tree t,
stmt_expr = finish_stmt_expr (stmt_expr, false);
cur_stmt_expr = old_stmt_expr;
+ /* If the resulting list of expression statement is empty,
+ fold it further into void_zero_node. */
+ if (empty_expr_stmt_p (cur_stmt_expr))
+ cur_stmt_expr = void_zero_node;
+
return stmt_expr;
}
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 34b5d57..5253df8 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -1847,6 +1847,32 @@ stmt_expr_value_expr (tree stmt_expr)
return t;
}
+/* Return TRUE iff EXPR_STMT is an empty list of
+ expression statements. */
+
+bool
+empty_expr_stmt_p (tree expr_stmt)
+{
+ tree body = NULL_TREE;
+
+ if (expr_stmt)
+ {
+ if (TREE_CODE (expr_stmt) == EXPR_STMT)
+ body = EXPR_STMT_EXPR (expr_stmt);
+ else if (TREE_CODE (expr_stmt) == STATEMENT_LIST)
+ body = expr_stmt;
+ }
+
+ if (body)
+ {
+ if (TREE_CODE (body) == STATEMENT_LIST)
+ return tsi_end_p (tsi_start (body));
+ else
+ return empty_expr_stmt_p (body);
+ }
+ return false;
+}
+
/* Perform Koenig lookup. FN is the postfix-expression representing
the function (or functions) to call; ARGS are the arguments to the
call. Returns the functions to be considered by overload
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 1c3e6f9..cad8b2b 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2009-11-28 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/36408
+ * g++.dg/template/stmtexpr2.C: New test.
+
2009-11-28 Richard Guenther <rguenther@suse.de>
PR tree-optimization/42183
diff --git a/gcc/testsuite/g++.dg/template/stmtexpr2.C b/gcc/testsuite/g++.dg/template/stmtexpr2.C
new file mode 100644
index 0000000..ef29b43
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/stmtexpr2.C
@@ -0,0 +1,26 @@
+// Contributed by Dodji Seketeli <dodji@redhat.com>
+// Origin: PR c++/36408
+// { dg-options "" }
+// { dg-do compile }
+
+template<int>
+void
+foo()
+{
+ int i = ({ }); // { dg-error "void value not ignored" }
+}
+
+template<int>
+void
+bar()
+{
+ int i = ({ ({}); }); // { dg-error "void value not ignored" }
+}
+
+int
+main ()
+{
+ foo<0> ();
+ bar<0> ();
+}
+