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
This commit is contained in:
parent
78b41ae280
commit
6ad86a5b26
@ -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
|
||||
|
@ -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. */
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -1,3 +1,11 @@
|
||||
2010-04-27 Fabien Chêne <fabien.chene@gmail.com>
|
||||
|
||||
* g++.dg/init/pr42844.C: New.
|
||||
* g++.dg/cpp0x/pr42844-2.C: New.
|
||||
* g++.dg/cpp0x/defaulted2.C: Adjust.
|
||||
* g++.dg/tree-ssa/pr27549.C: Likewise.
|
||||
* g++.old-deja/g++.mike/dyncast8.C: Likewise.
|
||||
|
||||
2010-04-27 Tobias Burnus <burnus@net-b.de>
|
||||
|
||||
PR fortran/18918
|
||||
|
@ -15,9 +15,9 @@ A::A() = default; // { dg-error "redefinition" }
|
||||
void g() {} // { dg-error "previous" }
|
||||
void g() = delete; // { dg-error "redefinition" }
|
||||
|
||||
struct B
|
||||
struct B // { dg-message "user-provided default constructor" }
|
||||
{
|
||||
B() = default;
|
||||
B() = default; // { dg-message "not user-provided" }
|
||||
};
|
||||
|
||||
const B b; // { dg-error "uninitialized const" }
|
||||
|
38
gcc/testsuite/g++.dg/cpp0x/pr42844-2.C
Normal file
38
gcc/testsuite/g++.dg/cpp0x/pr42844-2.C
Normal file
@ -0,0 +1,38 @@
|
||||
// PR c++/42844
|
||||
// { dg-do compile }
|
||||
// { dg-options "-std=c++0x" }
|
||||
|
||||
struct A // { dg-message "user-provided default constructor" }
|
||||
{
|
||||
A() = default; // { dg-message "not user-provided" }
|
||||
};
|
||||
|
||||
struct Base
|
||||
{
|
||||
Base() {}
|
||||
};
|
||||
|
||||
struct Derived : Base // { dg-message "user-provided default constructor" }
|
||||
{
|
||||
Derived() = default; // { dg-message "not user-provided" }
|
||||
};
|
||||
|
||||
struct Derived2 : Base // { dg-message "user-provided default constructor" }
|
||||
{
|
||||
Derived2() = default; // { dg-message "not user-provided" }
|
||||
Derived2( Derived2 const& ) = default;
|
||||
};
|
||||
|
||||
struct Derived3 : Base // { dg-message "user-provided default constructor" }
|
||||
{
|
||||
Derived3( Derived3 const& ) = default;
|
||||
Derived3() = default; // { dg-message "not user-provided" }
|
||||
};
|
||||
|
||||
void f()
|
||||
{
|
||||
const A a; // { dg-error "uninitialized const" }
|
||||
const Derived d; // { dg-error "uninitialized const" }
|
||||
const Derived2 d2; // { dg-error "uninitialized const" }
|
||||
const Derived3 d3; // { dg-error "uninitialized const" }
|
||||
}
|
56
gcc/testsuite/g++.dg/init/pr42844.C
Normal file
56
gcc/testsuite/g++.dg/init/pr42844.C
Normal file
@ -0,0 +1,56 @@
|
||||
// PR c++/42844
|
||||
// { dg-do compile }
|
||||
|
||||
struct A
|
||||
{
|
||||
A(){}
|
||||
};
|
||||
|
||||
struct B : A {}; // { dg-message "user-provided default constructor" }
|
||||
|
||||
struct C : A {}; // { dg-message "user-provided default constructor" }
|
||||
|
||||
struct D : B { D() {} };
|
||||
|
||||
struct E {}; // { dg-message "user-provided default constructor" }
|
||||
|
||||
template <class T>
|
||||
struct F : A {}; // { dg-message "user-provided default constructor" }
|
||||
|
||||
template <class T>
|
||||
struct G {}; // { dg-message "user-provided default constructor" }
|
||||
|
||||
void f ()
|
||||
{
|
||||
B const b; // { dg-error "uninitialized const" }
|
||||
extern B const bext;
|
||||
|
||||
C const c[ 1 ]; // { dg-error "uninitialized const" }
|
||||
extern C const cext[ 1 ];
|
||||
|
||||
D const d;
|
||||
extern D const dext;
|
||||
|
||||
E const e; // { dg-error "uninitialized const" }
|
||||
extern E const eext;
|
||||
|
||||
F<int> const f; // { dg-error "uninitialized const" }
|
||||
extern F<int> const fext;
|
||||
|
||||
G<int> const g; // { dg-error "uninitialized const" }
|
||||
extern G<int> const gext;
|
||||
}
|
||||
|
||||
struct H {}; // { dg-message "user-provided default constructor" }
|
||||
|
||||
struct I : A {}; // { dg-message "user-provided default constructor" }
|
||||
|
||||
template <class T>
|
||||
void g ()
|
||||
{
|
||||
T const t; // { dg-error "uninitialized const" }
|
||||
extern T const text;
|
||||
}
|
||||
|
||||
template void g<H> ();
|
||||
template void g<I> ();
|
@ -13,6 +13,7 @@ struct E
|
||||
|
||||
struct F : public E
|
||||
{
|
||||
F () {}
|
||||
virtual ~F () {}
|
||||
virtual size_t e () const { return 0; }
|
||||
virtual void f (char *x) const { *x = '\0'; }
|
||||
|
@ -7,7 +7,11 @@ public:
|
||||
virtual ~Base() { }
|
||||
};
|
||||
|
||||
class Derived : public Base { };
|
||||
class Derived : public Base
|
||||
{
|
||||
public:
|
||||
Derived() {}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
|
@ -1,3 +1,13 @@
|
||||
2010-04-27 Fabien Chêne <fabien.chene@gmail.com>
|
||||
|
||||
* testsuite/util/testsuite_error.h: Add empty default constructor
|
||||
to __gnu_test::test_category and
|
||||
__gnu_test::test_derived_category.
|
||||
* src/future.cc: Add empty default constructor to
|
||||
future_error_category.
|
||||
* src/system_error.cc: Add default ctor to generic_error_category
|
||||
and system_error_category.
|
||||
|
||||
2010-04-27 Alexander Monakov <amonakov@ispras.ru>
|
||||
|
||||
* testsuite/22_locale/codecvt/unshift/char/1.c (test01): Clarify size
|
||||
|
@ -1,6 +1,6 @@
|
||||
// future -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
// Copyright (C) 2009, 2010 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
@ -28,6 +28,8 @@ namespace
|
||||
{
|
||||
struct future_error_category : public std::error_category
|
||||
{
|
||||
future_error_category() {}
|
||||
|
||||
virtual const char*
|
||||
name() const
|
||||
{ return "future"; }
|
||||
|
@ -34,6 +34,8 @@ namespace
|
||||
|
||||
struct generic_error_category : public std::error_category
|
||||
{
|
||||
generic_error_category() {}
|
||||
|
||||
virtual const char*
|
||||
name() const
|
||||
{ return "generic"; }
|
||||
@ -49,6 +51,8 @@ namespace
|
||||
|
||||
struct system_error_category : public std::error_category
|
||||
{
|
||||
system_error_category() {}
|
||||
|
||||
virtual const char*
|
||||
name() const
|
||||
{ return "system"; }
|
||||
|
@ -1,7 +1,7 @@
|
||||
// -*- C++ -*-
|
||||
// Error handling utils for the C++ library testsuite.
|
||||
//
|
||||
// Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
|
||||
// Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
@ -29,6 +29,8 @@ namespace __gnu_test
|
||||
{
|
||||
struct test_category : public std::error_category
|
||||
{
|
||||
test_category() {}
|
||||
|
||||
virtual const char*
|
||||
name() const
|
||||
{
|
||||
@ -43,6 +45,8 @@ namespace __gnu_test
|
||||
|
||||
struct test_derived_category : public test_category
|
||||
{
|
||||
test_derived_category() {}
|
||||
|
||||
virtual const char*
|
||||
name() const
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user