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
This commit is contained in:
Mark Mitchell 2006-01-22 00:42:40 +00:00 committed by Mark Mitchell
parent 5826ba2218
commit 0e686aa6f7
8 changed files with 102 additions and 30 deletions

View File

@ -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.

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -0,0 +1,4 @@
// PR c++/25856
struct A; // { dg-error "forward" }
A::~A() {} // { dg-error "undefined" }

View File

@ -0,0 +1,7 @@
// PR c++/25858
namespace N {
template<int> struct A {};
}
struct B N::A<0> {}; // { dg-error "invalid" }