Commit 0e686aa6 by Mark Mitchell Committed by Mark Mitchell

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
parent 5826ba22
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> 2006-01-20 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
* parser.c (cp_lexer_next_token_is_keyword): Simplify. * parser.c (cp_lexer_next_token_is_keyword): Simplify.
......
...@@ -289,13 +289,23 @@ build_base_path (enum tree_code code, ...@@ -289,13 +289,23 @@ build_base_path (enum tree_code code,
offset = BINFO_OFFSET (binfo); offset = BINFO_OFFSET (binfo);
fixed_type_p = resolves_to_fixed_type_p (expr, &nonnull); 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? */ /* Do we need to look in the vtable for the real offset? */
virtual_access = (v_binfo && fixed_type_p <= 0); virtual_access = (v_binfo && fixed_type_p <= 0);
/* Do we need to check for a null pointer? */ /* Do we need to check for a null pointer? */
if (want_pointer && !nonnull && (virtual_access || !integer_zerop (offset))) if (want_pointer && !nonnull)
null_test = error_mark_node; {
/* 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. */ /* Protect against multiple evaluation if necessary. */
if (TREE_SIDE_EFFECTS (expr) && (null_test || virtual_access)) if (TREE_SIDE_EFFECTS (expr) && (null_test || virtual_access))
...@@ -376,8 +386,6 @@ build_base_path (enum tree_code code, ...@@ -376,8 +386,6 @@ build_base_path (enum tree_code code,
offset = v_offset; offset = v_offset;
} }
target_type = code == PLUS_EXPR ? BINFO_TYPE (binfo) : BINFO_TYPE (d_binfo);
target_type = cp_build_qualified_type target_type = cp_build_qualified_type
(target_type, cp_type_quals (TREE_TYPE (TREE_TYPE (expr)))); (target_type, cp_type_quals (TREE_TYPE (TREE_TYPE (expr))));
ptr_target_type = build_pointer_type (target_type); ptr_target_type = build_pointer_type (target_type);
......
...@@ -10628,18 +10628,23 @@ begin_destructor_body (void) ...@@ -10628,18 +10628,23 @@ begin_destructor_body (void)
{ {
tree compound_stmt; tree compound_stmt;
compound_stmt = begin_compound_stmt (0); /* If the CURRENT_CLASS_TYPE is incomplete, we will have already
issued an error message. We still want to try to process the
/* Make all virtual function table pointers in non-virtual base body of the function, but initialize_vtbl_ptrs will crash if
classes point to CURRENT_CLASS_TYPE's virtual function TYPE_BINFO is NULL. */
tables. */ if (COMPLETE_TYPE_P (current_class_type))
initialize_vtbl_ptrs (current_class_ptr); {
compound_stmt = begin_compound_stmt (0);
finish_compound_stmt (compound_stmt); /* Make all virtual function table pointers in non-virtual base
classes point to CURRENT_CLASS_TYPE's virtual function
/* And insert cleanups for our bases and members so that they tables. */
will be properly destroyed if we throw. */ initialize_vtbl_ptrs (current_class_ptr);
push_base_cleanups (); 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 /* At the end of every destructor we generate code to delete the object if
......
...@@ -11479,22 +11479,24 @@ cp_parser_direct_declarator (cp_parser* parser, ...@@ -11479,22 +11479,24 @@ cp_parser_direct_declarator (cp_parser* parser,
if (TREE_CODE (unqualified_name) == TYPE_DECL) if (TREE_CODE (unqualified_name) == TYPE_DECL)
{ {
if (qualifying_scope tree name_type = TREE_TYPE (unqualified_name);
&& CLASSTYPE_USE_TEMPLATE (TREE_TYPE (unqualified_name))) if (class_type && same_type_p (name_type, class_type))
{ {
error ("invalid use of constructor as a template"); if (qualifying_scope
inform ("use %<%T::%D%> instead of %<%T::%T%> to name " && CLASSTYPE_USE_TEMPLATE (name_type))
"the constructor in a qualified name", {
class_type, error ("invalid use of constructor as a template");
DECL_NAME (TYPE_TI_TEMPLATE (class_type)), inform ("use %<%T::%D%> instead of %<%T::%D%> to "
class_type, class_type); "name the constructor in a qualified name",
declarator = cp_error_declarator; class_type,
break; 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 else
{ {
/* We do not attempt to print the declarator /* We do not attempt to print the declarator
......
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> 2005-01-21 Paul Thomas <pault@gcc.gnu.org>
PR fortran/25124 PR fortran/25124
// 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;
}
// PR c++/25856
struct A; // { dg-error "forward" }
A::~A() {} // { dg-error "undefined" }
// PR c++/25858
namespace N {
template<int> struct A {};
}
struct B N::A<0> {}; // { dg-error "invalid" }
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