Commit 26bcf8fc by Mark Mitchell Committed by Mark Mitchell

semantics.c (finish_pseudo_destructor_expr): Allow differing cv-qualification…

semantics.c (finish_pseudo_destructor_expr): Allow differing cv-qualification between the type named by the...


	* semantics.c (finish_pseudo_destructor_expr): Allow differing
	cv-qualification between the type named by the
	pseudo-destructor-name and the object-type.

	* search.c (accessible_base_p): Handle non-proper bases.

	* name-lookup.c (do_nonmember_using_decl): If a using declaration
	refers to a single overloaded function, set the type of the
	function.
	* tree.c (lvalue_type): Simplify.
	* typeck.c (type_unknown_p): Do not assume all OVERLOADs have an
	unknown type.
	(build_unary_op): Handle OVERLOADs with known types.

	* decl.c (duplicate_decls): Do not destroy DECL_ARGUMENTS for
	function templates.

	* parser.c (cp_parser_postfix_expression): Handle the use of
	"typename" in non-dependent contexts.  Convert appropriately when
	when using a qualified name after "->" or ".".

	* call.c (conditional_conversion): Honor the requirement that some
	conversions refer to the original object.

	* g++.dg/expr/dtor2.C: New test.

	* g++.dg/lookup/anon4.C: New test.

	* g++.dg/overload/using1.C: New test.

	* g++.dg/template/lookup7.C: New test.

	* g++.dg/template/typename6.C: New test.

	* g++.dg/expr/cond6.C: New test.

