re PR c++/29000 (ICE on invalid use of template in statement-expr)
authorJason Merrill <jason@redhat.com>
Tue, 28 Aug 2007 16:58:59 +0000 (12:58 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 28 Aug 2007 16:58:59 +0000 (12:58 -0400)
        PR c++/29000
        * pt.c (build_non_dependent_expr, type_dependent_expression_p):
        Look inside STMT_EXPR.
        * semantics.c (stmt_expr_value_expr): New fn.
        * cp-tree.h: Declare it.
        * g++.dg/ext/stmtexpr12.C: New test.

From-SVN: r127868

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/pt.c
gcc/cp/semantics.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ext/stmtexpr12.C [new file with mode: 0644]

index c6b2aaf82651c7e9c21d42005b599553baebfced..a56349b5402db23355b19c76fd1f3df08542bb1d 100644 (file)
 
 2007-08-27  Jason Merrill  <jason@redhat.com>
 
+       PR c++/29000
+       * pt.c (build_non_dependent_expr, type_dependent_expression_p): 
+       Look inside STMT_EXPR.
+       * semantics.c (stmt_expr_value_expr): New fn.
+       * cp-tree.h: Declare it.
+
        PR c++/28558
        * decl.c (groktypename): Ignore attributes applied to class type.
 
index d196ddca1e35ae7e892ee5ce5d69b86b1336a6e1..e07c0bd40b51704175888700a7e166e15e4a03c2 100644 (file)
@@ -4609,6 +4609,7 @@ extern tree finish_non_static_data_member       (tree, tree, tree);
 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);
 extern tree perform_koenig_lookup              (tree, tree);
 extern tree finish_call_expr                   (tree, tree, bool, bool);
 extern tree finish_increment_expr              (tree, enum tree_code);
index e33197c5c45dd33256b2959a22f16a194b36adb9..e1eda243c2d86b3fb87b5ba3263bb6e7319cd765 100644 (file)
@@ -15277,6 +15277,9 @@ type_dependent_expression_p (tree expression)
       && !DECL_TEMPLATE_TEMPLATE_PARM_P (expression))
     return false;
 
+  if (TREE_CODE (expression) == STMT_EXPR)
+    expression = stmt_expr_value_expr (expression);
+
   if (TREE_TYPE (expression) == unknown_type_node)
     {
       if (TREE_CODE (expression) == ADDR_EXPR)
@@ -15617,6 +15620,8 @@ build_non_dependent_expr (tree expr)
   /* Preserve OVERLOADs; the functions must be available to resolve
      types.  */
   inner_expr = expr;
+  if (TREE_CODE (inner_expr) == STMT_EXPR)
+    inner_expr = stmt_expr_value_expr (inner_expr);
   if (TREE_CODE (inner_expr) == ADDR_EXPR)
     inner_expr = TREE_OPERAND (inner_expr, 0);
   if (TREE_CODE (inner_expr) == COMPONENT_REF)
index 583ce33a23bad364dd45330479a1535dce78dac1..9faa413b3761c6c6bad576c6c08c7e52e63ab901 100644 (file)
@@ -1754,6 +1754,25 @@ finish_stmt_expr (tree stmt_expr, bool has_no_scope)
   return result;
 }
 
+/* Returns the expression which provides the value of STMT_EXPR.  */
+
+tree
+stmt_expr_value_expr (tree stmt_expr)
+{
+  tree t = STMT_EXPR_STMT (stmt_expr);
+
+  if (TREE_CODE (t) == BIND_EXPR)
+    t = BIND_EXPR_BODY (t);
+
+  if (TREE_CODE (t) == STATEMENT_LIST)
+    t = STATEMENT_LIST_TAIL (t)->stmt;
+
+  if (TREE_CODE (t) == EXPR_STMT)
+    t = EXPR_STMT_EXPR (t);
+
+  return t;
+}
+
 /* 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
index 6254d202c4941c46f5c37f9bfd0b805ffe04618e..64225d1d71ccd3a8ae1134ea27850a867487e965 100644 (file)
@@ -20,6 +20,9 @@
 
 2007-08-28  Jason Merrill  <jason@redhat.com>
 
+       PR c++/29000
+       * g++.dg/ext/stmtexpr12.C: New test.
+
        PR c++/28558
        * g++.dg/ext/attrib28.C: New test.
 
diff --git a/gcc/testsuite/g++.dg/ext/stmtexpr12.C b/gcc/testsuite/g++.dg/ext/stmtexpr12.C
new file mode 100644 (file)
index 0000000..c35f41b
--- /dev/null
@@ -0,0 +1,7 @@
+// PR c++/29000
+// { dg-options "" }
+
+template<int> int foo()
+{
+  return ({foo;})==0;          // { dg-error "insufficient context" }
+}