aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/class.c
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2011-05-18 13:19:15 -0400
committerJason Merrill <jason@gcc.gnu.org>2011-05-18 13:19:15 -0400
commit0515f4d2ba0a438d1a6dadb6a88b7c6e5449a129 (patch)
tree610494ba7abd94cabdfb2a873151cbc9247c7d95 /gcc/cp/class.c
parent41d471d612cc2929a39553fea761e587ed3076ab (diff)
downloadgcc-0515f4d2ba0a438d1a6dadb6a88b7c6e5449a129.zip
gcc-0515f4d2ba0a438d1a6dadb6a88b7c6e5449a129.tar.gz
gcc-0515f4d2ba0a438d1a6dadb6a88b7c6e5449a129.tar.bz2
re PR c++/48948 ([C++0x] constexpr friend function cannot be defined in-class)
PR c++/48948 PR c++/49015 * class.c (finalize_literal_type_property): Do check for constexpr member functions of non-literal class. (finish_struct): Don't call check_deferred_constexpr_decls. * cp-tree.h: Don't declare it. (DECL_DEFERRED_CONSTEXPR_CHECK): Remove. * decl.c (grok_special_member_properties): Don't check it (grokfnedcl): Don't call validate_constexpr_fundecl. (start_preparsed_function): Do call it. * pt.c (tsubst_decl): Don't call it. (instantiate_class_template_1): Don't call check_deferred_constexpr_decls. * semantics.c (literal_type_p): Check for any incompleteness. (ensure_literal_type_for_constexpr_object): Likewise. (is_valid_constexpr_fn): Revert deferral changes. (validate_constexpr_fundecl): Likewise. (register_constexpr_fundef): Likewise. (check_deferred_constexpr_decls): Remove. From-SVN: r173869
Diffstat (limited to 'gcc/cp/class.c')
-rw-r--r--gcc/cp/class.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index dc2c509..4e52b18 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -4582,6 +4582,8 @@ type_requires_array_cookie (tree type)
static void
finalize_literal_type_property (tree t)
{
+ tree fn;
+
if (cxx_dialect < cxx0x
|| TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t)
/* FIXME These constraints seem unnecessary; remove from standard.
@@ -4591,6 +4593,18 @@ finalize_literal_type_property (tree t)
else if (CLASSTYPE_LITERAL_P (t) && !TYPE_HAS_TRIVIAL_DFLT (t)
&& !TYPE_HAS_CONSTEXPR_CTOR (t))
CLASSTYPE_LITERAL_P (t) = false;
+
+ if (!CLASSTYPE_LITERAL_P (t))
+ for (fn = TYPE_METHODS (t); fn; fn = DECL_CHAIN (fn))
+ if (DECL_DECLARED_CONSTEXPR_P (fn)
+ && TREE_CODE (fn) != TEMPLATE_DECL
+ && DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)
+ && !DECL_CONSTRUCTOR_P (fn))
+ {
+ DECL_DECLARED_CONSTEXPR_P (fn) = false;
+ if (!DECL_TEMPLATE_INFO (fn))
+ error ("enclosing class of %q+#D is not a literal type", fn);
+ }
}
/* Check the validity of the bases and members declared in T. Add any
@@ -5831,8 +5845,6 @@ finish_struct (tree t, tree attributes)
else
error ("trying to finish struct, but kicked out due to previous parse errors");
- check_deferred_constexpr_decls ();
-
if (processing_template_decl && at_function_scope_p ())
add_stmt (build_min (TAG_DEFN, t));