aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorFabien ChĂȘne <fabien.chene@gmail.com>2010-04-27 18:56:13 +0000
committerJason Merrill <jason@gcc.gnu.org>2010-04-27 14:56:13 -0400
commit6ad86a5b264dcf68f9eee93da90af06d15d91e4a (patch)
treec95fa21322f4c7608254fa16bb33ea36db219406 /gcc/cp
parent78b41ae280b857079da43d91e81356c7afad8512 (diff)
downloadgcc-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/ChangeLog10
-rw-r--r--gcc/cp/class.c30
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/decl.c32
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);