From-SVN: r79671
parent ff3fcb8a
2004-03-18 Mark Mitchell <mark@codesourcery.com>
* semantics.c (finish_pseudo_destructor_expr): Allow differing
cv-qualification between the type named by the
pseudo-destructor-name and the object-type.
* search.c (accessible_base_p): Handle non-proper bases.
* name-lookup.c (do_nonmember_using_decl): If a using declaration
refers to a single overloaded function, set the type of the
function.
* tree.c (lvalue_type): Simplify.
* typeck.c (type_unknown_p): Do not assume all OVERLOADs have an
unknown type.
(build_unary_op): Handle OVERLOADs with known types.
* decl.c (duplicate_decls): Do not destroy DECL_ARGUMENTS for
function templates.
* parser.c (cp_parser_postfix_expression): Handle the use of
"typename" in non-dependent contexts. Convert appropriately when
when using a qualified name after "->" or ".".
* call.c (conditional_conversion): Honor the requirement that some
conversions refer to the original object.
2004-03-18 Mark Mitchell <mark@codesourcery.com>
* call.c (build_conditional_expr): Do not call force_rvalue for
operands of void_type when the conditional expression itself has
void type.
......
......@@ -3072,10 +3072,7 @@ conditional_conversion (tree e1, tree e2)
same cv-qualification as, or a greater cv-qualification than, the
cv-qualification of T1. If the conversion is applied, E1 is
changed to an rvalue of type T2 that still refers to the original
source class object (or the appropriate subobject thereof).
FIXME we can't express an rvalue that refers to the original object;
we have to create a new one. */
source class object (or the appropriate subobject thereof). */
if (CLASS_TYPE_P (t1) && CLASS_TYPE_P (t2)
&& ((good_base = DERIVED_FROM_P (t2, t1)) || DERIVED_FROM_P (t1, t2)))
{
......@@ -3084,10 +3081,7 @@ conditional_conversion (tree e1, tree e2)
conv = build_identity_conv (t1, e1);
if (!same_type_p (TYPE_MAIN_VARIANT (t1),
TYPE_MAIN_VARIANT (t2)))
{
conv = build_conv (ck_base, t2, conv);
conv->need_temporary_p = true;
}
conv = build_conv (ck_base, t2, conv);
else
conv = build_conv (ck_rvalue, t2, conv);
return conv;
......
......@@ -1581,6 +1581,9 @@ duplicate_decls (tree newdecl, tree olddecl)
DECL_SOURCE_LOCATION (olddecl)
= DECL_SOURCE_LOCATION (DECL_TEMPLATE_RESULT (olddecl))
= DECL_SOURCE_LOCATION (newdecl);
if (DECL_FUNCTION_TEMPLATE_P (newdecl))
DECL_ARGUMENTS (DECL_TEMPLATE_RESULT (olddecl))
= DECL_ARGUMENTS (DECL_TEMPLATE_RESULT (newdecl));
}
if (DECL_FUNCTION_TEMPLATE_P (newdecl))
......
......@@ -2194,9 +2194,21 @@ do_nonmember_using_decl (tree scope, tree name, tree oldval, tree oldtype,
if (tmp1)
continue;
/* If we are adding to an existing OVERLOAD, then we no
longer know the type of the set of functions. */
if (*newval && TREE_CODE (*newval) == OVERLOAD)
TREE_TYPE (*newval) = unknown_type_node;
/* Add this new function to the set. */
*newval = build_overload (OVL_CURRENT (tmp), *newval);
/* If there is only one function, then we use its type. (A
using-declaration naming a single function can be used in
contexts where overload resolution cannot be
performed.) */
if (TREE_CODE (*newval) != OVERLOAD)
*newval = ovl_cons (*newval, NULL_TREE);
{
*newval = ovl_cons (*newval, NULL_TREE);
TREE_TYPE (*newval) = TREE_TYPE (OVL_CURRENT (tmp));
}
OVL_USED (*newval) = 1;
}
}
......
......@@ -3629,10 +3629,16 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
/* If that didn't work, try an identifier. */
if (!cp_parser_parse_definitely (parser))
id = cp_parser_identifier (parser);
/* If we look up a template-id in a non-dependent qualifying
scope, there's no need to create a dependent type. */
if (TREE_CODE (id) == TYPE_DECL
&& !dependent_type_p (parser->scope))
type = TREE_TYPE (id);
/* Create a TYPENAME_TYPE to represent the type to which the
functional cast is being performed. */
type = make_typename_type (parser->scope, id,
/*complain=*/1);
else
type = make_typename_type (parser->scope, id,
/*complain=*/1);
postfix_expression = cp_parser_functional_cast (parser, type);
}
......@@ -3971,6 +3977,9 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
parser->qualifying_scope = NULL_TREE;
parser->object_scope = NULL_TREE;
}
if (scope && name && BASELINK_P (name))
adjust_result_of_qualified_name_lookup
(name, BINFO_TYPE (BASELINK_BINFO (name)), scope);
postfix_expression
= finish_class_member_access_expr (postfix_expression, name);
}
......
......@@ -232,7 +232,7 @@ lookup_base_r (tree binfo, tree base, base_access access,
}
/* Returns true if type BASE is accessible in T. (BASE is known to be
a base class of T.) */
a (possibly non-proper) base class of T.) */
bool
accessible_base_p (tree t, tree base)
......@@ -242,7 +242,12 @@ accessible_base_p (tree t, tree base)
/* [class.access.base]
A base class is said to be accessible if an invented public
member of the base class is accessible. */
member of the base class is accessible.
If BASE is a non-proper base, this condition is trivially
true. */
if (same_type_p (t, base))
return true;
/* Rather than inventing a public member, we use the implicit
public typedef created in the scope of every class. */
decl = TYPE_FIELDS (base);
......
......@@ -1803,7 +1803,21 @@ finish_pseudo_destructor_expr (tree object, tree scope, tree destructor)
return error_mark_node;
}
if (!same_type_p (TREE_TYPE (object), destructor))
/* [expr.pseudo] says both:
The type designated by the pseudo-destructor-name shall be
the same as the object type.
and:
The cv-unqualified versions of the object type and of the
type designated by the pseudo-destructor-name shall be the
same type.
We implement the more generous second sentence, since that is
what most other compilers do. */
if (!same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (object),
destructor))
{
error ("`%E' is not of type `%T'", object, destructor);
return error_mark_node;
......
......@@ -1646,8 +1646,6 @@ tree
lvalue_type (tree arg)
{
tree type = TREE_TYPE (arg);
if (TREE_CODE (arg) == OVERLOAD)
type = unknown_type_node;
return type;
}
......
......@@ -163,8 +163,7 @@ complete_type_or_diagnostic (tree type, tree value, int diag_type)
int
type_unknown_p (tree exp)
{
return (TREE_CODE (exp) == OVERLOAD
|| TREE_CODE (exp) == TREE_LIST
return (TREE_CODE (exp) == TREE_LIST
|| TREE_TYPE (exp) == unknown_type_node);
}
......@@ -4022,7 +4021,11 @@ build_unary_op (enum tree_code code, tree xarg, int noconvert)
if (! lvalue_p (arg) && pedantic)
pedwarn ("ISO C++ forbids taking the address of a cast to a non-lvalue expression");
break;
case OVERLOAD:
arg = OVL_CURRENT (arg);
break;
default:
break;
}
......
2004-03-18 Mark Mitchell <mark@codesourcery.com>
* g++.dg/expr/dtor2.C: New test.
* g++.dg/lookup/anon4.C: New test.
* g++.dg/overload/using1.C: New test.
* g++.dg/template/lookup7.C: New test.
* g++.dg/template/typename6.C: New test.
* g++.dg/expr/cond6.C: New test.
2004-03-18 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* gcc.dg/torture/builtin-convert-1.c: Test more math builtins.
......
// { dg-do "run" }
extern "C" void abort ();
struct B {
B() {}
B(const B& b) { abort (); }
};
struct D : public B {
D() {}
D(const D& d) : B() {}
};
D d;
B b;
D f() {
return d;
}
int main () {
b = (true ? f() : b);
}
typedef const int I;
int i;
void f() {
i.I::~I();
}
static union {
int i;
};
int *ip;
void g() {
ip = &i;
}
void f();
namespace N {
using ::f;
}
bool b;
void g() {
b = N::f == ::f;
}
class S;
template<class T>
int f(T, S);
class S {
template<class T>
friend int f(T t, S) { t; return 0; }
};
struct O {
template <typename T>
struct I {
I (int);
};
};
template <typename T>
void f() {
typename ::O::I<int>(3);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment