diff options
author | Mark Mitchell <mark@codesourcery.com> | 2006-01-22 00:42:40 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2006-01-22 00:42:40 +0000 |
commit | 0e686aa6f7af3db2a7fc3a8f988d14d4e75282f4 (patch) | |
tree | 34bf7e47e301d282bde70b7e5eec5fcaa0d764a1 | |
parent | 5826ba2218e090eeb05a7e60bd88305b1dd250a1 (diff) | |
download | gcc-0e686aa6f7af3db2a7fc3a8f988d14d4e75282f4.zip gcc-0e686aa6f7af3db2a7fc3a8f988d14d4e75282f4.tar.gz gcc-0e686aa6f7af3db2a7fc3a8f988d14d4e75282f4.tar.bz2 |
re PR c++/25895 (wrong code with ?: and derived class pointers)
PR c++/25895
* class.c (build_base_path): Generate a NOP_EXPR instead of a
COMPONENT_REF if the base and derived classes are at the same
address.
PR c++/25856
* decl.c (begin_destructor_body): Robustify.
PR c++/25858
* parser.c (cp_parser_direct_declarator): Robustify.
PR c++/25895
* g++.dg/inherit/conv2.C: New test.
PR c++/25856
* g++.dg/parse/dtor7.C: New test.
PR c++/25858
* g++.dg/template/crash44.C: New test.
From-SVN: r110084
-rw-r--r-- | gcc/cp/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/cp/class.c | 16 | ||||
-rw-r--r-- | gcc/cp/decl.c | 29 | ||||
-rw-r--r-- | gcc/cp/parser.c | 30 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/inherit/conv2.C | 22 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/parse/dtor7.C | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/crash44.C | 7 |
8 files changed, 102 insertions, 30 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 42c69e8..ea7355b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,16 @@ +2006-01-21 Mark Mitchell <mark@codesourcery.com> + + PR c++/25895 + * class.c (build_base_path): Generate a NOP_EXPR instead of a + COMPONENT_REF if the base and derived classes are at the same + address. + + PR c++/25856 + * decl.c (begin_destructor_body): Robustify. + + PR c++/25858 + * parser.c (cp_parser_direct_declarator): Robustify. + 2006-01-20 Volker Reichelt <reichelt@igpm.rwth-aachen.de> * parser.c (cp_lexer_next_token_is_keyword): Simplify. diff --git a/gcc/cp/class.c b/gcc/cp/class.c index bd89b55..6b075cb 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -289,13 +289,23 @@ build_base_path (enum tree_code code, offset = BINFO_OFFSET (binfo); fixed_type_p = resolves_to_fixed_type_p (expr, &nonnull); + target_type = code == PLUS_EXPR ? BINFO_TYPE (binfo) : BINFO_TYPE (d_binfo); /* Do we need to look in the vtable for the real offset? */ virtual_access = (v_binfo && fixed_type_p <= 0); /* Do we need to check for a null pointer? */ - if (want_pointer && !nonnull && (virtual_access || !integer_zerop (offset))) - null_test = error_mark_node; + if (want_pointer && !nonnull) + { + /* If we know the conversion will not actually change the value + of EXPR, then we can avoid testing the expression for NULL. + We have to avoid generating a COMPONENT_REF for a base class + field, because other parts of the compiler know that such + expressions are always non-NULL. */ + if (!virtual_access && integer_zerop (offset)) + return build_nop (build_pointer_type (target_type), expr); + null_test = error_mark_node; + } /* Protect against multiple evaluation if necessary. */ if (TREE_SIDE_EFFECTS (expr) && (null_test || virtual_access)) @@ -376,8 +386,6 @@ build_base_path (enum tree_code code, offset = v_offset; } - target_type = code == PLUS_EXPR ? BINFO_TYPE (binfo) : BINFO_TYPE (d_binfo); - target_type = cp_build_qualified_type (target_type, cp_type_quals (TREE_TYPE (TREE_TYPE (expr)))); ptr_target_type = build_pointer_type (target_type); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index ae0b7e8..3c98d49 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -10628,18 +10628,23 @@ begin_destructor_body (void) { tree compound_stmt; - compound_stmt = begin_compound_stmt (0); - - /* Make all virtual function table pointers in non-virtual base - classes point to CURRENT_CLASS_TYPE's virtual function - tables. */ - initialize_vtbl_ptrs (current_class_ptr); - - finish_compound_stmt (compound_stmt); - - /* And insert cleanups for our bases and members so that they - will be properly destroyed if we throw. */ - push_base_cleanups (); + /* If the CURRENT_CLASS_TYPE is incomplete, we will have already + issued an error message. We still want to try to process the + body of the function, but initialize_vtbl_ptrs will crash if + TYPE_BINFO is NULL. */ + if (COMPLETE_TYPE_P (current_class_type)) + { + compound_stmt = begin_compound_stmt (0); + /* Make all virtual function table pointers in non-virtual base + classes point to CURRENT_CLASS_TYPE's virtual function + tables. */ + initialize_vtbl_ptrs (current_class_ptr); + finish_compound_stmt (compound_stmt); + + /* And insert cleanups for our bases and members so that they + will be properly destroyed if we throw. */ + push_base_cleanups (); + } } /* At the end of every destructor we generate code to delete the object if diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 148eb1d..4c09b2f 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -11479,22 +11479,24 @@ cp_parser_direct_declarator (cp_parser* parser, if (TREE_CODE (unqualified_name) == TYPE_DECL) { - if (qualifying_scope - && CLASSTYPE_USE_TEMPLATE (TREE_TYPE (unqualified_name))) + tree name_type = TREE_TYPE (unqualified_name); + if (class_type && same_type_p (name_type, class_type)) { - error ("invalid use of constructor as a template"); - inform ("use %<%T::%D%> instead of %<%T::%T%> to name " - "the constructor in a qualified name", - class_type, - DECL_NAME (TYPE_TI_TEMPLATE (class_type)), - class_type, class_type); - declarator = cp_error_declarator; - break; + if (qualifying_scope + && CLASSTYPE_USE_TEMPLATE (name_type)) + { + error ("invalid use of constructor as a template"); + inform ("use %<%T::%D%> instead of %<%T::%D%> to " + "name the constructor in a qualified name", + class_type, + DECL_NAME (TYPE_TI_TEMPLATE (class_type)), + class_type, name_type); + declarator = cp_error_declarator; + break; + } + else + unqualified_name = constructor_name (class_type); } - else if (class_type - && same_type_p (TREE_TYPE (unqualified_name), - class_type)) - unqualified_name = constructor_name (class_type); else { /* We do not attempt to print the declarator diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7c28e0e..07aa699 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,14 @@ +2006-01-21 Mark Mitchell <mark@codesourcery.com> + + PR c++/25895 + * g++.dg/inherit/conv2.C: New test. + + PR c++/25856 + * g++.dg/parse/dtor7.C: New test. + + PR c++/25858 + * g++.dg/template/crash44.C: New test. + 2005-01-21 Paul Thomas <pault@gcc.gnu.org> PR fortran/25124 diff --git a/gcc/testsuite/g++.dg/inherit/conv2.C b/gcc/testsuite/g++.dg/inherit/conv2.C new file mode 100644 index 0000000..fd00838 --- /dev/null +++ b/gcc/testsuite/g++.dg/inherit/conv2.C @@ -0,0 +1,22 @@ +// PR c++/25895 +// { dg-do run } + +class base { +public: + base() {} +private: + int val_; +}; + +class derived : public base { +public: + derived() {} +}; + +static bool x = true ? (derived*)0 : (base*)0; + +int main () +{ + if (x) + return 1; +} diff --git a/gcc/testsuite/g++.dg/parse/dtor7.C b/gcc/testsuite/g++.dg/parse/dtor7.C new file mode 100644 index 0000000..3525624 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/dtor7.C @@ -0,0 +1,4 @@ +// PR c++/25856 + +struct A; // { dg-error "forward" } +A::~A() {} // { dg-error "undefined" } diff --git a/gcc/testsuite/g++.dg/template/crash44.C b/gcc/testsuite/g++.dg/template/crash44.C new file mode 100644 index 0000000..d5596c1 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash44.C @@ -0,0 +1,7 @@ +// PR c++/25858 + +namespace N { + template<int> struct A {}; +} + +struct B N::A<0> {}; // { dg-error "invalid" } |