diff options
author | Mark Mitchell <mark@codesourcery.com> | 2004-03-19 07:27:30 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2004-03-19 07:27:30 +0000 |
commit | 26bcf8fc16a06d4fe16ac25ce79739e2e6cb7445 (patch) | |
tree | 78c8fee7aeff0e01a8b8cc9aef49a891bccb39a7 | |
parent | ff3fcb8a50f89eff597c9d5e8f8d1cf6e31b809b (diff) | |
download | gcc-26bcf8fc16a06d4fe16ac25ce79739e2e6cb7445.zip gcc-26bcf8fc16a06d4fe16ac25ce79739e2e6cb7445.tar.gz gcc-26bcf8fc16a06d4fe16ac25ce79739e2e6cb7445.tar.bz2 |
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
-rw-r--r-- | gcc/cp/ChangeLog | 26 | ||||
-rw-r--r-- | gcc/cp/call.c | 10 | ||||
-rw-r--r-- | gcc/cp/decl.c | 3 | ||||
-rw-r--r-- | gcc/cp/name-lookup.c | 14 | ||||
-rw-r--r-- | gcc/cp/parser.c | 13 | ||||
-rw-r--r-- | gcc/cp/search.c | 9 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 16 | ||||
-rw-r--r-- | gcc/cp/tree.c | 2 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 9 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/expr/cond6.C | 24 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/expr/dtor2.C | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/lookup/anon4.C | 9 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/overload/using1.C | 11 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/lookup7.C | 9 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/typename6.C | 11 |
16 files changed, 167 insertions, 19 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 1052abe..3822563 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,31 @@ 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. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 7a3039b..7270ed6 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -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; diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 29232f2..29d6588 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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)) diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 1589682..e0a919d 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -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; } } diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 0dc63cd..c05e375 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -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); } diff --git a/gcc/cp/search.c b/gcc/cp/search.c index 30dc0d2..11c7ded 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -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); diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index e7d3771..50cb153 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -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; diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 290317e..85855ac 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -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; } diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index e353d3f..32d8177 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -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; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 03a37e6..391bfa3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,17 @@ +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. diff --git a/gcc/testsuite/g++.dg/expr/cond6.C b/gcc/testsuite/g++.dg/expr/cond6.C new file mode 100644 index 0000000..9308c17 --- /dev/null +++ b/gcc/testsuite/g++.dg/expr/cond6.C @@ -0,0 +1,24 @@ +// { 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); +} diff --git a/gcc/testsuite/g++.dg/expr/dtor2.C b/gcc/testsuite/g++.dg/expr/dtor2.C new file mode 100644 index 0000000..5f37242 --- /dev/null +++ b/gcc/testsuite/g++.dg/expr/dtor2.C @@ -0,0 +1,6 @@ +typedef const int I; +int i; + +void f() { + i.I::~I(); +} diff --git a/gcc/testsuite/g++.dg/lookup/anon4.C b/gcc/testsuite/g++.dg/lookup/anon4.C new file mode 100644 index 0000000..40c4ab4 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/anon4.C @@ -0,0 +1,9 @@ +static union { + int i; +}; + +int *ip; + +void g() { + ip = &i; +} diff --git a/gcc/testsuite/g++.dg/overload/using1.C b/gcc/testsuite/g++.dg/overload/using1.C new file mode 100644 index 0000000..bc46c60 --- /dev/null +++ b/gcc/testsuite/g++.dg/overload/using1.C @@ -0,0 +1,11 @@ +void f(); + +namespace N { + using ::f; +} + +bool b; + +void g() { + b = N::f == ::f; +} diff --git a/gcc/testsuite/g++.dg/template/lookup7.C b/gcc/testsuite/g++.dg/template/lookup7.C new file mode 100644 index 0000000..0e05c5f --- /dev/null +++ b/gcc/testsuite/g++.dg/template/lookup7.C @@ -0,0 +1,9 @@ +class S; + +template<class T> +int f(T, S); + +class S { + template<class T> + friend int f(T t, S) { t; return 0; } +}; diff --git a/gcc/testsuite/g++.dg/template/typename6.C b/gcc/testsuite/g++.dg/template/typename6.C new file mode 100644 index 0000000..937ea96 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typename6.C @@ -0,0 +1,11 @@ +struct O { + template <typename T> + struct I { + I (int); + }; +}; + +template <typename T> +void f() { + typename ::O::I<int>(3); +} |