Commit e5e459bf by Alexandre Oliva Committed by Alexandre Oliva

re PR c++/17788 (poor diagnostic for missing reference initializer)

gcc/cp/ChangeLog:
PR c++/17788
* class.c (add_implicitly_declared_members, check_field_decl)
(check_field_decls, check_bases): Remove arguments, tests and
assignments of cant_have_default_ctor-related variables.
gcc/testsuite/ChangeLog:
PR c++/17788
* g++.dg/init/ctor4.C: New.
* g++.old-deja/g++.bugs/900205_04.C: Adjust.

From-SVN: r95071
parent 39a87435
2005-02-15 Alexandre Oliva <aoliva@redhat.com> 2005-02-15 Alexandre Oliva <aoliva@redhat.com>
PR c++/17788
* class.c (add_implicitly_declared_members, check_field_decl)
(check_field_decls, check_bases): Remove arguments, tests and
assignments of cant_have_default_ctor-related variables.
2005-02-15 Alexandre Oliva <aoliva@redhat.com>
* decl2.c (mark_used): Set the source location of the used decl to * decl2.c (mark_used): Set the source location of the used decl to
the current input location here... the current input location here...
* method.c (synthesize_method): ... not here. Set input_location * method.c (synthesize_method): ... not here. Set input_location
......
...@@ -123,7 +123,7 @@ static void finish_struct_methods (tree); ...@@ -123,7 +123,7 @@ static void finish_struct_methods (tree);
static void maybe_warn_about_overly_private_class (tree); static void maybe_warn_about_overly_private_class (tree);
static int method_name_cmp (const void *, const void *); static int method_name_cmp (const void *, const void *);
static int resort_method_name_cmp (const void *, const void *); static int resort_method_name_cmp (const void *, const void *);
static void add_implicitly_declared_members (tree, int, int, int); static void add_implicitly_declared_members (tree, int, int);
static tree fixed_type_or_null (tree, int *, int *); static tree fixed_type_or_null (tree, int *, int *);
static tree resolve_address_of_overloaded_function (tree, tree, tsubst_flags_t, static tree resolve_address_of_overloaded_function (tree, tree, tsubst_flags_t,
bool, tree); bool, tree);
...@@ -133,13 +133,13 @@ static tree build_vtbl_initializer (tree, tree, tree, tree, int *); ...@@ -133,13 +133,13 @@ static tree build_vtbl_initializer (tree, tree, tree, tree, int *);
static int count_fields (tree); static int count_fields (tree);
static int add_fields_to_record_type (tree, struct sorted_fields_type*, int); static int add_fields_to_record_type (tree, struct sorted_fields_type*, int);
static void check_bitfield_decl (tree); static void check_bitfield_decl (tree);
static void check_field_decl (tree, tree, int *, int *, int *, int *); static void check_field_decl (tree, tree, int *, int *, int *);
static void check_field_decls (tree, tree *, int *, int *, int *); static void check_field_decls (tree, tree *, int *, int *);
static tree *build_base_field (record_layout_info, tree, splay_tree, tree *); static tree *build_base_field (record_layout_info, tree, splay_tree, tree *);
static void build_base_fields (record_layout_info, splay_tree, tree *); static void build_base_fields (record_layout_info, splay_tree, tree *);
static void check_methods (tree); static void check_methods (tree);
static void remove_zero_width_bit_fields (tree); static void remove_zero_width_bit_fields (tree);
static void check_bases (tree, int *, int *, int *); static void check_bases (tree, int *, int *);
static void check_bases_and_members (tree); static void check_bases_and_members (tree);
static tree create_vtable_ptr (tree, tree *); static tree create_vtable_ptr (tree, tree *);
static void include_empty_classes (record_layout_info); static void include_empty_classes (record_layout_info);
...@@ -1207,14 +1207,12 @@ handle_using_decl (tree using_decl, tree t) ...@@ -1207,14 +1207,12 @@ handle_using_decl (tree using_decl, tree t)
alter_access (t, fdecl, access); alter_access (t, fdecl, access);
} }
/* Run through the base classes of T, updating /* Run through the base classes of T, updating CANT_HAVE_CONST_CTOR_P,
CANT_HAVE_DEFAULT_CTOR_P, CANT_HAVE_CONST_CTOR_P, and and NO_CONST_ASN_REF_P. Also set flag bits in T based on
NO_CONST_ASN_REF_P. Also set flag bits in T based on properties of properties of the bases. */
the bases. */
static void static void
check_bases (tree t, check_bases (tree t,
int* cant_have_default_ctor_p,
int* cant_have_const_ctor_p, int* cant_have_const_ctor_p,
int* no_const_asn_ref_p) int* no_const_asn_ref_p)
{ {
...@@ -1247,18 +1245,6 @@ check_bases (tree t, ...@@ -1247,18 +1245,6 @@ check_bases (tree t,
if (TYPE_HAS_ASSIGN_REF (basetype) if (TYPE_HAS_ASSIGN_REF (basetype)
&& !TYPE_HAS_CONST_ASSIGN_REF (basetype)) && !TYPE_HAS_CONST_ASSIGN_REF (basetype))
*no_const_asn_ref_p = 1; *no_const_asn_ref_p = 1;
/* Similarly, if the base class doesn't have a default
constructor, then the derived class won't have an
automatically generated default constructor. */
if (TYPE_HAS_CONSTRUCTOR (basetype)
&& ! TYPE_HAS_DEFAULT_CONSTRUCTOR (basetype))
{
*cant_have_default_ctor_p = 1;
if (! TYPE_HAS_CONSTRUCTOR (t))
pedwarn ("base %qT with only non-default constructor in class "
"without a constructor",
basetype);
}
if (BINFO_VIRTUAL_P (base_binfo)) if (BINFO_VIRTUAL_P (base_binfo))
/* A virtual base does not effect nearly emptiness. */ /* A virtual base does not effect nearly emptiness. */
...@@ -2503,16 +2489,14 @@ maybe_add_class_template_decl_list (tree type, tree t, int friend_p) ...@@ -2503,16 +2489,14 @@ maybe_add_class_template_decl_list (tree type, tree t, int friend_p)
} }
/* Create default constructors, assignment operators, and so forth for /* Create default constructors, assignment operators, and so forth for
the type indicated by T, if they are needed. the type indicated by T, if they are needed. CANT_HAVE_CONST_CTOR,
CANT_HAVE_DEFAULT_CTOR, CANT_HAVE_CONST_CTOR, and and CANT_HAVE_CONST_ASSIGNMENT are nonzero if, for whatever reason,
CANT_HAVE_CONST_ASSIGNMENT are nonzero if, for whatever reason, the the class cannot have a default constructor, copy constructor
class cannot have a default constructor, copy constructor taking a taking a const reference argument, or an assignment operator taking
const reference argument, or an assignment operator taking a const a const reference, respectively. */
reference, respectively. */
static void static void
add_implicitly_declared_members (tree t, add_implicitly_declared_members (tree t,
int cant_have_default_ctor,
int cant_have_const_cctor, int cant_have_const_cctor,
int cant_have_const_assignment) int cant_have_const_assignment)
{ {
...@@ -2565,7 +2549,7 @@ add_implicitly_declared_members (tree t, ...@@ -2565,7 +2549,7 @@ add_implicitly_declared_members (tree t,
} }
/* Default constructor. */ /* Default constructor. */
if (! TYPE_HAS_CONSTRUCTOR (t) && ! cant_have_default_ctor) if (! TYPE_HAS_CONSTRUCTOR (t))
{ {
TYPE_HAS_DEFAULT_CONSTRUCTOR (t) = 1; TYPE_HAS_DEFAULT_CONSTRUCTOR (t) = 1;
CLASSTYPE_LAZY_DEFAULT_CTOR (t) = 1; CLASSTYPE_LAZY_DEFAULT_CTOR (t) = 1;
...@@ -2713,7 +2697,6 @@ static void ...@@ -2713,7 +2697,6 @@ static void
check_field_decl (tree field, check_field_decl (tree field,
tree t, tree t,
int* cant_have_const_ctor, int* cant_have_const_ctor,
int* cant_have_default_ctor,
int* no_const_asn_ref, int* no_const_asn_ref,
int* any_default_members) int* any_default_members)
{ {
...@@ -2732,8 +2715,7 @@ check_field_decl (tree field, ...@@ -2732,8 +2715,7 @@ check_field_decl (tree field,
for (fields = TYPE_FIELDS (type); fields; fields = TREE_CHAIN (fields)) for (fields = TYPE_FIELDS (type); fields; fields = TREE_CHAIN (fields))
if (TREE_CODE (fields) == FIELD_DECL && !DECL_C_BIT_FIELD (field)) if (TREE_CODE (fields) == FIELD_DECL && !DECL_C_BIT_FIELD (field))
check_field_decl (fields, t, cant_have_const_ctor, check_field_decl (fields, t, cant_have_const_ctor,
cant_have_default_ctor, no_const_asn_ref, no_const_asn_ref, any_default_members);
any_default_members);
} }
/* Check members with class type for constructors, destructors, /* Check members with class type for constructors, destructors,
etc. */ etc. */
...@@ -2769,10 +2751,6 @@ check_field_decl (tree field, ...@@ -2769,10 +2751,6 @@ check_field_decl (tree field,
if (!TYPE_HAS_CONST_ASSIGN_REF (type)) if (!TYPE_HAS_CONST_ASSIGN_REF (type))
*no_const_asn_ref = 1; *no_const_asn_ref = 1;
if (TYPE_HAS_CONSTRUCTOR (type)
&& ! TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
*cant_have_default_ctor = 1;
} }
if (DECL_INITIAL (field) != NULL_TREE) if (DECL_INITIAL (field) != NULL_TREE)
{ {
...@@ -2795,10 +2773,6 @@ check_field_decl (tree field, ...@@ -2795,10 +2773,6 @@ check_field_decl (tree field,
EMPTY_P EMPTY_P
The class is empty, i.e., contains no non-static data members. The class is empty, i.e., contains no non-static data members.
CANT_HAVE_DEFAULT_CTOR_P
This class cannot have an implicitly generated default
constructor.
CANT_HAVE_CONST_CTOR_P CANT_HAVE_CONST_CTOR_P
This class cannot have an implicitly generated copy constructor This class cannot have an implicitly generated copy constructor
taking a const reference. taking a const reference.
...@@ -2815,7 +2789,6 @@ check_field_decl (tree field, ...@@ -2815,7 +2789,6 @@ check_field_decl (tree field,
static void static void
check_field_decls (tree t, tree *access_decls, check_field_decls (tree t, tree *access_decls,
int *cant_have_default_ctor_p,
int *cant_have_const_ctor_p, int *cant_have_const_ctor_p,
int *no_const_asn_ref_p) int *no_const_asn_ref_p)
{ {
...@@ -2959,7 +2932,6 @@ check_field_decls (tree t, tree *access_decls, ...@@ -2959,7 +2932,6 @@ check_field_decls (tree t, tree *access_decls,
aggregate, initialization by a brace-enclosed list) is the aggregate, initialization by a brace-enclosed list) is the
only way to initialize nonstatic const and reference only way to initialize nonstatic const and reference
members. */ members. */
*cant_have_default_ctor_p = 1;
TYPE_HAS_COMPLEX_ASSIGN_REF (t) = 1; TYPE_HAS_COMPLEX_ASSIGN_REF (t) = 1;
if (! TYPE_HAS_CONSTRUCTOR (t) && CLASSTYPE_NON_AGGREGATE (t) if (! TYPE_HAS_CONSTRUCTOR (t) && CLASSTYPE_NON_AGGREGATE (t)
...@@ -3007,7 +2979,6 @@ check_field_decls (tree t, tree *access_decls, ...@@ -3007,7 +2979,6 @@ check_field_decls (tree t, tree *access_decls,
aggregate, initialization by a brace-enclosed list) is the aggregate, initialization by a brace-enclosed list) is the
only way to initialize nonstatic const and reference only way to initialize nonstatic const and reference
members. */ members. */
*cant_have_default_ctor_p = 1;
TYPE_HAS_COMPLEX_ASSIGN_REF (t) = 1; TYPE_HAS_COMPLEX_ASSIGN_REF (t) = 1;
if (! TYPE_HAS_CONSTRUCTOR (t) && CLASSTYPE_NON_AGGREGATE (t) if (! TYPE_HAS_CONSTRUCTOR (t) && CLASSTYPE_NON_AGGREGATE (t)
...@@ -3036,7 +3007,6 @@ check_field_decls (tree t, tree *access_decls, ...@@ -3036,7 +3007,6 @@ check_field_decls (tree t, tree *access_decls,
else else
check_field_decl (x, t, check_field_decl (x, t,
cant_have_const_ctor_p, cant_have_const_ctor_p,
cant_have_default_ctor_p,
no_const_asn_ref_p, no_const_asn_ref_p,
&any_default_members); &any_default_members);
} }
...@@ -4062,9 +4032,6 @@ type_requires_array_cookie (tree type) ...@@ -4062,9 +4032,6 @@ type_requires_array_cookie (tree type)
static void static void
check_bases_and_members (tree t) check_bases_and_members (tree t)
{ {
/* Nonzero if we are not allowed to generate a default constructor
for this case. */
int cant_have_default_ctor;
/* Nonzero if the implicitly generated copy constructor should take /* Nonzero if the implicitly generated copy constructor should take
a non-const reference argument. */ a non-const reference argument. */
int cant_have_const_ctor; int cant_have_const_ctor;
...@@ -4075,12 +4042,11 @@ check_bases_and_members (tree t) ...@@ -4075,12 +4042,11 @@ check_bases_and_members (tree t)
/* By default, we use const reference arguments and generate default /* By default, we use const reference arguments and generate default
constructors. */ constructors. */
cant_have_default_ctor = 0;
cant_have_const_ctor = 0; cant_have_const_ctor = 0;
no_const_asn_ref = 0; no_const_asn_ref = 0;
/* Check all the base-classes. */ /* Check all the base-classes. */
check_bases (t, &cant_have_default_ctor, &cant_have_const_ctor, check_bases (t, &cant_have_const_ctor,
&no_const_asn_ref); &no_const_asn_ref);
/* Check all the method declarations. */ /* Check all the method declarations. */
...@@ -4091,7 +4057,6 @@ check_bases_and_members (tree t) ...@@ -4091,7 +4057,6 @@ check_bases_and_members (tree t)
as check_field_decls depends on TYPE_HAS_NONTRIVIAL_DESTRUCTOR as check_field_decls depends on TYPE_HAS_NONTRIVIAL_DESTRUCTOR
being set appropriately. */ being set appropriately. */
check_field_decls (t, &access_decls, check_field_decls (t, &access_decls,
&cant_have_default_ctor,
&cant_have_const_ctor, &cant_have_const_ctor,
&no_const_asn_ref); &no_const_asn_ref);
...@@ -4116,7 +4081,7 @@ check_bases_and_members (tree t) ...@@ -4116,7 +4081,7 @@ check_bases_and_members (tree t)
|= TYPE_HAS_ASSIGN_REF (t) || TYPE_CONTAINS_VPTR_P (t); |= TYPE_HAS_ASSIGN_REF (t) || TYPE_CONTAINS_VPTR_P (t);
/* Synthesize any needed methods. */ /* Synthesize any needed methods. */
add_implicitly_declared_members (t, cant_have_default_ctor, add_implicitly_declared_members (t,
cant_have_const_ctor, cant_have_const_ctor,
no_const_asn_ref); no_const_asn_ref);
......
2005-02-15 Alexandre Oliva <aoliva@redhat.com>
PR c++/17788
* g++.dg/init/ctor4.C: New.
* g++.old-deja/g++.bugs/900205_04.C: Adjust.
2005-02-15 Joseph S. Myers <joseph@codesourcery.com> 2005-02-15 Joseph S. Myers <joseph@codesourcery.com>
* gcc.dg/overflow-warn-1.c, gcc.dg/overflow-warn-2.c, * gcc.dg/overflow-warn-1.c, gcc.dg/overflow-warn-2.c,
......
// PR c++/17788
// { dg-do compile }
class foo {
public:
foo();
};
class bar: public foo {
private:
int &a;
};
foo::foo() {
}
int main(int argc, char **argv)
{
bar x; // { dg-error "uninitialized" }
}
...@@ -9,19 +9,23 @@ ...@@ -9,19 +9,23 @@
// keywords: default constructor, inheritance // keywords: default constructor, inheritance
struct struct0 { // In ISO C++ 1998, such a derived class is not ill-formed, but if the
// implicitly-declared constructor is used, then it is implicitly
// defined and found to be ill-formed.
struct struct0 { // { dg-error "note" }
int data_member; int data_member;
struct0 (int, void *); // suppresses implicit default constructor struct0 (int, void *); // suppresses implicit default constructor
}; };
struct0::struct0 (int, void *) struct0::struct0 (int, void *) // { dg-error "note" }
{ {
} }
struct struct0_derived_struct_0 : public struct0 { // { dg-error "" } struct struct0_derived_struct_0 : public struct0 { // { dg-error "" }
}; };
// struct0_derived_struct_0 object; // would give g++ error if compiled struct0_derived_struct_0 object;
int main () { return 0; } int main () { return 0; }
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