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:
parent
0a3d71f54a
commit
a5201a9197
11 changed files with 131 additions and 47 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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.
|
||||
|
|
17
gcc/testsuite/g++.dg/lookup/ns2.C
Normal file
17
gcc/testsuite/g++.dg/lookup/ns2.C
Normal file
|
@ -0,0 +1,17 @@
|
|||
// PR c++/18161
|
||||
|
||||
namespace m
|
||||
{
|
||||
namespace n
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
namespace n
|
||||
{
|
||||
}
|
||||
|
||||
namespace o
|
||||
{
|
||||
namespace n = ::m::n;
|
||||
}
|
9
gcc/testsuite/g++.dg/template/enum4.C
Normal file
9
gcc/testsuite/g++.dg/template/enum4.C
Normal file
|
@ -0,0 +1,9 @@
|
|||
// PR c++/18020
|
||||
|
||||
template <typename> struct bar {
|
||||
enum {
|
||||
e1 = 1,
|
||||
e2 = ~e1
|
||||
};
|
||||
};
|
||||
template struct bar<int>;
|
8
gcc/testsuite/g++.dg/template/expr1.C
Normal file
8
gcc/testsuite/g++.dg/template/expr1.C
Normal 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 <>;
|
Loading…
Add table
Reference in a new issue