re PR c++/18093 (bogus conflict in namespace aliasing)

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
This commit is contained in:
Mark Mitchell 2004-10-27 02:23:16 +00:00 committed by Mark Mitchell
parent 0a3d71f54a
commit a5201a9197
11 changed files with 131 additions and 47 deletions

View 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

View 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

View 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. */

View 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))

View 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);
}

View 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)
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 (current_class_type)
return current_class_type;
if (current_class_type == NULL_TREE)
if (current_function_decl)
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)))
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;

View 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)
{

View 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.

View file

@ -0,0 +1,17 @@
// PR c++/18161
namespace m
{
namespace n
{
}
}
namespace n
{
}
namespace o
{
namespace n = ::m::n;
}

View file

@ -0,0 +1,9 @@
// PR c++/18020
template <typename> struct bar {
enum {
e1 = 1,
e2 = ~e1
};
};
template struct bar<int>;

View file

@ -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 <>;