aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMartin Liska <mliska@suse.cz>2021-06-03 12:52:48 +0200
committerMartin Liska <mliska@suse.cz>2021-06-03 12:52:48 +0200
commit022cc8a989a810c5aaf9e1690f7bc2a510e2e64c (patch)
tree6eaaf5f0f28175a7e3924bfb0cb40fcb3e645b34 /gcc
parent0d9e5270f10a21bd5549f3dd12a3b0c7c5f83362 (diff)
parentc1681f22b4b44096f7bd8a2cf42f54762305c3ae (diff)
downloadgcc-022cc8a989a810c5aaf9e1690f7bc2a510e2e64c.zip
gcc-022cc8a989a810c5aaf9e1690f7bc2a510e2e64c.tar.gz
gcc-022cc8a989a810c5aaf9e1690f7bc2a510e2e64c.tar.bz2
Merge branch 'master' into devel/sphinx
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog64
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/c/c-typeck.c7
-rw-r--r--gcc/common.opt11
-rw-r--r--gcc/config/arc/arc.md28
-rw-r--r--gcc/config/rs6000/rs6000-logue.c11
-rw-r--r--gcc/config/xtensa/xtensa.h7
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/call.c6
-rw-r--r--gcc/cp/pt.c1
-rw-r--r--gcc/cp/semantics.c28
-rw-r--r--gcc/dwarf2out.c345
-rw-r--r--gcc/opts.c41
-rw-r--r--gcc/ree.c30
-rw-r--r--gcc/testsuite/ChangeLog19
-rw-r--r--gcc/testsuite/g++.dg/gomp/depend-iterator-3.C43
-rw-r--r--gcc/testsuite/g++.dg/gomp/this-1.C16
-rw-r--r--gcc/testsuite/g++.dg/init/no-elide2.C32
-rw-r--r--gcc/testsuite/gcc.dg/spellcheck-options-23.c5
-rw-r--r--gcc/testsuite/gcc.target/aarch64/cpunative/info_162
-rw-r--r--gcc/testsuite/gcc.target/aarch64/cpunative/info_172
-rw-r--r--gcc/testsuite/gnat.dg/inline22.adb19
-rw-r--r--gcc/tree-inline.c36
23 files changed, 523 insertions, 240 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ef69e6a..5d118a5 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,67 @@
+2021-06-02 Christoph Muellner <cmuellner@gcc.gnu.org>
+
+ PR rtl-optimization/100264
+ * ree.c (get_sub_rtx): Ignore SET expressions without register
+ destinations and remove assertion, as it is not valid anymore
+ with this new behaviour.
+ (merge_def_and_ext): Eliminate destination check for register
+ as such SET expressions can't occur anymore.
+ (combine_reaching_defs): Likewise.
+
+2021-06-02 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/100841
+ * config/xtensa/xtensa.h (LEAF_REG_REMAP): Cast REGNO to int to avoid
+ -Wtype-limits warnings.
+ (DWARF_FRAME_REGISTER): Rewrite into ternary operator with addition
+ in operands to avoid -Wsign-compare warnings.
+
+2021-06-02 Pat Haugen <pthaugen@linux.ibm.com>
+
+ * config/rs6000/rs6000-logue.c (rs6000_emit_prologue): Use
+ gen_frame_store.
+
+2021-06-02 Vineet Gupta <vgupta@synopsys.com>
+
+ * config/arc/arc.h (TARGET_CPU_DEFAULT): Change to hs38_linux.
+
+2021-06-02 Ilya Leoshkevich <iii@linux.ibm.com>
+
+ * config/s390/s390.md(*ashrdi3_31<setcc><cconly>): Use a single
+ constraint.
+ * config/s390/subst.md(cconly_subst): Use a single constraint
+ in (match_scratch).
+
+2021-06-02 Martin Liska <mliska@suse.cz>
+
+ * ipa-icf.h: Use auto_vec for memory_access_types.
+
+2021-06-02 Jeff Law <jeffreyalaw@gmail.com>
+
+ * config/h8300/h8300-protos.h (compute_a_shift_length): Drop unused
+ argument from prototype.
+ (output_logical_op): Add rtx_code argument.
+ (compute_logical_op_length): Likewise.
+ * config/h8300/h8300.c (h8300_and_costs): Pass additional argument
+ to compute_a_shift_length.
+ (output_logical_op); New argument with the rtx code rather than
+ extracting it from an operand. Handle QImode too.
+ (compute_logical_op_length): Similary.
+ (compute_a_shift_length): Drop unused argument.
+ * config/h8300/h8300.md (logicals): New code iterator.
+ * config/h8300/logical.md (<code><mode>3 expander): Combine
+ the "and" expander with the "ior"/"xor" expander.
+ (bclr<mode>msx): Combine the QI/HI mode patterns.
+ (<logical><mode>3 insns): Use code iterator rather than match_operator.
+ Handle QImode as well. Update call to output_logical_op and
+ compute_logical_op_length to pass in rtx_code
+ Fix split condition on all define_insn_and_split patterns.
+ (one_cmpl<mode>2<cczn>): Use <cczn> to support both clobbering
+ the flags and setting ZN via existing define_subst.
+ * config/h8300/shiftrotate.md: Drop unused argument from
+ calls to compute_a_shift_length.
+ Signed-off-by: Jeff Law <jeffreyalaw@gmail.com>
+
2021-06-01 Andrew Pinski <apinski@marvell.com>
PR tree-optimization/25290
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 54b764a..d185478 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20210602
+20210603
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 5f32287..be3f4f0 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -14557,7 +14557,6 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
}
break;
- case OMP_CLAUSE_AFFINITY:
case OMP_CLAUSE_DEPEND:
t = OMP_CLAUSE_DECL (c);
if (t == NULL_TREE)
@@ -14566,8 +14565,7 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
== OMP_CLAUSE_DEPEND_SOURCE);
break;
}
- if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
- && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
+ if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
{
gcc_assert (TREE_CODE (t) == TREE_LIST);
for (; t; t = TREE_CHAIN (t))
@@ -14595,6 +14593,9 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
}
break;
}
+ /* FALLTHRU */
+ case OMP_CLAUSE_AFFINITY:
+ t = OMP_CLAUSE_DECL (c);
if (TREE_CODE (t) == TREE_LIST
&& TREE_PURPOSE (t)
&& TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
diff --git a/gcc/common.opt b/gcc/common.opt
index ffb968d..7f5fc39 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -1037,9 +1037,18 @@ Common Driver Joined
Select what to sanitize.
fsanitize-coverage=
-Common Joined
+Common Joined RejectNegative Enum(sanitize_coverage)
Select type of coverage sanitization.
+Enum
+Name(sanitize_coverage) Type(int)
+
+EnumValue
+Enum(sanitize_coverage) String(trace-pc) Value(SANITIZE_COV_TRACE_PC)
+
+EnumValue
+Enum(sanitize_coverage) String(trace-cmp) Value(SANITIZE_COV_TRACE_CMP)
+
fasan-shadow-offset=
Common Joined RejectNegative Var(common_deferred_options) Defer
-fasan-shadow-offset=<number> Use custom shadow memory offset.
diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
index b6f2d8e..a67bb58 100644
--- a/gcc/config/arc/arc.md
+++ b/gcc/config/arc/arc.md
@@ -5016,34 +5016,6 @@ core_3, archs4x, archs4xd, archs4xd_slow"
(if_then_else (match_test "get_attr_length (insn) == 6")
(const_string "true") (const_string "false")))])
-; ??? When testing a bit from a DImode register, combine creates a
-; zero_extract in DImode. This goes via an AND with a DImode constant,
-; so can only be observed on 64 bit hosts.
-(define_insn_and_split "*bbit_di"
- [(set (pc)
- (if_then_else
- (match_operator 3 "equality_comparison_operator"
- [(zero_extract:DI (match_operand:SI 1 "register_operand" "Rcqq,c")
- (const_int 1)
- (match_operand 2 "immediate_operand" "L,L"))
- (const_int 0)])
- (label_ref (match_operand 0 "" ""))
- (pc)))
- (clobber (reg:CC_ZN CC_REG))]
- "!CROSSING_JUMP_P (insn)"
- "#"
- ""
- [(parallel
- [(set (pc) (if_then_else (match_dup 3) (label_ref (match_dup 0)) (pc)))
- (clobber (reg:CC_ZN CC_REG))])]
-{
- rtx xtr;
-
- xtr = gen_rtx_ZERO_EXTRACT (SImode, operands[1], const1_rtx, operands[2]);
- operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
- xtr, const0_rtx);
-})
-
;; -------------------------------------------------------------------
;; Hardware loop
;; -------------------------------------------------------------------
diff --git a/gcc/config/rs6000/rs6000-logue.c b/gcc/config/rs6000/rs6000-logue.c
index 13c00e7..07337c4 100644
--- a/gcc/config/rs6000/rs6000-logue.c
+++ b/gcc/config/rs6000/rs6000-logue.c
@@ -3257,7 +3257,7 @@ rs6000_emit_prologue (void)
if (!WORLD_SAVE_P (info) && info->lr_save_p
&& !cfun->machine->lr_is_wrapped_separately)
{
- rtx addr, reg, mem;
+ rtx reg;
reg = gen_rtx_REG (Pmode, 0);
START_USE (0);
@@ -3267,13 +3267,8 @@ rs6000_emit_prologue (void)
if (!(strategy & (SAVE_NOINLINE_GPRS_SAVES_LR
| SAVE_NOINLINE_FPRS_SAVES_LR)))
{
- addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
- GEN_INT (info->lr_save_offset + frame_off));
- mem = gen_rtx_MEM (Pmode, addr);
- /* This should not be of rs6000_sr_alias_set, because of
- __builtin_return_address. */
-
- insn = emit_move_insn (mem, reg);
+ insn = emit_insn (gen_frame_store (reg, frame_reg_rtx,
+ info->lr_save_offset + frame_off));
rs6000_frame_related (insn, frame_reg_rtx, sp_off - frame_off,
NULL_RTX, NULL_RTX);
END_USE (0);
diff --git a/gcc/config/xtensa/xtensa.h b/gcc/config/xtensa/xtensa.h
index b01f6af..923ab5a 100644
--- a/gcc/config/xtensa/xtensa.h
+++ b/gcc/config/xtensa/xtensa.h
@@ -279,7 +279,7 @@ extern const char xtensa_leaf_regs[FIRST_PSEUDO_REGISTER];
/* For Xtensa, no remapping is necessary, but this macro must be
defined if LEAF_REGISTERS is defined. */
-#define LEAF_REG_REMAP(REGNO) (REGNO)
+#define LEAF_REG_REMAP(REGNO) ((int) (REGNO))
/* This must be declared if LEAF_REGISTERS is set. */
extern int leaf_function;
@@ -775,8 +775,9 @@ typedef struct xtensa_args
#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, 0)
#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (0)
#define DWARF_ALT_FRAME_RETURN_COLUMN 16
-#define DWARF_FRAME_REGISTERS (DWARF_ALT_FRAME_RETURN_COLUMN \
- + (TARGET_WINDOWED_ABI ? 0 : 1))
+#define DWARF_FRAME_REGISTERS (TARGET_WINDOWED_ABI \
+ ? DWARF_ALT_FRAME_RETURN_COLUMN \
+ : DWARF_ALT_FRAME_RETURN_COLUMN + 1)
#define EH_RETURN_DATA_REGNO(N) ((N) < 2 ? (N) + 2 : INVALID_REGNUM)
#define ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL) \
(flag_pic \
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 9a5fa79..e40cc6b 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,11 @@
+2021-06-02 Jason Merrill <jason@redhat.com>
+
+ PR c++/100838
+ * call.c (convert_like_internal): Clear tf_no_cleanup when
+ recursing.
+ (build_user_type_conversion_1): Only add ck_rvalue if
+ LOOKUP_ONLYCONVERTING.
+
2021-06-01 Patrick Palka <ppalka@redhat.com>
PR c++/65816
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 90192b1..17fc60c 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -4110,7 +4110,7 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags,
{
cand->second_conv = build_identity_conv (totype, NULL_TREE);
- /* If totype isn't a reference, and LOOKUP_NO_TEMP_BIND isn't
+ /* If totype isn't a reference, and LOOKUP_ONLYCONVERTING is
set, then this is copy-initialization. In that case, "The
result of the call is then used to direct-initialize the
object that is the destination of the copy-initialization."
@@ -4119,6 +4119,8 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags,
We represent this in the conversion sequence with an
rvalue conversion, which means a constructor call. */
if (!TYPE_REF_P (totype)
+ && cxx_dialect < cxx17
+ && (flags & LOOKUP_ONLYCONVERTING)
&& !(convflags & LOOKUP_NO_TEMP_BIND))
cand->second_conv
= build_conv (ck_rvalue, totype, cand->second_conv);
@@ -7800,7 +7802,7 @@ convert_like_internal (conversion *convs, tree expr, tree fn, int argnum,
expr = convert_like (next_conversion (convs), expr, fn, argnum,
convs->kind == ck_ref_bind
? issue_conversion_warnings : false,
- c_cast_p, complain);
+ c_cast_p, complain & ~tf_no_cleanup);
if (expr == error_mark_node)
return error_mark_node;
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 3130280..15ef488 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -17399,6 +17399,7 @@ tsubst_omp_clauses (tree clauses, enum c_omp_region_type ort,
case OMP_CLAUSE_COPYPRIVATE:
case OMP_CLAUSE_UNIFORM:
case OMP_CLAUSE_DEPEND:
+ case OMP_CLAUSE_AFFINITY:
case OMP_CLAUSE_FROM:
case OMP_CLAUSE_TO:
case OMP_CLAUSE_MAP:
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index e40462d..d08c1dd 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -4968,7 +4968,11 @@ handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types,
if (REFERENCE_REF_P (t))
t = TREE_OPERAND (t, 0);
}
- if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL)
+ if (TREE_CODE (t) == FIELD_DECL
+ && (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY
+ || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND))
+ ret = finish_non_static_data_member (t, NULL_TREE, NULL_TREE);
+ else if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL)
{
if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
return NULL_TREE;
@@ -4985,7 +4989,9 @@ handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types,
else if (ort == C_ORT_OMP
&& TREE_CODE (t) == PARM_DECL
&& DECL_ARTIFICIAL (t)
- && DECL_NAME (t) == this_identifier)
+ && DECL_NAME (t) == this_identifier
+ && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_AFFINITY
+ && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND)
{
error_at (OMP_CLAUSE_LOCATION (c),
"%<this%> allowed in OpenMP only in %<declare simd%>"
@@ -7468,7 +7474,6 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
}
goto handle_field_decl;
- case OMP_CLAUSE_AFFINITY:
case OMP_CLAUSE_DEPEND:
t = OMP_CLAUSE_DECL (c);
if (t == NULL_TREE)
@@ -7477,13 +7482,15 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
== OMP_CLAUSE_DEPEND_SOURCE);
break;
}
- if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
- && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
+ if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
{
if (cp_finish_omp_clause_depend_sink (c))
remove = true;
break;
}
+ /* FALLTHRU */
+ case OMP_CLAUSE_AFFINITY:
+ t = OMP_CLAUSE_DECL (c);
if (TREE_CODE (t) == TREE_LIST
&& TREE_PURPOSE (t)
&& TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
@@ -7516,13 +7523,6 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
}
if (t == error_mark_node)
remove = true;
- else if (ort != C_ORT_ACC && t == current_class_ptr)
- {
- error_at (OMP_CLAUSE_LOCATION (c),
- "%<this%> allowed in OpenMP only in %<declare simd%>"
- " clauses");
- remove = true;
- }
else if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
break;
else if (!lvalue_p (t))
@@ -7543,11 +7543,9 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
&& TREE_CODE (TREE_OPERAND (t, 1)) == FIELD_DECL
&& DECL_BIT_FIELD (TREE_OPERAND (t, 1)))
{
- gcc_assert (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
- || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY);
error_at (OMP_CLAUSE_LOCATION (c),
"bit-field %qE in %qs clause", t,
- omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
+ omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
remove = true;
}
else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index b99598e..88eb3f9 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -15176,7 +15176,7 @@ scompare_loc_descriptor_narrow (enum dwarf_location_atom op, rtx rtl,
return compare_loc_descriptor (op, op0, op1);
}
-/* Return location descriptor for unsigned comparison OP RTL. */
+/* Return location descriptor for signed comparison OP RTL. */
static dw_loc_descr_ref
scompare_loc_descriptor (enum dwarf_location_atom op, rtx rtl,
@@ -16407,11 +16407,13 @@ mem_loc_descriptor (rtx rtl, machine_mode mode,
if ((!dwarf_strict || dwarf_version >= 5)
&& is_a <scalar_int_mode> (mode, &int_mode))
{
- if (GET_MODE_SIZE (int_mode) > DWARF2_ADDR_SIZE)
+ /* We can use a signed divide if the sign bit is not set. */
+ if (GET_MODE_SIZE (int_mode) < DWARF2_ADDR_SIZE)
{
op = DW_OP_div;
goto do_binop;
}
+
mem_loc_result = typed_binop (DW_OP_div, rtl,
base_type_for_mode (int_mode, 1),
int_mode, mem_mode);
@@ -17994,6 +17996,8 @@ struct loc_descr_context
bool placeholder_arg;
/* True if PLACEHOLDER_EXPR has been seen. */
bool placeholder_seen;
+ /* True if strict preservation of signedness has been requested. */
+ bool strict_signedness;
};
/* DWARF procedures generation
@@ -18062,7 +18066,7 @@ new_dwarf_proc_die (dw_loc_descr_ref location, tree fndecl,
/* Return whether TYPE is a supported type as a DWARF procedure argument
type or return type (we handle only scalar types and pointer types that
- aren't wider than the DWARF expression evaluation stack. */
+ aren't wider than the DWARF expression evaluation stack). */
static bool
is_handled_procedure_type (tree type)
@@ -18204,6 +18208,12 @@ resolve_args_picking_1 (dw_loc_descr_ref loc, unsigned initial_frame_offset,
case DW_OP_bit_piece:
case DW_OP_implicit_value:
case DW_OP_stack_value:
+ case DW_OP_deref_type:
+ case DW_OP_convert:
+ case DW_OP_reinterpret:
+ case DW_OP_GNU_deref_type:
+ case DW_OP_GNU_convert:
+ case DW_OP_GNU_reinterpret:
break;
case DW_OP_addr:
@@ -18335,9 +18345,6 @@ resolve_args_picking_1 (dw_loc_descr_ref loc, unsigned initial_frame_offset,
case DW_OP_entry_value:
case DW_OP_const_type:
case DW_OP_regval_type:
- case DW_OP_deref_type:
- case DW_OP_convert:
- case DW_OP_reinterpret:
case DW_OP_form_tls_address:
case DW_OP_GNU_push_tls_address:
case DW_OP_GNU_uninit:
@@ -18346,9 +18353,6 @@ resolve_args_picking_1 (dw_loc_descr_ref loc, unsigned initial_frame_offset,
case DW_OP_GNU_entry_value:
case DW_OP_GNU_const_type:
case DW_OP_GNU_regval_type:
- case DW_OP_GNU_deref_type:
- case DW_OP_GNU_convert:
- case DW_OP_GNU_reinterpret:
case DW_OP_GNU_parameter_ref:
/* loc_list_from_tree will probably not output these operations for
size functions, so assume they will not appear here. */
@@ -18397,8 +18401,8 @@ resolve_args_picking (dw_loc_descr_ref loc, unsigned initial_frame_offset,
this operation. */
hash_map<dw_loc_descr_ref, unsigned> frame_offsets;
- return resolve_args_picking_1 (loc, initial_frame_offset, dpi,
- frame_offsets);
+ return
+ resolve_args_picking_1 (loc, initial_frame_offset, dpi, frame_offsets);
}
/* Try to generate a DWARF procedure that computes the same result as FNDECL.
@@ -18407,8 +18411,15 @@ resolve_args_picking (dw_loc_descr_ref loc, unsigned initial_frame_offset,
static dw_die_ref
function_to_dwarf_procedure (tree fndecl)
{
- struct loc_descr_context ctx;
struct dwarf_procedure_info dpi;
+ struct loc_descr_context ctx = {
+ NULL_TREE, /* context_type */
+ NULL_TREE, /* base_decl */
+ &dpi, /* dpi */
+ false, /* placeholder_arg */
+ false, /* placeholder_seen */
+ true /* strict_signedness */
+ };
dw_die_ref dwarf_proc_die;
tree tree_body = DECL_SAVED_TREE (fndecl);
dw_loc_descr_ref loc_body, epilogue;
@@ -18453,11 +18464,6 @@ function_to_dwarf_procedure (tree fndecl)
cause an infinite recursion if its call graph has a cycle. This is very
unlikely for size functions, however, so don't bother with such things at
the moment. */
- ctx.context_type = NULL_TREE;
- ctx.base_decl = NULL_TREE;
- ctx.dpi = &dpi;
- ctx.placeholder_arg = false;
- ctx.placeholder_seen = false;
dpi.fndecl = fndecl;
dpi.args_count = list_length (DECL_ARGUMENTS (fndecl));
loc_body = loc_descriptor_from_tree (tree_body, 0, &ctx);
@@ -18499,6 +18505,48 @@ function_to_dwarf_procedure (tree fndecl)
return dwarf_proc_die;
}
+/* Helper function for loc_list_from_tree. Perform OP binary op,
+ but after converting arguments to type_die, afterwards convert
+ back to unsigned. */
+
+static dw_loc_list_ref
+typed_binop_from_tree (enum dwarf_location_atom op, tree loc,
+ dw_die_ref type_die, scalar_int_mode mode,
+ struct loc_descr_context *context)
+{
+ dw_loc_list_ref op0, op1;
+ dw_loc_descr_ref cvt, binop;
+
+ if (type_die == NULL)
+ return NULL;
+
+ op0 = loc_list_from_tree (TREE_OPERAND (loc, 0), 0, context);
+ op1 = loc_list_from_tree (TREE_OPERAND (loc, 1), 0, context);
+ if (op0 == NULL || op1 == NULL)
+ return NULL;
+
+ cvt = new_loc_descr (dwarf_OP (DW_OP_convert), 0, 0);
+ cvt->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
+ cvt->dw_loc_oprnd1.v.val_die_ref.die = type_die;
+ cvt->dw_loc_oprnd1.v.val_die_ref.external = 0;
+ add_loc_descr_to_each (op0, cvt);
+
+ cvt = new_loc_descr (dwarf_OP (DW_OP_convert), 0, 0);
+ cvt->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
+ cvt->dw_loc_oprnd1.v.val_die_ref.die = type_die;
+ cvt->dw_loc_oprnd1.v.val_die_ref.external = 0;
+ add_loc_descr_to_each (op1, cvt);
+
+ add_loc_list (&op0, op1);
+ if (op0 == NULL)
+ return NULL;
+
+ binop = new_loc_descr (op, 0, 0);
+ convert_descriptor_to_mode (mode, binop);
+ add_loc_descr_to_each (op0, binop);
+
+ return op0;
+}
/* Generate Dwarf location list representing LOC.
If WANT_ADDRESS is false, expression computing LOC will be computed
@@ -18586,47 +18634,48 @@ loc_list_from_tree_1 (tree loc, int want_address,
case CALL_EXPR:
{
- const int nargs = call_expr_nargs (loc);
tree callee = get_callee_fndecl (loc);
- int i;
dw_die_ref dwarf_proc;
- if (callee == NULL_TREE)
- goto call_expansion_failed;
-
- /* We handle only functions that return an integer. */
- if (!is_handled_procedure_type (TREE_TYPE (TREE_TYPE (callee))))
- goto call_expansion_failed;
-
- dwarf_proc = function_to_dwarf_procedure (callee);
- if (dwarf_proc == NULL)
- goto call_expansion_failed;
-
- /* Evaluate arguments right-to-left so that the first argument will
- be the top-most one on the stack. */
- for (i = nargs - 1; i >= 0; --i)
+ if (callee
+ && is_handled_procedure_type (TREE_TYPE (TREE_TYPE (callee)))
+ && (dwarf_proc = function_to_dwarf_procedure (callee)))
{
- dw_loc_descr_ref loc_descr
- = loc_descriptor_from_tree (CALL_EXPR_ARG (loc, i), 0,
- context);
+ /* DWARF procedures are used for size functions, which are built
+ when size expressions contain conditional constructs, so we
+ request strict preservation of signedness for comparisons. */
+ bool old_strict_signedness;
+ if (context)
+ {
+ old_strict_signedness = context->strict_signedness;
+ context->strict_signedness = true;
+ }
- if (loc_descr == NULL)
- goto call_expansion_failed;
+ /* Evaluate arguments right-to-left so that the first argument
+ will be the top-most one on the stack. */
+ for (int i = call_expr_nargs (loc) - 1; i >= 0; --i)
+ {
+ tree arg = CALL_EXPR_ARG (loc, i);
+ ret1 = loc_descriptor_from_tree (arg, 0, context);
+ if (!ret1)
+ {
+ expansion_failed (arg, NULL_RTX, "CALL_EXPR argument");
+ return NULL;
+ }
+ add_loc_descr (&ret, ret1);
+ }
- add_loc_descr (&ret, loc_descr);
+ ret1 = new_loc_descr (DW_OP_call4, 0, 0);
+ ret1->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
+ ret1->dw_loc_oprnd1.v.val_die_ref.die = dwarf_proc;
+ ret1->dw_loc_oprnd1.v.val_die_ref.external = 0;
+ add_loc_descr (&ret, ret1);
+ if (context)
+ context->strict_signedness = old_strict_signedness;
}
-
- ret1 = new_loc_descr (DW_OP_call4, 0, 0);
- ret1->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
- ret1->dw_loc_oprnd1.v.val_die_ref.die = dwarf_proc;
- ret1->dw_loc_oprnd1.v.val_die_ref.external = 0;
- add_loc_descr (&ret, ret1);
+ else
+ expansion_failed (loc, NULL_RTX, "CALL_EXPR target");
break;
-
- call_expansion_failed:
- expansion_failed (loc, NULL_RTX, "CALL_EXPR");
- /* There are no opcodes for these operations. */
- return 0;
}
case PREINCREMENT_EXPR:
@@ -18780,25 +18829,25 @@ loc_list_from_tree_1 (tree loc, int want_address,
{
if (TREE_CODE (loc) != FUNCTION_DECL
&& early_dwarf
- && current_function_decl
&& want_address != 1
&& ! DECL_IGNORED_P (loc)
&& (INTEGRAL_TYPE_P (TREE_TYPE (loc))
|| POINTER_TYPE_P (TREE_TYPE (loc)))
- && DECL_CONTEXT (loc) == current_function_decl
&& (GET_MODE_SIZE (SCALAR_INT_TYPE_MODE (TREE_TYPE (loc)))
<= DWARF2_ADDR_SIZE))
{
dw_die_ref ref = lookup_decl_die (loc);
- ret = new_loc_descr (DW_OP_GNU_variable_value, 0, 0);
if (ref)
{
+ ret = new_loc_descr (DW_OP_GNU_variable_value, 0, 0);
ret->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
ret->dw_loc_oprnd1.v.val_die_ref.die = ref;
ret->dw_loc_oprnd1.v.val_die_ref.external = 0;
}
- else
+ else if (current_function_decl
+ && DECL_CONTEXT (loc) == current_function_decl)
{
+ ret = new_loc_descr (DW_OP_GNU_variable_value, 0, 0);
ret->dw_loc_oprnd1.val_class = dw_val_class_decl_ref;
ret->dw_loc_oprnd1.v.val_decl_ref = loc;
}
@@ -19091,13 +19140,53 @@ loc_list_from_tree_1 (tree loc, int want_address,
op = DW_OP_or;
goto do_binop;
+ case EXACT_DIV_EXPR:
case FLOOR_DIV_EXPR:
+ case TRUNC_DIV_EXPR:
+ /* Turn a divide by a power of 2 into a shift when possible. */
+ if (TYPE_UNSIGNED (TREE_TYPE (loc))
+ && tree_fits_uhwi_p (TREE_OPERAND (loc, 1)))
+ {
+ const int log2 = exact_log2 (tree_to_uhwi (TREE_OPERAND (loc, 1)));
+ if (log2 > 0)
+ {
+ list_ret
+ = loc_list_from_tree_1 (TREE_OPERAND (loc, 0), 0, context);
+ if (list_ret == 0)
+ return 0;
+
+ add_loc_descr_to_each (list_ret, uint_loc_descriptor (log2));
+ add_loc_descr_to_each (list_ret,
+ new_loc_descr (DW_OP_shr, 0, 0));
+ break;
+ }
+ }
+
+ /* fall through */
+
case CEIL_DIV_EXPR:
case ROUND_DIV_EXPR:
- case TRUNC_DIV_EXPR:
- case EXACT_DIV_EXPR:
if (TYPE_UNSIGNED (TREE_TYPE (loc)))
- return 0;
+ {
+ enum machine_mode mode = TYPE_MODE (TREE_TYPE (loc));
+ scalar_int_mode int_mode;
+
+ if ((dwarf_strict && dwarf_version < 5)
+ || !is_a <scalar_int_mode> (mode, &int_mode))
+ return 0;
+
+ /* We can use a signed divide if the sign bit is not set. */
+ if (GET_MODE_SIZE (int_mode) < DWARF2_ADDR_SIZE)
+ {
+ op = DW_OP_div;
+ goto do_binop;
+ }
+
+ list_ret = typed_binop_from_tree (DW_OP_div, loc,
+ base_type_for_mode (int_mode, 1),
+ int_mode, context);
+ break;
+ }
op = DW_OP_div;
goto do_binop;
@@ -19286,7 +19375,14 @@ loc_list_from_tree_1 (tree loc, int want_address,
= loc_list_from_tree_1 (TREE_OPERAND (loc, 2), 0, context);
dw_loc_descr_ref bra_node, jump_node, tmp;
- list_ret = loc_list_from_tree_1 (TREE_OPERAND (loc, 0), 0, context);
+ /* DW_OP_bra is branch-on-nonzero so avoid doing useless work. */
+ if (TREE_CODE (TREE_OPERAND (loc, 0)) == NE_EXPR
+ && integer_zerop (TREE_OPERAND (TREE_OPERAND (loc, 0), 1)))
+ list_ret
+ = loc_list_from_tree_1 (TREE_OPERAND (TREE_OPERAND (loc, 0), 0),
+ 0, context);
+ else
+ list_ret = loc_list_from_tree_1 (TREE_OPERAND (loc, 0), 0, context);
if (list_ret == 0 || lhs == 0 || rhs == 0)
return 0;
@@ -19366,23 +19462,50 @@ loc_list_from_tree_1 (tree loc, int want_address,
if (!want_address && have_address)
{
HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (loc));
+ enum machine_mode mode = TYPE_MODE (TREE_TYPE (loc));
+ scalar_int_mode int_mode;
+ dw_die_ref type_die;
+ dw_loc_descr_ref deref;
+ /* If the size is greater than DWARF2_ADDR_SIZE, bail out. */
if (size > DWARF2_ADDR_SIZE || size == -1)
{
expansion_failed (loc, NULL_RTX,
"DWARF address size mismatch");
return 0;
}
+
+ /* If it is equal to DWARF2_ADDR_SIZE, extension does not matter. */
else if (size == DWARF2_ADDR_SIZE)
- op = DW_OP_deref;
+ deref = new_loc_descr (DW_OP_deref, size, 0);
+
+ /* If it is lower than DWARF2_ADDR_SIZE, DW_OP_deref_size will zero-
+ extend the value, which is really OK for unsigned types only. */
+ else if (!(context && context->strict_signedness)
+ || TYPE_UNSIGNED (TREE_TYPE (loc))
+ || (dwarf_strict && dwarf_version < 5)
+ || !is_a <scalar_int_mode> (mode, &int_mode)
+ || !(type_die = base_type_for_mode (mode, false)))
+ deref = new_loc_descr (DW_OP_deref_size, size, 0);
+
+ /* Use DW_OP_deref_type for signed integral types if possible, but
+ convert back to the generic type to avoid type mismatches later. */
else
- op = DW_OP_deref_size;
+ {
+ deref = new_loc_descr (dwarf_OP (DW_OP_deref_type), size, 0);
+ deref->dw_loc_oprnd2.val_class = dw_val_class_die_ref;
+ deref->dw_loc_oprnd2.v.val_die_ref.die = type_die;
+ deref->dw_loc_oprnd2.v.val_die_ref.external = 0;
+ add_loc_descr (&deref,
+ new_loc_descr (dwarf_OP (DW_OP_convert), 0, 0));
+ }
if (ret)
- add_loc_descr (&ret, new_loc_descr (op, size, 0));
+ add_loc_descr (&ret, deref);
else
- add_loc_descr_to_each (list_ret, new_loc_descr (op, size, 0));
+ add_loc_descr_to_each (list_ret, deref);
}
+
if (ret)
list_ret = new_loc_list (ret, NULL, 0, NULL, 0, NULL);
@@ -19465,35 +19588,6 @@ round_up_to_align (const offset_int &t, unsigned int align)
return wi::udiv_trunc (t + align - 1, align) * align;
}
-/* Compute the size of TYPE in bytes. If possible, return NULL and store the
- size as an integer constant in CST_SIZE. Otherwise, if possible, return a
- DWARF expression that computes the size. Return NULL and set CST_SIZE to -1
- if we fail to return the size in one of these two forms. */
-
-static dw_loc_descr_ref
-type_byte_size (const_tree type, HOST_WIDE_INT *cst_size)
-{
- tree tree_size;
- struct loc_descr_context ctx;
-
- /* Return a constant integer in priority, if possible. */
- *cst_size = int_size_in_bytes (type);
- if (*cst_size != -1)
- return NULL;
-
- ctx.context_type = const_cast<tree> (type);
- ctx.base_decl = NULL_TREE;
- ctx.dpi = NULL;
- ctx.placeholder_arg = false;
- ctx.placeholder_seen = false;
-
- type = TYPE_MAIN_VARIANT (type);
- tree_size = TYPE_SIZE_UNIT (type);
- return ((tree_size != NULL_TREE)
- ? loc_descriptor_from_tree (tree_size, 0, &ctx)
- : NULL);
-}
-
/* Helper structure for RECORD_TYPE processing. */
struct vlr_context
{
@@ -19668,12 +19762,14 @@ field_byte_offset (const_tree decl, struct vlr_context *ctx,
*cst_offset = wi::to_offset (tree_result).to_shwi ();
return NULL;
}
+
struct loc_descr_context loc_ctx = {
ctx->struct_type, /* context_type */
NULL_TREE, /* base_decl */
NULL, /* dpi */
false, /* placeholder_arg */
- false /* placeholder_seen */
+ false, /* placeholder_seen */
+ false /* strict_signedness */
};
loc_result = loc_list_from_tree (tree_result, 0, &loc_ctx);
@@ -21433,7 +21529,6 @@ add_byte_size_attribute (dw_die_ref die, tree tree_node)
{
dw_die_ref decl_die;
HOST_WIDE_INT size;
- dw_loc_descr_ref size_expr = NULL;
switch (TREE_CODE (tree_node))
{
@@ -21450,7 +21545,7 @@ add_byte_size_attribute (dw_die_ref die, tree tree_node)
add_AT_die_ref (die, DW_AT_byte_size, decl_die);
return;
}
- size_expr = type_byte_size (tree_node, &size);
+ size = int_size_in_bytes (tree_node);
break;
case FIELD_DECL:
/* For a data member of a struct or union, the DW_AT_byte_size is
@@ -21463,19 +21558,32 @@ add_byte_size_attribute (dw_die_ref die, tree tree_node)
gcc_unreachable ();
}
- /* Support for dynamically-sized objects was introduced by DWARFv3.
- At the moment, GDB does not handle variable byte sizes very well,
- though. */
- if ((dwarf_version >= 3 || !dwarf_strict)
- && gnat_encodings == DWARF_GNAT_ENCODINGS_MINIMAL
- && size_expr != NULL)
- add_AT_loc (die, DW_AT_byte_size, size_expr);
-
/* Note that `size' might be -1 when we get to this point. If it is, that
- indicates that the byte size of the entity in question is variable and
- that we could not generate a DWARF expression that computes it. */
+ indicates that the byte size of the entity in question is variable. */
if (size >= 0)
add_AT_unsigned (die, DW_AT_byte_size, size);
+
+ /* Support for dynamically-sized objects was introduced in DWARF3. */
+ else if (TYPE_P (tree_node)
+ && (dwarf_version >= 3 || !dwarf_strict)
+ && gnat_encodings == DWARF_GNAT_ENCODINGS_MINIMAL)
+ {
+ struct loc_descr_context ctx = {
+ const_cast<tree> (tree_node), /* context_type */
+ NULL_TREE, /* base_decl */
+ NULL, /* dpi */
+ false, /* placeholder_arg */
+ false, /* placeholder_seen */
+ false /* strict_signedness */
+ };
+
+ tree tree_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (tree_node));
+ add_scalar_info (die, DW_AT_byte_size, tree_size,
+ dw_scalar_form_constant
+ | dw_scalar_form_exprloc
+ | dw_scalar_form_reference,
+ &ctx);
+ }
}
/* Add a DW_AT_alignment attribute to DIE with TREE_NODE's non-default
@@ -22308,8 +22416,14 @@ gen_descr_array_type_die (tree type, struct array_descr_info *info,
{
const dw_die_ref scope_die = scope_die_for (type, context_die);
const dw_die_ref array_die = new_die (DW_TAG_array_type, scope_die, type);
- struct loc_descr_context context = { type, info->base_decl, NULL,
- false, false };
+ struct loc_descr_context context = {
+ type, /* context_type */
+ info->base_decl, /* base_decl */
+ NULL, /* dpi */
+ false, /* placeholder_arg */
+ false, /* placeholder_seen */
+ false /* strict_signedness */
+ };
enum dwarf_tag subrange_tag = DW_TAG_subrange_type;
int dim;
@@ -25292,13 +25406,6 @@ gen_variant_part (tree variant_part_decl, struct vlr_context *vlr_ctx,
{
const tree variant_part_type = TREE_TYPE (variant_part_decl);
tree variant_part_offset = vlr_ctx->variant_part_offset;
- struct loc_descr_context ctx = {
- vlr_ctx->struct_type, /* context_type */
- NULL_TREE, /* base_decl */
- NULL, /* dpi */
- false, /* placeholder_arg */
- false /* placeholder_seen */
- };
/* The FIELD_DECL node in STRUCT_TYPE that acts as the discriminant, or
NULL_TREE if there is no such field. */
@@ -25329,11 +25436,19 @@ gen_variant_part (tree variant_part_decl, struct vlr_context *vlr_ctx,
}
/* If the offset for this variant part is more complex than a constant,
- create a DWARF procedure for it so that we will not have to generate DWARF
- expressions for it for each member. */
+ create a DWARF procedure for it so that we will not have to generate
+ DWARF expressions for it for each member. */
if (TREE_CODE (variant_part_offset) != INTEGER_CST
&& (dwarf_version >= 3 || !dwarf_strict))
{
+ struct loc_descr_context ctx = {
+ vlr_ctx->struct_type, /* context_type */
+ NULL_TREE, /* base_decl */
+ NULL, /* dpi */
+ false, /* placeholder_arg */
+ false, /* placeholder_seen */
+ false /* strict_signedness */
+ };
const tree dwarf_proc_fndecl
= build_decl (UNKNOWN_LOCATION, FUNCTION_DECL, NULL_TREE,
build_function_type (TREE_TYPE (variant_part_offset),
diff --git a/gcc/opts.c b/gcc/opts.c
index a751d95..52e9e3a 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -1908,17 +1908,6 @@ const struct sanitizer_opts_s sanitizer_opts[] =
{ NULL, 0U, 0UL, false }
};
-/* -f{,no-}sanitize-coverage= suboptions. */
-const struct sanitizer_opts_s coverage_sanitizer_opts[] =
-{
-#define COVERAGE_SANITIZER_OPT(name, flags) \
- { #name, flags, sizeof #name - 1, true }
- COVERAGE_SANITIZER_OPT (trace-pc, SANITIZE_COV_TRACE_PC),
- COVERAGE_SANITIZER_OPT (trace-cmp, SANITIZE_COV_TRACE_CMP),
-#undef COVERAGE_SANITIZER_OPT
- { NULL, 0U, 0UL, false }
-};
-
/* -fzero-call-used-regs= suboptions. */
const struct zero_call_used_regs_opts_s zero_call_used_regs_opts[] =
{
@@ -1969,8 +1958,7 @@ struct edit_distance_traits<const string_fragment &>
/* Given ARG, an unrecognized sanitizer option, return the best
matching sanitizer option, or NULL if there isn't one.
OPTS is array of candidate sanitizer options.
- CODE is OPT_fsanitize_, OPT_fsanitize_recover_ or
- OPT_fsanitize_coverage_.
+ CODE is OPT_fsanitize_ or OPT_fsanitize_recover_.
VALUE is non-zero for the regular form of the option, zero
for the "no-" form (e.g. "-fno-sanitize-recover="). */
@@ -2010,12 +1998,6 @@ parse_sanitizer_options (const char *p, location_t loc, int scode,
{
enum opt_code code = (enum opt_code) scode;
- const struct sanitizer_opts_s *opts;
- if (code == OPT_fsanitize_coverage_)
- opts = coverage_sanitizer_opts;
- else
- opts = sanitizer_opts;
-
while (*p != 0)
{
size_t len, i;
@@ -2033,11 +2015,12 @@ parse_sanitizer_options (const char *p, location_t loc, int scode,
}
/* Check to see if the string matches an option class name. */
- for (i = 0; opts[i].name != NULL; ++i)
- if (len == opts[i].len && memcmp (p, opts[i].name, len) == 0)
+ for (i = 0; sanitizer_opts[i].name != NULL; ++i)
+ if (len == sanitizer_opts[i].len
+ && memcmp (p, sanitizer_opts[i].name, len) == 0)
{
/* Handle both -fsanitize and -fno-sanitize cases. */
- if (value && opts[i].flag == ~0U)
+ if (value && sanitizer_opts[i].flag == ~0U)
{
if (code == OPT_fsanitize_)
{
@@ -2054,14 +2037,14 @@ parse_sanitizer_options (const char *p, location_t loc, int scode,
-fsanitize-recover=return if -fsanitize-recover=undefined
is selected. */
if (code == OPT_fsanitize_recover_
- && opts[i].flag == SANITIZE_UNDEFINED)
+ && sanitizer_opts[i].flag == SANITIZE_UNDEFINED)
flags |= (SANITIZE_UNDEFINED
& ~(SANITIZE_UNREACHABLE | SANITIZE_RETURN));
else
- flags |= opts[i].flag;
+ flags |= sanitizer_opts[i].flag;
}
else
- flags &= ~opts[i].flag;
+ flags &= ~sanitizer_opts[i].flag;
found = true;
break;
}
@@ -2070,13 +2053,11 @@ parse_sanitizer_options (const char *p, location_t loc, int scode,
{
const char *hint
= get_closest_sanitizer_option (string_fragment (p, len),
- opts, code, value);
+ sanitizer_opts, code, value);
const char *suffix;
if (code == OPT_fsanitize_recover_)
suffix = "-recover";
- else if (code == OPT_fsanitize_coverage_)
- suffix = "-coverage";
else
suffix = "";
@@ -2527,9 +2508,7 @@ common_handle_option (struct gcc_options *opts,
break;
case OPT_fsanitize_coverage_:
- opts->x_flag_sanitize_coverage
- = parse_sanitizer_options (arg, loc, code,
- opts->x_flag_sanitize_coverage, value, true);
+ opts->x_flag_sanitize_coverage = value;
break;
case OPT_O:
diff --git a/gcc/ree.c b/gcc/ree.c
index 65457c5..e31ca2f 100644
--- a/gcc/ree.c
+++ b/gcc/ree.c
@@ -658,10 +658,11 @@ make_defs_and_copies_lists (rtx_insn *extend_insn, const_rtx set_pat,
return ret;
}
-/* If DEF_INSN has single SET expression, possibly buried inside
- a PARALLEL, return the address of the SET expression, else
- return NULL. This is similar to single_set, except that
- single_set allows multiple SETs when all but one is dead. */
+/* If DEF_INSN has single SET expression with a register
+ destination, possibly buried inside a PARALLEL, return
+ the address of the SET expression, else return NULL.
+ This is similar to single_set, except that single_set
+ allows multiple SETs when all but one is dead. */
static rtx *
get_sub_rtx (rtx_insn *def_insn)
{
@@ -675,6 +676,8 @@ get_sub_rtx (rtx_insn *def_insn)
rtx s_expr = XVECEXP (PATTERN (def_insn), 0, i);
if (GET_CODE (s_expr) != SET)
continue;
+ if (!REG_P (SET_DEST (s_expr)))
+ continue;
if (sub_rtx == NULL)
sub_rtx = &XVECEXP (PATTERN (def_insn), 0, i);
@@ -686,14 +689,12 @@ get_sub_rtx (rtx_insn *def_insn)
}
}
else if (code == SET)
- sub_rtx = &PATTERN (def_insn);
- else
{
- /* It is not a PARALLEL or a SET, what could it be ? */
- return NULL;
+ rtx s_expr = PATTERN (def_insn);
+ if (REG_P (SET_DEST (s_expr)))
+ sub_rtx = &PATTERN (def_insn);
}
- gcc_assert (sub_rtx != NULL);
return sub_rtx;
}
@@ -712,13 +713,12 @@ merge_def_and_ext (ext_cand *cand, rtx_insn *def_insn, ext_state *state)
if (sub_rtx == NULL)
return false;
- if (REG_P (SET_DEST (*sub_rtx))
- && (GET_MODE (SET_DEST (*sub_rtx)) == ext_src_mode
+ if (GET_MODE (SET_DEST (*sub_rtx)) == ext_src_mode
|| ((state->modified[INSN_UID (def_insn)].kind
== (cand->code == ZERO_EXTEND
? EXT_MODIFIED_ZEXT : EXT_MODIFIED_SEXT))
&& state->modified[INSN_UID (def_insn)].mode
- == ext_src_mode)))
+ == ext_src_mode))
{
if (GET_MODE_UNIT_SIZE (GET_MODE (SET_DEST (*sub_rtx)))
>= GET_MODE_UNIT_SIZE (cand->mode))
@@ -853,8 +853,7 @@ combine_reaching_defs (ext_cand *cand, const_rtx set_pat, ext_state *state)
CAND->insn, then this transformation is not safe. Note we have
to test in the widened mode. */
rtx *dest_sub_rtx = get_sub_rtx (def_insn);
- if (dest_sub_rtx == NULL
- || !REG_P (SET_DEST (*dest_sub_rtx)))
+ if (dest_sub_rtx == NULL)
return false;
rtx tmp_reg = gen_rtx_REG (GET_MODE (SET_DEST (set)),
@@ -947,8 +946,7 @@ combine_reaching_defs (ext_cand *cand, const_rtx set_pat, ext_state *state)
break;
rtx *dest_sub_rtx2 = get_sub_rtx (def_insn2);
- if (dest_sub_rtx2 == NULL
- || !REG_P (SET_DEST (*dest_sub_rtx2)))
+ if (dest_sub_rtx2 == NULL)
break;
/* On RISC machines we must make sure that changing the mode of
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 46dc814..a8bb582 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,22 @@
+2021-06-02 Jason Merrill <jason@redhat.com>
+
+ PR c++/100838
+ * g++.dg/init/no-elide2.C: New test.
+
+2021-06-02 Ilya Leoshkevich <iii@linux.ibm.com>
+
+ * gcc.target/s390/ashr.c: New test.
+
+2021-06-02 Tobias Burnus <tobias@codesourcery.com>
+
+ PR middle-end/99928
+ * gfortran.dg/gomp/taskloop-2.f90: New.
+
+2021-06-02 Jakub Jelinek <jakub@redhat.com>
+
+ * g++.dg/ext/builtin-shufflevector-1.C: Add -Wno-psabi -w to
+ dg-options.
+
2021-06-01 Patrick Palka <ppalka@redhat.com>
PR c++/65816
diff --git a/gcc/testsuite/g++.dg/gomp/depend-iterator-3.C b/gcc/testsuite/g++.dg/gomp/depend-iterator-3.C
new file mode 100644
index 0000000..1a7f29a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/gomp/depend-iterator-3.C
@@ -0,0 +1,43 @@
+// PR c++/100859
+
+struct S {
+ S () {}
+};
+
+struct W {
+ S c[10];
+ W () {
+#pragma omp task affinity (iterator (i = 0 : 10 : 1): c[i])
+ ;
+#pragma omp task depend (iterator (i = 0 : 10 : 1), inout: c[i])
+ ;
+#pragma omp task affinity (this[0])
+ ;
+#pragma omp task depend (inout: this[0])
+ ;
+#pragma omp taskwait
+ }
+};
+
+template <typename T>
+struct U {
+ T c[10];
+ U () {
+#pragma omp task affinity (iterator (i = 0 : 10 : 1): c[i])
+ ;
+#pragma omp task depend (iterator (i = 0 : 10 : 1), inout: c[i])
+ ;
+#pragma omp task affinity (this[0])
+ ;
+#pragma omp task depend (inout: this[0])
+ ;
+#pragma omp taskwait
+ }
+};
+
+struct V : public U<S> {
+ V () : U<S> () {}
+};
+
+W w;
+V v;
diff --git a/gcc/testsuite/g++.dg/gomp/this-1.C b/gcc/testsuite/g++.dg/gomp/this-1.C
index e7bd583..1bffc91 100644
--- a/gcc/testsuite/g++.dg/gomp/this-1.C
+++ b/gcc/testsuite/g++.dg/gomp/this-1.C
@@ -21,9 +21,13 @@ S::bar ()
#pragma omp for linear (this) // { dg-error ".this. allowed in OpenMP only in .declare simd. clauses" }
for (int i = 0; i < 10; i++)
;
- #pragma omp task depend(inout: this) // { dg-error ".this. allowed in OpenMP only in .declare simd. clauses" }
+ #pragma omp task depend(inout: this) // { dg-error ".this. is not lvalue expression nor array section in .depend. clause" }
;
- #pragma omp task depend(inout: this[0]) // { dg-error ".this. allowed in OpenMP only in .declare simd. clauses" }
+ #pragma omp task depend(inout: this[0])
+ ;
+ #pragma omp task affinity(this) // { dg-error ".this. is not lvalue expression nor array section in .affinity. clause" }
+ ;
+ #pragma omp task affinity(this[0])
;
#pragma omp parallel private (this) // { dg-error ".this. allowed in OpenMP only in .declare simd. clauses" }
{
@@ -54,9 +58,13 @@ T<N>::bar ()
#pragma omp for linear (this) // { dg-error ".this. allowed in OpenMP only in .declare simd. clauses" }
for (int i = 0; i < 10; i++)
;
- #pragma omp task depend(inout: this) // { dg-error ".this. allowed in OpenMP only in .declare simd. clauses" }
+ #pragma omp task depend(inout: this) // { dg-error ".this. is not lvalue expression nor array section in .depend. clause" }
+ ;
+ #pragma omp task depend(inout: this[0])
+ ;
+ #pragma omp task affinity(this) // { dg-error ".this. is not lvalue expression nor array section in .affinity. clause" }
;
- #pragma omp task depend(inout: this[0]) // { dg-error ".this. allowed in OpenMP only in .declare simd. clauses" }
+ #pragma omp task affinity(this[0])
;
#pragma omp parallel private (this) // { dg-error ".this. allowed in OpenMP only in .declare simd. clauses" }
{
diff --git a/gcc/testsuite/g++.dg/init/no-elide2.C b/gcc/testsuite/g++.dg/init/no-elide2.C
new file mode 100644
index 0000000..9a0ba19
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/no-elide2.C
@@ -0,0 +1,32 @@
+// PR c++/100838
+// { dg-do run }
+// { dg-additional-options -fno-elide-constructors }
+
+extern "C" int puts (const char *);
+
+int c,d;
+class MyString {
+public:
+ MyString(const char* s = "") {
+ puts ("ctor");
+ ++c;
+ }
+ ~MyString() {
+ puts ("dtor");
+ ++d;
+ }
+ MyString(const MyString& s) {
+ puts ("copy ctor");
+ ++c;
+ }
+ MyString& operator=(const MyString& s);
+};
+
+int main() {
+ {
+ MyString s1 = "Hello";
+ puts ("main");
+ }
+ if (c != d)
+ __builtin_abort();
+}
diff --git a/gcc/testsuite/gcc.dg/spellcheck-options-23.c b/gcc/testsuite/gcc.dg/spellcheck-options-23.c
new file mode 100644
index 0000000..575a28d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/spellcheck-options-23.c
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+/* { dg-options "-fsanitize-coverage=tracecmp" } */
+
+/* { dg-error "unrecognized argument in option '-fsanitize-coverage=tracecmp'" "" { target *-*-* } 0 } */
+/* { dg-message "valid arguments to '-fsanitize-coverage=' are: trace-cmp trace-pc; did you mean 'trace-cmp'?" "" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/gcc.target/aarch64/cpunative/info_16 b/gcc/testsuite/gcc.target/aarch64/cpunative/info_16
index b067957..2c04ff1 100644
--- a/gcc/testsuite/gcc.target/aarch64/cpunative/info_16
+++ b/gcc/testsuite/gcc.target/aarch64/cpunative/info_16
@@ -1,7 +1,7 @@
processor : 0
BogoMIPS : 100.00
Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 asimddp sve sve2
-CPU implementer : 0xff
+CPU implementer : 0xfe
CPU architecture: 8
CPU variant : 0x0
CPU part : 0xd08
diff --git a/gcc/testsuite/gcc.target/aarch64/cpunative/info_17 b/gcc/testsuite/gcc.target/aarch64/cpunative/info_17
index b067957..2c04ff1 100644
--- a/gcc/testsuite/gcc.target/aarch64/cpunative/info_17
+++ b/gcc/testsuite/gcc.target/aarch64/cpunative/info_17
@@ -1,7 +1,7 @@
processor : 0
BogoMIPS : 100.00
Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 asimddp sve sve2
-CPU implementer : 0xff
+CPU implementer : 0xfe
CPU architecture: 8
CPU variant : 0x0
CPU part : 0xd08
diff --git a/gcc/testsuite/gnat.dg/inline22.adb b/gcc/testsuite/gnat.dg/inline22.adb
new file mode 100644
index 0000000..5812c2f
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/inline22.adb
@@ -0,0 +1,19 @@
+-- { dg-compile }
+
+procedure Inline22 (L, U : Integer) is
+
+ type Arr is array (Integer range L .. U) of Boolean;
+
+ function Get_Zero return Arr;
+ pragma Inline_Always (Get_Zero);
+
+ function Get_Zero return Arr is
+ begin
+ return (others => False);
+ end;
+
+ A : Arr;
+
+begin
+ A := Get_Zero;
+end;
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index d38e861..05d1a25 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -1453,6 +1453,27 @@ copy_tree_body_r (tree *tp, int *walk_subtrees, void *data)
*walk_subtrees = 0;
}
+ else if (TREE_CODE (*tp) == OMP_CLAUSE
+ && (OMP_CLAUSE_CODE (*tp) == OMP_CLAUSE_AFFINITY
+ || OMP_CLAUSE_CODE (*tp) == OMP_CLAUSE_DEPEND))
+ {
+ tree t = OMP_CLAUSE_DECL (*tp);
+ if (TREE_CODE (t) == TREE_LIST
+ && TREE_PURPOSE (t)
+ && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
+ {
+ *walk_subtrees = 0;
+ OMP_CLAUSE_DECL (*tp) = copy_node (t);
+ t = OMP_CLAUSE_DECL (*tp);
+ TREE_PURPOSE (t) = copy_node (TREE_PURPOSE (t));
+ for (int i = 0; i <= 4; i++)
+ walk_tree (&TREE_VEC_ELT (TREE_PURPOSE (t), i),
+ copy_tree_body_r, id, NULL);
+ if (TREE_VEC_ELT (TREE_PURPOSE (t), 5))
+ remap_block (&TREE_VEC_ELT (TREE_PURPOSE (t), 5), id);
+ walk_tree (&TREE_VALUE (t), copy_tree_body_r, id, NULL);
+ }
+ }
}
/* Keep iterating. */
@@ -4004,17 +4025,10 @@ inline_forbidden_p (tree fndecl)
wi.info = (void *) fndecl;
wi.pset = &visited_nodes;
- /* We cannot inline a function with a VLA typed argument or result since
- we have no implementation materializing a variable of such type in
- the caller. */
- if (COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (fndecl)))
- && !poly_int_tree_p (TYPE_SIZE (TREE_TYPE (TREE_TYPE (fndecl)))))
- {
- inline_forbidden_reason
- = G_("function %q+F can never be inlined because "
- "it has a VLA return argument");
- return true;
- }
+ /* We cannot inline a function with a variable-sized parameter because we
+ cannot materialize a temporary of such a type in the caller if need be.
+ Note that the return case is not symmetrical because we can guarantee
+ that a temporary is not needed by means of CALL_EXPR_RETURN_SLOT_OPT. */
for (tree parm = DECL_ARGUMENTS (fndecl); parm; parm = DECL_CHAIN (parm))
if (!poly_int_tree_p (DECL_SIZE (parm)))
{