re PR c++/53599 (gcc-4.7.1_rc20120606 segfaults compiling boost.karma)
authorJason Merrill <jason@redhat.com>
Tue, 12 Jun 2012 18:32:04 +0000 (14:32 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 12 Jun 2012 18:32:04 +0000 (14:32 -0400)
PR c++/53599
* name-lookup.c (pushtag_1): Add a DECL_EXPR for a local class.
* semantics.c (finish_cond): Build a COMPOUND_EXPR.
* pt.c (tsubst_expr) [COMPOUND_EXPR]: Handle.
[DECL_EXPR]: Don't call cp_finish_decl for an implicit typedef.
Don't return the decl.

From-SVN: r188473

gcc/cp/ChangeLog
gcc/cp/name-lookup.c
gcc/cp/pt.c
gcc/cp/semantics.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/local7.C [new file with mode: 0644]

index 29c721fb7bf799817a81930a4c51a176a746d311..203955e3bc7d8bce5d556551576fe04ec5c25c87 100644 (file)
@@ -1,3 +1,12 @@
+2012-06-09  Jason Merrill  <jason@redhat.com>
+
+       PR c++/53599
+       * name-lookup.c (pushtag_1): Add a DECL_EXPR for a local class.
+       * semantics.c (finish_cond): Build a COMPOUND_EXPR.
+       * pt.c (tsubst_expr) [COMPOUND_EXPR]: Handle.
+       [DECL_EXPR]: Don't call cp_finish_decl for an implicit typedef.
+       Don't return the decl.
+
 2012-06-11  Richard Guenther  <rguenther@suse.de>
 
        PR c++/53605
index 9cc6d39fffa1a99920b635cf9e10e1213f4f9933..0f2882044c7297433edef7643554ba3f72255246 100644 (file)
@@ -5796,7 +5796,16 @@ pushtag_1 (tree name, tree type, tag_scope scope)
         class.)  */
       if (TYPE_CONTEXT (type)
          && TREE_CODE (TYPE_CONTEXT (type)) == FUNCTION_DECL)
-       VEC_safe_push (tree, gc, local_classes, type);
+       {
+         if (processing_template_decl)
+           {
+             /* Push a DECL_EXPR so we call pushtag at the right time in
+                template instantiation rather than in some nested context.  */
+             add_decl_expr (decl);
+           }
+         else
+           VEC_safe_push (tree, gc, local_classes, type);
+       }
     }
   if (b->kind == sk_class
       && !COMPLETE_TYPE_P (current_class_type))
index df80159cf7594b3ee11b79c30ea10ae783205a25..04f7be81f3e7f23a3fb62ad01088b8355687f90b 100644 (file)
@@ -12887,6 +12887,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
                    DECL_CONTEXT (decl) = current_function_decl;
                    insert_capture_proxy (decl);
                  }
+               else if (DECL_IMPLICIT_TYPEDEF_P (t))
+                 /* We already did a pushtag.  */;
                else
                  {
                    int const_init = false;
@@ -12930,9 +12932,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
              }
          }
 
-       /* A DECL_EXPR can also be used as an expression, in the condition
-          clause of an if/for/while construct.  */
-       return decl;
+       break;
       }
 
     case FOR_STMT:
@@ -13341,6 +13341,15 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
       error ("use %<...%> to expand argument pack");
       return error_mark_node;
 
+    case COMPOUND_EXPR:
+      tmp = RECUR (TREE_OPERAND (t, 0));
+      if (tmp == NULL_TREE)
+       /* If the first operand was a statement, we're done with it.  */
+       return RECUR (TREE_OPERAND (t, 1));
+      return build_x_compound_expr (EXPR_LOCATION (t), tmp,
+                                   RECUR (TREE_OPERAND (t, 1)),
+                                   complain);
+
     default:
       gcc_assert (!STATEMENT_CODE_P (TREE_CODE (t)));
 
index 7769bbaa36fba4babb417379d6926637e4c9e225..f8ad2a5884a91a1cdbb56c039483e87484677930 100644 (file)
@@ -509,11 +509,14 @@ finish_cond (tree *cond_p, tree expr)
   if (processing_template_decl)
     {
       tree cond = pop_stmt_list (*cond_p);
-      if (TREE_CODE (cond) == DECL_EXPR)
-       expr = cond;
 
-      if (check_for_bare_parameter_packs (expr))
-        *cond_p = error_mark_node;
+      if (expr == NULL_TREE)
+       /* Empty condition in 'for'.  */
+       gcc_assert (empty_expr_stmt_p (cond));
+      else if (check_for_bare_parameter_packs (expr))
+        expr = error_mark_node;
+      else if (!empty_expr_stmt_p (cond))
+       expr = build2 (COMPOUND_EXPR, TREE_TYPE (expr), cond, expr);
     }
   *cond_p = expr;
 }
index 953ccb908141ae2ad55643faee7a9039c688c32d..908e25b07fc5510741d9bb6621b6ce8850efba6e 100644 (file)
@@ -1,3 +1,8 @@
+2012-06-07  Jason Merrill  <jason@redhat.com>
+
+       PR c++/53599
+       * g++.dg/template/local7.C: New.
+
 2012-06-12  Oleg Endo  <olegendo@gcc.gnu.org>
 
        PR target/53511
diff --git a/gcc/testsuite/g++.dg/template/local7.C b/gcc/testsuite/g++.dg/template/local7.C
new file mode 100644 (file)
index 0000000..3045534
--- /dev/null
@@ -0,0 +1,15 @@
+// PR c++/53599
+
+template <typename T>
+int foo ()
+{
+  struct F;
+  struct G
+  {
+    static int F::* bar();
+  };
+
+  return sizeof(G);
+}
+
+int z = foo <int> ();