From 81c160c6f36e29dd25639f1a327d681c9c1a62ba Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 18 Apr 2016 15:00:00 -0400 Subject: [PATCH] re PR c++/70690 (r235002 miscompiles tcmalloc) PR c++/70690 PR c++/70528 * class.c (type_maybe_constexpr_default_constructor): New. (type_has_constexpr_default_constructor): Revert. From-SVN: r235165 --- gcc/cp/ChangeLog | 7 +++++++ gcc/cp/class.c | 29 +++++++++++++++++++++++------ gcc/testsuite/g++.dg/init/array41.C | 27 +++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/g++.dg/init/array41.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 1dd48b6de81..104da7b58d2 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2016-04-18 Jason Merrill + + PR c++/70690 + PR c++/70528 + * class.c (type_maybe_constexpr_default_constructor): New. + (type_has_constexpr_default_constructor): Revert. + 2016-04-16 Sandra Loosemore PR target/1078 diff --git a/gcc/cp/class.c b/gcc/cp/class.c index e6d5bb0fe9c..2c5ce7384da 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -214,6 +214,7 @@ static bool base_derived_from (tree, tree); static int empty_base_at_nonzero_offset_p (tree, tree, splay_tree); static tree end_of_base (tree); static tree get_vcall_index (tree, tree); +static bool type_maybe_constexpr_default_constructor (tree); /* Variables shared between class.c and call.c. */ @@ -3346,7 +3347,11 @@ add_implicitly_declared_members (tree t, tree* access_decls, CLASSTYPE_LAZY_DEFAULT_CTOR (t) = 1; if (cxx_dialect >= cxx11) TYPE_HAS_CONSTEXPR_CTOR (t) - = type_has_constexpr_default_constructor (t); + /* Don't force the declaration to get a hard answer; if the + definition would have made the class non-literal, it will still be + non-literal because of the base or member in question, and that + gives a better diagnostic. */ + = type_maybe_constexpr_default_constructor (t); } /* [class.ctor] @@ -5348,16 +5353,28 @@ type_has_constexpr_default_constructor (tree t) { if (!TYPE_HAS_COMPLEX_DFLT (t)) return trivial_default_constructor_is_constexpr (t); - /* Assume it's constexpr to avoid unnecessary instantiation; if the - definition would have made the class non-literal, it will still be - non-literal because of the base or member in question, and that - gives a better diagnostic. */ - return true; + /* Non-trivial, we need to check subobject constructors. */ + lazily_declare_fn (sfk_constructor, t); } fns = locate_ctor (t); return (fns && DECL_DECLARED_CONSTEXPR_P (fns)); } +/* Returns true iff class T has a constexpr default constructor or has an + implicitly declared default constructor that we can't tell if it's constexpr + without forcing a lazy declaration (which might cause undesired + instantiations). */ + +bool +type_maybe_constexpr_default_constructor (tree t) +{ + if (CLASS_TYPE_P (t) && CLASSTYPE_LAZY_DEFAULT_CTOR (t) + && TYPE_HAS_COMPLEX_DFLT (t)) + /* Assume it's constexpr. */ + return true; + return type_has_constexpr_default_constructor (t); +} + /* Returns true iff class TYPE has a virtual destructor. */ bool diff --git a/gcc/testsuite/g++.dg/init/array41.C b/gcc/testsuite/g++.dg/init/array41.C new file mode 100644 index 00000000000..e8ee18116a8 --- /dev/null +++ b/gcc/testsuite/g++.dg/init/array41.C @@ -0,0 +1,27 @@ +// PR c++/70690 +// { dg-do run } + +struct A { + A() {} +}; + +struct APadded : public A { + char pad[63]; +}; + +int f(); +int i = f(); +APadded cache[50]; +APadded *p = cache; + +int f() +{ + cache[0].pad[0] = 42; + return 1; +} + +int main() +{ + if (cache[0].pad[0] != 42) + __builtin_abort(); +} -- 2.30.2