[PATCH] PR c++/36408

Dodji Seketeli dodji@redhat.com
Sun Nov 29 14:42:00 GMT 2009


On Sat, Nov 28, 2009 at 08:10:37PM -0800, H.J. Lu wrote:
> The new testcase compiles without any error messages and failed.

Argh. You are right. Sigh.
I tested a patch on a tree and posted/committed another one from another
tree. Sorry about that.

Please find below two attanchments. The first one is the patch that I
tested and wanted to submit initially. The second one is the same patch,
but diff-ed against the current svn. So the second patch is what I would
commit now if it is accepted.

I carefully tested *this* patch this time.

Sorry again for the messing up.

        Dodji
-------------- next part --------------
commit 1d8c3e24e677e796b964eab9ba3212cce288bbb1
Author: dodji <dodji@138bc75d-0d04-0410-961f-82ee72b054a4>
Date:   Sat Nov 28 22:55:52 2009 +0000

    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.
    

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..dd86cee 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 (stmt_expr))
+	  stmt_expr = void_zero_node;
+
 	return stmt_expr;
       }
 
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 34b5d57..6a43632 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -1847,6 +1847,35 @@ 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 == void_zero_node)
+    return true;
+
+  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/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> ();
+}
+
-------------- next part --------------
gcc/cp/ChangeLog:

	PR c++/36408
	* semantics.c (empty_expr_stmt_p): Handle void_zero_node and fix
	bad indentation.
	* pt.c (tsubst_copy_and_build): Fix typo.

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index eb1cdd3..dd86cee 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -12546,8 +12546,8 @@ tsubst_copy_and_build (tree t,
 
 	/* 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;
+	if (empty_expr_stmt_p (stmt_expr))
+	  stmt_expr = void_zero_node;
 
 	return stmt_expr;
       }
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 5253df8..6a43632 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -1855,6 +1855,9 @@ empty_expr_stmt_p (tree expr_stmt)
 {
   tree body = NULL_TREE;
 
+  if (expr_stmt == void_zero_node)
+    return true;
+
   if (expr_stmt)
     {
       if (TREE_CODE (expr_stmt) == EXPR_STMT)
@@ -1863,13 +1866,13 @@ empty_expr_stmt_p (tree expr_stmt)
 	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);
-      }
+  if (body)
+    {
+      if (TREE_CODE (body) == STATEMENT_LIST)
+	return tsi_end_p (tsi_start (body));
+      else
+	return empty_expr_stmt_p (body);
+    }
   return false;
 }


More information about the Gcc-patches mailing list