From 63d182b29306e582bfb151cf762820211ea1cc7e Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 31 May 2021 12:36:25 -0400 Subject: c++: missing dtor with -fno-elide-constructors [PR100838] tf_no_cleanup only applies to the outermost TARGET_EXPR, and we already clear it for nested calls in build_over_call, but in this case both constructor calls came from convert_like, so we need to clear it in the recursive call as well. This revealed that we were adding an extra ck_rvalue in direct-initialization cases where it was wrong. PR c++/100838 gcc/cp/ChangeLog: * call.c (convert_like_internal): Clear tf_no_cleanup when recursing. (build_user_type_conversion_1): Only add ck_rvalue if LOOKUP_ONLYCONVERTING. gcc/testsuite/ChangeLog: * g++.dg/init/no-elide2.C: New test. --- gcc/cp/call.c | 6 ++++-- gcc/testsuite/g++.dg/init/no-elide2.C | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/init/no-elide2.C (limited to 'gcc') 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/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(); +} -- cgit v1.1 From d2d74c9fc0cf46f66cd02698a52f5e5db109271d Mon Sep 17 00:00:00 2001 From: Pat Haugen Date: Wed, 2 Jun 2021 15:03:40 -0500 Subject: Make sure link reg save MEM has frame alias set. gcc/ChangeLog: * config/rs6000/rs6000-logue.c (rs6000_emit_prologue): Use gen_frame_store. --- gcc/config/rs6000/rs6000-logue.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'gcc') 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); -- cgit v1.1 From 50b1de860a58bf85b40a72219bc2fdfaf0dff355 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 2 Jun 2021 22:09:53 +0200 Subject: xtensa: Fix 2 warnings during xtensa build [PR100841] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When building gcc targetting xtensa-linux, there are 2 warnings the PR complains about: ../../gcc/dwarf2cfi.c: In function ‘void init_one_dwarf_reg_size(int, machine_mode, rtx, machine_mode, init_one_dwarf_reg_state*)’: ../../gcc/dwarf2cfi.c:291:12: warning: comparison of integer expressions of different signedness: ‘const unsigned int’ and ‘int’ [-Wsign-compare] 291 | if (rnum >= DWARF_FRAME_REGISTERS) ../../gcc/function.c: In function ‘void gen_call_used_regs_seq(rtx_insn*, unsigned int)’: ../../gcc/function.c:5897:63: warning: comparison of unsigned expression in ‘< 0’ is always false [-Wtype-limits] 5897 | if (crtl->uses_only_leaf_regs && LEAF_REG_REMAP (regno) < 0) which might during bootstrap or when configured with --enable-werror-always be turned into errors. The first one is the -Wsign-compare warning, in c-family we do: 2281 /* Do not warn if the signed quantity is an unsuffixed integer 2282 literal (or some static constant expression involving such 2283 literals or a conditional expression involving such literals) 2284 and it is non-negative. */ 2285 if (tree_expr_nonnegative_warnv_p (sop, &ovf)) 2286 /* OK */; and so don't warn if that function determines the expression is non-negative. But xtensa defines DWARF_FRAME_REGISTERS as (16 + (something ? 0 : 1)) and that isn't handled by tree_expr_nonnegative_warnv_p, VRP can handle it of course, but that is much later. The second chunk rewrites it into a form that tree_expr_nonnegative_warnv_p can handle, in particular (something ? 16 : 16 + 1), where for COND_EXPRs that function checks both the 2nd and 3rd operand of the ternary operator and if both are nonnegative, returns true. The other warning has been introduced fairly recently; LEAF_REG_REMAP is currently used by 2 targets only, and is documented to yield -1 if a hard reg number can't be remapped and the remapped register number otherwise. That means that the type of the expression should be signed (otherwise -1 could never appear), and on SPARC indeed it is defined as extern char leaf_reg_remap[]; #define LEAF_REG_REMAP(REGNO) (leaf_reg_remap[REGNO]) so unless the host is -funsigned-char by default it works fine. I guess sparc.[ch] should be fixed to use signed char of leaf_reg_remap, Eric? The argument to LEAF_REG_REMAP is often unsigned int though, hard register numbers are usually not negative, and thus the warning. I think xtensa doesn't have 2G hard registers and so it is ok to just cast it to int. 2021-06-02 Jakub Jelinek 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. --- gcc/config/xtensa/xtensa.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'gcc') 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 \ -- cgit v1.1 From d5ba2eaf7032f234fdcf11d9cfc513ce7be0a255 Mon Sep 17 00:00:00 2001 From: Christoph Muellner Date: Mon, 10 May 2021 14:39:03 +0200 Subject: REE: PR rtl-optimization/100264: Handle more PARALLEL SET expressions Move the check for register targets (i.e. REG_P ()) into the function get_sub_rtx () and change the restriction of REE to "only one child of a PARALLEL expression is a SET register expression" (was "only one child of a PARALLEL expression is a SET expression"). This allows to handle more PARALLEL SET expressions. gcc/ChangeLog: 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. --- gcc/ree.c | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) (limited to 'gcc') 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 -- cgit v1.1 From 9663c744e2d0942f14eafa725a1bd9f766f02a16 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Thu, 3 Jun 2021 00:16:23 +0000 Subject: Daily bump. --- gcc/ChangeLog | 64 +++++++++++++++++++++++++++++++++++++++++++++++++ gcc/DATESTAMP | 2 +- gcc/cp/ChangeLog | 8 +++++++ gcc/testsuite/ChangeLog | 19 +++++++++++++++ 4 files changed, 92 insertions(+), 1 deletion(-) (limited to 'gcc') 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 + + 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 + + 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 + + * config/rs6000/rs6000-logue.c (rs6000_emit_prologue): Use + gen_frame_store. + +2021-06-02 Vineet Gupta + + * config/arc/arc.h (TARGET_CPU_DEFAULT): Change to hs38_linux. + +2021-06-02 Ilya Leoshkevich + + * config/s390/s390.md(*ashrdi3_31): Use a single + constraint. + * config/s390/subst.md(cconly_subst): Use a single constraint + in (match_scratch). + +2021-06-02 Martin Liska + + * ipa-icf.h: Use auto_vec for memory_access_types. + +2021-06-02 Jeff Law + + * 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 (3 expander): Combine + the "and" expander with the "ior"/"xor" expander. + (bclrmsx): Combine the QI/HI mode patterns. + (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_cmpl2): Use 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 + 2021-06-01 Andrew Pinski 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/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 + + 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 PR c++/65816 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 + + PR c++/100838 + * g++.dg/init/no-elide2.C: New test. + +2021-06-02 Ilya Leoshkevich + + * gcc.target/s390/ashr.c: New test. + +2021-06-02 Tobias Burnus + + PR middle-end/99928 + * gfortran.dg/gomp/taskloop-2.f90: New. + +2021-06-02 Jakub Jelinek + + * g++.dg/ext/builtin-shufflevector-1.C: Add -Wno-psabi -w to + dg-options. + 2021-06-01 Patrick Palka PR c++/65816 -- cgit v1.1 From bff9a7ec6e3b8bf9d9635445c94e6c166e6f43e1 Mon Sep 17 00:00:00 2001 From: Kewen Lin Date: Wed, 2 Jun 2021 21:15:17 -0500 Subject: arc: Remove define_insn_and_split *bbit_di define_insn_and_split *bbit_di has unexpected empty split condition when its insn condition isn't empty. But as Claudiu pointed out, this pattern looks useless and it's better to remove it. gcc/ChangeLog: * config/arc/arc.md (*bbit_di): Remove. --- gcc/config/arc/arc.md | 28 ---------------------------- 1 file changed, 28 deletions(-) (limited to 'gcc') 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 ;; ------------------------------------------------------------------- -- cgit v1.1 From 098f4e989beb1a1be1157430c56ea4f158c1d538 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 3 Jun 2021 10:38:08 +0200 Subject: openmp: Assorted depend/affinity/iterator related fixes [PR100859] The depend-iterator-3.C testcases shows various bugs. 1) tsubst_omp_clauses didn't handle OMP_CLAUSE_AFFINITY (should be handled like OMP_CLAUSE_DEPEND) 2) because locators can be arbitrary lvalue expressions, we need to allow for C++ array section base (especially when array section is just an array reference) FIELD_DECLs, handle them as this->member, but don't need to privatize in any way 3) similarly for this as base 4) depend(inout: this) is invalid, but for different reason than the reported one, again this is an expression, but not lvalue expression, so that should be reported 5) the ctor/dtor cloning in the C++ FE (which is using walk_tree with copy_tree_body_r) didn't handle iterators correctly, walk_tree normally doesn't walk TREE_PURPOSE of TREE_LIST, and in the iterator case that TREE_VEC contains also a BLOCK that needs special handling during copy_tree_body_r 2021-06-03 Jakub Jelinek PR c++/100859 gcc/ * tree-inline.c (copy_tree_body_r): Handle iterators on OMP_CLAUSE_AFFINITY or OMP_CLAUSE_DEPEND. gcc/c/ * c-typeck.c (c_finish_omp_clauses): Move OMP_CLAUSE_AFFINITY after depend only cases. gcc/cp/ * semantics.c (handle_omp_array_sections_1): For OMP_CLAUSE_{AFFINITY,DEPEND} handle FIELD_DECL base using finish_non_static_data_member and allow this as base. (finish_omp_clauses): Move OMP_CLAUSE_AFFINITY after depend only cases. Let this be diagnosed by !lvalue_p case for OMP_CLAUSE_{AFFINITY,DEPEND} and remove useless assert. * pt.c (tsubst_omp_clauses): Handle OMP_CLAUSE_AFFINITY. gcc/testsuite/ * g++.dg/gomp/depend-iterator-3.C: New test. * g++.dg/gomp/this-1.C: Don't expect any diagnostics for this as base expression of depend array section, expect a different error wording for this as depend locator and add testcases for affinity clauses. --- gcc/c/c-typeck.c | 7 +++-- gcc/cp/pt.c | 1 + gcc/cp/semantics.c | 28 ++++++++--------- gcc/testsuite/g++.dg/gomp/depend-iterator-3.C | 43 +++++++++++++++++++++++++++ gcc/testsuite/g++.dg/gomp/this-1.C | 16 +++++++--- gcc/tree-inline.c | 21 +++++++++++++ 6 files changed, 94 insertions(+), 22 deletions(-) create mode 100644 gcc/testsuite/g++.dg/gomp/depend-iterator-3.C (limited to 'gcc') 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/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 &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 &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), "% allowed in OpenMP only in %" @@ -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), - "% allowed in OpenMP only in %" - " 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/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 +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 { + V () : U () {} +}; + +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::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/tree-inline.c b/gcc/tree-inline.c index d38e861..5396131 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. */ -- cgit v1.1 From d9a83b99349071e1c6e78df7fea3424338390d5e Mon Sep 17 00:00:00 2001 From: Tamar Christina Date: Thu, 3 Jun 2021 10:26:02 +0100 Subject: AArch64: Fix failing testcase for native cpu detection A late change in the patch changed the implemented ID to one that hasn't been used yet to avoid any ambiguity. Unfortunately the chosen value of 0xFF matches the value of -1 which is used as an invalid implementer so the test started failing. This patch changes it to 0xFE which is the highest usable number. gcc/testsuite/ChangeLog: * gcc.target/aarch64/cpunative/info_16: Update implementer. * gcc.target/aarch64/cpunative/info_17: Likewise --- gcc/testsuite/gcc.target/aarch64/cpunative/info_16 | 2 +- gcc/testsuite/gcc.target/aarch64/cpunative/info_17 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'gcc') 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 -- cgit v1.1 From e26b748a62e5bc59f6671faab75f737503c87319 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Fri, 28 May 2021 19:18:37 +0200 Subject: Fix signedness issue in DWARF functions (1) The compiler can synthesize DWARF functions to describe the location and size of components in discriminated record types with variant part in Ada, but a limitation is that most quantities must have DWARF2_ADDR_SIZE or else be the result of a zero-extension to DWARF2_ADDR_SIZE of a smaller quantity, as documented in loc_list_from_tree_1: /* ??? Most of the time we do not take proper care for sign/zero extending the values properly. Hopefully this won't be a real problem... */ In Ada discriminants may be either signed or unsigned, so this limitation is problematic. Therefore the attached patch adds a strict_signedness field to the loc_descr_context that is passed around in parts of the DWARF back-end and changes loc_list_from_tree_1 to act upon it being set to true. It also contains an optimization to avoid emitting useless comparisons. gcc/ * dwarf2out.c (scompare_loc_descriptor): Fix head comment. (is_handled_procedure_type): Likewise. (struct loc_descr_context): Add strict_signedness field. (resolve_args_picking_1): Deal with DW_OP_[GNU_]deref_type, DW_OP_[GNU_]convert and DW_OP_[GNU_]reinterpret. (resolve_args_picking): Minor tweak. (function_to_dwarf_procedure): Initialize strict_signedness field. (type_byte_size): Likewise. (field_byte_offset): Likewise. (gen_descr_array_type_die): Likewise. (gen_variant_part): Likewise. (loc_list_from_tree_1) : Tidy up and set strict_signedness to true when a context is present before evaluating the arguments. : Do not generate a useless comparison with zero. When dereferencing an address, if strict_signedness is true and the type is small and signed, use DW_OP_deref_type to do the dereference and then DW_OP_convert to convert back to the generic type. --- gcc/dwarf2out.c | 203 ++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 124 insertions(+), 79 deletions(-) (limited to 'gcc') diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index b99598e..fbda47e 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, @@ -17994,6 +17994,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 +18064,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 +18206,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 +18343,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 +18351,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 +18399,8 @@ resolve_args_picking (dw_loc_descr_ref loc, unsigned initial_frame_offset, this operation. */ hash_map 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 +18409,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 +18462,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); @@ -18586,47 +18590,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: @@ -19286,7 +19291,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 +19378,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 (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); @@ -19473,25 +19512,22 @@ round_up_to_align (const offset_int &t, unsigned int align) 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 (type); - ctx.base_decl = NULL_TREE; - ctx.dpi = NULL; - ctx.placeholder_arg = false; - ctx.placeholder_seen = false; + struct loc_descr_context ctx = { + const_cast (type), /* context_type */ + NULL_TREE, /* base_decl */ + NULL, /* dpi */ + false, /* placeholder_arg */ + false, /* placeholder_seen */ + false /* strict_signedness */ + }; - 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); + tree tree_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type)); + return tree_size ? loc_descriptor_from_tree (tree_size, 0, &ctx) : NULL; } /* Helper structure for RECORD_TYPE processing. */ @@ -19668,12 +19704,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); @@ -22308,8 +22346,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 +25336,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 +25366,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), -- cgit v1.1 From df741be17ee09974ad46750ebbbacf55f8e108a8 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Fri, 28 May 2021 19:31:18 +0200 Subject: Fix signedness issue in DWARF functions (2) The compiler can synthesize DWARF functions to describe the location and size of components in discriminated record types with variant part in Ada, but in peculiar cases the compiler drops expressions on the floor, for example in the divide case: case ROUND_DIV_EXPR: case TRUNC_DIV_EXPR: case EXACT_DIV_EXPR: if (TYPE_UNSIGNED (TREE_TYPE (loc))) return 0; op = DW_OP_div; goto do_binop; Now sizetype and bitsizetype are unsigned types, which means that any divide expression in them is dropped. gcc/ * dwarf2out.c (mem_loc_descriptor) : Fix typo. (typed_binop_from_tree): New function. (loc_list_from_tree_1) : For an unsigned type, turn a divide by a power of 2 into a shift. : For an unsigned type, use a signed divide if the size of the mode is lower than DWARF2_ADDR_SIZE; otherwise, do a typed divide by calling typed_binop_from_tree. --- gcc/dwarf2out.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 88 insertions(+), 4 deletions(-) (limited to 'gcc') diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index fbda47e..523735e 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -16407,11 +16407,13 @@ mem_loc_descriptor (rtx rtl, machine_mode mode, if ((!dwarf_strict || dwarf_version >= 5) && is_a (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); @@ -18503,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 @@ -19096,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 (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; -- cgit v1.1 From 602463fb98740efa3570198a323eed92e2e09319 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Fri, 28 May 2021 19:40:47 +0200 Subject: Also generate DW_OP_GNU_variable_value at file scope But only for the reference variant (dw_val_class_die_ref). This is needed for variable-sized types declared at library level in Ada. gcc/ * dwarf2out.c (loc_list_from_tree_1) : Also generate DW_OP_GNU_variable_value referencing an existing DIE at file scope. (type_byte_size): Inline into... (add_byte_size_attribute): ...this and call add_scalar_info. --- gcc/dwarf2out.c | 70 +++++++++++++++++++++++---------------------------------- 1 file changed, 28 insertions(+), 42 deletions(-) (limited to 'gcc') diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 523735e..88eb3f9 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -18829,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; } @@ -19588,32 +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) -{ - /* Return a constant integer in priority, if possible. */ - *cst_size = int_size_in_bytes (type); - if (*cst_size != -1) - return NULL; - - struct loc_descr_context ctx = { - const_cast (type), /* 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 (type)); - return tree_size ? loc_descriptor_from_tree (tree_size, 0, &ctx) : NULL; -} - /* Helper structure for RECORD_TYPE processing. */ struct vlr_context { @@ -21555,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)) { @@ -21572,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 @@ -21585,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_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 -- cgit v1.1 From ad085ef5fb4142df2027f81ea03992fdafc6e2f6 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Thu, 3 Jun 2021 12:39:39 +0200 Subject: Tame fix for PR ipa/99122 The return part has a major performance impact in Ada where variable-sized types are first-class citizens, but it turns out that it is not exercized in the testsuite yet, so back it out for now. gcc/ PR ipa/99122 * tree-inline.c (inline_forbidden_p): Remove test on return type. gcc/testsuite/ * gnat.dg/inline22.adb: New test. --- gcc/testsuite/gnat.dg/inline22.adb | 19 +++++++++++++++++++ gcc/tree-inline.c | 15 ++++----------- 2 files changed, 23 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/gnat.dg/inline22.adb (limited to 'gcc') 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 5396131..05d1a25 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -4025,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))) { -- cgit v1.1 From c1681f22b4b44096f7bd8a2cf42f54762305c3ae Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Thu, 20 May 2021 10:57:49 +0200 Subject: Simplify option handling for -fsanitize-coverage gcc/ChangeLog: * common.opt: Use proper Enum values. * opts.c (COVERAGE_SANITIZER_OPT): Remove. (parse_sanitizer_options): Handle only sanitizer_opts. (common_handle_option): Just assign value. gcc/testsuite/ChangeLog: * gcc.dg/spellcheck-options-23.c: New test. --- gcc/common.opt | 11 +++++++- gcc/opts.c | 41 +++++++--------------------- gcc/testsuite/gcc.dg/spellcheck-options-23.c | 5 ++++ 3 files changed, 25 insertions(+), 32 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/spellcheck-options-23.c (limited to 'gcc') 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= Use custom shadow memory 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 /* 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/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 } */ -- cgit v1.1