2009-07-22 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 22 Jul 2009 08:43:19 +0000 (08:43 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 22 Jul 2009 08:43:19 +0000 (08:43 +0000)
PR c++/40799
* cp-gimplify.c (cp_gimplify_expr): Move handling of using
related exprs to ...
(cp_genericize_r): ... genericization stage.
(cp_genericize): Adjust.

* g++.dg/lookup/using21.C: New testcase.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@149919 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/cp-gimplify.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/lookup/using21.C [new file with mode: 0644]

index 24ffd8b..c86770e 100644 (file)
@@ -1,3 +1,11 @@
+2009-07-22  Richard Guenther  <rguenther@suse.de>
+
+       PR c++/40799
+       * cp-gimplify.c (cp_gimplify_expr): Move handling of using
+       related exprs to ...
+       (cp_genericize_r): ... genericization stage.
+       (cp_genericize): Adjust.
+
 2009-07-21  Jason Merrill  <jason@redhat.com>
 
        Core issue 934
index 4cf78df..184ae9e 100644 (file)
@@ -503,8 +503,6 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
   int saved_stmts_are_full_exprs_p = 0;
   enum tree_code code = TREE_CODE (*expr_p);
   enum gimplify_status ret;
-  tree block = NULL;
-  VEC(gimple, heap) *bind_expr_stack = NULL;
 
   if (STATEMENT_CODE_P (code))
     {
@@ -571,37 +569,7 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
       break;
 
     case USING_STMT:
-      /* Get the innermost inclosing GIMPLE_BIND that has a non NULL
-         BLOCK, and append an IMPORTED_DECL to its
-        BLOCK_VARS chained list.  */
-
-      bind_expr_stack = gimple_bind_expr_stack ();
-      if (bind_expr_stack)
-       {
-         int i;
-         for (i = VEC_length (gimple, bind_expr_stack) - 1; i >= 0; i--)
-           if ((block = gimple_bind_block (VEC_index (gimple,
-                                                      bind_expr_stack,
-                                                      i))))
-             break;
-       }
-      if (block)
-       {
-         tree using_directive;
-         gcc_assert (TREE_OPERAND (*expr_p, 0));
-
-         using_directive = make_node (IMPORTED_DECL);
-         TREE_TYPE (using_directive) = void_type_node;
-
-         IMPORTED_DECL_ASSOCIATED_DECL (using_directive)
-           = TREE_OPERAND (*expr_p, 0);
-         TREE_CHAIN (using_directive) = BLOCK_VARS (block);
-         BLOCK_VARS (block) = using_directive;
-       }
-      /* The USING_STMT won't appear in GIMPLE.  */
-      *expr_p = NULL;
-      ret = GS_ALL_DONE;
-      break;
+      gcc_unreachable ();
 
     case FOR_STMT:
       gimplify_for_stmt (expr_p, pre_p);
@@ -693,6 +661,12 @@ cxx_int_tree_map_hash (const void *item)
   return ((const struct cxx_int_tree_map *)item)->uid;
 }
 
+struct cp_genericize_data
+{
+  struct pointer_set_t *p_set;
+  VEC (tree, heap) *bind_expr_stack;
+};
+
 /* Perform any pre-gimplification lowering of C++ front end trees to
    GENERIC.  */
 
@@ -700,7 +674,8 @@ static tree
 cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
 {
   tree stmt = *stmt_p;
-  struct pointer_set_t *p_set = (struct pointer_set_t*) data;
+  struct cp_genericize_data *wtd = (struct cp_genericize_data *) data;
+  struct pointer_set_t *p_set = wtd->p_set;
 
   if (is_invisiref_parm (stmt)
       /* Don't dereference parms in a thunk, pass the references through. */
@@ -759,7 +734,7 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
            *walk_subtrees = 0;
            if (OMP_CLAUSE_LASTPRIVATE_STMT (stmt))
              cp_walk_tree (&OMP_CLAUSE_LASTPRIVATE_STMT (stmt),
-                           cp_genericize_r, p_set, NULL);
+                           cp_genericize_r, data, NULL);
          }
        break;
       case OMP_CLAUSE_PRIVATE:
@@ -829,6 +804,56 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
        }
     }
 
