aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/method.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2019-10-05 09:38:21 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2019-10-05 09:38:21 +0200
commit8e007055dd1374ca4c44406a4ead172be0dfa3a8 (patch)
tree6d2808d70c3cd75cdf81b49e2d1d7495f7ae4516 /gcc/cp/method.c
parent0043b5280e6f571819d8764d76594a7a20467d00 (diff)
downloadgcc-8e007055dd1374ca4c44406a4ead172be0dfa3a8.zip
gcc-8e007055dd1374ca4c44406a4ead172be0dfa3a8.tar.gz
gcc-8e007055dd1374ca4c44406a4ead172be0dfa3a8.tar.bz2
PR c++/91369 - Implement P0784R7: constexpr new
PR c++/91369 - Implement P0784R7: constexpr new c-family/ * c-cppbuiltin.c (c_cpp_builtins): Predefine __cpp_constexpr_dynamic_alloc=201907 for -std=c++2a. cp/ * cp-tree.h (enum cp_tree_index): Add CPTI_HEAP_UNINIT_IDENTIFIER, CPTI_HEAP_IDENTIFIER and CPTI_HEAP_DELETED_IDENTIFIER. (heap_uninit_identifier, heap_identifier, heap_deleted_identifier): Define. (type_has_constexpr_destructor, build_new_constexpr_heap_type, cxx_constant_dtor): Declare. * class.c (type_maybe_constexpr_default_constructor): Make static. (type_maybe_constexpr_destructor, type_has_constexpr_destructor): New functions. (finalize_literal_type_property): For c++2a, don't clear CLASSTYPE_LITERAL_P for types without trivial destructors unless they have non-constexpr destructors. (explain_non_literal_class): For c++2a, complain about non-constexpr destructors rather than about non-trivial destructors. * constexpr.c: Include stor-layout.h. (struct constexpr_global_ctx): New type. (struct constexpr_ctx): Add global field, remove values and constexpr_ops_count. (cxx_replaceable_global_alloc_fn): New inline function. (cxx_eval_call_expression): For c++2a allow calls to replaceable global allocation functions, for new return address of a heap uninit var, for delete record its deletion. Change ctx->values->{get,put} to ctx->global->values.{get,put}. (non_const_var_error): Add auto_diagnostic_group sentinel. Emit special diagnostics for heap variables. (cxx_eval_store_expression): Change ctx->values->{get,put} to ctx->global->values.{get,put}. (cxx_eval_loop_expr): Initialize jump_target if NULL. Change new_ctx.values->remove to ctx->global->values.remove. (cxx_eval_constant_expression): Change *ctx->constexpr_ops_count to ctx->global->constexpr_ops_count. Change ctx->values->{get,put} to ctx->global->values.{get,put}. <case NOP_EXPR>: Formatting fix. On cast of replaceable global allocation function to some pointer type, adjust the type of the heap variable and change name from heap_uninit_identifier to heap_identifier. (find_heap_var_refs): New function. (cxx_eval_outermost_constant_expr): Add constexpr_dtor argument, handle evaluation of constexpr dtors and add tracking of heap variables. Use tf_no_cleanup for get_target_expr_with_sfinae. (cxx_constant_value): Adjust cxx_eval_outermost_constant_expr caller. (cxx_constant_dtor): New function. (maybe_constant_value, fold_non_dependent_expr_template, maybe_constant_init_1): Adjust cxx_eval_outermost_constant_expr callers. (potential_constant_expression_1): Ignore clobbers. Allow COND_EXPR_IS_VEC_DELETE for c++2a. * decl.c (initialize_predefined_identifiers): Add heap identifiers. (decl_maybe_constant_destruction): New function. (cp_finish_decl): Don't clear TREE_READONLY for constexpr variables with non-trivial, but constexpr destructors. (register_dtor_fn): For constexpr variables with constexpr non-trivial destructors call cxx_maybe_build_cleanup instead of adding destructor calls at runtime. (expand_static_init): For constexpr variables with constexpr non-trivial destructors call cxx_maybe_build_cleanup. (grokdeclarator): Allow constexpr destructors for c++2a. Formatting fix. (cxx_maybe_build_cleanup): For constexpr variables with constexpr non-trivial destructors call cxx_constant_dtor instead of adding destructor calls at runtime. * init.c: Include stor-layout.h. (build_new_constexpr_heap_type, maybe_wrap_new_for_constexpr): New functions. (build_new_1): For c++2a and new[], add cast around the alloc call to help constexpr evaluation figure out the type of the heap storage. (build_vec_delete_1): Set DECL_INITIAL of tbase and emit a DECL_EXPR for it instead of initializing an uninitialized variable. * method.c: Include intl.h. (SFK_CTOR_P, SFK_DTOR_P, SFK_ASSIGN_P, SFK_COPY_P, SFK_MOVE_P): Move definitions earlier. (process_subob_fn): Add sfk argument, adjust non-constexpr call diagnostics based on it. (walk_field_subobs): Formatting fixes. Adjust process_subob_fn caller. (synthesized_method_base_walk): Likewise. (synthesized_method_walk): Set *constexpr_p to true for dtors in c++2a. Fix up DR number in comment. (implicitly_declare_fn): Formatting fix. * typeck2.c (store_init_value): Don't call cp_fully_fold_init on initializers of automatic non-constexpr variables in constexpr functions. testsuite/ * g++.dg/cpp0x/constexpr-delete2.C: Adjust expected diagnostics for c++2a. * g++.dg/cpp0x/locations1.C: Only expect constexpr ~S() diagnostics in c++17_down, adjust expected wording. * g++.dg/cpp1y/constexpr-new.C: Only expect diagnostics in c++17_down. * g++.dg/cpp2a/constexpr-dtor1.C: New test. * g++.dg/cpp2a/constexpr-dtor2.C: New test. * g++.dg/cpp2a/constexpr-dtor3.C: New test. * g++.dg/cpp2a/constexpr-new1.C: New test. * g++.dg/cpp2a/constexpr-new2.C: New test. * g++.dg/cpp2a/constexpr-new3.C: New test. * g++.dg/cpp2a/constexpr-new4.C: New test. * g++.dg/cpp2a/feat-cxx2a.C: Add __cpp_constinit and __cpp_constexpr_dynamic_alloc tests. Tweak __cpp_* tests for c++2a features to use style like older features, including #ifdef test. * g++.dg/ext/is_literal_type3.C: New test. From-SVN: r276622
Diffstat (limited to 'gcc/cp/method.c')
-rw-r--r--gcc/cp/method.c69
1 files changed, 37 insertions, 32 deletions
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index 53fa85b..01bf534 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -30,6 +30,7 @@ along with GCC; see the file COPYING3. If not see
#include "cgraph.h"
#include "varasm.h"
#include "toplev.h"
+#include "intl.h"
#include "common/common-target.h"
static void do_build_copy_assign (tree);
@@ -1237,12 +1238,24 @@ is_xible (enum tree_code code, tree to, tree from)
return !!expr;
}
+/* Categorize various special_function_kinds. */
+#define SFK_CTOR_P(sfk) \
+ ((sfk) >= sfk_constructor && (sfk) <= sfk_move_constructor)
+#define SFK_DTOR_P(sfk) \
+ ((sfk) == sfk_destructor || (sfk) == sfk_virtual_destructor)
+#define SFK_ASSIGN_P(sfk) \
+ ((sfk) == sfk_copy_assignment || (sfk) == sfk_move_assignment)
+#define SFK_COPY_P(sfk) \
+ ((sfk) == sfk_copy_constructor || (sfk) == sfk_copy_assignment)
+#define SFK_MOVE_P(sfk) \
+ ((sfk) == sfk_move_constructor || (sfk) == sfk_move_assignment)
+
/* Subroutine of synthesized_method_walk. Update SPEC_P, TRIVIAL_P and
DELETED_P or give an error message MSG with argument ARG. */
static void
-process_subob_fn (tree fn, tree *spec_p, bool *trivial_p,
- bool *deleted_p, bool *constexpr_p,
+process_subob_fn (tree fn, special_function_kind sfk, tree *spec_p,
+ bool *trivial_p, bool *deleted_p, bool *constexpr_p,
bool diag, tree arg, bool dtor_from_ctor = false)
{
if (!fn || fn == error_mark_node)
@@ -1283,24 +1296,15 @@ process_subob_fn (tree fn, tree *spec_p, bool *trivial_p,
if (diag)
{
inform (DECL_SOURCE_LOCATION (fn),
- "defaulted constructor calls non-%<constexpr%> %qD", fn);
+ SFK_DTOR_P (sfk)
+ ? G_("defaulted destructor calls non-%<constexpr%> %qD")
+ : G_("defaulted constructor calls non-%<constexpr%> %qD"),
+ fn);
explain_invalid_constexpr_fn (fn);
}
}
}
-/* Categorize various special_function_kinds. */
-#define SFK_CTOR_P(sfk) \
- ((sfk) >= sfk_constructor && (sfk) <= sfk_move_constructor)
-#define SFK_DTOR_P(sfk) \
- ((sfk) == sfk_destructor || (sfk) == sfk_virtual_destructor)
-#define SFK_ASSIGN_P(sfk) \
- ((sfk) == sfk_copy_assignment || (sfk) == sfk_move_assignment)
-#define SFK_COPY_P(sfk) \
- ((sfk) == sfk_copy_constructor || (sfk) == sfk_copy_assignment)
-#define SFK_MOVE_P(sfk) \
- ((sfk) == sfk_move_constructor || (sfk) == sfk_move_assignment)
-
/* Subroutine of synthesized_method_walk to allow recursion into anonymous
aggregates. If DTOR_FROM_CTOR is true, we're walking subobject destructors
called from a synthesized constructor, in which case we don't consider
@@ -1318,8 +1322,7 @@ walk_field_subobs (tree fields, special_function_kind sfk, tree fnname,
{
tree mem_type, argtype, rval;
- if (TREE_CODE (field) != FIELD_DECL
- || DECL_ARTIFICIAL (field))
+ if (TREE_CODE (field) != FIELD_DECL || DECL_ARTIFICIAL (field))
continue;
/* Variant members only affect deletedness. In particular, they don't
@@ -1457,7 +1460,7 @@ walk_field_subobs (tree fields, special_function_kind sfk, tree fnname,
rval = locate_fn_flags (mem_type, fnname, argtype, flags, complain);
- process_subob_fn (rval, spec_p, trivial_p, deleted_p,
+ process_subob_fn (rval, sfk, spec_p, trivial_p, deleted_p,
constexpr_p, diag, field, dtor_from_ctor);
}
}
@@ -1510,23 +1513,23 @@ synthesized_method_base_walk (tree binfo, tree base_binfo,
&& DECL_CONTEXT (*inheriting_ctor) == DECL_CONTEXT (rval))
*inheriting_ctor = DECL_CLONED_FUNCTION (rval);
- process_subob_fn (rval, spec_p, trivial_p, deleted_p,
+ process_subob_fn (rval, sfk, spec_p, trivial_p, deleted_p,
constexpr_p, diag, BINFO_TYPE (base_binfo));
- if (SFK_CTOR_P (sfk) &&
- (!BINFO_VIRTUAL_P (base_binfo)
- || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (BINFO_TYPE (base_binfo))))
+ if (SFK_CTOR_P (sfk)
+ && (!BINFO_VIRTUAL_P (base_binfo)
+ || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (BINFO_TYPE (base_binfo))))
{
/* In a constructor we also need to check the subobject
destructors for cleanup of partially constructed objects. */
tree dtor = locate_fn_flags (base_binfo, complete_dtor_identifier,
NULL_TREE, flags,
diag ? tf_warning_or_error : tf_none);
- /* Note that we don't pass down trivial_p; the subobject
- destructors don't affect triviality of the constructor. Nor
- do they affect constexpr-ness (a constant expression doesn't
- throw) or exception-specification (a throw from one of the
- dtors would be a double-fault). */
- process_subob_fn (dtor, NULL, NULL, deleted_p, NULL, false,
+ /* Note that we don't pass down trivial_p; the subobject
+ destructors don't affect triviality of the constructor. Nor
+ do they affect constexpr-ness (a constant expression doesn't
+ throw) or exception-specification (a throw from one of the
+ dtors would be a double-fault). */
+ process_subob_fn (dtor, sfk, NULL, NULL, deleted_p, NULL, false,
BINFO_TYPE (base_binfo), /*dtor_from_ctor*/true);
}
@@ -1608,7 +1611,8 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
member is a constexpr function. */
if (constexpr_p)
*constexpr_p = (SFK_CTOR_P (sfk)
- || (SFK_ASSIGN_P (sfk) && cxx_dialect >= cxx14));
+ || (SFK_ASSIGN_P (sfk) && cxx_dialect >= cxx14)
+ || (SFK_DTOR_P (sfk) && cxx_dialect >= cxx2a));
bool expected_trivial = type_has_trivial_fn (ctype, sfk);
if (trivial_p)
@@ -1704,8 +1708,8 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
else if (vec_safe_is_empty (vbases))
/* No virtual bases to worry about. */;
else if (ABSTRACT_CLASS_TYPE_P (ctype) && cxx_dialect >= cxx14
- /* DR 1658 specifis that vbases of abstract classes are
- ignored for both ctors and dtors. Except DR 2338
+ /* DR 1658 specifies that vbases of abstract classes are
+ ignored for both ctors and dtors. Except DR 2336
overrides that skipping when determing the eh-spec of a
virtual destructor. */
&& sfk != sfk_virtual_destructor)
@@ -2046,7 +2050,8 @@ implicitly_declare_fn (special_function_kind kind, tree type,
constexpr_p = false;
/* A trivial copy/move constructor is also a constexpr constructor,
unless the class has virtual bases (7.1.5p4). */
- else if (trivial_p && cxx_dialect >= cxx11
+ else if (trivial_p
+ && cxx_dialect >= cxx11
&& (kind == sfk_copy_constructor
|| kind == sfk_move_constructor)
&& !CLASSTYPE_VBASECLASSES (type))