diff options
author | Fabien ChĂȘne <fabien.chene@gmail.com> | 2010-04-27 18:56:13 +0000 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2010-04-27 14:56:13 -0400 |
commit | 6ad86a5b264dcf68f9eee93da90af06d15d91e4a (patch) | |
tree | c95fa21322f4c7608254fa16bb33ea36db219406 /gcc/cp | |
parent | 78b41ae280b857079da43d91e81356c7afad8512 (diff) | |
download | gcc-6ad86a5b264dcf68f9eee93da90af06d15d91e4a.zip gcc-6ad86a5b264dcf68f9eee93da90af06d15d91e4a.tar.gz gcc-6ad86a5b264dcf68f9eee93da90af06d15d91e4a.tar.bz2 |
re PR c++/42844 (const variable requires initializer / no explicitly declared default constructor)
PR c++/42844
* decl.c (check_for_uninitialized_const_var): Handle classes that need
constructing, too.
(check_initializer): Call it for classes that need constructing, too.
* class.c (in_class_defaulted_default_constructor): New.
* cp-tree.h: Declare it.
Co-Authored-By: Jason Merrill <jason@redhat.com>
From-SVN: r158797
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/cp/class.c | 30 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 1 | ||||
-rw-r--r-- | gcc/cp/decl.c | 32 |
4 files changed, 66 insertions, 7 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6dec7c3..a996461 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +2010-04-27 Fabien ChĂȘne <fabien.chene@gmail.com> + Jason Merrill <jason@redhat.com> + + PR c++/42844 + * decl.c (check_for_uninitialized_const_var): Handle classes that need + constructing, too. + (check_initializer): Call it for classes that need constructing, too. + * class.c (in_class_defaulted_default_constructor): New. + * cp-tree.h: Declare it. + 2010-04-20 Jason Merrill <jason@redhat.com> PR c++/9335 diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 1bab07d..26da21b 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -1,6 +1,6 @@ /* Functions related to building classes and their related objects. Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009 + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com) @@ -4177,6 +4177,34 @@ type_has_user_nondefault_constructor (tree t) return false; } +/* Returns the defaulted constructor if T has one. Otherwise, returns + NULL_TREE. */ + +tree +in_class_defaulted_default_constructor (tree t) +{ + tree fns, args; + + if (!TYPE_HAS_USER_CONSTRUCTOR (t)) + return NULL_TREE; + + for (fns = CLASSTYPE_CONSTRUCTORS (t); fns; fns = OVL_NEXT (fns)) + { + tree fn = OVL_CURRENT (fns); + + if (DECL_DEFAULTED_IN_CLASS_P (fn)) + { + args = FUNCTION_FIRST_USER_PARMTYPE (fn); + while (args && TREE_PURPOSE (args)) + args = TREE_CHAIN (args); + if (!args || args == void_list_node) + return fn; + } + } + + return NULL_TREE; +} + /* Returns true iff FN is a user-provided function, i.e. user-declared and not defaulted at its first declaration; or explicit, private, protected, or non-const. */ diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 26059046..a7ed134 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4611,6 +4611,7 @@ extern void check_for_override (tree, tree); extern void push_class_stack (void); extern void pop_class_stack (void); extern bool type_has_user_nondefault_constructor (tree); +extern tree in_class_defaulted_default_constructor (tree); extern bool user_provided_p (tree); extern bool type_has_user_provided_constructor (tree); extern bool type_has_user_provided_default_constructor (tree); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 580f6f8..346b7b4 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -1,6 +1,6 @@ /* Process declarations and variables for C++ compiler. Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 + 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com) @@ -4692,7 +4692,7 @@ maybe_commonize_var (tree decl) static void check_for_uninitialized_const_var (tree decl) { - tree type = TREE_TYPE (decl); + tree type = strip_array_types (TREE_TYPE (decl)); if (TREE_CODE (decl) == VAR_DECL && DECL_DECLARED_CONSTEXPR_P (decl) && DECL_INITIAL (decl) == NULL) @@ -4704,11 +4704,28 @@ check_for_uninitialized_const_var (tree decl) else if (TREE_CODE (decl) == VAR_DECL && TREE_CODE (type) != REFERENCE_TYPE && CP_TYPE_CONST_P (type) - && !TYPE_NEEDS_CONSTRUCTING (type) + && (!TYPE_NEEDS_CONSTRUCTING (type) + || !type_has_user_provided_default_constructor (type)) && !DECL_INITIAL (decl)) - error ("uninitialized const %qD", decl); -} + { + permerror (DECL_SOURCE_LOCATION (decl), + "uninitialized const %qD", decl); + if (CLASS_TYPE_P (type) + && !type_has_user_provided_default_constructor (type)) + { + tree defaulted_ctor; + + inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (type)), + "%q#T has no user-provided default constructor", type); + defaulted_ctor = in_class_defaulted_default_constructor (type); + if (defaulted_ctor) + inform (DECL_SOURCE_LOCATION (defaulted_ctor), + "constructor is not user-provided because it is " + "explicitly defaulted in the class body"); + } + } +} /* Structure holding the current initializer being processed by reshape_init. CUR is a pointer to the current element being processed, END is a pointer @@ -5261,7 +5278,10 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup) else if (DECL_EXTERNAL (decl)) ; else if (TYPE_P (type) && TYPE_NEEDS_CONSTRUCTING (type)) - return build_aggr_init_full_exprs (decl, init, flags); + { + check_for_uninitialized_const_var (decl); + return build_aggr_init_full_exprs (decl, init, flags); + } else if (MAYBE_CLASS_TYPE_P (type)) { tree core_type = strip_array_types (type); |