mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-19 03:40:26 +08:00
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:
parent
5826ba2218
commit
0e686aa6f7
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
22
gcc/testsuite/g++.dg/inherit/conv2.C
Normal file
22
gcc/testsuite/g++.dg/inherit/conv2.C
Normal 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;
|
||||
}
|
4
gcc/testsuite/g++.dg/parse/dtor7.C
Normal file
4
gcc/testsuite/g++.dg/parse/dtor7.C
Normal file
@ -0,0 +1,4 @@
|
||||
// PR c++/25856
|
||||
|
||||
struct A; // { dg-error "forward" }
|
||||
A::~A() {} // { dg-error "undefined" }
|
7
gcc/testsuite/g++.dg/template/crash44.C
Normal file
7
gcc/testsuite/g++.dg/template/crash44.C
Normal file
@ -0,0 +1,7 @@
|
||||
// PR c++/25858
|
||||
|
||||
namespace N {
|
||||
template<int> struct A {};
|
||||
}
|
||||
|
||||
struct B N::A<0> {}; // { dg-error "invalid" }
|
Loading…
x
Reference in New Issue
Block a user