Commit 9d809e8f by Fabien Chêne Committed by Jason Merrill

re PR c++/25811 (No failure creating a POD containing a const member, using new…

re PR c++/25811 (No failure creating a POD containing a const member, using new without a new-initializer.)

	PR c++/25811
	* cp-tree.h (diagnose_uninitialized_cst_or_ref_member): Declare.
	* init.c (build_new_1): Check for uninitialized const members and
	uninitialized reference members, when using new without
	new-initializer. Call diagnose_uninitialized_cst_or_ref_member.
	(diagnose_uninitialized_cst_or_ref_member): Define, call
	diagnose_uninitialized_cst_or_ref_member_1.
	(diagnose_uninitialized_cst_or_ref_member_1): New function.

From-SVN: r158239
parent c7392d11
2010-04-12 Fabien Chene <fabien.chene@gmail.com>
PR c++/25811
* cp-tree.h (diagnose_uninitialized_cst_or_ref_member): Declare.
* init.c (build_new_1): Check for uninitialized const members and
uninitialized reference members, when using new without
new-initializer. Call diagnose_uninitialized_cst_or_ref_member.
(diagnose_uninitialized_cst_or_ref_member): Define, call
diagnose_uninitialized_cst_or_ref_member_1.
(diagnose_uninitialized_cst_or_ref_member_1): New function.
2010-04-12 Richard Guenther <rguenther@suse.de>
PR c++/43611
......
/* Definitions for C++ parsing and type checking.
Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com)
......@@ -4852,6 +4852,7 @@ extern tree create_temporary_var (tree);
extern void initialize_vtbl_ptrs (tree);
extern tree build_java_class_ref (tree);
extern tree integral_constant_value (tree);
extern void diagnose_uninitialized_cst_or_ref_member (tree, bool);
/* in lex.c */
extern void cxx_dup_lang_specific_decl (tree);
......
/* Handle initialization things in C++.
Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com)
......@@ -54,6 +54,7 @@ static tree dfs_initialize_vtbl_ptrs (tree, void *);
static tree build_dtor_call (tree, special_function_kind, int);
static tree build_field_list (tree, tree, int *);
static tree build_vtbl_address (tree);
static void diagnose_uninitialized_cst_or_ref_member_1 (tree, tree, bool);
/* We are about to generate some complex initialization code.
Conceptually, it is all a single expression. However, we may want
......@@ -1753,6 +1754,59 @@ build_raw_new_expr (VEC(tree,gc) *placement, tree type, tree nelts,
return new_expr;
}
/* Diagnose uninitialized const members or reference members of type
TYPE. USING_NEW is used to disambiguate the diagnostic between a
new expression without a new-initializer and a declaration */
static void
diagnose_uninitialized_cst_or_ref_member_1 (tree type, tree origin,
bool using_new)
{
tree field;
for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
{
tree field_type;
if (TREE_CODE (field) != FIELD_DECL)
continue;
field_type = strip_array_types (TREE_TYPE (field));
if (TREE_CODE (field_type) == REFERENCE_TYPE)
{
if (using_new)
error ("uninitialized reference member in %q#T using %<new%>",
origin);
else
error ("uninitialized reference member in %q#T", origin);
inform (DECL_SOURCE_LOCATION (field),
"%qD should be initialized", field);
}
if (CP_TYPE_CONST_P (field_type))
{
if (using_new)
error ("uninitialized const member in %q#T using %<new%>",
origin);
else
error ("uninitialized const member in %q#T", origin);
inform (DECL_SOURCE_LOCATION (field),
"%qD should be initialized", field);
}
if (CLASS_TYPE_P (field_type))
diagnose_uninitialized_cst_or_ref_member_1 (field_type,
origin, using_new);
}
}
void
diagnose_uninitialized_cst_or_ref_member (tree type, bool using_new)
{
diagnose_uninitialized_cst_or_ref_member_1 (type, type, using_new);
}
/* Generate code for a new-expression, including calling the "operator
new" function, initializing the object, and, if an exception occurs
during construction, cleaning up. The arguments are as for
......@@ -1839,6 +1893,38 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts,
is_initialized = (TYPE_NEEDS_CONSTRUCTING (elt_type) || *init != NULL);
if (*init == NULL && !type_has_user_provided_constructor (elt_type))
{
bool uninitialized_error = false;
/* A program that calls for default-initialization [...] of an
entity of reference type is ill-formed. */
if (CLASSTYPE_REF_FIELDS_NEED_INIT (elt_type))
uninitialized_error = true;
/* A new-expression that creates an object of type T initializes
that object as follows:
- If the new-initializer is omitted:
-- If T is a (possibly cv-qualified) non-POD class type
(or array thereof), the object is default-initialized (8.5).
[...]
-- Otherwise, the object created has indeterminate
value. If T is a const-qualified type, or a (possibly
cv-qualified) POD class type (or array thereof)
containing (directly or indirectly) a member of
const-qualified type, the program is ill-formed; */
if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (elt_type))
uninitialized_error = true;
if (uninitialized_error)
{
if (complain & tf_error)
diagnose_uninitialized_cst_or_ref_member (elt_type,
/*using_new*/true);
return error_mark_node;
}
}
if (CP_TYPE_CONST_P (elt_type) && *init == NULL
&& !type_has_user_provided_default_constructor (elt_type))
{
......
2010-04-12 Fabien Chene <fabien.chene@gmail.com>
PR c++/25811
* g++.dg/init/pr25811.C: New test.
2010-04-12 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* g++.dg/warn/miss-format-1.C: Removed *-*-solaris2.7 from
......
// PR c++/25811
// { dg-do compile }
struct A1
{
int const j; // { dg-message "should be initialized" }
};
struct A2
{
int const volatile i; // { dg-message "should be initialized" }
};
struct A3
{
int& ref; // { dg-message "should be initialized" }
};
struct A4
{
int const& ref; // { dg-message "should be initialized" }
};
struct A5
{
int& ref; // { dg-message "should be initialized" }
int const i; // { dg-message "should be initialized" }
};
template <class T> struct S1
{
T const i; // { dg-message "should be initialized" }
};
template <class T> struct S2
{
T const volatile i; // { dg-message "should be initialized" }
};
template <class T> struct S3
{
T& ref; // { dg-message "should be initialized" }
};
template <class T> struct S4
{
T const i; // { dg-message "should be initialized" }
T& ref; // { dg-message "should be initialized" }
};
struct X
{
X () : c (0), r (c) {}
int const c;
int const& r;
};
struct Y11
{
int const i; // { dg-message "should be initialized" }
};
struct Y1
{
Y11 a[1];
};
struct Y22
{
int& ref; // { dg-message "should be initialized" }
};
struct Y2
{
Y22 a[1];
};
struct Z1
{
int const i; // { dg-message "should be initialized" }
};
struct Z2
{
int& ref; // { dg-message "should be initialized" }
};
struct Z3
{
int const i; // { dg-message "should be initialized" }
};
struct Z4
{
int& ref; // { dg-message "should be initialized" }
};
struct Z5
{
int i;
};
struct Z
{
Z1 z1;
Z2 z2;
Z3 z3;
Z4 z4;
Z5 z5;
};
union U
{
int const i; // { dg-message "should be initialized" }
};
void f1 ()
{
new A1; // { dg-error "uninitialized const member" }
}
void f2 ()
{
new A2; // { dg-error "uninitialized const member" }
}
void f3 ()
{
new A3; // { dg-error "uninitialized reference member" }
}
void f4 ()
{
new A4; // { dg-error "uninitialized reference member" }
}
void f5 ()
{
new A5; // { dg-error "uninitialized reference member|uninitialized const member" }
}
void f6 ()
{
new S1<int>; // { dg-error "uninitialized const member" }
}
void f7 ()
{
new S2<int>; // { dg-error "uninitialized const member" }
}
void f8 ()
{
new S3<int>; // { dg-error "uninitialized reference member" }
}
void f9 ()
{
new S4<int>; // { dg-error "uninitialized reference member|uninitialized const member" }
}
void f10 ()
{
new X;
}
void f11 ()
{
new A1[1]; // { dg-error "uninitialized const member" }
}
void f12 ()
{
new A3[1]; // { dg-error "uninitialized reference member" }
}
void f13 ()
{
new Y1; // { dg-error "uninitialized const member" }
}
void f14 ()
{
new Y2; // { dg-error "uninitialized reference member" }
}
void f15 ()
{
new Z; // { dg-error "uninitialized reference member|uninitialized const member" }
}
void f16 ()
{
new U; // { dg-error "uninitialized const member" }
}
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