+  else if (TREE_CODE (stmt) == BIND_EXPR)
+    {
+      VEC_safe_push (tree, heap, wtd->bind_expr_stack, stmt);
+      cp_walk_tree (&BIND_EXPR_BODY (stmt),
+                   cp_genericize_r, data, NULL);
+      VEC_pop (tree, wtd->bind_expr_stack);
+      *walk_subtrees = 0;
+    }
+
+  else if (TREE_CODE (stmt) == USING_STMT)
+    {
+      tree block = NULL_TREE;
+
+      /* Get the innermost inclosing GIMPLE_BIND that has a non NULL
+         BLOCK, and append an IMPORTED_DECL to its
+        BLOCK_VARS chained list.  */
+      if (wtd->bind_expr_stack)
+       {
+         int i;
+         for (i = VEC_length (tree, wtd->bind_expr_stack) - 1; i >= 0; i--)
+           if ((block = BIND_EXPR_BLOCK (VEC_index (tree,
+                                                    wtd->bind_expr_stack, i))))
+             break;
+       }
+      if (block)
+       {
+         tree using_directive;
+         gcc_assert (TREE_OPERAND (stmt, 0));
+
+         using_directive = make_node (IMPORTED_DECL);
+         TREE_TYPE (using_directive) = void_type_node;
+
+         IMPORTED_DECL_ASSOCIATED_DECL (using_directive)
+           = TREE_OPERAND (stmt, 0);
+         TREE_CHAIN (using_directive) = BLOCK_VARS (block);
+         BLOCK_VARS (block) = using_directive;
+       }
+      /* The USING_STMT won't appear in GENERIC.  */
+      *stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node);
+      *walk_subtrees = 0;
+    }
+
+  else if (TREE_CODE (stmt) == DECL_EXPR
+          && TREE_CODE (DECL_EXPR_DECL (stmt)) == USING_DECL)
+    {
+      /* Using decls inside DECL_EXPRs are just dropped on the floor.  */
+      *stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node);
+      *walk_subtrees = 0;
+    }
+
   pointer_set_insert (p_set, *stmt_p);
 
   return NULL;
@@ -838,7 +863,7 @@ void
 cp_genericize (tree fndecl)
 {
   tree t;
-  struct pointer_set_t *p_set;
+  struct cp_genericize_data wtd;
 
   /* Fix up the types of parms passed by invisible reference.  */
   for (t = DECL_ARGUMENTS (fndecl); t; t = TREE_CHAIN (t))
@@ -872,9 +897,11 @@ cp_genericize (tree fndecl)
 
   /* We do want to see every occurrence of the parms, so we can't just use
      walk_tree's hash functionality.  */
-  p_set = pointer_set_create ();
-  cp_walk_tree (&DECL_SAVED_TREE (fndecl), cp_genericize_r, p_set, NULL);
-  pointer_set_destroy (p_set);
+  wtd.p_set = pointer_set_create ();
+  wtd.bind_expr_stack = NULL;
+  cp_walk_tree (&DECL_SAVED_TREE (fndecl), cp_genericize_r, &wtd, NULL);
+  pointer_set_destroy (wtd.p_set);
+  VEC_free (tree, heap, wtd.bind_expr_stack);
 
   /* Do everything else.  */
   c_genericize (fndecl);
index 234c028..4f4e247 100644 (file)
@@ -1,3 +1,8 @@
+2009-07-22  Richard Guenther  <rguenther@suse.de>
+
+       PR c++/40799
+       * g++.dg/lookup/using21.C: New testcase.
+
 2009-07-21  Jason Merrill  <jason@redhat.com>
 
        * g++.dg/init/aggr4.C: New.
diff --git a/gcc/testsuite/g++.dg/lookup/using21.C b/gcc/testsuite/g++.dg/lookup/using21.C
new file mode 100644 (file)
index 0000000..30f18c5
--- /dev/null
@@ -0,0 +1,26 @@
+// PR c++/40799
+
+namespace Bar {
+  typedef int A;
+}
+class CollectionDeleteGuard {
+public:
+  CollectionDeleteGuard(int);
+};
+CollectionDeleteGuard::CollectionDeleteGuard(int)
+{
+  using Bar::A;
+}
+// PR c++/40799
+
+namespace Bar {
+  typedef int A;
+};
+class CollectionDeleteGuard {
+public:
+  CollectionDeleteGuard(int);
+};
+CollectionDeleteGuard::CollectionDeleteGuard(int)
+{
+  using Bar::A;
+}