diff options
author | Jason Merrill <jason@redhat.com> | 2009-05-17 14:01:33 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2009-05-17 14:01:33 -0400 |
commit | 7e361ae60a7b275571bba267b2354b72df40c99a (patch) | |
tree | 097a2b317a3f015b864632a6294fe207c4fd91d4 /gcc/cp | |
parent | 8fa6fa79177806a38422c7c13a29a8fc12e38bf3 (diff) | |
download | gcc-7e361ae60a7b275571bba267b2354b72df40c99a.zip gcc-7e361ae60a7b275571bba267b2354b72df40c99a.tar.gz gcc-7e361ae60a7b275571bba267b2354b72df40c99a.tar.bz2 |
re PR c++/40139 (ICE on invalid use of destructor)
PR c++/40139
* pt.c (tsubst_qualified_id): Retain the type if we aren't dealing
with a dependent type. Actually look up the destructor.
* semantics.c (finish_id_expression): Fix logic.
(finish_qualified_id_expr): Don't try to use 'this' if we aren't in
a function.
* typeck.c (build_x_unary_op): Diagnose taking the address of a
constructor or destructor.
* tree.c (get_first_fn): Handle OFFSET_REF.
From-SVN: r147638
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/cp/pt.c | 25 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 27 | ||||
-rw-r--r-- | gcc/cp/tree.c | 3 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 16 |
5 files changed, 60 insertions, 23 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index bffec90..af4b69c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,15 @@ +2009-05-16 Jason Merrill <jason@redhat.com> + + PR c++/40139 + * pt.c (tsubst_qualified_id): Retain the type if we aren't dealing + with a dependent type. Actually look up the destructor. + * semantics.c (finish_id_expression): Fix logic. + (finish_qualified_id_expr): Don't try to use 'this' if we aren't in + a function. + * typeck.c (build_x_unary_op): Diagnose taking the address of a + constructor or destructor. + * tree.c (get_first_fn): Handle OFFSET_REF. + 2009-05-17 Joseph Myers <joseph@codesourcery.com> * tree.c (cxx_printable_name_internal): Allow consecutive diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index e100d6b..2ca28d6 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -9930,16 +9930,29 @@ tsubst_qualified_id (tree qualified_id, tree args, expr = name; if (dependent_type_p (scope)) - return build_qualified_name (/*type=*/NULL_TREE, - scope, expr, - QUALIFIED_NAME_IS_TEMPLATE (qualified_id)); + { + tree type = NULL_TREE; + if (DECL_P (expr) && !dependent_scope_p (scope)) + type = TREE_TYPE (expr); + return build_qualified_name (type, scope, expr, + QUALIFIED_NAME_IS_TEMPLATE (qualified_id)); + } if (!BASELINK_P (name) && !DECL_P (expr)) { if (TREE_CODE (expr) == BIT_NOT_EXPR) - /* If this were actually a destructor call, it would have been - parsed as such by the parser. */ - expr = error_mark_node; + { + /* A BIT_NOT_EXPR is used to represent a destructor. */ + if (!check_dtor_name (scope, TREE_OPERAND (expr, 0))) + { + error ("qualifying type %qT does not match destructor name ~%qT", + scope, TREE_OPERAND (expr, 0)); + expr = error_mark_node; + } + else + expr = lookup_qualified_name (scope, complete_dtor_identifier, + /*is_type_p=*/0, false); + } else expr = lookup_qualified_name (scope, expr, /*is_type_p=*/0, false); if (TREE_CODE (TREE_CODE (expr) == TEMPLATE_DECL diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 8c0a1e5..18aa051 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -1664,11 +1664,10 @@ finish_qualified_id_expr (tree qualifying_class, fns = BASELINK_FUNCTIONS (expr); if (TREE_CODE (fns) == TEMPLATE_ID_EXPR) fns = TREE_OPERAND (fns, 0); - /* If so, the expression may be relative to the current - class. */ + /* If so, the expression may be relative to 'this'. */ if (!shared_member_p (fns) - && current_class_type - && DERIVED_FROM_P (qualifying_class, current_class_type)) + && current_class_ref + && DERIVED_FROM_P (qualifying_class, TREE_TYPE (current_class_ref))) expr = (build_class_member_access_expr (maybe_dummy_object (qualifying_class, NULL), expr, @@ -2871,16 +2870,16 @@ finish_id_expression (tree id_expression, done, address_p, template_p, template_arg_p); - else if (dependent_scope_p (scope)) - decl = build_qualified_name (/*type=*/NULL_TREE, - scope, - id_expression, - template_p); - else if (DECL_P (decl)) - decl = build_qualified_name (TREE_TYPE (decl), - scope, - id_expression, - template_p); + else + { + tree type = NULL_TREE; + if (DECL_P (decl) && !dependent_scope_p (scope)) + type = TREE_TYPE (decl); + decl = build_qualified_name (type, + scope, + id_expression, + template_p); + } } if (TREE_TYPE (decl)) decl = convert_from_reference (decl); diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 219cb39..f1868f5 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -1200,7 +1200,8 @@ get_first_fn (tree from) { gcc_assert (is_overloaded_fn (from)); /* A baselink is also considered an overloaded function. */ - if (TREE_CODE (from) == COMPONENT_REF) + if (TREE_CODE (from) == OFFSET_REF + || TREE_CODE (from) == COMPONENT_REF) from = TREE_OPERAND (from, 1); if (BASELINK_P (from)) from = BASELINK_FUNCTIONS (from); diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 4486b90..069a057 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -4141,8 +4141,20 @@ build_x_unary_op (enum tree_code code, tree xarg, tsubst_flags_t complain) /*overloaded_p=*/NULL, complain); if (!exp && code == ADDR_EXPR) { - /* A pointer to member-function can be formed only by saying - &X::mf. */ + if (is_overloaded_fn (xarg)) + { + tree fn = get_first_fn (xarg); + if (DECL_CONSTRUCTOR_P (fn) || DECL_DESTRUCTOR_P (fn)) + { + const char *type = + (DECL_CONSTRUCTOR_P (fn) ? "constructor" : "destructor"); + error ("taking address of %s %qE", type, xarg); + return error_mark_node; + } + } + + /* A pointer to member-function can be formed only by saying + &X::mf. */ if (!flag_ms_extensions && TREE_CODE (TREE_TYPE (xarg)) == METHOD_TYPE && (TREE_CODE (xarg) != OFFSET_REF || !PTRMEM_OK_P (xarg))) { |