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> 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 * call.c (build_conditional_expr): Do not call force_rvalue for
operands of void_type when the conditional expression itself has operands of void_type when the conditional expression itself has
void type. void type.
......
...@@ -3072,10 +3072,7 @@ conditional_conversion (tree e1, tree e2) ...@@ -3072,10 +3072,7 @@ conditional_conversion (tree e1, tree e2)
same cv-qualification as, or a greater cv-qualification than, the same cv-qualification as, or a greater cv-qualification than, the
cv-qualification of T1. If the conversion is applied, E1 is cv-qualification of T1. If the conversion is applied, E1 is
changed to an rvalue of type T2 that still refers to the original changed to an rvalue of type T2 that still refers to the original
source class object (or the appropriate subobject thereof). 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. */
if (CLASS_TYPE_P (t1) && CLASS_TYPE_P (t2) if (CLASS_TYPE_P (t1) && CLASS_TYPE_P (t2)
&& ((good_base = DERIVED_FROM_P (t2, t1)) || DERIVED_FROM_P (t1, t2))) && ((good_base = DERIVED_FROM_P (t2, t1)) || DERIVED_FROM_P (t1, t2)))
{ {
...@@ -3084,10 +3081,7 @@ conditional_conversion (tree e1, tree e2) ...@@ -3084,10 +3081,7 @@ conditional_conversion (tree e1, tree e2)
conv = build_identity_conv (t1, e1); conv = build_identity_conv (t1, e1);
if (!same_type_p (TYPE_MAIN_VARIANT (t1), if (!same_type_p (TYPE_MAIN_VARIANT (t1),
TYPE_MAIN_VARIANT (t2))) TYPE_MAIN_VARIANT (t2)))
{ conv = build_conv (ck_base, t2, conv);
conv = build_conv (ck_base, t2, conv);
conv->need_temporary_p = true;
}
else else
conv = build_conv (ck_rvalue, t2, conv); conv = build_conv (ck_rvalue, t2, conv);
return conv; return conv;
......
...@@ -1581,6 +1581,9 @@ duplicate_decls (tree newdecl, tree olddecl) ...@@ -1581,6 +1581,9 @@ duplicate_decls (tree newdecl, tree olddecl)
DECL_SOURCE_LOCATION (olddecl) DECL_SOURCE_LOCATION (olddecl)
= DECL_SOURCE_LOCATION (DECL_TEMPLATE_RESULT (olddecl)) = DECL_SOURCE_LOCATION (DECL_TEMPLATE_RESULT (olddecl))
= DECL_SOURCE_LOCATION (newdecl); = 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)) if (DECL_FUNCTION_TEMPLATE_P (newdecl))
......
...@@ -2194,9 +2194,21 @@ do_nonmember_using_decl (tree scope, tree name, tree oldval, tree oldtype, ...@@ -2194,9 +2194,21 @@ do_nonmember_using_decl (tree scope, tree name, tree oldval, tree oldtype,
if (tmp1) if (tmp1)
continue; 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); *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) 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; OVL_USED (*newval) = 1;
} }
} }
......
...@@ -3629,10 +3629,16 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p) ...@@ -3629,10 +3629,16 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
/* If that didn't work, try an identifier. */ /* If that didn't work, try an identifier. */
if (!cp_parser_parse_definitely (parser)) if (!cp_parser_parse_definitely (parser))
id = cp_parser_identifier (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 /* Create a TYPENAME_TYPE to represent the type to which the
functional cast is being performed. */ functional cast is being performed. */
type = make_typename_type (parser->scope, id, else
/*complain=*/1); type = make_typename_type (parser->scope, id,
/*complain=*/1);
postfix_expression = cp_parser_functional_cast (parser, type); postfix_expression = cp_parser_functional_cast (parser, type);
} }
...@@ -3971,6 +3977,9 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p) ...@@ -3971,6 +3977,9 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
parser->qualifying_scope = NULL_TREE; parser->qualifying_scope = NULL_TREE;
parser->object_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 postfix_expression
= finish_class_member_access_expr (postfix_expression, name); = finish_class_member_access_expr (postfix_expression, name);
} }
......
...@@ -232,7 +232,7 @@ lookup_base_r (tree binfo, tree base, base_access access, ...@@ -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 /* 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 bool
accessible_base_p (tree t, tree base) accessible_base_p (tree t, tree base)
...@@ -242,7 +242,12 @@ accessible_base_p (tree t, tree base) ...@@ -242,7 +242,12 @@ accessible_base_p (tree t, tree base)
/* [class.access.base] /* [class.access.base]
A base class is said to be accessible if an invented public 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 /* Rather than inventing a public member, we use the implicit
public typedef created in the scope of every class. */ public typedef created in the scope of every class. */
decl = TYPE_FIELDS (base); decl = TYPE_FIELDS (base);
......
...@@ -1803,7 +1803,21 @@ finish_pseudo_destructor_expr (tree object, tree scope, tree destructor) ...@@ -1803,7 +1803,21 @@ finish_pseudo_destructor_expr (tree object, tree scope, tree destructor)
return error_mark_node; 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); error ("`%E' is not of type `%T'", object, destructor);
return error_mark_node; return error_mark_node;
......
...@@ -1646,8 +1646,6 @@ tree ...@@ -1646,8 +1646,6 @@ tree
lvalue_type (tree arg) lvalue_type (tree arg)
{ {
tree type = TREE_TYPE (arg); tree type = TREE_TYPE (arg);
if (TREE_CODE (arg) == OVERLOAD)
type = unknown_type_node;
return type; return type;
} }
......
...@@ -163,8 +163,7 @@ complete_type_or_diagnostic (tree type, tree value, int diag_type) ...@@ -163,8 +163,7 @@ complete_type_or_diagnostic (tree type, tree value, int diag_type)
int int
type_unknown_p (tree exp) type_unknown_p (tree exp)
{ {
return (TREE_CODE (exp) == OVERLOAD return (TREE_CODE (exp) == TREE_LIST
|| TREE_CODE (exp) == TREE_LIST
|| TREE_TYPE (exp) == unknown_type_node); || TREE_TYPE (exp) == unknown_type_node);
} }
...@@ -4022,7 +4021,11 @@ build_unary_op (enum tree_code code, tree xarg, int noconvert) ...@@ -4022,7 +4021,11 @@ build_unary_op (enum tree_code code, tree xarg, int noconvert)
if (! lvalue_p (arg) && pedantic) if (! lvalue_p (arg) && pedantic)
pedwarn ("ISO C++ forbids taking the address of a cast to a non-lvalue expression"); pedwarn ("ISO C++ forbids taking the address of a cast to a non-lvalue expression");
break; break;
case OVERLOAD:
arg = OVL_CURRENT (arg);
break;
default: default:
break; 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> 2004-03-18 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* gcc.dg/torture/builtin-convert-1.c: Test more math builtins. * 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