aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/init.c
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2021-09-13 10:37:49 -0700
committerIan Lance Taylor <iant@golang.org>2021-09-13 10:37:49 -0700
commite252b51ccde010cbd2a146485d8045103cd99533 (patch)
treee060f101cdc32bf5e520de8e5275db9d4236b74c /gcc/cp/init.c
parentf10c7c4596dda99d2ee872c995ae4aeda65adbdf (diff)
parent104c05c5284b7822d770ee51a7d91946c7e56d50 (diff)
downloadgcc-e252b51ccde010cbd2a146485d8045103cd99533.zip
gcc-e252b51ccde010cbd2a146485d8045103cd99533.tar.gz
gcc-e252b51ccde010cbd2a146485d8045103cd99533.tar.bz2
Merge from trunk revision 104c05c5284b7822d770ee51a7d91946c7e56d50.
Diffstat (limited to 'gcc/cp/init.c')
-rw-r--r--gcc/cp/init.c104
1 files changed, 71 insertions, 33 deletions
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 7d598f6..1426f9a 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -34,13 +34,13 @@ along with GCC; see the file COPYING3. If not see
#include "attribs.h"
#include "asan.h"
#include "stor-layout.h"
-#include "builtins.h"
+#include "pointer-query.h"
static bool begin_init_stmts (tree *, tree *);
static tree finish_init_stmts (bool, tree, tree);
static void construct_virtual_base (tree, tree);
-static void expand_aggr_init_1 (tree, tree, tree, tree, int, tsubst_flags_t);
-static void expand_default_init (tree, tree, tree, tree, int, tsubst_flags_t);
+static bool expand_aggr_init_1 (tree, tree, tree, tree, int, tsubst_flags_t);
+static bool expand_default_init (tree, tree, tree, tree, int, tsubst_flags_t);
static void perform_member_init (tree, tree);
static int member_init_ok_or_else (tree, tree, tree);
static void expand_virtual_init (tree, tree);
@@ -427,6 +427,11 @@ build_value_init_noctor (tree type, tsubst_flags_t complain)
== NULL_TREE))
continue;
+ /* Ignore unnamed zero-width bitfields. */
+ if (DECL_UNNAMED_BIT_FIELD (field)
+ && integer_zerop (DECL_SIZE (field)))
+ continue;
+
/* We could skip vfields and fields of types with
user-defined constructors, but I think that won't improve
performance at all; it should be simpler in general just
@@ -586,16 +591,21 @@ get_nsdmi (tree member, bool in_ctor, tsubst_flags_t complain)
bool pushed = false;
tree ctx = DECL_CONTEXT (member);
- if (!currently_open_class (ctx)
- && !LOCAL_CLASS_P (ctx))
+
+ processing_template_decl_sentinel ptds (/*reset*/false);
+ if (!currently_open_class (ctx))
{
- push_to_top_level ();
+ if (!LOCAL_CLASS_P (ctx))
+ push_to_top_level ();
+ else
+ /* push_to_top_level would lose the necessary function context,
+ just reset processing_template_decl. */
+ processing_template_decl = 0;
push_nested_class (ctx);
+ push_deferring_access_checks (dk_no_deferred);
pushed = true;
}
- gcc_checking_assert (!processing_template_decl);
-
inject_this_parameter (ctx, TYPE_UNQUALIFIED);
start_lambda_scope (member);
@@ -616,8 +626,10 @@ get_nsdmi (tree member, bool in_ctor, tsubst_flags_t complain)
if (pushed)
{
+ pop_deferring_access_checks ();
pop_nested_class ();
- pop_from_top_level ();
+ if (!LOCAL_CLASS_P (ctx))
+ pop_from_top_level ();
}
input_location = sloc;
@@ -1831,12 +1843,14 @@ build_aggr_init (tree exp, tree init, int flags, tsubst_flags_t complain)
is_global = begin_init_stmts (&stmt_expr, &compound_stmt);
destroy_temps = stmts_are_full_exprs_p ();
current_stmt_tree ()->stmts_are_full_exprs_p = 0;
- expand_aggr_init_1 (TYPE_BINFO (type), exp, exp,
- init, LOOKUP_NORMAL|flags, complain);
+ bool ok = expand_aggr_init_1 (TYPE_BINFO (type), exp, exp,
+ init, LOOKUP_NORMAL|flags, complain);
stmt_expr = finish_init_stmts (is_global, stmt_expr, compound_stmt);
current_stmt_tree ()->stmts_are_full_exprs_p = destroy_temps;
TREE_READONLY (exp) = was_const;
TREE_THIS_VOLATILE (exp) = was_volatile;
+ if (!ok)
+ return error_mark_node;
if ((VAR_P (exp) || TREE_CODE (exp) == PARM_DECL)
&& TREE_SIDE_EFFECTS (stmt_expr)
@@ -1847,7 +1861,7 @@ build_aggr_init (tree exp, tree init, int flags, tsubst_flags_t complain)
return stmt_expr;
}
-static void
+static bool
expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags,
tsubst_flags_t complain)
{
@@ -1882,6 +1896,9 @@ expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags,
happen for direct-initialization, too. */
init = digest_init (type, init, complain);
+ if (init == error_mark_node)
+ return false;
+
/* A CONSTRUCTOR of the target's type is a previously digested
initializer, whether that happened just above or in
cp_parser_late_parsing_nsdmi.
@@ -1903,7 +1920,7 @@ expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags,
init = build2 (INIT_EXPR, TREE_TYPE (exp), exp, init);
TREE_SIDE_EFFECTS (init) = 1;
finish_expr_stmt (init);
- return;
+ return true;
}
if (init && TREE_CODE (init) != TREE_LIST
@@ -1920,8 +1937,12 @@ expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags,
have already built up the constructor call so we could wrap it
in an exception region. */;
else
- init = ocp_convert (type, init, CONV_IMPLICIT|CONV_FORCE_TEMP,
- flags, complain | tf_no_cleanup);
+ {
+ init = ocp_convert (type, init, CONV_IMPLICIT|CONV_FORCE_TEMP,
+ flags, complain | tf_no_cleanup);
+ if (init == error_mark_node)
+ return false;
+ }
if (TREE_CODE (init) == MUST_NOT_THROW_EXPR)
/* We need to protect the initialization of a catch parm with a
@@ -1937,7 +1958,7 @@ expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags,
init = build2 (INIT_EXPR, TREE_TYPE (exp), exp, init);
TREE_SIDE_EFFECTS (init) = 1;
finish_expr_stmt (init);
- return;
+ return true;
}
if (init == NULL_TREE)
@@ -1975,6 +1996,8 @@ expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags,
&parms, binfo, flags,
complain);
base = fold_build_cleanup_point_expr (void_type_node, base);
+ if (complete == error_mark_node || base == error_mark_node)
+ return false;
rval = build_if_in_charge (complete, base);
}
else
@@ -1984,6 +2007,8 @@ expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags,
rval = build_special_member_call (exp, ctor_name, &parms, binfo, flags,
complain);
+ if (rval == error_mark_node)
+ return false;
}
if (parms != NULL)
@@ -2003,10 +2028,12 @@ expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags,
/* FIXME put back convert_to_void? */
if (TREE_SIDE_EFFECTS (rval))
finish_expr_stmt (rval);
+
+ return true;
}
/* This function is responsible for initializing EXP with INIT
- (if any).
+ (if any). Returns true on success, false on failure.
BINFO is the binfo of the type for who we are performing the
initialization. For example, if W is a virtual base class of A and B,
@@ -2025,7 +2052,7 @@ expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags,
FLAGS is just passed to `build_new_method_call'. See that function
for its description. */
-static void
+static bool
expand_aggr_init_1 (tree binfo, tree true_exp, tree exp, tree init, int flags,
tsubst_flags_t complain)
{
@@ -2051,7 +2078,7 @@ expand_aggr_init_1 (tree binfo, tree true_exp, tree exp, tree init, int flags,
if (init)
finish_expr_stmt (init);
gcc_assert (!cleanups);
- return;
+ return true;
}
/* List-initialization from {} becomes value-initialization for non-aggregate
@@ -2071,9 +2098,9 @@ expand_aggr_init_1 (tree binfo, tree true_exp, tree exp, tree init, int flags,
that's value-initialization. */
if (init == void_type_node)
{
- /* If the type has data but no user-provided ctor, we need to zero
+ /* If the type has data but no user-provided default ctor, we need to zero
out the object. */
- if (!type_has_user_provided_constructor (type)
+ if (type_has_non_user_provided_default_constructor (type)
&& !is_really_empty_class (type, /*ignore_vptr*/true))
{
tree field_size = NULL_TREE;
@@ -2089,7 +2116,7 @@ expand_aggr_init_1 (tree binfo, tree true_exp, tree exp, tree init, int flags,
/* If we don't need to mess with the constructor at all,
then we're done. */
if (! type_build_ctor_call (type))
- return;
+ return true;
/* Otherwise fall through and call the constructor. */
init = NULL_TREE;
@@ -2097,7 +2124,7 @@ expand_aggr_init_1 (tree binfo, tree true_exp, tree exp, tree init, int flags,
/* We know that expand_default_init can handle everything we want
at this point. */
- expand_default_init (binfo, true_exp, exp, init, flags, complain);
+ return expand_default_init (binfo, true_exp, exp, init, flags, complain);
}
/* Report an error if TYPE is not a user-defined, class type. If
@@ -2207,7 +2234,7 @@ build_offset_ref (tree type, tree member, bool address_p,
if (!ok)
return error_mark_node;
if (DECL_STATIC_FUNCTION_P (t))
- return t;
+ return member;
member = t;
}
else
@@ -3529,11 +3556,11 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
the arguments to the constructor call. */
{
/* CLEANUP is compiler-generated, so no diagnostics. */
- TREE_NO_WARNING (cleanup) = true;
+ suppress_warning (cleanup);
init_expr = build2 (TRY_CATCH_EXPR, void_type_node,
init_expr, cleanup);
/* Likewise, this try-catch is compiler-generated. */
- TREE_NO_WARNING (init_expr) = true;
+ suppress_warning (init_expr);
}
else
/* Ack! First we allocate the memory. Then we set our sentry
@@ -3555,7 +3582,7 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
sentry = TARGET_EXPR_SLOT (begin);
/* CLEANUP is compiler-generated, so no diagnostics. */
- TREE_NO_WARNING (cleanup) = true;
+ suppress_warning (cleanup);
TARGET_EXPR_CLEANUP (begin)
= build3 (COND_EXPR, void_type_node, sentry,
@@ -3569,7 +3596,7 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
build2 (COMPOUND_EXPR, void_type_node, init_expr,
end));
/* Likewise, this is compiler-generated. */
- TREE_NO_WARNING (init_expr) = true;
+ suppress_warning (init_expr);
}
}
}
@@ -3816,7 +3843,7 @@ build_new (location_t loc, vec<tree, va_gc> **placement, tree type,
/* Wrap it in a NOP_EXPR so warn_if_unused_value doesn't complain. */
rval = build1_loc (loc, NOP_EXPR, TREE_TYPE (rval), rval);
- TREE_NO_WARNING (rval) = 1;
+ suppress_warning (rval, OPT_Wunused_value);
return rval;
}
@@ -3988,7 +4015,7 @@ build_vec_delete_1 (location_t loc, tree base, tree maxindex, tree type,
fold_convert (TREE_TYPE (base), nullptr_node));
/* This is a compiler generated comparison, don't emit
e.g. -Wnonnull-compare warning for it. */
- TREE_NO_WARNING (cond) = 1;
+ suppress_warning (cond, OPT_Wnonnull_compare);
body = build3_loc (loc, COND_EXPR, void_type_node,
cond, body, integer_zero_node);
COND_EXPR_IS_VEC_DELETE (body) = true;
@@ -4215,6 +4242,14 @@ build_vec_init (tree base, tree maxindex, tree init,
else
ptype = atype;
+ if (integer_all_onesp (maxindex))
+ {
+ /* Shortcut zero element case to avoid unneeded constructor synthesis. */
+ if (init && TREE_SIDE_EFFECTS (init))
+ base = build2 (COMPOUND_EXPR, ptype, init, base);
+ return base;
+ }
+
/* The code we are generating looks like:
({
T* t1 = (T*) base;
@@ -4650,7 +4685,7 @@ build_vec_init (tree base, tree maxindex, tree init,
atype = build_pointer_type (atype);
stmt_expr = build1 (NOP_EXPR, atype, stmt_expr);
stmt_expr = cp_build_fold_indirect_ref (stmt_expr);
- TREE_NO_WARNING (stmt_expr) = 1;
+ suppress_warning (stmt_expr /* What warning? */);
}
return stmt_expr;
@@ -4874,7 +4909,10 @@ build_delete (location_t loc, tree otype, tree addr,
complain);
}
- if (!destroying_delete && type_build_dtor_call (type))
+ if (destroying_delete)
+ /* The operator delete will call the destructor. */
+ expr = addr;
+ else if (type_build_dtor_call (type))
expr = build_dtor_call (cp_build_fold_indirect_ref (addr),
auto_delete, flags, complain);
else
@@ -4917,7 +4955,7 @@ build_delete (location_t loc, tree otype, tree addr,
/* This is a compiler generated comparison, don't emit
e.g. -Wnonnull-compare warning for it. */
else if (TREE_CODE (ifexp) == NE_EXPR)
- TREE_NO_WARNING (ifexp) = 1;
+ suppress_warning (ifexp, OPT_Wnonnull_compare);
if (!integer_nonzerop (ifexp))
expr = build3 (COND_EXPR, void_type_node, ifexp, expr, void_node);