re PR c++/18093 (bogus conflict in namespace aliasing)
authorMark Mitchell <mark@codesourcery.com>
Wed, 27 Oct 2004 02:23:16 +0000 (02:23 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Wed, 27 Oct 2004 02:23:16 +0000 (02:23 +0000)
PR c++/18093
* search.c (current_scope): Return the innermost non-block scope,
not the innermost non-block, non-namespace scope.
(at_namespace_scope_p): Adjust accordingly.
(dfs_accessible_post): Do not pass namespaces to is_friend.
(dfs_walk_once_accessible_r): Likewise.
* decl.c (grokvardecl): Adjust call to current_scope.
(build_enumerator): Likewise.
* parser.c (cp_parser_using_declaration): Likewise.
(cp_parser_direct_declarator): Use at_namespace_scope_p instead of
current_scope.
(cp_parser_class_head): Adjust call to current_scope.
* name-lookup.c (do_namespace_alias): Set the DECL_CONTEXT for the
alias.

PR c++/18020
* pt.c (tusbst_copy_and_build): Resolve enumeration constants to
their underlying values.

PR c++/18161
* typeck.c (build_binary_op): Honor build_type, even when in a
template.

PR c++/18093
* g++.dg/lookup/ns2.C: New test.

PR c++/18020
* g++.dg/template/enum4.C: New test.

PR c++/18161
* g++.dg/template/expr1.C: New test.

From-SVN: r89627

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/cp/name-lookup.c
gcc/cp/parser.c
gcc/cp/pt.c
gcc/cp/search.c
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/lookup/ns2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/enum4.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/expr1.C [new file with mode: 0644]

index 39f6e41..d9e8ce7 100644 (file)
@@ -1,3 +1,28 @@
+2004-10-26  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/18093
+       * search.c (current_scope): Return the innermost non-block scope,
+       not the innermost non-block, non-namespace scope.
+       (at_namespace_scope_p): Adjust accordingly.
+       (dfs_accessible_post): Do not pass namespaces to is_friend.
+       (dfs_walk_once_accessible_r): Likewise.
+       * decl.c (grokvardecl): Adjust call to current_scope.
+       (build_enumerator): Likewise.
+       * parser.c (cp_parser_using_declaration): Likewise.
+       (cp_parser_direct_declarator): Use at_namespace_scope_p instead of
+       current_scope.
+       (cp_parser_class_head): Adjust call to current_scope.
+       * name-lookup.c (do_namespace_alias): Set the DECL_CONTEXT for the
+       alias.
+
+       PR c++/18020
+       * pt.c (tusbst_copy_and_build): Resolve enumeration constants to
+       their underlying values.
+
+       PR c++/18161
+       * typeck.c (build_binary_op): Honor build_type, even when in a
+       template.
+
 2004-10-26  Nathan Sidwell  <nathan@codesourcery.com>
 
        * parser.c (cp_lexer_get_preprocessor_token): Remove unneeded
index 2aca629..9d9f70b 100644 (file)
@@ -5918,11 +5918,7 @@ grokvardecl (tree type,
       if (declspecs->storage_class == sc_extern)
        scope = current_namespace;
       else if (!at_function_scope_p ())
-       {
-         scope = current_scope ();
-         if (!scope)
-           scope = current_namespace;
-       }
+       scope = current_scope ();
     }
 
   if (scope
@@ -9746,8 +9742,6 @@ build_enumerator (tree name, tree value, tree enumtype)
 
   /* C++ associates enums with global, function, or class declarations.  */
   context = current_scope ();
-  if (!context)
-    context = current_namespace;
 
   /* Build the actual enumeration constant.  Note that the enumeration
     constants have the type of their initializers until the
index 6634f87..423a4b9 100644 (file)
@@ -3227,6 +3227,7 @@ do_namespace_alias (tree alias, tree namespace)
   alias = build_lang_decl (NAMESPACE_DECL, alias, void_type_node);     
   DECL_NAMESPACE_ALIAS (alias) = namespace;
   DECL_EXTERNAL (alias) = 1;
+  DECL_CONTEXT (alias) = current_scope ();
   pushdecl (alias);
 
   /* Emit debug info for namespace alias.  */
index fe3b3c6..b6e5432 100644 (file)
@@ -10047,7 +10047,6 @@ cp_parser_using_declaration (cp_parser* parser)
   bool global_scope_p;
   tree decl;
   tree identifier;
-  tree scope;
   tree qscope;
 
   /* Look for the `using' keyword.  */
@@ -10106,8 +10105,7 @@ cp_parser_using_declaration (cp_parser* parser)
     error ("a template-id may not appear in a using-declaration");
   else
     {
-      scope = current_scope ();
-      if (scope && TYPE_P (scope))
+      if (at_class_scope_p ())
        {
          /* Create the USING_DECL.  */
          decl = do_class_using_decl (build_nt (SCOPE_REF,
@@ -10121,7 +10119,7 @@ cp_parser_using_declaration (cp_parser* parser)
          decl = cp_parser_lookup_name_simple (parser, identifier);
          if (decl == error_mark_node)
            cp_parser_name_lookup_error (parser, identifier, decl, NULL);
-         else if (scope)
+         else if (!at_namespace_scope_p ())
            do_local_using_decl (decl, qscope, identifier);
          else
            do_toplevel_using_decl (decl, qscope, identifier);
@@ -10982,7 +10980,7 @@ cp_parser_direct_declarator (cp_parser* parser,
              break;
            }
 
-         if (TREE_CODE (id) == SCOPE_REF && !current_scope ())
+         if (TREE_CODE (id) == SCOPE_REF && at_namespace_scope_p ())
            {
              tree scope = TREE_OPERAND (id, 0);
 
@@ -12560,8 +12558,6 @@ cp_parser_class_head (cp_parser* parser,
       tree scope;
       /* Figure out in what scope the declaration is being placed.  */
       scope = current_scope ();
-      if (!scope)
-       scope = current_namespace;
       /* If that scope does not contain the scope in which the
         class was originally declared, the program is invalid.  */
       if (scope && !is_ancestor (scope, nested_name_specifier))
index 1ced238..99f4e7b 100644 (file)
@@ -8761,6 +8761,14 @@ tsubst_copy_and_build (tree t,
        return stmt_expr;
       }
 
+    case CONST_DECL:
+      t = tsubst_copy (t, args, complain, in_decl);
+      /* As in finish_id_expression, we resolve enumeration constants
+        to their underlying values.  */
+      if (TREE_CODE (t) == CONST_DECL)
+       return DECL_INITIAL (t);
+      return t;
+
     default:
       return tsubst_copy (t, args, complain, in_decl);
     }
index 5b060da..5f8f081 100644 (file)
@@ -497,7 +497,13 @@ lookup_field_1 (tree type, tree name, bool want_type)
   return NULL_TREE;
 }
 
-/* There are a number of cases we need to be aware of here:
+/* Return the FUNCTION_DECL, RECORD_TYPE, UNION_TYPE, or
+   NAMESPACE_DECL corresponding to the innermost non-block scope.  */  
+
+tree
+current_scope ()
+{
+  /* There are a number of cases we need to be aware of here:
                         current_class_type     current_function_decl
      global                    NULL                    NULL
      fn-local                  NULL                    SET
@@ -505,30 +511,26 @@ lookup_field_1 (tree type, tree name, bool want_type)
      class->fn                 SET                     SET
      fn->class                 SET                     SET
 
-   Those last two make life interesting.  If we're in a function which is
-   itself inside a class, we need decls to go into the fn's decls (our
-   second case below).  But if we're in a class and the class itself is
-   inside a function, we need decls to go into the decls for the class.  To
-   achieve this last goal, we must see if, when both current_class_ptr and
-   current_function_decl are set, the class was declared inside that
-   function.  If so, we know to put the decls into the class's scope.  */
-
-tree
-current_scope (void)
-{
-  if (current_function_decl == NULL_TREE)
-    return current_class_type;
-  if (current_class_type == NULL_TREE)
+     Those last two make life interesting.  If we're in a function which is
+     itself inside a class, we need decls to go into the fn's decls (our
+     second case below).  But if we're in a class and the class itself is
+     inside a function, we need decls to go into the decls for the class.  To
+     achieve this last goal, we must see if, when both current_class_ptr and
+     current_function_decl are set, the class was declared inside that
+     function.  If so, we know to put the decls into the class's scope.  */
+  if (current_function_decl && current_class_type
+      && ((DECL_FUNCTION_MEMBER_P (current_function_decl)
+          && same_type_p (DECL_CONTEXT (current_function_decl),
+                          current_class_type))
+         || (DECL_FRIEND_CONTEXT (current_function_decl)
+             && same_type_p (DECL_FRIEND_CONTEXT (current_function_decl),
+                             current_class_type))))
     return current_function_decl;
-  if ((DECL_FUNCTION_MEMBER_P (current_function_decl)
-       && same_type_p (DECL_CONTEXT (current_function_decl),
-                      current_class_type))
-      || (DECL_FRIEND_CONTEXT (current_function_decl)
-         && same_type_p (DECL_FRIEND_CONTEXT (current_function_decl),
-                         current_class_type)))
+  if (current_class_type)
+    return current_class_type;
+  if (current_function_decl)
     return current_function_decl;
-
-  return current_class_type;
+  return current_namespace;
 }
 
 /* Returns nonzero if we are currently in a function scope.  Note
@@ -556,9 +558,8 @@ at_class_scope_p (void)
 bool
 at_namespace_scope_p (void)
 {
-  /* We are in a namespace scope if we are not it a class scope or a
-     function scope.  */
-  return !current_scope();
+  tree cs = current_scope ();
+  return cs && TREE_CODE (cs) == NAMESPACE_DECL;
 }
 
 /* Return the scope of DECL, as appropriate when doing name-lookup.  */
@@ -833,9 +834,13 @@ friend_accessible_p (tree scope, tree decl, tree binfo)
 static tree
 dfs_accessible_post (tree binfo, void *data ATTRIBUTE_UNUSED)
 {
-  if (BINFO_ACCESS (binfo) != ak_none
-      && is_friend (BINFO_TYPE (binfo), current_scope ()))
-    return binfo;
+  if (BINFO_ACCESS (binfo) != ak_none)
+    {
+      tree scope = current_scope ();
+      if (scope && TREE_CODE (scope) != NAMESPACE_DECL
+         && is_friend (BINFO_TYPE (binfo), scope))
+       return binfo;
+    }
   
   return NULL_TREE;
 }
@@ -1700,9 +1705,17 @@ dfs_walk_once_accessible_r (tree binfo, bool friends_p, bool once,
       /* If the base is inherited via private or protected
         inheritance, then we can't see it, unless we are a friend of
         the current binfo.  */
-      if (BINFO_BASE_ACCESS (binfo, ix) != access_public_node
-         && !(friends_p && is_friend (BINFO_TYPE (binfo), current_scope ())))
-       continue;
+      if (BINFO_BASE_ACCESS (binfo, ix) != access_public_node)
+       {
+         tree scope;
+         if (!friends_p)
+           continue;
+         scope = current_scope ();
+         if (!scope 
+             || TREE_CODE (scope) == NAMESPACE_DECL
+             || !is_friend (BINFO_TYPE (binfo), scope))
+           continue;
+       }
 
       if (mark)
        BINFO_MARKED (base_binfo) = 1;
index cc91b65..5e7bf90 100644 (file)
@@ -3201,7 +3201,9 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
   /* If we're in a template, the only thing we need to know is the
      RESULT_TYPE.  */
   if (processing_template_decl)
-    return build2 (resultcode, result_type, op0, op1);
+    return build2 (resultcode, 
+                  build_type ? build_type : result_type, 
+                  op0, op1);
 
   if (arithmetic_types_p)
     {
index 58e8756..e248aef 100644 (file)
@@ -1,3 +1,14 @@
+2004-10-26  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/18093
+       * g++.dg/lookup/ns2.C: New test.
+
+       PR c++/18020
+       * g++.dg/template/enum4.C: New test.
+
+       PR c++/18161
+       * g++.dg/template/expr1.C: New test.
+
 2004-10-26  Ben Elliston  <bje@au.ibm.com>
 
        * gcc.dg/tree-ssa/20030922-2.c: Now passing, so remove xfail.
diff --git a/gcc/testsuite/g++.dg/lookup/ns2.C b/gcc/testsuite/g++.dg/lookup/ns2.C
new file mode 100644 (file)
index 0000000..2ad2ec0
--- /dev/null
@@ -0,0 +1,17 @@
+// PR c++/18161
+
+namespace m
+{
+  namespace n
+  {
+  }
+}
+
+namespace n
+{
+}
+
+namespace o
+{
+  namespace n = ::m::n;
+}
diff --git a/gcc/testsuite/g++.dg/template/enum4.C b/gcc/testsuite/g++.dg/template/enum4.C
new file mode 100644 (file)
index 0000000..97e0b84
--- /dev/null
@@ -0,0 +1,9 @@
+// PR c++/18020
+
+template <typename> struct bar {
+  enum {
+    e1 = 1,
+    e2 = ~e1
+  };
+};
+template struct bar<int>;
diff --git a/gcc/testsuite/g++.dg/template/expr1.C b/gcc/testsuite/g++.dg/template/expr1.C
new file mode 100644 (file)
index 0000000..079865d
--- /dev/null
@@ -0,0 +1,8 @@
+// PR c++/18161
+// { dg-options "" }
+
+template <class T> struct Y;
+template <> struct Y<bool> {};
+
+template <typename T = typeof (1 == 1)> struct X { Y<T> a; };
+template struct X <>;