diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2018-10-08 14:44:49 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2018-10-08 14:44:49 +0000 |
commit | e4ca607bcff0531a124c6603c1a0496c21b5c1d2 (patch) | |
tree | eff67e0dc5d748e398ea1a7ffa36f6a3bbda072b | |
parent | 504cafd97cd40223dac4beb4a28cb85368cff5b9 (diff) | |
parent | 3cbb7cbb096134746588d08a469778b11ae6ac73 (diff) | |
download | gcc-e4ca607bcff0531a124c6603c1a0496c21b5c1d2.zip gcc-e4ca607bcff0531a124c6603c1a0496c21b5c1d2.tar.gz gcc-e4ca607bcff0531a124c6603c1a0496c21b5c1d2.tar.bz2 |
Merge from trunk revision 264932.
From-SVN: r264933
114 files changed, 1667 insertions, 1017 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 53c9c89..0e10c55 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,67 @@ +2018-10-08 Paul Koning <ni1d@arrl.net> + + * config/pdp11/pdp11-protos.h (output_block_move): Remove. + (expand_block_move): New function. + * config/pdp11/pdp11.c (output_block_move): Remove. + (expand_block_move): New function. + * config/pdp11/pdp11.h (MOVE_RATIO): New definition. + * config/pdp11/pdp11.md (movmemhi): Use expand_block_move. + (*movmemhi1): Remove. + +2018-10-08 Robin Dapp <rdapp@linux.ibm.com> + + * config/s390/2827.md: Increase latencies for some FP instructions. + +2018-10-08 Richard Biener <rguenther@suse.de> + + * tree-vect-loop.c (vect_compute_single_scalar_iteration_cost): + Open a dump scope. + * tree-vectorizer.c (dump_stmt_cost): Add cost param and dump it. + * tree-vectorizer.h (dump_stmt_cost): Adjust. + (add_stmt_cost): Dump return value of the hook. + +2018-10-08 Richard Biener <rguenther@suse.de> + + PR tree-optimization/63155 + * tree-ssa-propagate.c (add_ssa_edge): Do cheap check first. + (ssa_propagation_engine::ssa_propagate): Remove redundant + bitmap bit clearing. + +2018-10-05 Peter Bergner <bergner@linux.ibm.com> + + PR rtl-optimization/86939 + PR rtl-optimization/87479 + * ira.h (non_conflicting_reg_copy_p): New prototype. + * ira-lives.c (ignore_reg_for_conflicts): New static variable. + (make_hard_regno_dead): Don't add conflicts for register + ignore_reg_for_conflicts. + (make_object_dead): Likewise. + (non_conflicting_reg_copy_p): New function. + (process_bb_node_lives): Set ignore_reg_for_conflicts for copies. + Remove special conflict handling of REAL_PIC_OFFSET_TABLE_REGNUM. + * lra-lives.c (ignore_reg_for_conflicts): New static variable. + (make_hard_regno_dead): Don't add conflicts for register + ignore_reg_for_conflicts. Remove special conflict handling of + REAL_PIC_OFFSET_TABLE_REGNUM. Remove now unused argument + check_pic_pseudo_p and update callers. + (mark_pseudo_dead): Don't add conflicts for register + ignore_reg_for_conflicts. + (process_bb_lives): Set ignore_reg_for_conflicts for copies. + +2018-10-05 Andrew Waterman <andrew@sifive.com> + Jim Wilson <jimw@sifive.com> + + * config/riscv/riscv.md (f<quiet_pattern>_quiet<ANYF:mode><X:mode>4): + Add define_expand. Add ! HONOR_SNANS check to current pattern. Add + new pattern using HONOR_SNANS that emits one extra instruction. + +2018-10-05 Segher Boessenkool <segher@kernel.crashing.org> + + * config/rs6000/rs6000.md (unnamed mfcr scc_comparison_operator + patterns): Merge SI and DI patterns to a GPR pattern. + (unnamed define_insn and define_split for record form of that): Merge + to a single define_insn_and_split pattern. + 2018-10-05 David Malcolm <dmalcolm@redhat.com> PR c++/56856 diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 3faa601..2327ffcb 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20181005 +20181008 diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index b6ff1f7..6307337 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,9 @@ +2018-10-08 Richard Sandiford <richard.sandiford@arm.com> + + PR c/87286 + * c-common.c (vector_types_compatible_elements_p): Use + INTEGRAL_TYPE_P instead of checking only for INTEGER_TYPE. + 2018-10-04 Vinay Kumar <vinay.kumar@blackfigtech.com> * c-attribs.c (get_priority): Add a warning flag warn_prio_ctor_dtor diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 10a8bc2..c0198e1 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -7465,8 +7465,11 @@ vector_types_compatible_elements_p (tree t1, tree t2) enum tree_code c1 = TREE_CODE (t1), c2 = TREE_CODE (t2); - gcc_assert ((c1 == INTEGER_TYPE || c1 == REAL_TYPE || c1 == FIXED_POINT_TYPE) - && (c2 == INTEGER_TYPE || c2 == REAL_TYPE + gcc_assert ((INTEGRAL_TYPE_P (t1) + || c1 == REAL_TYPE + || c1 == FIXED_POINT_TYPE) + && (INTEGRAL_TYPE_P (t2) + || c2 == REAL_TYPE || c2 == FIXED_POINT_TYPE)); t1 = c_common_signed_type (t1); @@ -7476,7 +7479,7 @@ vector_types_compatible_elements_p (tree t1, tree t2) if (t1 == t2) return true; if (opaque && c1 == c2 - && (c1 == INTEGER_TYPE || c1 == REAL_TYPE) + && (INTEGRAL_TYPE_P (t1) || c1 == REAL_TYPE) && TYPE_PRECISION (t1) == TYPE_PRECISION (t2)) return true; return false; diff --git a/gcc/config/pdp11/pdp11-protos.h b/gcc/config/pdp11/pdp11-protos.h index 0ce72fd..0ed61ea 100644 --- a/gcc/config/pdp11/pdp11-protos.h +++ b/gcc/config/pdp11/pdp11-protos.h @@ -26,7 +26,7 @@ extern int legitimate_const_double_p (rtx); extern void notice_update_cc_on_set (rtx, rtx); extern void output_addr_const_pdp11 (FILE *, rtx); extern const char *output_move_multiple (rtx *); -extern const char *output_block_move (rtx *); +extern void expand_block_move (rtx *); extern const char *output_jump (rtx *, int, int); extern void print_operand_address (FILE *, rtx); typedef enum { no_action, dec_before, inc_after } pdp11_action; diff --git a/gcc/config/pdp11/pdp11.c b/gcc/config/pdp11/pdp11.c index b3b7ced..06129f1 100644 --- a/gcc/config/pdp11/pdp11.c +++ b/gcc/config/pdp11/pdp11.c @@ -45,6 +45,7 @@ along with GCC; see the file COPYING3. If not see #include "expr.h" #include "builtins.h" #include "dbxout.h" +#include "explow.h" #include "expmed.h" /* This file should be included last. */ @@ -1513,173 +1514,48 @@ no_side_effect_operand(rtx op, machine_mode mode ATTRIBUTE_UNUSED) /* - * output a block move: + * expand a block move: * * operands[0] ... to * operands[1] ... from * operands[2] ... length * operands[3] ... alignment - * operands[4] ... scratch register */ - -const char * -output_block_move(rtx *operands) +void +expand_block_move(rtx *operands) { - static int count = 0; - char buf[200]; - int unroll; - int lastbyte = 0; - - /* Move of zero bytes is a NOP. */ - if (operands[2] == const0_rtx) - return ""; - - /* Look for moves by small constant byte counts, those we'll - expand to straight line code. */ - if (CONSTANT_P (operands[2])) - { - if (INTVAL (operands[2]) < 16 - && (!optimize_size || INTVAL (operands[2]) < 5) - && INTVAL (operands[3]) == 1) - { - register int i; - - for (i = 1; i <= INTVAL (operands[2]); i++) - output_asm_insn("movb\t(%1)+,(%0)+", operands); - - return ""; - } - else if (INTVAL(operands[2]) < 32 - && (!optimize_size || INTVAL (operands[2]) < 9) - && INTVAL (operands[3]) >= 2) - { - register int i; - - for (i = 1; i <= INTVAL (operands[2]) / 2; i++) - output_asm_insn ("mov\t(%1)+,(%0)+", operands); - if (INTVAL (operands[2]) & 1) - output_asm_insn ("movb\t(%1),(%0)", operands); - - return ""; - } - } - - /* Ideally we'd look for moves that are multiples of 4 or 8 - bytes and handle those by unrolling the move loop. That - makes for a lot of code if done at run time, but it's ok - for constant counts. Also, for variable counts we have - to worry about odd byte count with even aligned pointers. - On 11/40 and up we handle that case; on older machines - we don't and just use byte-wise moves all the time. */ - - if (CONSTANT_P (operands[2]) ) - { - if (INTVAL (operands[3]) < 2) - unroll = 0; - else - { - lastbyte = INTVAL (operands[2]) & 1; - - if (optimize_size || INTVAL (operands[2]) & 2) - unroll = 1; - else if (INTVAL (operands[2]) & 4) - unroll = 2; - else - unroll = 3; - } - - /* Loop count is byte count scaled by unroll. */ - operands[2] = GEN_INT (INTVAL (operands[2]) >> unroll); - output_asm_insn ("mov\t%2,%4", operands); - } - else - { - /* Variable byte count; use the input register - as the scratch. */ - operands[4] = operands[2]; - - /* Decide whether to move by words, and check - the byte count for zero. */ - if (TARGET_40_PLUS && INTVAL (operands[3]) > 1) - { - unroll = 1; - output_asm_insn ("asr\t%4", operands); - } - else - { - unroll = 0; - output_asm_insn ("tst\t%4", operands); - } - sprintf (buf, "beq movestrhi%d", count + 1); - output_asm_insn (buf, NULL); - } + rtx lb, test; + rtx fromop, toop, counter; + int count; - /* Output the loop label. */ - sprintf (buf, "\nmovestrhi%d:", count); - output_asm_insn (buf, NULL); + /* Transform BLKmode MEM reference into a (reg)+ operand. */ + toop = copy_to_mode_reg (Pmode, XEXP (operands[0], 0)); + toop = gen_rtx_POST_INC (Pmode, toop); + fromop = copy_to_mode_reg (Pmode, XEXP (operands[1], 0)); + fromop = gen_rtx_POST_INC (Pmode, fromop); - /* Output the appropriate move instructions. */ - switch (unroll) - { - case 0: - output_asm_insn ("movb\t(%1)+,(%0)+", operands); - break; - - case 1: - output_asm_insn ("mov\t(%1)+,(%0)+", operands); - break; - - case 2: - output_asm_insn ("mov\t(%1)+,(%0)+", operands); - output_asm_insn ("mov\t(%1)+,(%0)+", operands); - break; - - default: - output_asm_insn ("mov\t(%1)+,(%0)+", operands); - output_asm_insn ("mov\t(%1)+,(%0)+", operands); - output_asm_insn ("mov\t(%1)+,(%0)+", operands); - output_asm_insn ("mov\t(%1)+,(%0)+", operands); - break; - } - - /* Output the decrement and test. */ - if (TARGET_40_PLUS) + count = INTVAL (operands[2]); + if (INTVAL (operands [3]) >= 2 && (count & 1) == 0) { - sprintf (buf, "sob\t%%4, movestrhi%d", count); - output_asm_insn (buf, operands); + count >>= 1; + toop = gen_rtx_MEM (HImode, toop); + fromop = gen_rtx_MEM (HImode, fromop); } else { - output_asm_insn ("dec\t%4", operands); - sprintf (buf, "bgt movestrhi%d", count); - output_asm_insn (buf, NULL); - } - count ++; - - /* If constant odd byte count, move the last byte. */ - if (lastbyte) - output_asm_insn ("movb\t(%1),(%0)", operands); - else if (!CONSTANT_P (operands[2])) - { - /* Output the destination label for the zero byte count check. */ - sprintf (buf, "\nmovestrhi%d:", count); - output_asm_insn (buf, NULL); - count++; - - /* If we did word moves, check for trailing last byte. */ - if (unroll) - { - sprintf (buf, "bcc movestrhi%d", count); - output_asm_insn (buf, NULL); - output_asm_insn ("movb\t(%1),(%0)", operands); - sprintf (buf, "\nmovestrhi%d:", count); - output_asm_insn (buf, NULL); - count++; - } + toop = gen_rtx_MEM (QImode, toop); + fromop = gen_rtx_MEM (QImode, fromop); } - - return ""; + counter = copy_to_mode_reg (HImode, gen_rtx_CONST_INT (HImode, count)); + + /* Label at top of loop */ + lb = gen_label_rtx (); + emit_label (lb); + emit_move_insn (toop, fromop); + emit_insn (gen_subhi3 (counter, counter, const1_rtx)); + test = gen_rtx_NE (HImode, counter, const0_rtx); + emit_jump_insn (gen_cbranchhi4 (test, counter, const0_rtx, lb)); } /* This function checks whether a real value can be encoded as diff --git a/gcc/config/pdp11/pdp11.h b/gcc/config/pdp11/pdp11.h index c68a74d..d65d8f5 100644 --- a/gcc/config/pdp11/pdp11.h +++ b/gcc/config/pdp11/pdp11.h @@ -439,9 +439,12 @@ extern int may_call_alloca; /* Max number of bytes we can move from memory to memory in one reasonably fast instruction. */ - #define MOVE_MAX 2 +/* Max number of insns to use for inline move rather than library + call. */ +#define MOVE_RATIO(speed) 6 + /* Nonzero if access to memory by byte is no faster than by word. */ #define SLOW_BYTE_ACCESS 1 diff --git a/gcc/config/pdp11/pdp11.md b/gcc/config/pdp11/pdp11.md index e51f538..a41e1590 100644 --- a/gcc/config/pdp11/pdp11.md +++ b/gcc/config/pdp11/pdp11.md @@ -570,48 +570,20 @@ clrf\t%0" [(set_attr "length" "2,2,4,4,2")]) -;; maybe fiddle a bit with move_ratio, then -;; let constraints only accept a register ... - +;; Expand a block move. We turn this into a move loop. (define_expand "movmemhi" - [(parallel [(set (match_operand:BLK 0 "general_operand" "=g,g") - (match_operand:BLK 1 "general_operand" "g,g")) - (use (match_operand:HI 2 "general_operand" "n,mr")) - (use (match_operand:HI 3 "immediate_operand" "i,i")) - (clobber (match_scratch:HI 6 "=&r,X")) - (clobber (match_dup 4)) - (clobber (match_dup 5)) - (clobber (match_dup 2))])] + [(match_operand:BLK 0 "general_operand" "=g") + (match_operand:BLK 1 "general_operand" "g") + (match_operand:HI 2 "immediate_operand" "i") + (match_operand:HI 3 "immediate_operand" "i")] "" " { - operands[0] - = replace_equiv_address (operands[0], - copy_to_mode_reg (Pmode, XEXP (operands[0], 0))); - operands[1] - = replace_equiv_address (operands[1], - copy_to_mode_reg (Pmode, XEXP (operands[1], 0))); - - operands[4] = XEXP (operands[0], 0); - operands[5] = XEXP (operands[1], 0); + if (INTVAL (operands[2]) != 0) + expand_block_move (operands); + DONE; }") - -(define_insn "*movmemhi1" - [(set (mem:BLK (match_operand:HI 0 "register_operand" "r,r")) - (mem:BLK (match_operand:HI 1 "register_operand" "r,r"))) - (use (match_operand:HI 2 "general_operand" "n,r")) - (use (match_operand:HI 3 "immediate_operand" "i,i")) - (clobber (match_scratch:HI 4 "=&r,X")) - (clobber (match_dup 0)) - (clobber (match_dup 1)) - (clobber (match_dup 2))] - "" - "* return output_block_move (operands);" -;;; just a guess - [(set_attr "length" "80")]) - - ;;- truncation instructions diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index 4162dc5..b6c2023 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -1957,19 +1957,41 @@ [(set_attr "type" "fcmp") (set_attr "mode" "<UNITMODE>")]) -(define_insn "f<quiet_pattern>_quiet<ANYF:mode><X:mode>4" - [(set (match_operand:X 0 "register_operand" "=r") +(define_expand "f<quiet_pattern>_quiet<ANYF:mode><X:mode>4" + [(parallel [(set (match_operand:X 0 "register_operand") + (unspec:X + [(match_operand:ANYF 1 "register_operand") + (match_operand:ANYF 2 "register_operand")] + QUIET_COMPARISON)) + (clobber (match_scratch:X 3))])] + "TARGET_HARD_FLOAT") + +(define_insn "*f<quiet_pattern>_quiet<ANYF:mode><X:mode>4_default" + [(set (match_operand:X 0 "register_operand" "=r") (unspec:X - [(match_operand:ANYF 1 "register_operand" " f") - (match_operand:ANYF 2 "register_operand" " f")] - QUIET_COMPARISON)) + [(match_operand:ANYF 1 "register_operand" " f") + (match_operand:ANYF 2 "register_operand" " f")] + QUIET_COMPARISON)) (clobber (match_scratch:X 3 "=&r"))] - "TARGET_HARD_FLOAT" + "TARGET_HARD_FLOAT && ! HONOR_SNANS (<ANYF:MODE>mode)" "frflags\t%3\n\tf<quiet_pattern>.<fmt>\t%0,%1,%2\n\tfsflags %3" [(set_attr "type" "fcmp") (set_attr "mode" "<UNITMODE>") (set (attr "length") (const_int 12))]) +(define_insn "*f<quiet_pattern>_quiet<ANYF:mode><X:mode>4_snan" + [(set (match_operand:X 0 "register_operand" "=r") + (unspec:X + [(match_operand:ANYF 1 "register_operand" " f") + (match_operand:ANYF 2 "register_operand" " f")] + QUIET_COMPARISON)) + (clobber (match_scratch:X 3 "=&r"))] + "TARGET_HARD_FLOAT && HONOR_SNANS (<ANYF:MODE>mode)" + "frflags\t%3\n\tf<quiet_pattern>.<fmt>\t%0,%1,%2\n\tfsflags %3\n\tfeq.<fmt>\tzero,%1,%2" + [(set_attr "type" "fcmp") + (set_attr "mode" "<UNITMODE>") + (set (attr "length") (const_int 16))]) + (define_insn "*seq_zero_<X:mode><GPR:mode>" [(set (match_operand:GPR 0 "register_operand" "=r") (eq:GPR (match_operand:X 1 "register_operand" " r") diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 5db3e57..0e7cf35 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -11765,10 +11765,10 @@ ;; cases the insns below which don't use an intermediate CR field will ;; be used instead. (define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (match_operator:SI 1 "scc_comparison_operator" - [(match_operand 2 "cc_reg_operand" "y") - (const_int 0)]))] + [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") + (match_operator:GPR 1 "scc_comparison_operator" + [(match_operand 2 "cc_reg_operand" "y") + (const_int 0)]))] "" "mfcr %0%Q2\;rlwinm %0,%0,%J1,1" [(set (attr "type") @@ -11778,21 +11778,7 @@ (const_string "mfcr"))) (set_attr "length" "8")]) -(define_insn "" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (match_operator:DI 1 "scc_comparison_operator" - [(match_operand 2 "cc_reg_operand" "y") - (const_int 0)]))] - "TARGET_POWERPC64" - "mfcr %0%Q2\;rlwinm %0,%0,%J1,1" - [(set (attr "type") - (cond [(match_test "TARGET_MFCRF") - (const_string "mfcrf") - ] - (const_string "mfcr"))) - (set_attr "length" "8")]) - -(define_insn "" +(define_insn_and_split "" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") (compare:CC (match_operator:SI 1 "scc_comparison_operator" [(match_operand 2 "cc_reg_operand" "y,y") @@ -11804,25 +11790,16 @@ "@ mfcr %3%Q2\;rlwinm. %3,%3,%J1,1 #" - [(set_attr "type" "shift") - (set_attr "dot" "yes") - (set_attr "length" "8,16")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand") - (compare:CC (match_operator:SI 1 "scc_comparison_operator" - [(match_operand 2 "cc_reg_operand") - (const_int 0)]) - (const_int 0))) - (set (match_operand:SI 3 "gpc_reg_operand") - (match_op_dup 1 [(match_dup 2) (const_int 0)]))] - "TARGET_32BIT && reload_completed" + "&& reload_completed" [(set (match_dup 3) (match_op_dup 1 [(match_dup 2) (const_int 0)])) (set (match_dup 0) (compare:CC (match_dup 3) (const_int 0)))] - "") + "" + [(set_attr "type" "shift") + (set_attr "dot" "yes") + (set_attr "length" "8,16")]) (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") diff --git a/gcc/config/s390/2827.md b/gcc/config/s390/2827.md index a709a2e..1fef0bb 100644 --- a/gcc/config/s390/2827.md +++ b/gcc/config/s390/2827.md @@ -38,9 +38,13 @@ (and (eq_attr "cpu" "zEC12") (eq_attr "mnemonic" "ltg,ogrk,lr,lghrl,x,asi,lhr,ar,lhrl,llgfr,clghrl,cgr,cli,agrk,ic,lrv,clg,cy,cghi,sy,clgfr,al,tm,lang,lghr,laa,ark,lh,or,icy,xi,n,llihl,afi,cs,nrk,sth,lgr,l,lcr,stey,xg,crt,slgfr,ny,ld,j,llihh,slgr,clfhsi,slg,lb,lgrl,lrl,llihf,llcr,laxg,mvghi,rllg,xrk,laag,alhsik,algfi,algr,aly,agfi,lrvr,d,crl,llgc,tmhl,algsi,lgh,icmh,clhrl,xgrk,icm,iilf,ork,cg,ldgr,lgf,iihf,llghr,sg,stam,tmhh,slgf,basr,lgb,cgfi,lax,clfit,lrvgr,nihl,ni,srdl,srk,xihf,stgrl,sthrl,algf,cgit,ng,lat,llghrl,ltgr,nihh,clgfrl,srlk,agr,ler,bcr_flush,stcy,cds,clfi,nihf,ly,clt,lgat,alg,lhy,lgfrl,clghsi,clrt,tmll,srlg,ay,sty,clr,lgfi,lan,clgt,ahik,sra,algrk,clgr,tmy,tmlh,alghsik,lcgr,mvi,ltgf,xr,larl,ldr,llgcr,clgrt,clrl,cghsi,cliy,oy,ogr,llgt,slr,chi,s,icmy,llc,ngr,clhhsi,ltgfr,llill,lhi,o,sll,clgrl,clgf,mviy,algfr,rll,sldl,lg,niy,st,sgr,ag,le,xgr,cr,stg,llilh,sr,cdsg,sllk,stoc,csg,clgit,chhsi,strl,llilf,lndfr,ngrk,clgfi,llgh,oill,la,llhrl,stc,lghi,oihl,xiy,sllg,llgf,cgrt,cl,sl,oi,oilh,nr,srak,oihh,ear,slgrk,og,c,slgfi,sthy,oilf,oiy,oihf,a,cfi,srag,brasl,alr,cgrl,llgfrl,cit,ley,exrl,lcdfr,lay,xilf,alsi,mvhhi,srl,chsi,lgfr,lrvg,cly,sgrk,ahi,nill,jg,slrk,lxr,sar,slfi,cpsdr,lcgfr,aghik,nilh,mvhi,lpdfr,xy,alrk,lao,agsi,ldy,nilf,llhr,alfi,laog,sly,aghi,bras,srda,lt,lbr,lzxr,lzdr,lzer")) "nothing") -(define_insn_reservation "zEC12_simple_fp" 1 +(define_insn_reservation "zEC12_simple_fp" 0 (and (eq_attr "cpu" "zEC12") - (eq_attr "mnemonic" "lnebr,sdbr,sebr,clfxtr,adbr,aebr,celfbr,clfebr,lpebr,msebr,lndbr,clfdbr,llgtr,cebr,lgbr,maebr,ltebr,clfdtr,ltr,cdlgbr,cxlftr,lpdbr,cdfbr,lcebr,clfxbr,msdbr,cdbr,madbr,meebr,clgxbr,clgdtr,ledbr,cegbr,cdlftr,cdlgtr,mdbr,clgebr,ltdbr,cdlfbr,cdgbr,clgxtr,lcdbr,celgbr,clgdbr,ldebr,cefbr,fidtr,fixtr,madb,msdb,mseb,fiebra,fidbra,fixbra,aeb,mdb,seb,cdb,tcdb,sdb,adb,tceb,maeb,ceb,meeb,ldeb")) "nothing") + (eq_attr "mnemonic" "llgtr,lgbr,ltr")) "nothing") + +(define_insn_reservation "zEC12_normal_fp" 8 + (and (eq_attr "cpu" "zEC12") + (eq_attr "mnemonic" "lnebr,sdbr,sebr,clfxtr,adbr,aebr,celfbr,clfebr,lpebr,msebr,lndbr,clfdbr,cebr,maebr,ltebr,clfdtr,cdlgbr,cxlftr,lpdbr,cdfbr,lcebr,clfxbr,msdbr,cdbr,madbr,meebr,clgxbr,clgdtr,ledbr,cegbr,cdlftr,cdlgtr,mdbr,clgebr,ltdbr,cdlfbr,cdgbr,clgxtr,lcdbr,celgbr,clgdbr,ldebr,cefbr,fidtr,fixtr,madb,msdb,mseb,fiebra,fidbra,aeb,mdb,seb,cdb,tcdb,sdb,adb,tceb,maeb,ceb,meeb,ldeb")) "nothing") (define_insn_reservation "zEC12_cgdbr" 2 (and (eq_attr "cpu" "zEC12") @@ -294,7 +298,7 @@ (and (eq_attr "cpu" "zEC12") (eq_attr "mnemonic" "locgr")) "nothing") -(define_insn_reservation "zEC12_debr" 23 +(define_insn_reservation "zEC12_debr" 29 (and (eq_attr "cpu" "zEC12") (eq_attr "mnemonic" "debr")) "nothing") @@ -422,7 +426,7 @@ (and (eq_attr "cpu" "zEC12") (eq_attr "mnemonic" "cxbr")) "nothing") -(define_insn_reservation "zEC12_ddbr" 30 +(define_insn_reservation "zEC12_ddbr" 36 (and (eq_attr "cpu" "zEC12") (eq_attr "mnemonic" "ddbr")) "nothing") @@ -430,7 +434,7 @@ (and (eq_attr "cpu" "zEC12") (eq_attr "mnemonic" "stmy")) "nothing") -(define_insn_reservation "zEC12_ste" 3 +(define_insn_reservation "zEC12_ste" 4 (and (eq_attr "cpu" "zEC12") (eq_attr "mnemonic" "ste")) "nothing") diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 97d7e8d..9a0a5ea 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2018-10-08 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/71128 + * pt.c (do_decl_instantiation): Per 12.6.8/5, a concept cannot be + explicitly instantiated. + 2018-10-05 David Malcolm <dmalcolm@redhat.com> PR c++/56856 diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index b8b6545..aced6f2 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -23127,6 +23127,14 @@ do_decl_instantiation (tree decl, tree storage) error ("explicit instantiation of non-template %q#D", decl); return; } + else if (DECL_DECLARED_CONCEPT_P (decl)) + { + if (VAR_P (decl)) + error ("explicit instantiation of variable concept %q#D", decl); + else + error ("explicit instantiation of function concept %q#D", decl); + return; + } bool var_templ = (DECL_TEMPLATE_INFO (decl) && variable_template_p (DECL_TI_TEMPLATE (decl))); diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 7eece23..6fc3857 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,37 @@ +2018-10-08 Cesar Philippidis <cesar@codesourcery.com> + + * expr.c (gfc_check_pointer_assign): Demote "Assignment to + contiguous pointer from non-contiguous target" to a warning. + +2018-10-08 Paul Thomas <pault@gcc.gnu.org> + + PR fortran/86372 + * trans-stmt.c (trans_associate_var): Character associate names + with variable string length do not have to be deferred length + for the string length to be set, if variable. + +2018-10-06 Thomas Koenig <tkoenig@gcc.gnu.org> + + PR fortran/86111 + * gfortran.h (enum arith): Add ARITH_WRONGCONCAT. + * arith.h (gfc_arith_error): Issue error for ARITH_WRONGCONCAT. + (gfc_arith_concat): If the types of op1 and op2 are not + character of if their kinds do not match, issue ARITH_WRONGCONCAT. + +2018-10-06 Paul Thomas <pault@gcc.gnu.org> + + PR fortran/83999 + * resolve.c (resolve_fl_procedure): Include class functions in + the test that elemental function results be scalar. + +2018-10-06 Thomas Koenig <tkoenig@gcc.gnu.org> + + PR fortran/84640 + * simplify.c (gfc_simplify_cshift): Extend size of hs_ex and ss_ex + by one. Set extents one past the array boundaries to zero to avoid + warning with instrumented compiler. + (gfc_simplify_eoshift): Likewise, only for ss_ex. + 2018-10-05 Paul Thomas <pault@gcc.gnu.org> PR fortran/87487 diff --git a/gcc/fortran/arith.c b/gcc/fortran/arith.c index 6f97d0f..98af27e 100644 --- a/gcc/fortran/arith.c +++ b/gcc/fortran/arith.c @@ -113,6 +113,11 @@ gfc_arith_error (arith code) p = _("Integer outside symmetric range implied by Standard Fortran at %L"); break; + case ARITH_WRONGCONCAT: + p = + _("Illegal type in character concatenation at %L"); + break; + default: gfc_internal_error ("gfc_arith_error(): Bad error code"); } @@ -982,7 +987,12 @@ gfc_arith_concat (gfc_expr *op1, gfc_expr *op2, gfc_expr **resultp) gfc_expr *result; size_t len; - gcc_assert (op1->ts.kind == op2->ts.kind); + /* By cleverly playing around with constructors, is is possible + to get mismaching types here. */ + if (op1->ts.type != BT_CHARACTER || op2->ts.type != BT_CHARACTER + || op1->ts.kind != op2->ts.kind) + return ARITH_WRONGCONCAT; + result = gfc_get_constant_expr (BT_CHARACTER, op1->ts.kind, &op1->where); diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c index 3315bb8..1cfda5f 100644 --- a/gcc/fortran/expr.c +++ b/gcc/fortran/expr.c @@ -3957,13 +3957,13 @@ gfc_check_pointer_assign (gfc_expr *lvalue, gfc_expr *rvalue) } } - /* Error for assignments of contiguous pointers to targets which is not + /* Warn for assignments of contiguous pointers to targets which is not contiguous. Be lenient in the definition of what counts as contiguous. */ if (lhs_attr.contiguous && !gfc_is_simply_contiguous (rvalue, false, true)) - gfc_error ("Assignment to contiguous pointer from non-contiguous " - "target at %L", &rvalue->where); + gfc_warning (OPT_Wextra, "Assignment to contiguous pointer from " + "non-contiguous target at %L", &rvalue->where); /* Warn if it is the LHS pointer may lives longer than the RHS target. */ if (warn_target_lifetime diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index b0518e2..8e50e4d 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -191,7 +191,8 @@ enum gfc_intrinsic_op /* Arithmetic results. */ enum arith { ARITH_OK = 1, ARITH_OVERFLOW, ARITH_UNDERFLOW, ARITH_NAN, - ARITH_DIV0, ARITH_INCOMMENSURATE, ARITH_ASYMMETRIC, ARITH_PROHIBIT + ARITH_DIV0, ARITH_INCOMMENSURATE, ARITH_ASYMMETRIC, ARITH_PROHIBIT, + ARITH_WRONGCONCAT }; /* Statements. */ diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c index a2beb7f..87e65df 100644 --- a/gcc/fortran/resolve.c +++ b/gcc/fortran/resolve.c @@ -12503,7 +12503,8 @@ resolve_fl_procedure (gfc_symbol *sym, int mp_flag) } /* An elemental function is required to return a scalar 12.7.1 */ - if (sym->attr.elemental && sym->attr.function && sym->as) + if (sym->attr.elemental && sym->attr.function + && (sym->as || (sym->ts.type == BT_CLASS && CLASS_DATA (sym)->as))) { gfc_error ("ELEMENTAL function %qs at %L must have a scalar " "result", sym->name, &sym->declared_at); diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c index d35bbba..7bdd23d 100644 --- a/gcc/fortran/simplify.c +++ b/gcc/fortran/simplify.c @@ -2011,11 +2011,11 @@ gfc_simplify_cshift (gfc_expr *array, gfc_expr *shift, gfc_expr *dim) ssize_t *shiftvec, *hptr; ssize_t shift_val, len; ssize_t count[GFC_MAX_DIMENSIONS], extent[GFC_MAX_DIMENSIONS], - hs_ex[GFC_MAX_DIMENSIONS], + hs_ex[GFC_MAX_DIMENSIONS + 1], hstride[GFC_MAX_DIMENSIONS], sstride[GFC_MAX_DIMENSIONS], a_extent[GFC_MAX_DIMENSIONS], a_stride[GFC_MAX_DIMENSIONS], h_extent[GFC_MAX_DIMENSIONS], - ss_ex[GFC_MAX_DIMENSIONS]; + ss_ex[GFC_MAX_DIMENSIONS + 1]; ssize_t rsoffset; int d, n; bool continue_loop; @@ -2110,6 +2110,8 @@ gfc_simplify_cshift (gfc_expr *array, gfc_expr *shift, gfc_expr *dim) n++; } } + ss_ex[n] = 0; + hs_ex[n] = 0; if (shiftvec) { @@ -2403,7 +2405,7 @@ gfc_simplify_eoshift (gfc_expr *array, gfc_expr *shift, gfc_expr *boundary, ssize_t shift_val, len; ssize_t count[GFC_MAX_DIMENSIONS], extent[GFC_MAX_DIMENSIONS], sstride[GFC_MAX_DIMENSIONS], a_extent[GFC_MAX_DIMENSIONS], - a_stride[GFC_MAX_DIMENSIONS], ss_ex[GFC_MAX_DIMENSIONS]; + a_stride[GFC_MAX_DIMENSIONS], ss_ex[GFC_MAX_DIMENSIONS + 1]; ssize_t rsoffset; int d, n; bool continue_loop; @@ -2546,6 +2548,7 @@ gfc_simplify_eoshift (gfc_expr *array, gfc_expr *shift, gfc_expr *boundary, n++; } } + ss_ex[n] = 0; continue_loop = true; d = array->rank; diff --git a/gcc/fortran/trans-stmt.c b/gcc/fortran/trans-stmt.c index ef9e519..6256e3f 100644 --- a/gcc/fortran/trans-stmt.c +++ b/gcc/fortran/trans-stmt.c @@ -1885,7 +1885,6 @@ trans_associate_var (gfc_symbol *sym, gfc_wrapped_block *block) } if (sym->ts.type == BT_CHARACTER - && sym->ts.deferred && !sym->attr.select_type_temporary && VAR_P (sym->ts.u.cl->backend_decl) && se.string_length != sym->ts.u.cl->backend_decl) diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 2c7a860..6e783c9 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -d0739c13ca3686df1f8d0fae7c6c5caaed058503 +a9da4d34a2f878a5058f7e7d2beef52aa62471a1 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/ira-lives.c b/gcc/ira-lives.c index f1a7d27..dd8b334 100644 --- a/gcc/ira-lives.c +++ b/gcc/ira-lives.c @@ -84,6 +84,10 @@ static int *allocno_saved_at_call; supplemental to recog_data. */ static alternative_mask preferred_alternatives; +/* If non-NULL, the source operand of a register to register copy for which + we should not add a conflict with the copy's destination operand. */ +static rtx ignore_reg_for_conflicts; + /* Record hard register REGNO as now being live. */ static void make_hard_regno_live (int regno) @@ -101,6 +105,11 @@ make_hard_regno_dead (int regno) { ira_object_t obj = ira_object_id_map[i]; + if (ignore_reg_for_conflicts != NULL_RTX + && REGNO (ignore_reg_for_conflicts) + == (unsigned int) ALLOCNO_REGNO (OBJECT_ALLOCNO (obj))) + continue; + SET_HARD_REG_BIT (OBJECT_CONFLICT_HARD_REGS (obj), regno); SET_HARD_REG_BIT (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), regno); } @@ -154,12 +163,38 @@ static void make_object_dead (ira_object_t obj) { live_range_t lr; + int ignore_regno = -1; + int end_regno = -1; sparseset_clear_bit (objects_live, OBJECT_CONFLICT_ID (obj)); + /* Check whether any part of IGNORE_REG_FOR_CONFLICTS already conflicts + with OBJ. */ + if (ignore_reg_for_conflicts != NULL_RTX + && REGNO (ignore_reg_for_conflicts) < FIRST_PSEUDO_REGISTER) + { + end_regno = END_REGNO (ignore_reg_for_conflicts); + int src_regno = ignore_regno = REGNO (ignore_reg_for_conflicts); + + while (src_regno < end_regno) + { + if (TEST_HARD_REG_BIT (OBJECT_CONFLICT_HARD_REGS (obj), src_regno)) + { + ignore_regno = end_regno = -1; + break; + } + src_regno++; + } + } + IOR_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj), hard_regs_live); IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), hard_regs_live); + /* If IGNORE_REG_FOR_CONFLICTS did not already conflict with OBJ, make + sure it still doesn't. */ + for (; ignore_regno < end_regno; ignore_regno++) + CLEAR_HARD_REG_BIT (OBJECT_CONFLICT_HARD_REGS (obj), ignore_regno); + lr = OBJECT_LIVE_RANGES (obj); ira_assert (lr != NULL); lr->finish = curr_point; @@ -1022,6 +1057,38 @@ find_call_crossed_cheap_reg (rtx_insn *insn) return cheap_reg; } +/* Determine whether INSN is a register to register copy of the type where + we do not need to make the source and destiniation registers conflict. + If this is a copy instruction, then return the source reg. Otherwise, + return NULL_RTX. */ +rtx +non_conflicting_reg_copy_p (rtx_insn *insn) +{ + rtx set = single_set (insn); + + /* Disallow anything other than a simple register to register copy + that has no side effects. */ + if (set == NULL_RTX + || !REG_P (SET_DEST (set)) + || !REG_P (SET_SRC (set)) + || side_effects_p (set)) + return NULL_RTX; + + int dst_regno = REGNO (SET_DEST (set)); + int src_regno = REGNO (SET_SRC (set)); + machine_mode mode = GET_MODE (SET_DEST (set)); + + /* Computing conflicts for register pairs is difficult to get right, so + for now, disallow it. */ + if ((dst_regno < FIRST_PSEUDO_REGISTER + && hard_regno_nregs (dst_regno, mode) != 1) + || (src_regno < FIRST_PSEUDO_REGISTER + && hard_regno_nregs (src_regno, mode) != 1)) + return NULL_RTX; + + return SET_SRC (set); +} + /* Process insns of the basic block given by its LOOP_TREE_NODE to update allocno live ranges, allocno hard register conflicts, intersected calls, and register pressure info for allocnos for the @@ -1107,22 +1174,7 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node) curr_point); call_p = CALL_P (insn); -#ifdef REAL_PIC_OFFSET_TABLE_REGNUM - int regno; - bool clear_pic_use_conflict_p = false; - /* Processing insn usage in call insn can create conflict - with pic pseudo and pic hard reg and that is wrong. - Check this situation and fix it at the end of the insn - processing. */ - if (call_p && pic_offset_table_rtx != NULL_RTX - && (regno = REGNO (pic_offset_table_rtx)) >= FIRST_PSEUDO_REGISTER - && (a = ira_curr_regno_allocno_map[regno]) != NULL) - clear_pic_use_conflict_p - = (find_regno_fusage (insn, USE, REAL_PIC_OFFSET_TABLE_REGNUM) - && ! TEST_HARD_REG_BIT (OBJECT_CONFLICT_HARD_REGS - (ALLOCNO_OBJECT (a, 0)), - REAL_PIC_OFFSET_TABLE_REGNUM)); -#endif + ignore_reg_for_conflicts = non_conflicting_reg_copy_p (insn); /* Mark each defined value as live. We need to do this for unused values because they still conflict with quantities @@ -1276,20 +1328,9 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node) } } -#ifdef REAL_PIC_OFFSET_TABLE_REGNUM - if (clear_pic_use_conflict_p) - { - regno = REGNO (pic_offset_table_rtx); - a = ira_curr_regno_allocno_map[regno]; - CLEAR_HARD_REG_BIT (OBJECT_CONFLICT_HARD_REGS (ALLOCNO_OBJECT (a, 0)), - REAL_PIC_OFFSET_TABLE_REGNUM); - CLEAR_HARD_REG_BIT (OBJECT_TOTAL_CONFLICT_HARD_REGS - (ALLOCNO_OBJECT (a, 0)), - REAL_PIC_OFFSET_TABLE_REGNUM); - } -#endif curr_point++; } + ignore_reg_for_conflicts = NULL_RTX; if (bb_has_eh_pred (bb)) for (j = 0; ; ++j) @@ -210,6 +210,9 @@ extern void ira_adjust_equiv_reg_cost (unsigned, int); /* ira-costs.c */ extern void ira_costs_c_finalize (void); +/* ira-lives.c */ +extern rtx non_conflicting_reg_copy_p (rtx_insn *); + /* Spilling static chain pseudo may result in generation of wrong non-local goto code using frame-pointer to address saved stack pointer value after restoring old frame pointer value. The diff --git a/gcc/lra-lives.c b/gcc/lra-lives.c index a3bc29c..0bf8cd0 100644 --- a/gcc/lra-lives.c +++ b/gcc/lra-lives.c @@ -96,6 +96,10 @@ static bitmap_head temp_bitmap; /* Pool for pseudo live ranges. */ static object_allocator<lra_live_range> lra_live_range_pool ("live ranges"); +/* If non-NULL, the source operand of a register to register copy for which + we should not add a conflict with the copy's destination operand. */ +static rtx ignore_reg_for_conflicts; + /* Free live range list LR. */ static void free_live_range_list (lra_live_range_t lr) @@ -239,11 +243,9 @@ make_hard_regno_live (int regno) /* Process the definition of hard register REGNO. This updates hard_regs_live, START_DYING and conflict hard regs for living - pseudos. Conflict hard regs for the pic pseudo is not updated if - REGNO is REAL_PIC_OFFSET_TABLE_REGNUM and CHECK_PIC_PSEUDO_P is - true. */ + pseudos. */ static void -make_hard_regno_dead (int regno, bool check_pic_pseudo_p ATTRIBUTE_UNUSED) +make_hard_regno_dead (int regno) { lra_assert (regno < FIRST_PSEUDO_REGISTER); if (! TEST_HARD_REG_BIT (hard_regs_live, regno)) @@ -251,13 +253,12 @@ make_hard_regno_dead (int regno, bool check_pic_pseudo_p ATTRIBUTE_UNUSED) sparseset_set_bit (start_dying, regno); unsigned int i; EXECUTE_IF_SET_IN_SPARSESET (pseudos_live, i) -#ifdef REAL_PIC_OFFSET_TABLE_REGNUM - if (! check_pic_pseudo_p - || regno != REAL_PIC_OFFSET_TABLE_REGNUM - || pic_offset_table_rtx == NULL - || i != REGNO (pic_offset_table_rtx)) -#endif + { + if (ignore_reg_for_conflicts != NULL_RTX + && REGNO (ignore_reg_for_conflicts) == i) + continue; SET_HARD_REG_BIT (lra_reg_info[i].conflict_hard_regs, regno); + } CLEAR_HARD_REG_BIT (hard_regs_live, regno); if (fixed_regs[regno] || TEST_HARD_REG_BIT (hard_regs_spilled_into, regno)) { @@ -294,14 +295,41 @@ static void mark_pseudo_dead (int regno, int point) { lra_live_range_t p; + int ignore_regno = -1; + int end_regno = -1; lra_assert (regno >= FIRST_PSEUDO_REGISTER); lra_assert (sparseset_bit_p (pseudos_live, regno)); sparseset_clear_bit (pseudos_live, regno); sparseset_set_bit (start_dying, regno); + /* Check whether any part of IGNORE_REG_FOR_CONFLICTS already conflicts + with REGNO. */ + if (ignore_reg_for_conflicts != NULL_RTX + && REGNO (ignore_reg_for_conflicts) < FIRST_PSEUDO_REGISTER) + { + end_regno = END_REGNO (ignore_reg_for_conflicts); + int src_regno = ignore_regno = REGNO (ignore_reg_for_conflicts); + + while (src_regno < end_regno) + { + if (TEST_HARD_REG_BIT (lra_reg_info[regno].conflict_hard_regs, + src_regno)) + { + ignore_regno = end_regno = -1; + break; + } + src_regno++; + } + } + IOR_HARD_REG_SET (lra_reg_info[regno].conflict_hard_regs, hard_regs_live); + /* If IGNORE_REG_FOR_CONFLICTS did not already conflict with REGNO, make + sure it still doesn't. */ + for (; ignore_regno < end_regno; ignore_regno++) + CLEAR_HARD_REG_BIT (lra_reg_info[regno].conflict_hard_regs, ignore_regno); + if (complete_info_p || lra_get_regno_hard_regno (regno) < 0) { p = lra_reg_info[regno].live_ranges; @@ -350,7 +378,7 @@ mark_regno_dead (int regno, machine_mode mode, int point) if (regno < FIRST_PSEUDO_REGISTER) { for (last = end_hard_regno (mode, regno); regno < last; regno++) - make_hard_regno_dead (regno, false); + make_hard_regno_dead (regno); } else { @@ -747,6 +775,7 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) } call_p = CALL_P (curr_insn); + ignore_reg_for_conflicts = non_conflicting_reg_copy_p (curr_insn); src_regno = (set != NULL_RTX && REG_P (SET_SRC (set)) ? REGNO (SET_SRC (set)) : -1); dst_regno = (set != NULL_RTX && REG_P (SET_DEST (set)) @@ -858,14 +887,13 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) for (reg = curr_static_id->hard_regs; reg != NULL; reg = reg->next) if (reg->type == OP_OUT && ! reg_early_clobber_p (reg, n_alt) && ! reg->subreg_p) - make_hard_regno_dead (reg->regno, false); + make_hard_regno_dead (reg->regno); if (curr_id->arg_hard_regs != NULL) for (i = 0; (regno = curr_id->arg_hard_regs[i]) >= 0; i++) if (regno >= FIRST_PSEUDO_REGISTER) - /* It is a clobber. Don't create conflict of used - REAL_PIC_OFFSET_TABLE_REGNUM and the pic pseudo. */ - make_hard_regno_dead (regno - FIRST_PSEUDO_REGISTER, true); + /* It is a clobber. */ + make_hard_regno_dead (regno - FIRST_PSEUDO_REGISTER); if (call_p) { @@ -926,8 +954,7 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) make_hard_regno_live (reg->regno); if (curr_id->arg_hard_regs != NULL) - /* Make argument hard registers live. Don't create conflict - of used REAL_PIC_OFFSET_TABLE_REGNUM and the pic pseudo. */ + /* Make argument hard registers live. */ for (i = 0; (regno = curr_id->arg_hard_regs[i]) >= 0; i++) if (regno < FIRST_PSEUDO_REGISTER) make_hard_regno_live (regno); @@ -955,7 +982,7 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) if (reg2->type != OP_OUT && reg2->regno == reg->regno) break; if (reg2 == NULL) - make_hard_regno_dead (reg->regno, false); + make_hard_regno_dead (reg->regno); } if (need_curr_point_incr) @@ -990,6 +1017,7 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) EXECUTE_IF_SET_IN_SPARSESET (unused_set, j) add_reg_note (curr_insn, REG_UNUSED, regno_reg_rtx[j]); } + ignore_reg_for_conflicts = NULL_RTX; if (bb_has_eh_pred (bb)) for (j = 0; ; ++j) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 37a035a..a4ee18f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,67 @@ +2018-10-08 Martin Liska <mliska@suse.cz> + + * gcc.target/i386/i386.exp: Move procedures to + target-supports.exp. + * g++.target/i386/i386.exp: New file. + * gcc.target/i386/mv*.C: Move here tests and remove + target filter in these tests. + +2018-10-08 Cesar Philippidis <cesar@codesourcery.com> + + * gfortran.dg/contiguous_4.f90: Adjust. + * gfortran.dg/contiguous_4.f90: New test. + +2018-10-08 Paul Thomas <pault@gcc.gnu.org> + + PR fortran/86372 + * gfortran.dg/associate_41.f90: New test. + +2018-10-08 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> + + * gcc.dg/merge-all-constants-2.c: Require string_merging support. + * gnat.dg/string_merge1.adb: Likewise. + * gnat.dg/string_merge2.adb: Likewise. + +2018-10-08 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> + + * c-c++-common/Wprio-ctor-dtor.c: Require init_priority support. + +2018-10-08 Martin Liska <mliska@suse.cz> + + * g++.dg/ext/pr82625.C: Add dg-compile filter. + +2018-10-08 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/71128 + * g++.dg/concepts/pr71128.C: New. + +2018-10-08 Richard Sandiford <richard.sandiford@arm.com> + + PR c/87286 + * gcc.dg/pr87286.c: New test. + +2018-10-06 Thomas Koenig <tkoenig@gcc.gnu.org> + + PR fortran/86111 + * gfortran.dg/array_constructor_type_23.f90: New test. + +2018-10-06 Paul Thomas <pault@gcc.gnu.org> + + PR fortran/83999 + * gfortran.dg/elemental_function_4.f90 : New test. + +2018-10-05 Peter Bergner <bergner@linux.ibm.com> + + PR rtl-optimization/86939 + PR rtl-optimization/87479 + * gcc.target/powerpc/pr86939.c: New test. + * gcc/testsuite/gcc.target/i386/pr49095.c: Fix expected results. + +2018-10-05 Bernd Edlinger <bernd.edlinger@hotmail.de> + + * gnat.dg/string_merge1.adb: Fix test expectations. + * gnat.dg/string_merge2.adb: Likewise. + 2018-10-05 David Malcolm <dmalcolm@redhat.com> PR c++/56856 diff --git a/gcc/testsuite/c-c++-common/Wprio-ctor-dtor.c b/gcc/testsuite/c-c++-common/Wprio-ctor-dtor.c index 5b08059..9da7254 100644 --- a/gcc/testsuite/c-c++-common/Wprio-ctor-dtor.c +++ b/gcc/testsuite/c-c++-common/Wprio-ctor-dtor.c @@ -1,4 +1,5 @@ /* { dg-do compile } */ +/* { dg-require-effective-target init_priority } */ /* { dg-options "-Wno-prio-ctor-dtor" } */ void construct1 () __attribute__ ((constructor (10))); diff --git a/gcc/testsuite/g++.dg/concepts/pr71128.C b/gcc/testsuite/g++.dg/concepts/pr71128.C new file mode 100644 index 0000000..8b4eb41 --- /dev/null +++ b/gcc/testsuite/g++.dg/concepts/pr71128.C @@ -0,0 +1,10 @@ +// { dg-do compile { target c++14 } } +// { dg-additional-options "-fconcepts" } + +template<typename T> +concept bool C() { return true; } +template bool C<int>(); // { dg-error "explicit instantiation of function concept" } + +template<typename T> +concept bool D = true; +template bool D<int>; // { dg-error "explicit instantiation of variable concept" } diff --git a/gcc/testsuite/g++.dg/ext/pr82625.C b/gcc/testsuite/g++.dg/ext/pr82625.C index 47bd2df..59b174f 100644 --- a/gcc/testsuite/g++.dg/ext/pr82625.C +++ b/gcc/testsuite/g++.dg/ext/pr82625.C @@ -1,6 +1,7 @@ /* { dg-do compile } */ /* { dg-require-ifunc "" } */ /* { dg-options "-O2 -fdump-tree-optimized" } */ +/* { dg-do compile { target i?86-*-* x86_64-*-* } } */ __attribute__ ((target ("default"))) static unsigned foo(const char *buf, unsigned size) { diff --git a/gcc/testsuite/g++.target/i386/i386.exp b/gcc/testsuite/g++.target/i386/i386.exp new file mode 100644 index 0000000..76a7e53 --- /dev/null +++ b/gcc/testsuite/g++.target/i386/i386.exp @@ -0,0 +1,43 @@ +# Copyright (C) 2018 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# <http://www.gnu.org/licenses/>. + +# GCC testsuite that uses the `g++.exp' driver. + +# Exit immediately if this isn't a x86 target. +if { ![istarget i?86*-*-*] && ![istarget x86_64-*-*] } then { + return +} + +# Load support procs. +load_lib g++-dg.exp +load_lib clearcap.exp + +global DEFAULT_CXXFLAGS +if ![info exists DEFAULT_CXXFLAGS] then { + set DEFAULT_CXXFLAGS " -pedantic-errors" +} + +# Initialize `dg'. +dg-init +clearcap-init + +# Main loop. +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.C]] \ + "" $DEFAULT_CXXFLAGS + +# All done. +clearcap-finish +dg-finish diff --git a/gcc/testsuite/g++.dg/ext/mv1.C b/gcc/testsuite/g++.target/i386/mv1.C index 4eedbff..fc71347 100644 --- a/gcc/testsuite/g++.dg/ext/mv1.C +++ b/gcc/testsuite/g++.target/i386/mv1.C @@ -1,5 +1,5 @@ /* Test case to check if Multiversioning works. */ -/* { dg-do run { target i?86-*-* x86_64-*-* } } */ +/* { dg-do run } */ /* { dg-require-ifunc "" } */ /* { dg-options "-O2 -fPIC" } */ diff --git a/gcc/testsuite/g++.dg/ext/mv10.C b/gcc/testsuite/g++.target/i386/mv10.C index 5dfe363..07fbd0e 100644 --- a/gcc/testsuite/g++.dg/ext/mv10.C +++ b/gcc/testsuite/g++.target/i386/mv10.C @@ -1,4 +1,4 @@ -// { dg-do assemble { target i?86-*-* x86_64-*-* } } +// { dg-do assemble } // { dg-options "" } __attribute__((target ("popcnt"), used)) diff --git a/gcc/testsuite/g++.dg/ext/mv11.C b/gcc/testsuite/g++.target/i386/mv11.C index 1f5c576..58aaf50 100644 --- a/gcc/testsuite/g++.dg/ext/mv11.C +++ b/gcc/testsuite/g++.target/i386/mv11.C @@ -1,4 +1,4 @@ -// { dg-do compile { target i?86-*-* x86_64-*-* } } +// { dg-do compile } // { dg-options "-msse2" } int foo () __attribute__ ((target("default"))); diff --git a/gcc/testsuite/g++.dg/ext/mv12-aux.cc b/gcc/testsuite/g++.target/i386/mv12-aux.cc index 611c679..611c679 100644 --- a/gcc/testsuite/g++.dg/ext/mv12-aux.cc +++ b/gcc/testsuite/g++.target/i386/mv12-aux.cc diff --git a/gcc/testsuite/g++.dg/ext/mv12.C b/gcc/testsuite/g++.target/i386/mv12.C index 8b2e423..2156962 100644 --- a/gcc/testsuite/g++.dg/ext/mv12.C +++ b/gcc/testsuite/g++.target/i386/mv12.C @@ -1,7 +1,7 @@ // Test case to check if multiversioning works as expected when the versions // are defined in different files. -// { dg-do run { target i?86-*-* x86_64-*-* } } +// { dg-do run } // { dg-require-ifunc "" } // { dg-options "-O2" } // { dg-additional-sources "mv12-aux.cc" } diff --git a/gcc/testsuite/g++.dg/ext/mv12.h b/gcc/testsuite/g++.target/i386/mv12.h index 650358d..650358d 100644 --- a/gcc/testsuite/g++.dg/ext/mv12.h +++ b/gcc/testsuite/g++.target/i386/mv12.h diff --git a/gcc/testsuite/g++.dg/ext/mv13.C b/gcc/testsuite/g++.target/i386/mv13.C index 5674d19..39d05c7 100644 --- a/gcc/testsuite/g++.dg/ext/mv13.C +++ b/gcc/testsuite/g++.target/i386/mv13.C @@ -1,7 +1,7 @@ // Test case to check if multiversioning functions that are extern "C" // generates errors. -// { dg-do compile { target i?86-*-* x86_64-*-* } } +// { dg-do compile } extern "C" __attribute__ ((target ("default"))) diff --git a/gcc/testsuite/g++.dg/ext/mv14.C b/gcc/testsuite/g++.target/i386/mv14.C index 1e7a161..ccebb33 100644 --- a/gcc/testsuite/g++.dg/ext/mv14.C +++ b/gcc/testsuite/g++.target/i386/mv14.C @@ -1,5 +1,5 @@ /* Test case to check if Multiversioning works. */ -/* { dg-do run { target i?86-*-* x86_64-*-* } } */ +/* { dg-do run } */ /* { dg-require-ifunc "" } */ /* { dg-options "-O2 -fPIC -march=x86-64" } */ diff --git a/gcc/testsuite/g++.dg/ext/mv15.C b/gcc/testsuite/g++.target/i386/mv15.C index c0beadf..4e867f2 100644 --- a/gcc/testsuite/g++.dg/ext/mv15.C +++ b/gcc/testsuite/g++.target/i386/mv15.C @@ -1,5 +1,5 @@ /* Test case to check if Multiversioning works. */ -/* { dg-do run { target i?86-*-* x86_64-*-* } } */ +/* { dg-do run } */ /* { dg-require-ifunc "" } */ /* { dg-options "-O2 -fPIC -march=x86-64" } */ diff --git a/gcc/testsuite/g++.dg/ext/mv16.C b/gcc/testsuite/g++.target/i386/mv16.C index 3e7c228..1091868 100644 --- a/gcc/testsuite/g++.dg/ext/mv16.C +++ b/gcc/testsuite/g++.target/i386/mv16.C @@ -2,7 +2,7 @@ // for Intel CPUs with the same internal GCC processor id // but slighly different sets of x86 extensions. -// { dg-do run { target i?86-*-* x86_64-*-* } } +// { dg-do run } // { dg-require-ifunc "" } // { dg-options "-O2" } diff --git a/gcc/testsuite/g++.dg/ext/mv17.C b/gcc/testsuite/g++.target/i386/mv17.C index 87c1324..fefbfaa 100644 --- a/gcc/testsuite/g++.dg/ext/mv17.C +++ b/gcc/testsuite/g++.target/i386/mv17.C @@ -1,6 +1,6 @@ // Test case to check if Multiversioning works for BMI and BMI2. -// { dg-do run { target i?86-*-* x86_64-*-* } } +// { dg-do run } // { dg-require-ifunc "" } // { dg-options "-O2" } diff --git a/gcc/testsuite/g++.dg/ext/mv18.C b/gcc/testsuite/g++.target/i386/mv18.C index 1f024de..b62bc36 100644 --- a/gcc/testsuite/g++.dg/ext/mv18.C +++ b/gcc/testsuite/g++.target/i386/mv18.C @@ -1,5 +1,5 @@ /* Test case to check if Multiversioning works. */ -/* { dg-do run { target i?86-*-* x86_64-*-* } } */ +/* { dg-do run } */ /* { dg-require-ifunc "" } */ /* { dg-require-effective-target pie } */ /* { dg-options "-O2 -fPIE -pie" } */ diff --git a/gcc/testsuite/g++.dg/ext/mv19.C b/gcc/testsuite/g++.target/i386/mv19.C index d1ea788..b014c2e 100644 --- a/gcc/testsuite/g++.dg/ext/mv19.C +++ b/gcc/testsuite/g++.target/i386/mv19.C @@ -1,5 +1,5 @@ /* Test case to check if Multiversioning works. */ -/* { dg-do run { target i?86-*-* x86_64-*-* } } */ +/* { dg-do run } */ /* { dg-require-ifunc "" } */ /* { dg-require-effective-target pie } */ /* { dg-options "-O2 -fPIE -pie -march=x86-64" } */ diff --git a/gcc/testsuite/g++.dg/ext/mv2.C b/gcc/testsuite/g++.target/i386/mv2.C index d4f1f92..3013a2f 100644 --- a/gcc/testsuite/g++.dg/ext/mv2.C +++ b/gcc/testsuite/g++.target/i386/mv2.C @@ -1,6 +1,6 @@ /* Test case to check if Multiversioning chooses the correct dispatching order when versions are for various ISAs. */ -/* { dg-do run { target i?86-*-* x86_64-*-* } } */ +/* { dg-do run } */ /* { dg-require-ifunc "" } */ /* { dg-options "-O2" } */ diff --git a/gcc/testsuite/g++.dg/ext/mv20.C b/gcc/testsuite/g++.target/i386/mv20.C index 98f7408..ed8607e 100644 --- a/gcc/testsuite/g++.dg/ext/mv20.C +++ b/gcc/testsuite/g++.target/i386/mv20.C @@ -1,5 +1,5 @@ /* Test case to check if Multiversioning works. */ -/* { dg-do run { target i?86-*-* x86_64-*-* } } */ +/* { dg-do run } */ /* { dg-require-ifunc "" } */ /* { dg-require-effective-target pie } */ /* { dg-options "-O2 -fPIE -pie -march=x86-64" } */ diff --git a/gcc/testsuite/g++.dg/ext/mv21.C b/gcc/testsuite/g++.target/i386/mv21.C index 9708ad9..a99805f 100644 --- a/gcc/testsuite/g++.dg/ext/mv21.C +++ b/gcc/testsuite/g++.target/i386/mv21.C @@ -1,5 +1,5 @@ /* Test case to check if Multiversioning works. */ -/* { dg-do run { target i?86-*-* x86_64-*-* } } */ +/* { dg-do run } */ /* { dg-require-ifunc "" } */ /* { dg-require-effective-target static } */ /* { dg-options "-O2 -static" } */ diff --git a/gcc/testsuite/g++.dg/ext/mv22.C b/gcc/testsuite/g++.target/i386/mv22.C index 2550136..5e43de7 100644 --- a/gcc/testsuite/g++.dg/ext/mv22.C +++ b/gcc/testsuite/g++.target/i386/mv22.C @@ -1,5 +1,5 @@ /* Test case to check if Multiversioning works. */ -/* { dg-do run { target i?86-*-* x86_64-*-* } } */ +/* { dg-do run } */ /* { dg-require-ifunc "" } */ /* { dg-require-effective-target static } */ /* { dg-options "-O2 -static -march=x86-64" } */ diff --git a/gcc/testsuite/g++.dg/ext/mv23.C b/gcc/testsuite/g++.target/i386/mv23.C index f00afb0..674a0ff 100644 --- a/gcc/testsuite/g++.dg/ext/mv23.C +++ b/gcc/testsuite/g++.target/i386/mv23.C @@ -1,5 +1,5 @@ /* Test case to check if Multiversioning works. */ -/* { dg-do run { target i?86-*-* x86_64-*-* } } */ +/* { dg-do run } */ /* { dg-require-ifunc "" } */ /* { dg-require-effective-target static } */ /* { dg-options "-O2 -static -march=x86-64" } */ diff --git a/gcc/testsuite/g++.dg/ext/mv24.C b/gcc/testsuite/g++.target/i386/mv24.C index 58292a8..f8736cc 100644 --- a/gcc/testsuite/g++.dg/ext/mv24.C +++ b/gcc/testsuite/g++.target/i386/mv24.C @@ -1,6 +1,6 @@ // Test case to check if Multiversioning works for AES -// { dg-do run { target i?86-*-* x86_64-*-* } } +// { dg-do run } // { dg-require-ifunc "" } // { dg-options "-O2" } diff --git a/gcc/testsuite/g++.dg/ext/mv25.C b/gcc/testsuite/g++.target/i386/mv25.C index fd40eca..2e2fcc3 100644 --- a/gcc/testsuite/g++.dg/ext/mv25.C +++ b/gcc/testsuite/g++.target/i386/mv25.C @@ -1,6 +1,6 @@ // Test case to check if Multiversioning works for PCLMUL -// { dg-do run { target i?86-*-* x86_64-*-* } } +// { dg-do run } // { dg-require-ifunc "" } // { dg-options "-O2" } diff --git a/gcc/testsuite/g++.dg/ext/mv26.C b/gcc/testsuite/g++.target/i386/mv26.C index 1b45513..6693ca1 100644 --- a/gcc/testsuite/g++.dg/ext/mv26.C +++ b/gcc/testsuite/g++.target/i386/mv26.C @@ -1,5 +1,5 @@ // PR c++/84059 -// { dg-do compile { target i?86-*-* x86_64-*-* } } +// { dg-do compile } // { dg-require-ifunc "" } template <typename> struct a diff --git a/gcc/testsuite/g++.dg/ext/mv27.C b/gcc/testsuite/g++.target/i386/mv27.C index 443a54b..60fa8ca 100644 --- a/gcc/testsuite/g++.dg/ext/mv27.C +++ b/gcc/testsuite/g++.target/i386/mv27.C @@ -1,5 +1,5 @@ // PR c++/83911 -// { dg-do compile { target i?86-*-* x86_64-*-* } } +// { dg-do compile } // { dg-require-ifunc "" } class SimdFloat diff --git a/gcc/testsuite/g++.dg/ext/mv3.C b/gcc/testsuite/g++.target/i386/mv3.C index ec2aa1f..4a57a52 100644 --- a/gcc/testsuite/g++.dg/ext/mv3.C +++ b/gcc/testsuite/g++.target/i386/mv3.C @@ -9,7 +9,7 @@ with a direct call to the popcnt version of foo. Hence, this test should pass. */ -/* { dg-do run { target i?86-*-* x86_64-*-* } } */ +/* { dg-do run } */ /* { dg-options "-O2" } */ diff --git a/gcc/testsuite/g++.dg/ext/mv4.C b/gcc/testsuite/g++.target/i386/mv4.C index ff1cc2f..c4c4d68 100644 --- a/gcc/testsuite/g++.dg/ext/mv4.C +++ b/gcc/testsuite/g++.target/i386/mv4.C @@ -2,7 +2,7 @@ when the default version of a multiversioned function is absent and its pointer is taken. */ -/* { dg-do compile { target i?86-*-* x86_64-*-* } } */ +/* { dg-do compile } */ /* { dg-require-ifunc "" } */ /* { dg-options "-O2" } */ diff --git a/gcc/testsuite/g++.dg/ext/mv5.C b/gcc/testsuite/g++.target/i386/mv5.C index fd62eee..6690a02 100644 --- a/gcc/testsuite/g++.dg/ext/mv5.C +++ b/gcc/testsuite/g++.target/i386/mv5.C @@ -1,7 +1,7 @@ /* Test case to check if multiversioned functions are still generated if they are marked comdat with inline keyword. */ -/* { dg-do run { target i?86-*-* x86_64-*-* } } */ +/* { dg-do run } */ /* { dg-require-ifunc "" } */ /* { dg-options "-O2" } */ diff --git a/gcc/testsuite/g++.dg/ext/mv6.C b/gcc/testsuite/g++.target/i386/mv6.C index 2273065..766b6de 100644 --- a/gcc/testsuite/g++.dg/ext/mv6.C +++ b/gcc/testsuite/g++.target/i386/mv6.C @@ -1,6 +1,6 @@ /* Test to check if member version multiversioning works correctly. */ -/* { dg-do run { target i?86-*-* x86_64-*-* } } */ +/* { dg-do run } */ /* { dg-require-ifunc "" } */ /* { dg-options "-march=x86-64" } */ diff --git a/gcc/testsuite/g++.dg/ext/mv7.C b/gcc/testsuite/g++.target/i386/mv7.C index 64c04fa..2a7ce65 100644 --- a/gcc/testsuite/g++.dg/ext/mv7.C +++ b/gcc/testsuite/g++.target/i386/mv7.C @@ -1,4 +1,4 @@ -// { dg-do compile { target i?86-*-* x86_64-*-* } } +// { dg-do compile } // { dg-options "" } __attribute__((target ("default"))) diff --git a/gcc/testsuite/g++.dg/ext/mv8.C b/gcc/testsuite/g++.target/i386/mv8.C index b49ef84..f25399d 100644 --- a/gcc/testsuite/g++.dg/ext/mv8.C +++ b/gcc/testsuite/g++.target/i386/mv8.C @@ -1,4 +1,4 @@ -// { dg-do compile { target i?86-*-* x86_64-*-* powerpc*-*-* aarch64*-*-* } } +// { dg-do compile } // { dg-options "" } __attribute__((target (11,12))) diff --git a/gcc/testsuite/g++.dg/ext/mv9.C b/gcc/testsuite/g++.target/i386/mv9.C index c59651e..876a736 100644 --- a/gcc/testsuite/g++.dg/ext/mv9.C +++ b/gcc/testsuite/g++.target/i386/mv9.C @@ -1,4 +1,4 @@ -// { dg-do compile { target i?86-*-* x86_64-*-* } } +// { dg-do compile } // { dg-options "" } void foo (); diff --git a/gcc/testsuite/g++.dg/ext/mvc1.C b/gcc/testsuite/g++.target/i386/mvc1.C index ff37238..b307d01 100644 --- a/gcc/testsuite/g++.dg/ext/mvc1.C +++ b/gcc/testsuite/g++.target/i386/mvc1.C @@ -1,4 +1,4 @@ -/* { dg-do run { target i?86-*-* x86_64-*-* } } */ +/* { dg-do run} */ /* { dg-require-ifunc "" } */ __attribute__((target_clones("avx","arch=slm","arch=core-avx2","default"))) diff --git a/gcc/testsuite/g++.dg/ext/mvc2.C b/gcc/testsuite/g++.target/i386/mvc2.C index 1b8c6f4d..7c1fb65 100644 --- a/gcc/testsuite/g++.dg/ext/mvc2.C +++ b/gcc/testsuite/g++.target/i386/mvc2.C @@ -1,4 +1,4 @@ -/* { dg-do compile { target i?86-*-* x86_64-*-* } } */ +/* { dg-do compile } */ /* { dg-require-ifunc "" } */ __attribute__((target_clones("avx","arch=slm","default"))) diff --git a/gcc/testsuite/g++.dg/ext/mvc3.C b/gcc/testsuite/g++.target/i386/mvc3.C index d32b2c9..5d634fd 100644 --- a/gcc/testsuite/g++.dg/ext/mvc3.C +++ b/gcc/testsuite/g++.target/i386/mvc3.C @@ -1,4 +1,4 @@ -/* { dg-do compile { target i?86-*-* x86_64-*-* } } */ +/* { dg-do compile } */ /* { dg-require-ifunc "" } */ __attribute__((target("avx"))) diff --git a/gcc/testsuite/g++.dg/ext/mvc4.C b/gcc/testsuite/g++.target/i386/mvc4.C index 6e18e56..68df5e3 100644 --- a/gcc/testsuite/g++.dg/ext/mvc4.C +++ b/gcc/testsuite/g++.target/i386/mvc4.C @@ -1,4 +1,4 @@ -/* { dg-do compile { target i?86-*-* x86_64-*-* } } */ +/* { dg-do compile } */ /* { dg-require-ifunc "" } */ /* { dg-options "-mavx" } */ diff --git a/gcc/testsuite/gcc.dg/merge-all-constants-2.c b/gcc/testsuite/gcc.dg/merge-all-constants-2.c index fbdb2bb..852d35e 100644 --- a/gcc/testsuite/gcc.dg/merge-all-constants-2.c +++ b/gcc/testsuite/gcc.dg/merge-all-constants-2.c @@ -1,4 +1,5 @@ /* { dg-do compile } */ +/* { dg-require-effective-target string_merging } */ /* { dg-options "-w -O2 -fmerge-all-constants" } */ const char str1[36] = "0123456789abcdefghijklmnopqrstuvwxyz"; diff --git a/gcc/testsuite/gcc.dg/pr87286.c b/gcc/testsuite/gcc.dg/pr87286.c new file mode 100644 index 0000000..d92d29c --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr87286.c @@ -0,0 +1,3 @@ +enum foo { F }; +typedef enum foo vec_foo __attribute__((vector_size (16))); +vec_foo add (vec_foo x, vec_foo y) { return x + y; } diff --git a/gcc/testsuite/gcc.target/i386/i386.exp b/gcc/testsuite/gcc.target/i386/i386.exp index 91fa2a6..42bb7e6 100644 --- a/gcc/testsuite/gcc.target/i386/i386.exp +++ b/gcc/testsuite/gcc.target/i386/i386.exp @@ -25,477 +25,6 @@ if { ![istarget i?86*-*-*] && ![istarget x86_64-*-*] } then { load_lib gcc-dg.exp load_lib clearcap.exp -# Return 1 if attribute ms_hook_prologue is supported. -proc check_effective_target_ms_hook_prologue { } { - if { [check_no_compiler_messages ms_hook_prologue object { - void __attribute__ ((__ms_hook_prologue__)) foo (); - } ""] } { - return 1 - } else { - return 0 - } -} - -# Return 1 if 3dnow instructions can be compiled. -proc check_effective_target_3dnow { } { - return [check_no_compiler_messages 3dnow object { - typedef int __m64 __attribute__ ((__vector_size__ (8))); - typedef float __v2sf __attribute__ ((__vector_size__ (8))); - - __m64 _m_pfadd (__m64 __A, __m64 __B) - { - return (__m64) __builtin_ia32_pfadd ((__v2sf)__A, (__v2sf)__B); - } - } "-O2 -m3dnow" ] -} - -# Return 1 if sse3 instructions can be compiled. -proc check_effective_target_sse3 { } { - return [check_no_compiler_messages sse3 object { - typedef double __m128d __attribute__ ((__vector_size__ (16))); - typedef double __v2df __attribute__ ((__vector_size__ (16))); - - __m128d _mm_addsub_pd (__m128d __X, __m128d __Y) - { - return (__m128d) __builtin_ia32_addsubpd ((__v2df)__X, (__v2df)__Y); - } - } "-O2 -msse3" ] -} - -# Return 1 if ssse3 instructions can be compiled. -proc check_effective_target_ssse3 { } { - return [check_no_compiler_messages ssse3 object { - typedef long long __m128i __attribute__ ((__vector_size__ (16))); - typedef int __v4si __attribute__ ((__vector_size__ (16))); - - __m128i _mm_abs_epi32 (__m128i __X) - { - return (__m128i) __builtin_ia32_pabsd128 ((__v4si)__X); - } - } "-O2 -mssse3" ] -} - -# Return 1 if aes instructions can be compiled. -proc check_effective_target_aes { } { - return [check_no_compiler_messages aes object { - typedef long long __m128i __attribute__ ((__vector_size__ (16))); - typedef long long __v2di __attribute__ ((__vector_size__ (16))); - - __m128i _mm_aesimc_si128 (__m128i __X) - { - return (__m128i) __builtin_ia32_aesimc128 ((__v2di)__X); - } - } "-O2 -maes" ] -} - -# Return 1 if vaes instructions can be compiled. -proc check_effective_target_vaes { } { - return [check_no_compiler_messages vaes object { - typedef long long __m128i __attribute__ ((__vector_size__ (16))); - typedef long long __v2di __attribute__ ((__vector_size__ (16))); - - __m128i _mm_aesimc_si128 (__m128i __X) - { - return (__m128i) __builtin_ia32_aesimc128 ((__v2di)__X); - } - } "-O2 -maes -mavx" ] -} - -# Return 1 if pclmul instructions can be compiled. -proc check_effective_target_pclmul { } { - return [check_no_compiler_messages pclmul object { - typedef long long __m128i __attribute__ ((__vector_size__ (16))); - typedef long long __v2di __attribute__ ((__vector_size__ (16))); - - __m128i pclmulqdq_test (__m128i __X, __m128i __Y) - { - return (__m128i) __builtin_ia32_pclmulqdq128 ((__v2di)__X, - (__v2di)__Y, - 1); - } - } "-O2 -mpclmul" ] -} - -# Return 1 if vpclmul instructions can be compiled. -proc check_effective_target_vpclmul { } { - return [check_no_compiler_messages vpclmul object { - typedef long long __m128i __attribute__ ((__vector_size__ (16))); - typedef long long __v2di __attribute__ ((__vector_size__ (16))); - - __m128i pclmulqdq_test (__m128i __X, __m128i __Y) - { - return (__m128i) __builtin_ia32_pclmulqdq128 ((__v2di)__X, - (__v2di)__Y, - 1); - } - } "-O2 -mpclmul -mavx" ] -} - -# Return 1 if sse4a instructions can be compiled. -proc check_effective_target_sse4a { } { - return [check_no_compiler_messages sse4a object { - typedef long long __m128i __attribute__ ((__vector_size__ (16))); - typedef long long __v2di __attribute__ ((__vector_size__ (16))); - - __m128i _mm_insert_si64 (__m128i __X,__m128i __Y) - { - return (__m128i) __builtin_ia32_insertq ((__v2di)__X, (__v2di)__Y); - } - } "-O2 -msse4a" ] -} - -# Return 1 if fma4 instructions can be compiled. -proc check_effective_target_fma4 { } { - return [check_no_compiler_messages fma4 object { - typedef float __m128 __attribute__ ((__vector_size__ (16))); - typedef float __v4sf __attribute__ ((__vector_size__ (16))); - __m128 _mm_macc_ps(__m128 __A, __m128 __B, __m128 __C) - { - return (__m128) __builtin_ia32_vfmaddps ((__v4sf)__A, - (__v4sf)__B, - (__v4sf)__C); - } - } "-O2 -mfma4" ] -} - -# Return 1 if fma instructions can be compiled. -proc check_effective_target_fma { } { - return [check_no_compiler_messages fma object { - typedef float __m128 __attribute__ ((__vector_size__ (16))); - typedef float __v4sf __attribute__ ((__vector_size__ (16))); - __m128 _mm_macc_ps(__m128 __A, __m128 __B, __m128 __C) - { - return (__m128) __builtin_ia32_vfmaddps ((__v4sf)__A, - (__v4sf)__B, - (__v4sf)__C); - } - } "-O2 -mfma" ] -} - -# Return 1 if xop instructions can be compiled. -proc check_effective_target_xop { } { - return [check_no_compiler_messages xop object { - typedef long long __m128i __attribute__ ((__vector_size__ (16))); - typedef short __v8hi __attribute__ ((__vector_size__ (16))); - __m128i _mm_maccs_epi16(__m128i __A, __m128i __B, __m128i __C) - { - return (__m128i) __builtin_ia32_vpmacssww ((__v8hi)__A, - (__v8hi)__B, - (__v8hi)__C); - } - } "-O2 -mxop" ] -} - -# Return 1 if lzcnt instruction can be compiled. -proc check_effective_target_lzcnt { } { - return [check_no_compiler_messages lzcnt object { - unsigned short _lzcnt (unsigned short __X) - { - return __builtin_clzs (__X); - } - } "-mlzcnt" ] -} - -# Return 1 if bmi instructions can be compiled. -proc check_effective_target_bmi { } { - return [check_no_compiler_messages bmi object { - unsigned int __bextr_u32 (unsigned int __X, unsigned int __Y) - { - return __builtin_ia32_bextr_u32 (__X, __Y); - } - } "-mbmi" ] -} - -# Return 1 if ADX instructions can be compiled. -proc check_effective_target_adx { } { - return [check_no_compiler_messages adx object { - unsigned char - _adxcarry_u32 (unsigned char __CF, unsigned int __X, - unsigned int __Y, unsigned int *__P) - { - return __builtin_ia32_addcarryx_u32 (__CF, __X, __Y, __P); - } - } "-madx" ] -} - -# Return 1 if rtm instructions can be compiled. -proc check_effective_target_rtm { } { - return [check_no_compiler_messages rtm object { - void - _rtm_xend (void) - { - return __builtin_ia32_xend (); - } - } "-mrtm" ] -} - -# Return 1 if avx512vl instructions can be compiled. -proc check_effective_target_avx512vl { } { - return [check_no_compiler_messages avx512vl object { - typedef long long __v4di __attribute__ ((__vector_size__ (32))); - __v4di - mm256_and_epi64 (__v4di __X, __v4di __Y) - { - __v4di __W; - return __builtin_ia32_pandq256_mask (__X, __Y, __W, -1); - } - } "-mavx512vl" ] -} - -# Return 1 if avx512cd instructions can be compiled. -proc check_effective_target_avx512cd { } { - return [check_no_compiler_messages avx512cd_trans object { - typedef long long __v8di __attribute__ ((__vector_size__ (64))); - __v8di - _mm512_conflict_epi64 (__v8di __W, __v8di __A) - { - return (__v8di) __builtin_ia32_vpconflictdi_512_mask ((__v8di) __A, - (__v8di) __W, - -1); - } - } "-Wno-psabi -mavx512cd" ] -} - -# Return 1 if avx512er instructions can be compiled. -proc check_effective_target_avx512er { } { - return [check_no_compiler_messages avx512er_trans object { - typedef float __v16sf __attribute__ ((__vector_size__ (64))); - __v16sf - mm512_exp2a23_ps (__v16sf __X) - { - return __builtin_ia32_exp2ps_mask (__X, __X, -1, 4); - } - } "-Wno-psabi -mavx512er" ] -} - -# Return 1 if sha instructions can be compiled. -proc check_effective_target_sha { } { - return [check_no_compiler_messages sha object { - typedef long long __m128i __attribute__ ((__vector_size__ (16))); - typedef int __v4si __attribute__ ((__vector_size__ (16))); - - __m128i _mm_sha1msg1_epu32 (__m128i __X, __m128i __Y) - { - return (__m128i) __builtin_ia32_sha1msg1 ((__v4si)__X, - (__v4si)__Y); - } - } "-O2 -msha" ] -} - -# Return 1 if avx512dq instructions can be compiled. -proc check_effective_target_avx512dq { } { - return [check_no_compiler_messages avx512dq object { - typedef long long __v8di __attribute__ ((__vector_size__ (64))); - __v8di - _mm512_mask_mullo_epi64 (__v8di __W, __v8di __A, __v8di __B) - { - return (__v8di) __builtin_ia32_pmullq512_mask ((__v8di) __A, - (__v8di) __B, - (__v8di) __W, - -1); - } - } "-mavx512dq" ] -} - -# Return 1 if avx512bw instructions can be compiled. -proc check_effective_target_avx512bw { } { - return [check_no_compiler_messages avx512bw object { - typedef short __v32hi __attribute__ ((__vector_size__ (64))); - __v32hi - _mm512_mask_mulhrs_epi16 (__v32hi __W, __v32hi __A, __v32hi __B) - { - return (__v32hi) __builtin_ia32_pmulhrsw512_mask ((__v32hi) __A, - (__v32hi) __B, - (__v32hi) __W, - -1); - } - } "-mavx512bw" ] -} - -# Return 1 if avx512ifma instructions can be compiled. -proc check_effective_target_avx512ifma { } { - return [check_no_compiler_messages avx512ifma object { - typedef long long __v8di __attribute__ ((__vector_size__ (64))); - __v8di - _mm512_madd52lo_epu64 (__v8di __X, __v8di __Y, __v8di __Z) - { - return (__v8di) __builtin_ia32_vpmadd52luq512_mask ((__v8di) __X, - (__v8di) __Y, - (__v8di) __Z, - -1); - } - } "-mavx512ifma" ] -} - -# Return 1 if avx512vbmi instructions can be compiled. -proc check_effective_target_avx512vbmi { } { - return [check_no_compiler_messages avx512vbmi object { - typedef char __v64qi __attribute__ ((__vector_size__ (64))); - __v64qi - _mm512_multishift_epi64_epi8 (__v64qi __X, __v64qi __Y) - { - return (__v64qi) __builtin_ia32_vpmultishiftqb512_mask ((__v64qi) __X, - (__v64qi) __Y, - (__v64qi) __Y, - -1); - } - } "-mavx512vbmi" ] -} - -# Return 1 if avx512_4fmaps instructions can be compiled. -proc check_effective_target_avx5124fmaps { } { - return [check_no_compiler_messages avx5124fmaps object { - typedef float __v16sf __attribute__ ((__vector_size__ (64))); - typedef float __v4sf __attribute__ ((__vector_size__ (16))); - - __v16sf - _mm512_mask_4fmadd_ps (__v16sf __DEST, __v16sf __A, __v16sf __B, __v16sf __C, - __v16sf __D, __v16sf __E, __v4sf *__F) - { - return (__v16sf) __builtin_ia32_4fmaddps_mask ((__v16sf) __A, - (__v16sf) __B, - (__v16sf) __C, - (__v16sf) __D, - (__v16sf) __E, - (const __v4sf *) __F, - (__v16sf) __DEST, - 0xffff); - } - } "-mavx5124fmaps" ] -} - -# Return 1 if avx512_4vnniw instructions can be compiled. -proc check_effective_target_avx5124vnniw { } { - return [check_no_compiler_messages avx5124vnniw object { - typedef int __v16si __attribute__ ((__vector_size__ (64))); - typedef int __v4si __attribute__ ((__vector_size__ (16))); - - __v16si - _mm512_4dpwssd_epi32 (__v16si __A, __v16si __B, __v16si __C, - __v16si __D, __v16si __E, __v4si *__F) - { - return (__v16si) __builtin_ia32_vp4dpwssd ((__v16si) __B, - (__v16si) __C, - (__v16si) __D, - (__v16si) __E, - (__v16si) __A, - (const __v4si *) __F); - } - } "-mavx5124vnniw" ] -} - -# Return 1 if avx512_vpopcntdq instructions can be compiled. -proc check_effective_target_avx512vpopcntdq { } { - return [check_no_compiler_messages avx512vpopcntdq object { - typedef int __v16si __attribute__ ((__vector_size__ (64))); - - __v16si - _mm512_popcnt_epi32 (__v16si __A) - { - return (__v16si) __builtin_ia32_vpopcountd_v16si ((__v16si) __A); - } - } "-mavx512vpopcntdq" ] -} - -# Return 1 if 128 or 256-bit avx512_vpopcntdq instructions can be compiled. -proc check_effective_target_avx512vpopcntdqvl { } { - return [check_no_compiler_messages avx512vpopcntdqvl object { - typedef int __v8si __attribute__ ((__vector_size__ (32))); - - __v8si - _mm256_popcnt_epi32 (__v8si __A) - { - return (__v8si) __builtin_ia32_vpopcountd_v8si ((__v8si) __A); - } - } "-mavx512vpopcntdq -mavx512vl" ] -} - -# Return 1 if gfni instructions can be compiled. -proc check_effective_target_gfni { } { - return [check_no_compiler_messages gfni object { - typedef char __v16qi __attribute__ ((__vector_size__ (16))); - - __v16qi - _mm_gf2p8affineinv_epi64_epi8 (__v16qi __A, __v16qi __B, const int __C) - { - return (__v16qi) __builtin_ia32_vgf2p8affineinvqb_v16qi ((__v16qi) __A, - (__v16qi) __B, - 0); - } - } "-mgfni" ] -} - -# Return 1 if avx512vbmi2 instructions can be compiled. -proc check_effective_target_avx512vbmi2 { } { - return [check_no_compiler_messages avx512vbmi2 object { - typedef char __v16qi __attribute__ ((__vector_size__ (16))); - typedef unsigned long long __mmask16; - - __v16qi - _mm_mask_compress_epi8 (__v16qi __A, __mmask16 __B, __v16qi __C) - { - return (__v16qi) __builtin_ia32_compressqi128_mask((__v16qi)__C, - (__v16qi)__A, - (__mmask16)__B); - } - } "-mavx512vbmi2 -mavx512vl" ] -} - -# Return 1 if avx512vbmi2 instructions can be compiled. -proc check_effective_target_avx512vnni { } { - return [check_no_compiler_messages avx512vnni object { - typedef int __v16si __attribute__ ((__vector_size__ (64))); - - __v16si - _mm_mask_compress_epi8 (__v16si __A, __v16si __B, __v16si __C) - { - return (__v16si) __builtin_ia32_vpdpbusd_v16si ((__v16si)__A, - (__v16si)__B, - (__v16si)__C); - } - } "-mavx512vnni -mavx512f" ] -} - -# Return 1 if vaes instructions can be compiled. -proc check_effective_target_avx512vaes { } { - return [check_no_compiler_messages avx512vaes object { - - typedef int __v16si __attribute__ ((__vector_size__ (64))); - - __v32qi - _mm256_aesdec_epi128 (__v32qi __A, __v32qi __B) - { - return (__v32qi)__builtin_ia32_vaesdec_v32qi ((__v32qi) __A, (__v32qi) __B); - } - } "-mvaes" ] -} - -# Return 1 if vpclmulqdq instructions can be compiled. -proc check_effective_target_vpclmulqdq { } { - return [check_no_compiler_messages vpclmulqdq object { - typedef long long __v4di __attribute__ ((__vector_size__ (32))); - - __v4di - _mm256_clmulepi64_epi128 (__v4di __A, __v4di __B) - { - return (__v4di) __builtin_ia32_vpclmulqdq_v4di (__A, __B, 0); - } - } "-mvpclmulqdq -mavx512vl" ] -} - -# Return 1 if avx512_bitalg instructions can be compiled. -proc check_effective_target_avx512bitalg { } { - return [check_no_compiler_messages avx512bitalg object { - typedef short int __v32hi __attribute__ ((__vector_size__ (64))); - - __v32hi - _mm512_popcnt_epi16 (__v32hi __A) - { - return (__v32hi) __builtin_ia32_vpopcountw_v32hi ((__v32hi) __A); - } - } "-mavx512bitalg" ] -} - # If a testcase doesn't have special options, use these. global DEFAULT_CFLAGS if ![info exists DEFAULT_CFLAGS] then { diff --git a/gcc/testsuite/gcc.target/i386/pr49095.c b/gcc/testsuite/gcc.target/i386/pr49095.c index 0780719..20175e7 100644 --- a/gcc/testsuite/gcc.target/i386/pr49095.c +++ b/gcc/testsuite/gcc.target/i386/pr49095.c @@ -73,4 +73,5 @@ G (long) /* { dg-final { scan-assembler-not "test\[lq\]" } } */ /* The {f,h}{char,short,int,long}xor functions aren't optimized into a RMW instruction, so need load, modify and store. FIXME eventually. */ -/* { dg-final { scan-assembler-times "\\), %" 8 } } */ +/* { dg-final { scan-assembler-times "\\), %" 57 { target { ia32 } } } } */ +/* { dg-final { scan-assembler-times "\\), %" 45 { target { ! ia32 } } } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/pr86939.c b/gcc/testsuite/gcc.target/powerpc/pr86939.c new file mode 100644 index 0000000..4bc9793 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr86939.c @@ -0,0 +1,12 @@ +/* { dg-do compile { target { powerpc*-*-* } } } */ +/* { dg-options "-O2" } */ + +typedef long (*fptr_t) (void); +long +func (fptr_t *p) +{ + if (p) + return (*p) (); + return 0; +} +/* { dg-final { scan-assembler-not {mr %?r?12,} } } */ diff --git a/gcc/testsuite/gfortran.dg/array_constructor_type_23.f90 b/gcc/testsuite/gfortran.dg/array_constructor_type_23.f90 new file mode 100644 index 0000000..cb88ad2 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/array_constructor_type_23.f90 @@ -0,0 +1,7 @@ +! { dg-do compile } +! PR 83999 - this used to ICE +! Origial test case by Gerhard Steinmetz + +program p + character(2) :: c = 'a' // [character :: [1]] ! { dg-error "Illegal type in character concatenation" } +end diff --git a/gcc/testsuite/gfortran.dg/associate_41.f90 b/gcc/testsuite/gfortran.dg/associate_41.f90 new file mode 100644 index 0000000..9177582a --- /dev/null +++ b/gcc/testsuite/gfortran.dg/associate_41.f90 @@ -0,0 +1,25 @@ +! { dg-do run } +! +! Test the fix for PR86372 in which the associate name string length was +! not being set, thereby causing a segfault. +! +! Contributed by Janus Weil <janus@gcc.gnu.org> +! +program xxx + + character(len=50) :: s + + s = repeat ('*', len(s)) + call sub(s) + if (s .ne. '**'//'123'//repeat ('*', len(s) - 5)) stop 1 + +contains + + subroutine sub(str) + character(len=*), intent(inout) :: str + associate (substr => str(3:5)) + substr = '123' + end associate + end subroutine + +end diff --git a/gcc/testsuite/gfortran.dg/contiguous_4.f90 b/gcc/testsuite/gfortran.dg/contiguous_4.f90 index b05dcfb..874ef8b 100644 --- a/gcc/testsuite/gfortran.dg/contiguous_4.f90 +++ b/gcc/testsuite/gfortran.dg/contiguous_4.f90 @@ -10,10 +10,10 @@ program cont_01_neg x = (/ (real(i),i=1,45) /) x2 = reshape(x,shape(x2)) - r => x(::3) ! { dg-error "Assignment to contiguous pointer" } - r2 => x2(2:,:) ! { dg-error "Assignment to contiguous pointer" } + r => x(::3) + r2 => x2(2:,:) r2 => x2(:,2:3) r => x2(2:3,1) r => x(::1) - r => x(::n) ! { dg-error "Assignment to contiguous pointer" } + r => x(::n) end program diff --git a/gcc/testsuite/gfortran.dg/contiguous_7.f90 b/gcc/testsuite/gfortran.dg/contiguous_7.f90 new file mode 100644 index 0000000..cccc89f --- /dev/null +++ b/gcc/testsuite/gfortran.dg/contiguous_7.f90 @@ -0,0 +1,24 @@ +! { dg-do compile } +! { dg-additional-options "-Wextra" } +! +! Ensure that contiguous pointers pointing to noncontiguous pointers +! to array results in a warning with -Wextra. + +program cont_01_neg + implicit none + real, pointer, contiguous :: r(:) + real, pointer, contiguous :: r2(:,:) + real, target :: x(45) + real, target :: x2(5,9) + integer :: i + integer :: n=1 + + x = (/ (real(i),i=1,45) /) + x2 = reshape(x,shape(x2)) + r => x(::3) ! { dg-warning "ssignment to contiguous pointer from non-contiguous target" } + r2 => x2(2:,:) ! { dg-warning "ssignment to contiguous pointer from non-contiguous target" } + r2 => x2(:,2:3) + r => x2(2:3,1) + r => x(::1) + r => x(::n) ! { dg-warning "ssignment to contiguous pointer from non-contiguous target" } +end program diff --git a/gcc/testsuite/gfortran.dg/elemental_function_4.f90 b/gcc/testsuite/gfortran.dg/elemental_function_4.f90 new file mode 100644 index 0000000..fbd55ac --- /dev/null +++ b/gcc/testsuite/gfortran.dg/elemental_function_4.f90 @@ -0,0 +1,18 @@ +! { dg-do compile } +! +! Tests the fix for PR83999, where the invalid function 'f' caused an ICE. +! +! Contributed by Gerhard Steinmetz <gscfq@t-online.de> +! +program p + type t + integer :: a + end type + type(t) :: x(3) + x = f() + print *, x +contains + elemental function f() result(z) ! { dg-error "must have a scalar result" } + type(t), pointer :: z(:) + end +end diff --git a/gcc/testsuite/gnat.dg/string_merge1.adb b/gcc/testsuite/gnat.dg/string_merge1.adb index f67c7c1..f3fcac9 100644 --- a/gcc/testsuite/gnat.dg/string_merge1.adb +++ b/gcc/testsuite/gnat.dg/string_merge1.adb @@ -1,4 +1,5 @@ -- { dg-do compile } +-- { dg-require-effective-target string_merging } -- { dg-options "-O1 -fmerge-all-constants" } procedure String_Merge1 is @@ -15,5 +16,3 @@ end; -- .string "ABCD" -- { dg-final { scan-assembler-times "\\.rodata\\.str" 1 } } --- { dg-final { scan-assembler-times "\\.string" 1 } } --- { dg-final { scan-assembler-times "\"ABCD\"" 1 } } diff --git a/gcc/testsuite/gnat.dg/string_merge2.adb b/gcc/testsuite/gnat.dg/string_merge2.adb index bbec005..3615b0d 100644 --- a/gcc/testsuite/gnat.dg/string_merge2.adb +++ b/gcc/testsuite/gnat.dg/string_merge2.adb @@ -1,4 +1,5 @@ -- { dg-do compile } +-- { dg-require-effective-target string_merging } -- { dg-options "-O1 -fmerge-all-constants" } procedure String_Merge2 is @@ -15,5 +16,3 @@ end; -- .string "ABCD" -- { dg-final { scan-assembler-times "\\.rodata\\.str" 1 } } --- { dg-final { scan-assembler-times "\\.string" 1 } } --- { dg-final { scan-assembler-times "\"ABCD\"" 1 } } diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index b82c332..fd74c04 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -7296,6 +7296,476 @@ proc check_effective_target_f16c { } { } "-O2 -mf16c" ] } +proc check_effective_target_ms_hook_prologue { } { + if { [check_no_compiler_messages ms_hook_prologue object { + void __attribute__ ((__ms_hook_prologue__)) foo (); + } ""] } { + return 1 + } else { + return 0 + } +} + +# Return 1 if 3dnow instructions can be compiled. +proc check_effective_target_3dnow { } { + return [check_no_compiler_messages 3dnow object { + typedef int __m64 __attribute__ ((__vector_size__ (8))); + typedef float __v2sf __attribute__ ((__vector_size__ (8))); + + __m64 _m_pfadd (__m64 __A, __m64 __B) + { + return (__m64) __builtin_ia32_pfadd ((__v2sf)__A, (__v2sf)__B); + } + } "-O2 -m3dnow" ] +} + +# Return 1 if sse3 instructions can be compiled. +proc check_effective_target_sse3 { } { + return [check_no_compiler_messages sse3 object { + typedef double __m128d __attribute__ ((__vector_size__ (16))); + typedef double __v2df __attribute__ ((__vector_size__ (16))); + + __m128d _mm_addsub_pd (__m128d __X, __m128d __Y) + { + return (__m128d) __builtin_ia32_addsubpd ((__v2df)__X, (__v2df)__Y); + } + } "-O2 -msse3" ] +} + +# Return 1 if ssse3 instructions can be compiled. +proc check_effective_target_ssse3 { } { + return [check_no_compiler_messages ssse3 object { + typedef long long __m128i __attribute__ ((__vector_size__ (16))); + typedef int __v4si __attribute__ ((__vector_size__ (16))); + + __m128i _mm_abs_epi32 (__m128i __X) + { + return (__m128i) __builtin_ia32_pabsd128 ((__v4si)__X); + } + } "-O2 -mssse3" ] +} + +# Return 1 if aes instructions can be compiled. +proc check_effective_target_aes { } { + return [check_no_compiler_messages aes object { + typedef long long __m128i __attribute__ ((__vector_size__ (16))); + typedef long long __v2di __attribute__ ((__vector_size__ (16))); + + __m128i _mm_aesimc_si128 (__m128i __X) + { + return (__m128i) __builtin_ia32_aesimc128 ((__v2di)__X); + } + } "-O2 -maes" ] +} + +# Return 1 if vaes instructions can be compiled. +proc check_effective_target_vaes { } { + return [check_no_compiler_messages vaes object { + typedef long long __m128i __attribute__ ((__vector_size__ (16))); + typedef long long __v2di __attribute__ ((__vector_size__ (16))); + + __m128i _mm_aesimc_si128 (__m128i __X) + { + return (__m128i) __builtin_ia32_aesimc128 ((__v2di)__X); + } + } "-O2 -maes -mavx" ] +} + +# Return 1 if pclmul instructions can be compiled. +proc check_effective_target_pclmul { } { + return [check_no_compiler_messages pclmul object { + typedef long long __m128i __attribute__ ((__vector_size__ (16))); + typedef long long __v2di __attribute__ ((__vector_size__ (16))); + + __m128i pclmulqdq_test (__m128i __X, __m128i __Y) + { + return (__m128i) __builtin_ia32_pclmulqdq128 ((__v2di)__X, + (__v2di)__Y, + 1); + } + } "-O2 -mpclmul" ] +} + +# Return 1 if vpclmul instructions can be compiled. +proc check_effective_target_vpclmul { } { + return [check_no_compiler_messages vpclmul object { + typedef long long __m128i __attribute__ ((__vector_size__ (16))); + typedef long long __v2di __attribute__ ((__vector_size__ (16))); + + __m128i pclmulqdq_test (__m128i __X, __m128i __Y) + { + return (__m128i) __builtin_ia32_pclmulqdq128 ((__v2di)__X, + (__v2di)__Y, + 1); + } + } "-O2 -mpclmul -mavx" ] +} + +# Return 1 if sse4a instructions can be compiled. +proc check_effective_target_sse4a { } { + return [check_no_compiler_messages sse4a object { + typedef long long __m128i __attribute__ ((__vector_size__ (16))); + typedef long long __v2di __attribute__ ((__vector_size__ (16))); + + __m128i _mm_insert_si64 (__m128i __X,__m128i __Y) + { + return (__m128i) __builtin_ia32_insertq ((__v2di)__X, (__v2di)__Y); + } + } "-O2 -msse4a" ] +} + +# Return 1 if fma4 instructions can be compiled. +proc check_effective_target_fma4 { } { + return [check_no_compiler_messages fma4 object { + typedef float __m128 __attribute__ ((__vector_size__ (16))); + typedef float __v4sf __attribute__ ((__vector_size__ (16))); + __m128 _mm_macc_ps(__m128 __A, __m128 __B, __m128 __C) + { + return (__m128) __builtin_ia32_vfmaddps ((__v4sf)__A, + (__v4sf)__B, + (__v4sf)__C); + } + } "-O2 -mfma4" ] +} + +# Return 1 if fma instructions can be compiled. +proc check_effective_target_fma { } { + return [check_no_compiler_messages fma object { + typedef float __m128 __attribute__ ((__vector_size__ (16))); + typedef float __v4sf __attribute__ ((__vector_size__ (16))); + __m128 _mm_macc_ps(__m128 __A, __m128 __B, __m128 __C) + { + return (__m128) __builtin_ia32_vfmaddps ((__v4sf)__A, + (__v4sf)__B, + (__v4sf)__C); + } + } "-O2 -mfma" ] +} + +# Return 1 if xop instructions can be compiled. +proc check_effective_target_xop { } { + return [check_no_compiler_messages xop object { + typedef long long __m128i __attribute__ ((__vector_size__ (16))); + typedef short __v8hi __attribute__ ((__vector_size__ (16))); + __m128i _mm_maccs_epi16(__m128i __A, __m128i __B, __m128i __C) + { + return (__m128i) __builtin_ia32_vpmacssww ((__v8hi)__A, + (__v8hi)__B, + (__v8hi)__C); + } + } "-O2 -mxop" ] +} + +# Return 1 if lzcnt instruction can be compiled. +proc check_effective_target_lzcnt { } { + return [check_no_compiler_messages lzcnt object { + unsigned short _lzcnt (unsigned short __X) + { + return __builtin_clzs (__X); + } + } "-mlzcnt" ] +} + +# Return 1 if bmi instructions can be compiled. +proc check_effective_target_bmi { } { + return [check_no_compiler_messages bmi object { + unsigned int __bextr_u32 (unsigned int __X, unsigned int __Y) + { + return __builtin_ia32_bextr_u32 (__X, __Y); + } + } "-mbmi" ] +} + +# Return 1 if ADX instructions can be compiled. +proc check_effective_target_adx { } { + return [check_no_compiler_messages adx object { + unsigned char + _adxcarry_u32 (unsigned char __CF, unsigned int __X, + unsigned int __Y, unsigned int *__P) + { + return __builtin_ia32_addcarryx_u32 (__CF, __X, __Y, __P); + } + } "-madx" ] +} + +# Return 1 if rtm instructions can be compiled. +proc check_effective_target_rtm { } { + return [check_no_compiler_messages rtm object { + void + _rtm_xend (void) + { + return __builtin_ia32_xend (); + } + } "-mrtm" ] +} + +# Return 1 if avx512vl instructions can be compiled. +proc check_effective_target_avx512vl { } { + return [check_no_compiler_messages avx512vl object { + typedef long long __v4di __attribute__ ((__vector_size__ (32))); + __v4di + mm256_and_epi64 (__v4di __X, __v4di __Y) + { + __v4di __W; + return __builtin_ia32_pandq256_mask (__X, __Y, __W, -1); + } + } "-mavx512vl" ] +} + +# Return 1 if avx512cd instructions can be compiled. +proc check_effective_target_avx512cd { } { + return [check_no_compiler_messages avx512cd_trans object { + typedef long long __v8di __attribute__ ((__vector_size__ (64))); + __v8di + _mm512_conflict_epi64 (__v8di __W, __v8di __A) + { + return (__v8di) __builtin_ia32_vpconflictdi_512_mask ((__v8di) __A, + (__v8di) __W, + -1); + } + } "-Wno-psabi -mavx512cd" ] +} + +# Return 1 if avx512er instructions can be compiled. +proc check_effective_target_avx512er { } { + return [check_no_compiler_messages avx512er_trans object { + typedef float __v16sf __attribute__ ((__vector_size__ (64))); + __v16sf + mm512_exp2a23_ps (__v16sf __X) + { + return __builtin_ia32_exp2ps_mask (__X, __X, -1, 4); + } + } "-Wno-psabi -mavx512er" ] +} + +# Return 1 if sha instructions can be compiled. +proc check_effective_target_sha { } { + return [check_no_compiler_messages sha object { + typedef long long __m128i __attribute__ ((__vector_size__ (16))); + typedef int __v4si __attribute__ ((__vector_size__ (16))); + + __m128i _mm_sha1msg1_epu32 (__m128i __X, __m128i __Y) + { + return (__m128i) __builtin_ia32_sha1msg1 ((__v4si)__X, + (__v4si)__Y); + } + } "-O2 -msha" ] +} + +# Return 1 if avx512dq instructions can be compiled. +proc check_effective_target_avx512dq { } { + return [check_no_compiler_messages avx512dq object { + typedef long long __v8di __attribute__ ((__vector_size__ (64))); + __v8di + _mm512_mask_mullo_epi64 (__v8di __W, __v8di __A, __v8di __B) + { + return (__v8di) __builtin_ia32_pmullq512_mask ((__v8di) __A, + (__v8di) __B, + (__v8di) __W, + -1); + } + } "-mavx512dq" ] +} + +# Return 1 if avx512bw instructions can be compiled. +proc check_effective_target_avx512bw { } { + return [check_no_compiler_messages avx512bw object { + typedef short __v32hi __attribute__ ((__vector_size__ (64))); + __v32hi + _mm512_mask_mulhrs_epi16 (__v32hi __W, __v32hi __A, __v32hi __B) + { + return (__v32hi) __builtin_ia32_pmulhrsw512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) __W, + -1); + } + } "-mavx512bw" ] +} + +# Return 1 if avx512ifma instructions can be compiled. +proc check_effective_target_avx512ifma { } { + return [check_no_compiler_messages avx512ifma object { + typedef long long __v8di __attribute__ ((__vector_size__ (64))); + __v8di + _mm512_madd52lo_epu64 (__v8di __X, __v8di __Y, __v8di __Z) + { + return (__v8di) __builtin_ia32_vpmadd52luq512_mask ((__v8di) __X, + (__v8di) __Y, + (__v8di) __Z, + -1); + } + } "-mavx512ifma" ] +} + +# Return 1 if avx512vbmi instructions can be compiled. +proc check_effective_target_avx512vbmi { } { + return [check_no_compiler_messages avx512vbmi object { + typedef char __v64qi __attribute__ ((__vector_size__ (64))); + __v64qi + _mm512_multishift_epi64_epi8 (__v64qi __X, __v64qi __Y) + { + return (__v64qi) __builtin_ia32_vpmultishiftqb512_mask ((__v64qi) __X, + (__v64qi) __Y, + (__v64qi) __Y, + -1); + } + } "-mavx512vbmi" ] +} + +# Return 1 if avx512_4fmaps instructions can be compiled. +proc check_effective_target_avx5124fmaps { } { + return [check_no_compiler_messages avx5124fmaps object { + typedef float __v16sf __attribute__ ((__vector_size__ (64))); + typedef float __v4sf __attribute__ ((__vector_size__ (16))); + + __v16sf + _mm512_mask_4fmadd_ps (__v16sf __DEST, __v16sf __A, __v16sf __B, __v16sf __C, + __v16sf __D, __v16sf __E, __v4sf *__F) + { + return (__v16sf) __builtin_ia32_4fmaddps_mask ((__v16sf) __A, + (__v16sf) __B, + (__v16sf) __C, + (__v16sf) __D, + (__v16sf) __E, + (const __v4sf *) __F, + (__v16sf) __DEST, + 0xffff); + } + } "-mavx5124fmaps" ] +} + +# Return 1 if avx512_4vnniw instructions can be compiled. +proc check_effective_target_avx5124vnniw { } { + return [check_no_compiler_messages avx5124vnniw object { + typedef int __v16si __attribute__ ((__vector_size__ (64))); + typedef int __v4si __attribute__ ((__vector_size__ (16))); + + __v16si + _mm512_4dpwssd_epi32 (__v16si __A, __v16si __B, __v16si __C, + __v16si __D, __v16si __E, __v4si *__F) + { + return (__v16si) __builtin_ia32_vp4dpwssd ((__v16si) __B, + (__v16si) __C, + (__v16si) __D, + (__v16si) __E, + (__v16si) __A, + (const __v4si *) __F); + } + } "-mavx5124vnniw" ] +} + +# Return 1 if avx512_vpopcntdq instructions can be compiled. +proc check_effective_target_avx512vpopcntdq { } { + return [check_no_compiler_messages avx512vpopcntdq object { + typedef int __v16si __attribute__ ((__vector_size__ (64))); + + __v16si + _mm512_popcnt_epi32 (__v16si __A) + { + return (__v16si) __builtin_ia32_vpopcountd_v16si ((__v16si) __A); + } + } "-mavx512vpopcntdq" ] +} + +# Return 1 if 128 or 256-bit avx512_vpopcntdq instructions can be compiled. +proc check_effective_target_avx512vpopcntdqvl { } { + return [check_no_compiler_messages avx512vpopcntdqvl object { + typedef int __v8si __attribute__ ((__vector_size__ (32))); + + __v8si + _mm256_popcnt_epi32 (__v8si __A) + { + return (__v8si) __builtin_ia32_vpopcountd_v8si ((__v8si) __A); + } + } "-mavx512vpopcntdq -mavx512vl" ] +} + +# Return 1 if gfni instructions can be compiled. +proc check_effective_target_gfni { } { + return [check_no_compiler_messages gfni object { + typedef char __v16qi __attribute__ ((__vector_size__ (16))); + + __v16qi + _mm_gf2p8affineinv_epi64_epi8 (__v16qi __A, __v16qi __B, const int __C) + { + return (__v16qi) __builtin_ia32_vgf2p8affineinvqb_v16qi ((__v16qi) __A, + (__v16qi) __B, + 0); + } + } "-mgfni" ] +} + +# Return 1 if avx512vbmi2 instructions can be compiled. +proc check_effective_target_avx512vbmi2 { } { + return [check_no_compiler_messages avx512vbmi2 object { + typedef char __v16qi __attribute__ ((__vector_size__ (16))); + typedef unsigned long long __mmask16; + + __v16qi + _mm_mask_compress_epi8 (__v16qi __A, __mmask16 __B, __v16qi __C) + { + return (__v16qi) __builtin_ia32_compressqi128_mask((__v16qi)__C, + (__v16qi)__A, + (__mmask16)__B); + } + } "-mavx512vbmi2 -mavx512vl" ] +} + +# Return 1 if avx512vbmi2 instructions can be compiled. +proc check_effective_target_avx512vnni { } { + return [check_no_compiler_messages avx512vnni object { + typedef int __v16si __attribute__ ((__vector_size__ (64))); + + __v16si + _mm_mask_compress_epi8 (__v16si __A, __v16si __B, __v16si __C) + { + return (__v16si) __builtin_ia32_vpdpbusd_v16si ((__v16si)__A, + (__v16si)__B, + (__v16si)__C); + } + } "-mavx512vnni -mavx512f" ] +} + +# Return 1 if vaes instructions can be compiled. +proc check_effective_target_avx512vaes { } { + return [check_no_compiler_messages avx512vaes object { + + typedef int __v16si __attribute__ ((__vector_size__ (64))); + + __v32qi + _mm256_aesdec_epi128 (__v32qi __A, __v32qi __B) + { + return (__v32qi)__builtin_ia32_vaesdec_v32qi ((__v32qi) __A, (__v32qi) __B); + } + } "-mvaes" ] +} + +# Return 1 if vpclmulqdq instructions can be compiled. +proc check_effective_target_vpclmulqdq { } { + return [check_no_compiler_messages vpclmulqdq object { + typedef long long __v4di __attribute__ ((__vector_size__ (32))); + + __v4di + _mm256_clmulepi64_epi128 (__v4di __A, __v4di __B) + { + return (__v4di) __builtin_ia32_vpclmulqdq_v4di (__A, __B, 0); + } + } "-mvpclmulqdq -mavx512vl" ] +} + +# Return 1 if avx512_bitalg instructions can be compiled. +proc check_effective_target_avx512bitalg { } { + return [check_no_compiler_messages avx512bitalg object { + typedef short int __v32hi __attribute__ ((__vector_size__ (64))); + + __v32hi + _mm512_popcnt_epi16 (__v32hi __A) + { + return (__v32hi) __builtin_ia32_vpopcountw_v32hi ((__v32hi) __A); + } + } "-mavx512bitalg" ] +} + # Return 1 if C wchar_t type is compatible with char16_t. proc check_effective_target_wchar_t_char16_t_compatible { } { diff --git a/gcc/tree-ssa-propagate.c b/gcc/tree-ssa-propagate.c index 4cb0fba..b1bfdd5 100644 --- a/gcc/tree-ssa-propagate.c +++ b/gcc/tree-ssa-propagate.c @@ -143,10 +143,12 @@ add_ssa_edge (tree var) FOR_EACH_IMM_USE_FAST (use_p, iter, var) { gimple *use_stmt = USE_STMT (use_p); - basic_block use_bb = gimple_bb (use_stmt); + if (!prop_simulate_again_p (use_stmt)) + continue; /* If we did not yet simulate the block wait for this to happen and do not add the stmt to the SSA edge worklist. */ + basic_block use_bb = gimple_bb (use_stmt); if (! (use_bb->flags & BB_VISITED)) continue; @@ -157,9 +159,6 @@ add_ssa_edge (tree var) & EDGE_EXECUTABLE)) continue; - if (!prop_simulate_again_p (use_stmt)) - continue; - bitmap worklist; if (bb_to_cfg_order[gimple_bb (use_stmt)->index] < curr_order) worklist = ssa_edge_worklist_back; @@ -804,7 +803,6 @@ ssa_propagation_engine::ssa_propagate (void) else { curr_order = next_stmt_bb_order; - bitmap_clear_bit (ssa_edge_worklist, next_stmt_uid); if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, "\nSimulating statement: "); diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c index 6ea1e77..177b284 100644 --- a/gcc/tree-vect-loop.c +++ b/gcc/tree-vect-loop.c @@ -1072,6 +1072,8 @@ vect_compute_single_scalar_iteration_cost (loop_vec_info loop_vinfo) int nbbs = loop->num_nodes, factor; int innerloop_iters, i; + DUMP_VECT_SCOPE ("vect_compute_single_scalar_iteration_cost"); + /* Gather costs for statements in the scalar loop. */ /* FORNOW. */ diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c index 747fb67..0ab366b 100644 --- a/gcc/tree-vectorizer.c +++ b/gcc/tree-vectorizer.c @@ -89,7 +89,7 @@ dump_user_location_t vect_location; void dump_stmt_cost (FILE *f, void *data, int count, enum vect_cost_for_stmt kind, - stmt_vec_info stmt_info, int misalign, + stmt_vec_info stmt_info, int misalign, unsigned cost, enum vect_cost_model_location where) { fprintf (f, "%p ", data); @@ -159,6 +159,7 @@ dump_stmt_cost (FILE *f, void *data, int count, enum vect_cost_for_stmt kind, fprintf (f, "%s ", ks); if (kind == unaligned_load || kind == unaligned_store) fprintf (f, "(misalign %d) ", misalign); + fprintf (f, "costs %u ", cost); const char *ws = "unknown"; switch (where) { diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h index 63cff79..9884568 100644 --- a/gcc/tree-vectorizer.h +++ b/gcc/tree-vectorizer.h @@ -1199,7 +1199,8 @@ init_cost (struct loop *loop_info) } extern void dump_stmt_cost (FILE *, void *, int, enum vect_cost_for_stmt, - stmt_vec_info, int, enum vect_cost_model_location); + stmt_vec_info, int, unsigned, + enum vect_cost_model_location); /* Alias targetm.vectorize.add_stmt_cost. */ @@ -1208,10 +1209,12 @@ add_stmt_cost (void *data, int count, enum vect_cost_for_stmt kind, stmt_vec_info stmt_info, int misalign, enum vect_cost_model_location where) { + unsigned cost = targetm.vectorize.add_stmt_cost (data, count, kind, + stmt_info, misalign, where); if (dump_file && (dump_flags & TDF_DETAILS)) - dump_stmt_cost (dump_file, data, count, kind, stmt_info, misalign, where); - return targetm.vectorize.add_stmt_cost (data, count, kind, - stmt_info, misalign, where); + dump_stmt_cost (dump_file, data, count, kind, stmt_info, misalign, + cost, where); + return cost; } /* Alias targetm.vectorize.finish_cost. */ diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index 6a8bcc2..bd5e037 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,24 @@ +2018-10-06 Janne Blomqvist <jb@gcc.gnu.org> + + * io/unix.c (compare_file_filename): Use gfc_charlen_type instead + of int for string length. + (inquire_sequential): Likewise. + (inquire_direct): Likewise. + (inquire_formatted): Likewise. + (inquire_unformatted): Likewise. + (inquire_access): Likewise. + (inquire_read): Likewise. + (inquire_write): Likewise. + (inquire_readwrite): Likewise. + * io/unix.h (compare_file_filename): Likewise. + (inquire_sequential): Likewise. + (inquire_direct): Likewise. + (inquire_formatted): Likewise. + (inquire_unformatted): Likewise. + (inquire_read): Likewise. + (inquire_write): Likewise. + (inquire_readwrite): Likewise. + 2018-10-02 Gerald Pfeifer <gerald@pfeifer.com> * io/close.c [!HAVE_UNLINK_OPEN_FILE]: Include <string.h>. diff --git a/libgfortran/io/unix.c b/libgfortran/io/unix.c index ad2577c..3550409 100644 --- a/libgfortran/io/unix.c +++ b/libgfortran/io/unix.c @@ -1622,7 +1622,7 @@ error_stream (void) filename. */ int -compare_file_filename (gfc_unit *u, const char *name, int len) +compare_file_filename (gfc_unit *u, const char *name, gfc_charlen_type len) { struct stat st; int ret; @@ -1918,7 +1918,7 @@ static const char yes[] = "YES", no[] = "NO", unknown[] = "UNKNOWN"; string. */ const char * -inquire_sequential (const char *string, int len) +inquire_sequential (const char *string, gfc_charlen_type len) { struct stat statbuf; @@ -1947,7 +1947,7 @@ inquire_sequential (const char *string, int len) suitable for direct access. Returns a C-style string. */ const char * -inquire_direct (const char *string, int len) +inquire_direct (const char *string, gfc_charlen_type len) { struct stat statbuf; @@ -1976,7 +1976,7 @@ inquire_direct (const char *string, int len) is suitable for formatted form. Returns a C-style string. */ const char * -inquire_formatted (const char *string, int len) +inquire_formatted (const char *string, gfc_charlen_type len) { struct stat statbuf; @@ -2006,7 +2006,7 @@ inquire_formatted (const char *string, int len) is suitable for unformatted form. Returns a C-style string. */ const char * -inquire_unformatted (const char *string, int len) +inquire_unformatted (const char *string, gfc_charlen_type len) { return inquire_formatted (string, len); } @@ -2016,7 +2016,7 @@ inquire_unformatted (const char *string, int len) suitable for access. */ static const char * -inquire_access (const char *string, int len, int mode) +inquire_access (const char *string, gfc_charlen_type len, int mode) { if (string == NULL) return no; @@ -2034,7 +2034,7 @@ inquire_access (const char *string, int len, int mode) suitable for READ access. */ const char * -inquire_read (const char *string, int len) +inquire_read (const char *string, gfc_charlen_type len) { return inquire_access (string, len, R_OK); } @@ -2044,7 +2044,7 @@ inquire_read (const char *string, int len) suitable for READ access. */ const char * -inquire_write (const char *string, int len) +inquire_write (const char *string, gfc_charlen_type len) { return inquire_access (string, len, W_OK); } @@ -2054,7 +2054,7 @@ inquire_write (const char *string, int len) suitable for read and write access. */ const char * -inquire_readwrite (const char *string, int len) +inquire_readwrite (const char *string, gfc_charlen_type len) { return inquire_access (string, len, R_OK | W_OK); } diff --git a/libgfortran/io/unix.h b/libgfortran/io/unix.h index 9ad6dfa..133e3e1 100644 --- a/libgfortran/io/unix.h +++ b/libgfortran/io/unix.h @@ -135,7 +135,7 @@ internal_proto(output_stream); extern stream *error_stream (void); internal_proto(error_stream); -extern int compare_file_filename (gfc_unit *, const char *, int); +extern int compare_file_filename (gfc_unit *, const char *, gfc_charlen_type); internal_proto(compare_file_filename); extern gfc_unit *find_file (const char *file, gfc_charlen_type file_len); @@ -150,25 +150,25 @@ internal_proto(file_exists); extern GFC_IO_INT file_size (const char *file, gfc_charlen_type file_len); internal_proto(file_size); -extern const char *inquire_sequential (const char *, int); +extern const char *inquire_sequential (const char *, gfc_charlen_type); internal_proto(inquire_sequential); -extern const char *inquire_direct (const char *, int); +extern const char *inquire_direct (const char *, gfc_charlen_type); internal_proto(inquire_direct); -extern const char *inquire_formatted (const char *, int); +extern const char *inquire_formatted (const char *, gfc_charlen_type); internal_proto(inquire_formatted); -extern const char *inquire_unformatted (const char *, int); +extern const char *inquire_unformatted (const char *, gfc_charlen_type); internal_proto(inquire_unformatted); -extern const char *inquire_read (const char *, int); +extern const char *inquire_read (const char *, gfc_charlen_type); internal_proto(inquire_read); -extern const char *inquire_write (const char *, int); +extern const char *inquire_write (const char *, gfc_charlen_type); internal_proto(inquire_write); -extern const char *inquire_readwrite (const char *, int); +extern const char *inquire_readwrite (const char *, gfc_charlen_type); internal_proto(inquire_readwrite); extern void flush_if_preconnected (stream *); diff --git a/libgo/MERGE b/libgo/MERGE index 9b90798..b2803e8 100644 --- a/libgo/MERGE +++ b/libgo/MERGE @@ -1,4 +1,4 @@ -41e62b8c49d21659b48a95216e3062032285250f +26957168c4c0cdcc7ca4f0b19d0eb19474d224ac The first line of this file holds the git revision number of the last merge done from the master library sources. diff --git a/libgo/VERSION b/libgo/VERSION index f3220fb..0ff4ff6 100644 --- a/libgo/VERSION +++ b/libgo/VERSION @@ -1 +1 @@ -go1.11 +go1.11.1 diff --git a/libgo/go/cmd/go/alldocs.go b/libgo/go/cmd/go/alldocs.go index ebbd154..1060e77 100644 --- a/libgo/go/cmd/go/alldocs.go +++ b/libgo/go/cmd/go/alldocs.go @@ -1449,6 +1449,12 @@ // The directory where the go command will write // temporary source files, packages, and binaries. // +// Each entry in the GOFLAGS list must be a standalone flag. +// Because the entries are space-separated, flag values must +// not contain spaces. In some cases, you can provide multiple flag +// values instead: for example, to set '-ldflags=-s -w' +// you can use 'GOFLAGS=-ldflags=-s -ldflags=-w'. +// // Environment variables for use with cgo: // // CC diff --git a/libgo/go/cmd/go/internal/help/helpdoc.go b/libgo/go/cmd/go/internal/help/helpdoc.go index aff4ce1..e2c4e61 100644 --- a/libgo/go/cmd/go/internal/help/helpdoc.go +++ b/libgo/go/cmd/go/internal/help/helpdoc.go @@ -507,6 +507,12 @@ General-purpose environment variables: The directory where the go command will write temporary source files, packages, and binaries. +Each entry in the GOFLAGS list must be a standalone flag. +Because the entries are space-separated, flag values must +not contain spaces. In some cases, you can provide multiple flag +values instead: for example, to set '-ldflags=-s -w' +you can use 'GOFLAGS=-ldflags=-s -ldflags=-w'. + Environment variables for use with cgo: CC diff --git a/libgo/go/cmd/go/internal/work/exec.go b/libgo/go/cmd/go/internal/work/exec.go index 84870e5..8aba293 100644 --- a/libgo/go/cmd/go/internal/work/exec.go +++ b/libgo/go/cmd/go/internal/work/exec.go @@ -224,7 +224,9 @@ func (b *Builder) buildActionID(a *Action) cache.ActionID { if len(p.SFiles) > 0 { fmt.Fprintf(h, "asm %q %q %q\n", b.toolID("asm"), forcedAsmflags, p.Internal.Asmflags) } - fmt.Fprintf(h, "GO$GOARCH=%s\n", os.Getenv("GO"+strings.ToUpper(cfg.BuildContext.GOARCH))) // GO386, GOARM, etc + // GO386, GOARM, GOMIPS, etc. + baseArch := strings.TrimSuffix(cfg.BuildContext.GOARCH, "le") + fmt.Fprintf(h, "GO$GOARCH=%s\n", os.Getenv("GO"+strings.ToUpper(baseArch))) // TODO(rsc): Convince compiler team not to add more magic environment variables, // or perhaps restrict the environment variables passed to subprocesses. diff --git a/libgo/go/cmd/go/internal/work/security.go b/libgo/go/cmd/go/internal/work/security.go index d5d1261..2132c5f 100644 --- a/libgo/go/cmd/go/internal/work/security.go +++ b/libgo/go/cmd/go/internal/work/security.go @@ -170,6 +170,7 @@ var validLinkerFlags = []*regexp.Regexp{ re(`-Wl,-e[=,][a-zA-Z0-9]*`), re(`-Wl,--enable-new-dtags`), re(`-Wl,--end-group`), + re(`-Wl,--(no-)?export-dynamic`), re(`-Wl,-framework,[^,@\-][^,]+`), re(`-Wl,-headerpad_max_install_names`), re(`-Wl,--no-undefined`), diff --git a/libgo/go/cmd/go/script_test.go b/libgo/go/cmd/go/script_test.go index 9e958e0..6399faa 100644 --- a/libgo/go/cmd/go/script_test.go +++ b/libgo/go/cmd/go/script_test.go @@ -635,6 +635,9 @@ func scriptMatch(ts *testScript, neg bool, args []string, text, name string) { text = string(data) } + // Matching against workdir would be misleading. + text = strings.Replace(text, ts.workdir, "$WORK", -1) + if neg { if re.MatchString(text) { if isGrep { diff --git a/libgo/go/crypto/x509/verify.go b/libgo/go/crypto/x509/verify.go index 210db4c..0b75778 100644 --- a/libgo/go/crypto/x509/verify.go +++ b/libgo/go/crypto/x509/verify.go @@ -894,8 +894,8 @@ func validHostname(host string) bool { if c == '-' && j != 0 { continue } - if c == '_' { - // _ is not a valid character in hostnames, but it's commonly + if c == '_' || c == ':' { + // Not valid characters in hostnames, but commonly // found in deployments outside the WebPKI. continue } diff --git a/libgo/go/crypto/x509/verify_test.go b/libgo/go/crypto/x509/verify_test.go index 7684145..0e24d3b 100644 --- a/libgo/go/crypto/x509/verify_test.go +++ b/libgo/go/crypto/x509/verify_test.go @@ -1881,6 +1881,7 @@ func TestValidHostname(t *testing.T) { {"foo.*.example.com", false}, {"exa_mple.com", true}, {"foo,bar", false}, + {"project-dev:us-central1:main", true}, } for _, tt := range tests { if got := validHostname(tt.host); got != tt.want { diff --git a/libgo/go/encoding/json/decode.go b/libgo/go/encoding/json/decode.go index 0b29249..7d23508 100644 --- a/libgo/go/encoding/json/decode.go +++ b/libgo/go/encoding/json/decode.go @@ -672,6 +672,7 @@ func (d *decodeState) object(v reflect.Value) error { } var mapElem reflect.Value + originalErrorContext := d.errorContext for { // Read opening " of string key or closing }. @@ -832,8 +833,7 @@ func (d *decodeState) object(v reflect.Value) error { return errPhase } - d.errorContext.Struct = "" - d.errorContext.Field = "" + d.errorContext = originalErrorContext } return nil } @@ -991,7 +991,7 @@ func (d *decodeState) literalStore(item []byte, v reflect.Value, fromQuoted bool if fromQuoted { return fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()) } - return &UnmarshalTypeError{Value: "number", Type: v.Type(), Offset: int64(d.readIndex())} + d.saveError(&UnmarshalTypeError{Value: "number", Type: v.Type(), Offset: int64(d.readIndex())}) case reflect.Interface: n, err := d.convertNumber(s) if err != nil { diff --git a/libgo/go/encoding/json/decode_test.go b/libgo/go/encoding/json/decode_test.go index ab83b81..5746ddf 100644 --- a/libgo/go/encoding/json/decode_test.go +++ b/libgo/go/encoding/json/decode_test.go @@ -371,6 +371,10 @@ func (b *intWithPtrMarshalText) UnmarshalText(data []byte) error { return (*intWithMarshalText)(b).UnmarshalText(data) } +type mapStringToStringData struct { + Data map[string]string `json:"data"` +} + type unmarshalTest struct { in string ptr interface{} @@ -401,6 +405,7 @@ var unmarshalTests = []unmarshalTest{ {in: `"invalid: \uD834x\uDD1E"`, ptr: new(string), out: "invalid: \uFFFDx\uFFFD"}, {in: "null", ptr: new(interface{}), out: nil}, {in: `{"X": [1,2,3], "Y": 4}`, ptr: new(T), out: T{Y: 4}, err: &UnmarshalTypeError{"array", reflect.TypeOf(""), 7, "T", "X"}}, + {in: `{"X": 23}`, ptr: new(T), out: T{}, err: &UnmarshalTypeError{"number", reflect.TypeOf(""), 8, "T", "X"}}, {in: `{"x": 1}`, ptr: new(tx), out: tx{}}, {in: `{"x": 1}`, ptr: new(tx), out: tx{}}, {in: `{"x": 1}`, ptr: new(tx), err: fmt.Errorf("json: unknown field \"x\""), disallowUnknownFields: true}, {in: `{"F1":1,"F2":2,"F3":3}`, ptr: new(V), out: V{F1: float64(1), F2: int32(2), F3: Number("3")}}, @@ -866,6 +871,18 @@ var unmarshalTests = []unmarshalTest{ err: fmt.Errorf("json: unknown field \"extra\""), disallowUnknownFields: true, }, + // issue 26444 + // UnmarshalTypeError without field & struct values + { + in: `{"data":{"test1": "bob", "test2": 123}}`, + ptr: new(mapStringToStringData), + err: &UnmarshalTypeError{Value: "number", Type: reflect.TypeOf(""), Offset: 37, Struct: "mapStringToStringData", Field: "data"}, + }, + { + in: `{"data":{"test1": 123, "test2": "bob"}}`, + ptr: new(mapStringToStringData), + err: &UnmarshalTypeError{Value: "number", Type: reflect.TypeOf(""), Offset: 21, Struct: "mapStringToStringData", Field: "data"}, + }, } func TestMarshal(t *testing.T) { diff --git a/libgo/go/go/types/api_test.go b/libgo/go/go/types/api_test.go index d4ed400..35050e1 100644 --- a/libgo/go/go/types/api_test.go +++ b/libgo/go/go/types/api_test.go @@ -262,6 +262,8 @@ func TestTypesInfo(t *testing.T) { {`package x0; func _() { var x struct {f string}; x.f := 0 }`, `x.f`, `string`}, {`package x1; func _() { var z string; type x struct {f string}; y := &x{q: z}}`, `z`, `string`}, {`package x2; func _() { var a, b string; type x struct {f string}; z := &x{f: a; f: b;}}`, `b`, `string`}, + {`package x3; var x = panic("");`, `panic`, `func(interface{})`}, + {`package x4; func _() { panic("") }`, `panic`, `func(interface{})`}, } for _, test := range tests { diff --git a/libgo/go/go/types/builtins.go b/libgo/go/go/types/builtins.go index 05e0324..d3f0c4d 100644 --- a/libgo/go/go/types/builtins.go +++ b/libgo/go/go/types/builtins.go @@ -476,7 +476,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b // panic(x) // record panic call if inside a function with result parameters // (for use in Checker.isTerminating) - if check.sig.results.Len() > 0 { + if check.sig != nil && check.sig.results.Len() > 0 { // function has result parameters p := check.isPanic if p == nil { diff --git a/libgo/go/net/dnsclient_unix.go b/libgo/go/net/dnsclient_unix.go index 6ec2f44..3b02930 100644 --- a/libgo/go/net/dnsclient_unix.go +++ b/libgo/go/net/dnsclient_unix.go @@ -27,6 +27,20 @@ import ( "golang_org/x/net/dns/dnsmessage" ) +var ( + errLameReferral = errors.New("lame referral") + errCannotUnmarshalDNSMessage = errors.New("cannot unmarshal DNS message") + errCannotMarshalDNSMessage = errors.New("cannot marshal DNS message") + errServerMisbehaving = errors.New("server misbehaving") + errInvalidDNSResponse = errors.New("invalid DNS response") + errNoAnswerFromDNSServer = errors.New("no answer from DNS server") + + // errServerTemporarlyMisbehaving is like errServerMisbehaving, except + // that when it gets translated to a DNSError, the IsTemporary field + // gets set to true. + errServerTemporarlyMisbehaving = errors.New("server misbehaving") +) + func newRequest(q dnsmessage.Question) (id uint16, udpReq, tcpReq []byte, err error) { id = uint16(rand.Int()) ^ uint16(time.Now().UnixNano()) b := dnsmessage.NewBuilder(make([]byte, 2, 514), dnsmessage.Header{ID: id, RecursionDesired: true}) @@ -105,14 +119,14 @@ func dnsStreamRoundTrip(c Conn, id uint16, query dnsmessage.Question, b []byte) var p dnsmessage.Parser h, err := p.Start(b[:n]) if err != nil { - return dnsmessage.Parser{}, dnsmessage.Header{}, errors.New("cannot unmarshal DNS message") + return dnsmessage.Parser{}, dnsmessage.Header{}, errCannotUnmarshalDNSMessage } q, err := p.Question() if err != nil { - return dnsmessage.Parser{}, dnsmessage.Header{}, errors.New("cannot unmarshal DNS message") + return dnsmessage.Parser{}, dnsmessage.Header{}, errCannotUnmarshalDNSMessage } if !checkResponse(id, query, h, q) { - return dnsmessage.Parser{}, dnsmessage.Header{}, errors.New("invalid DNS response") + return dnsmessage.Parser{}, dnsmessage.Header{}, errInvalidDNSResponse } return p, h, nil } @@ -122,7 +136,7 @@ func (r *Resolver) exchange(ctx context.Context, server string, q dnsmessage.Que q.Class = dnsmessage.ClassINET id, udpReq, tcpReq, err := newRequest(q) if err != nil { - return dnsmessage.Parser{}, dnsmessage.Header{}, errors.New("cannot marshal DNS message") + return dnsmessage.Parser{}, dnsmessage.Header{}, errCannotMarshalDNSMessage } for _, network := range []string{"udp", "tcp"} { ctx, cancel := context.WithDeadline(ctx, time.Now().Add(timeout)) @@ -147,31 +161,31 @@ func (r *Resolver) exchange(ctx context.Context, server string, q dnsmessage.Que return dnsmessage.Parser{}, dnsmessage.Header{}, mapErr(err) } if err := p.SkipQuestion(); err != dnsmessage.ErrSectionDone { - return dnsmessage.Parser{}, dnsmessage.Header{}, errors.New("invalid DNS response") + return dnsmessage.Parser{}, dnsmessage.Header{}, errInvalidDNSResponse } if h.Truncated { // see RFC 5966 continue } return p, h, nil } - return dnsmessage.Parser{}, dnsmessage.Header{}, errors.New("no answer from DNS server") + return dnsmessage.Parser{}, dnsmessage.Header{}, errNoAnswerFromDNSServer } // checkHeader performs basic sanity checks on the header. func checkHeader(p *dnsmessage.Parser, h dnsmessage.Header, name, server string) error { + if h.RCode == dnsmessage.RCodeNameError { + return errNoSuchHost + } + _, err := p.AnswerHeader() if err != nil && err != dnsmessage.ErrSectionDone { - return &DNSError{ - Err: "cannot unmarshal DNS message", - Name: name, - Server: server, - } + return errCannotUnmarshalDNSMessage } // libresolv continues to the next server when it receives // an invalid referral response. See golang.org/issue/15434. if h.RCode == dnsmessage.RCodeSuccess && !h.Authoritative && !h.RecursionAvailable && err == dnsmessage.ErrSectionDone { - return &DNSError{Err: "lame referral", Name: name, Server: server} + return errLameReferral } if h.RCode != dnsmessage.RCodeSuccess && h.RCode != dnsmessage.RCodeNameError { @@ -180,11 +194,10 @@ func checkHeader(p *dnsmessage.Parser, h dnsmessage.Header, name, server string) // a name error and we didn't get success, // the server is behaving incorrectly or // having temporary trouble. - err := &DNSError{Err: "server misbehaving", Name: name, Server: server} if h.RCode == dnsmessage.RCodeServerFailure { - err.IsTemporary = true + return errServerTemporarlyMisbehaving } - return err + return errServerMisbehaving } return nil @@ -194,28 +207,16 @@ func skipToAnswer(p *dnsmessage.Parser, qtype dnsmessage.Type, name, server stri for { h, err := p.AnswerHeader() if err == dnsmessage.ErrSectionDone { - return &DNSError{ - Err: errNoSuchHost.Error(), - Name: name, - Server: server, - } + return errNoSuchHost } if err != nil { - return &DNSError{ - Err: "cannot unmarshal DNS message", - Name: name, - Server: server, - } + return errCannotUnmarshalDNSMessage } if h.Type == qtype { return nil } if err := p.SkipAnswer(); err != nil { - return &DNSError{ - Err: "cannot unmarshal DNS message", - Name: name, - Server: server, - } + return errCannotUnmarshalDNSMessage } } } @@ -229,7 +230,7 @@ func (r *Resolver) tryOneName(ctx context.Context, cfg *dnsConfig, name string, n, err := dnsmessage.NewName(name) if err != nil { - return dnsmessage.Parser{}, "", errors.New("cannot marshal DNS message") + return dnsmessage.Parser{}, "", errCannotMarshalDNSMessage } q := dnsmessage.Question{ Name: n, @@ -243,38 +244,62 @@ func (r *Resolver) tryOneName(ctx context.Context, cfg *dnsConfig, name string, p, h, err := r.exchange(ctx, server, q, cfg.timeout) if err != nil { - lastErr = &DNSError{ + dnsErr := &DNSError{ Err: err.Error(), Name: name, Server: server, } if nerr, ok := err.(Error); ok && nerr.Timeout() { - lastErr.(*DNSError).IsTimeout = true + dnsErr.IsTimeout = true } // Set IsTemporary for socket-level errors. Note that this flag // may also be used to indicate a SERVFAIL response. if _, ok := err.(*OpError); ok { - lastErr.(*DNSError).IsTemporary = true + dnsErr.IsTemporary = true } + lastErr = dnsErr continue } - // The name does not exist, so trying another server won't help. - // - // TODO: indicate this in a more obvious way, such as a field on DNSError? - if h.RCode == dnsmessage.RCodeNameError { - return dnsmessage.Parser{}, "", &DNSError{Err: errNoSuchHost.Error(), Name: name, Server: server} - } - - lastErr = checkHeader(&p, h, name, server) - if lastErr != nil { + if err := checkHeader(&p, h, name, server); err != nil { + dnsErr := &DNSError{ + Err: err.Error(), + Name: name, + Server: server, + } + if err == errServerTemporarlyMisbehaving { + dnsErr.IsTemporary = true + } + if err == errNoSuchHost { + // The name does not exist, so trying + // another server won't help. + // + // TODO: indicate this in a more + // obvious way, such as a field on + // DNSError? + return p, server, dnsErr + } + lastErr = dnsErr continue } - lastErr = skipToAnswer(&p, qtype, name, server) - if lastErr == nil { + err = skipToAnswer(&p, qtype, name, server) + if err == nil { return p, server, nil } + lastErr = &DNSError{ + Err: err.Error(), + Name: name, + Server: server, + } + if err == errNoSuchHost { + // The name does not exist, so trying another + // server won't help. + // + // TODO: indicate this in a more obvious way, + // such as a field on DNSError? + return p, server, lastErr + } } } return dnsmessage.Parser{}, "", lastErr diff --git a/libgo/go/net/dnsclient_unix_test.go b/libgo/go/net/dnsclient_unix_test.go index f1bb09d..8992480 100644 --- a/libgo/go/net/dnsclient_unix_test.go +++ b/libgo/go/net/dnsclient_unix_test.go @@ -1427,28 +1427,35 @@ func TestDNSGoroutineRace(t *testing.T) { } } +func lookupWithFake(fake fakeDNSServer, name string, typ dnsmessage.Type) error { + r := Resolver{PreferGo: true, Dial: fake.DialContext} + + resolvConf.mu.RLock() + conf := resolvConf.dnsConfig + resolvConf.mu.RUnlock() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + _, _, err := r.tryOneName(ctx, conf, name, typ) + return err +} + // Issue 8434: verify that Temporary returns true on an error when rcode // is SERVFAIL func TestIssue8434(t *testing.T) { - msg := dnsmessage.Message{ - Header: dnsmessage.Header{ - RCode: dnsmessage.RCodeServerFailure, + err := lookupWithFake(fakeDNSServer{ + rh: func(n, _ string, q dnsmessage.Message, _ time.Time) (dnsmessage.Message, error) { + return dnsmessage.Message{ + Header: dnsmessage.Header{ + ID: q.ID, + Response: true, + RCode: dnsmessage.RCodeServerFailure, + }, + Questions: q.Questions, + }, nil }, - } - b, err := msg.Pack() - if err != nil { - t.Fatal("Pack failed:", err) - } - var p dnsmessage.Parser - h, err := p.Start(b) - if err != nil { - t.Fatal("Start failed:", err) - } - if err := p.SkipAllQuestions(); err != nil { - t.Fatal("SkipAllQuestions failed:", err) - } - - err = checkHeader(&p, h, "golang.org", "foo:53") + }, "golang.org.", dnsmessage.TypeALL) if err == nil { t.Fatal("expected an error") } @@ -1464,50 +1471,76 @@ func TestIssue8434(t *testing.T) { } } -// Issue 12778: verify that NXDOMAIN without RA bit errors as -// "no such host" and not "server misbehaving" +// TestNoSuchHost verifies that tryOneName works correctly when the domain does +// not exist. +// +// Issue 12778: verify that NXDOMAIN without RA bit errors as "no such host" +// and not "server misbehaving" // // Issue 25336: verify that NXDOMAIN errors fail fast. -func TestIssue12778(t *testing.T) { - lookups := 0 - fake := fakeDNSServer{ - rh: func(n, _ string, q dnsmessage.Message, _ time.Time) (dnsmessage.Message, error) { - lookups++ - return dnsmessage.Message{ - Header: dnsmessage.Header{ - ID: q.ID, - Response: true, - RCode: dnsmessage.RCodeNameError, - RecursionAvailable: false, - }, - Questions: q.Questions, - }, nil +// +// Issue 27525: verify that empty answers fail fast. +func TestNoSuchHost(t *testing.T) { + tests := []struct { + name string + f func(string, string, dnsmessage.Message, time.Time) (dnsmessage.Message, error) + }{ + { + "NXDOMAIN", + func(n, _ string, q dnsmessage.Message, _ time.Time) (dnsmessage.Message, error) { + return dnsmessage.Message{ + Header: dnsmessage.Header{ + ID: q.ID, + Response: true, + RCode: dnsmessage.RCodeNameError, + RecursionAvailable: false, + }, + Questions: q.Questions, + }, nil + }, + }, + { + "no answers", + func(n, _ string, q dnsmessage.Message, _ time.Time) (dnsmessage.Message, error) { + return dnsmessage.Message{ + Header: dnsmessage.Header{ + ID: q.ID, + Response: true, + RCode: dnsmessage.RCodeSuccess, + RecursionAvailable: false, + Authoritative: true, + }, + Questions: q.Questions, + }, nil + }, }, } - r := Resolver{PreferGo: true, Dial: fake.DialContext} - - resolvConf.mu.RLock() - conf := resolvConf.dnsConfig - resolvConf.mu.RUnlock() - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - _, _, err := r.tryOneName(ctx, conf, ".", dnsmessage.TypeALL) + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + lookups := 0 + err := lookupWithFake(fakeDNSServer{ + rh: func(n, s string, q dnsmessage.Message, d time.Time) (dnsmessage.Message, error) { + lookups++ + return test.f(n, s, q, d) + }, + }, ".", dnsmessage.TypeALL) - if lookups != 1 { - t.Errorf("got %d lookups, wanted 1", lookups) - } + if lookups != 1 { + t.Errorf("got %d lookups, wanted 1", lookups) + } - if err == nil { - t.Fatal("expected an error") - } - de, ok := err.(*DNSError) - if !ok { - t.Fatalf("err = %#v; wanted a *net.DNSError", err) - } - if de.Err != errNoSuchHost.Error() { - t.Fatalf("Err = %#v; wanted %q", de.Err, errNoSuchHost.Error()) + if err == nil { + t.Fatal("expected an error") + } + de, ok := err.(*DNSError) + if !ok { + t.Fatalf("err = %#v; wanted a *net.DNSError", err) + } + if de.Err != errNoSuchHost.Error() { + t.Fatalf("Err = %#v; wanted %q", de.Err, errNoSuchHost.Error()) + } + }) } } @@ -1535,3 +1568,56 @@ func TestDNSDialTCP(t *testing.T) { t.Fatal("exhange failed:", err) } } + +// Issue 27763: verify that two strings in one TXT record are concatenated. +func TestTXTRecordTwoStrings(t *testing.T) { + fake := fakeDNSServer{ + rh: func(n, _ string, q dnsmessage.Message, _ time.Time) (dnsmessage.Message, error) { + r := dnsmessage.Message{ + Header: dnsmessage.Header{ + ID: q.Header.ID, + Response: true, + RCode: dnsmessage.RCodeSuccess, + }, + Questions: q.Questions, + Answers: []dnsmessage.Resource{ + { + Header: dnsmessage.ResourceHeader{ + Name: q.Questions[0].Name, + Type: dnsmessage.TypeA, + Class: dnsmessage.ClassINET, + }, + Body: &dnsmessage.TXTResource{ + TXT: []string{"string1 ", "string2"}, + }, + }, + { + Header: dnsmessage.ResourceHeader{ + Name: q.Questions[0].Name, + Type: dnsmessage.TypeA, + Class: dnsmessage.ClassINET, + }, + Body: &dnsmessage.TXTResource{ + TXT: []string{"onestring"}, + }, + }, + }, + } + return r, nil + }, + } + r := Resolver{PreferGo: true, Dial: fake.DialContext} + txt, err := r.lookupTXT(context.Background(), "golang.org") + if err != nil { + t.Fatal("LookupTXT failed:", err) + } + if want := 2; len(txt) != want { + t.Fatalf("len(txt), got %d, want %d", len(txt), want) + } + if want := "string1 string2"; txt[0] != want { + t.Errorf("txt[0], got %q, want %q", txt[0], want) + } + if want := "onestring"; txt[1] != want { + t.Errorf("txt[1], got %q, want %q", txt[1], want) + } +} diff --git a/libgo/go/net/http/roundtrip_js.go b/libgo/go/net/http/roundtrip_js.go index 16b7b89..38e4f55 100644 --- a/libgo/go/net/http/roundtrip_js.go +++ b/libgo/go/net/http/roundtrip_js.go @@ -116,7 +116,9 @@ func (t *Transport) RoundTrip(req *Request) (*Response, error) { b := result.Get("body") var body io.ReadCloser - if b != js.Undefined() { + // The body is undefined when the browser does not support streaming response bodies (Firefox), + // and null in certain error cases, i.e. when the request is blocked because of CORS settings. + if b != js.Undefined() && b != js.Null() { body = &streamReader{stream: b.Call("getReader")} } else { // Fall back to using ArrayBuffer diff --git a/libgo/go/net/lookup_unix.go b/libgo/go/net/lookup_unix.go index 76d6ae3..39e8b72 100644 --- a/libgo/go/net/lookup_unix.go +++ b/libgo/go/net/lookup_unix.go @@ -299,11 +299,21 @@ func (r *Resolver) lookupTXT(ctx context.Context, name string) ([]string, error) Server: server, } } + // Multiple strings in one TXT record need to be + // concatenated without separator to be consistent + // with previous Go resolver. + n := 0 + for _, s := range txt.TXT { + n += len(s) + } + txtJoin := make([]byte, 0, n) + for _, s := range txt.TXT { + txtJoin = append(txtJoin, s...) + } if len(txts) == 0 { - txts = txt.TXT - } else { - txts = append(txts, txt.TXT...) + txts = make([]string, 0, 1) } + txts = append(txts, string(txtJoin)) } return txts, nil } diff --git a/libgo/go/net/splice_test.go b/libgo/go/net/splice_test.go index 40ed19b..3be1c7e 100644 --- a/libgo/go/net/splice_test.go +++ b/libgo/go/net/splice_test.go @@ -124,6 +124,7 @@ func testSpliceBig(t *testing.T) { func testSpliceHonorsLimitedReader(t *testing.T) { t.Run("stopsAfterN", testSpliceStopsAfterN) t.Run("updatesN", testSpliceUpdatesN) + t.Run("readerAtLimit", testSpliceReaderAtLimit) } func testSpliceStopsAfterN(t *testing.T) { @@ -210,7 +211,7 @@ func testSpliceUpdatesN(t *testing.T) { } } -func testSpliceReaderAtEOF(t *testing.T) { +func testSpliceReaderAtLimit(t *testing.T) { clientUp, serverUp, err := spliceTestSocketPair("tcp") if err != nil { t.Fatal(err) @@ -224,22 +225,64 @@ func testSpliceReaderAtEOF(t *testing.T) { defer clientDown.Close() defer serverDown.Close() - serverUp.Close() - _, err, handled := splice(serverDown.(*TCPConn).fd, serverUp) + lr := &io.LimitedReader{ + N: 0, + R: serverUp, + } + _, err, handled := splice(serverDown.(*TCPConn).fd, lr) if !handled { if serr, ok := err.(*os.SyscallError); ok && serr.Syscall == "pipe2" && serr.Err == syscall.ENOSYS { t.Skip("pipe2 not supported") } - t.Errorf("closed connection: got err = %v, handled = %t, want handled = true", err, handled) + t.Errorf("exhausted LimitedReader: got err = %v, handled = %t, want handled = true", err, handled) } - lr := &io.LimitedReader{ - N: 0, - R: serverUp, +} + +func testSpliceReaderAtEOF(t *testing.T) { + clientUp, serverUp, err := spliceTestSocketPair("tcp") + if err != nil { + t.Fatal(err) } - _, err, handled = splice(serverDown.(*TCPConn).fd, lr) - if !handled { - t.Errorf("exhausted LimitedReader: got err = %v, handled = %t, want handled = true", err, handled) + defer clientUp.Close() + clientDown, serverDown, err := spliceTestSocketPair("tcp") + if err != nil { + t.Fatal(err) + } + defer clientDown.Close() + + serverUp.Close() + + // We'd like to call net.splice here and check the handled return + // value, but we disable splice on old Linux kernels. + // + // In that case, poll.Splice and net.splice return a non-nil error + // and handled == false. We'd ideally like to see handled == true + // because the source reader is at EOF, but if we're running on an old + // kernel, and splice is disabled, we won't see EOF from net.splice, + // because we won't touch the reader at all. + // + // Trying to untangle the errors from net.splice and match them + // against the errors created by the poll package would be brittle, + // so this is a higher level test. + // + // The following ReadFrom should return immediately, regardless of + // whether splice is disabled or not. The other side should then + // get a goodbye signal. Test for the goodbye signal. + msg := "bye" + go func() { + serverDown.(*TCPConn).ReadFrom(serverUp) + io.WriteString(serverDown, msg) + serverDown.Close() + }() + + buf := make([]byte, 3) + _, err = io.ReadFull(clientDown, buf) + if err != nil { + t.Errorf("clientDown: %v", err) + } + if string(buf) != msg { + t.Errorf("clientDown got %q, want %q", buf, msg) } } diff --git a/libgo/go/reflect/all_test.go b/libgo/go/reflect/all_test.go index eb893e9..472988f 100644 --- a/libgo/go/reflect/all_test.go +++ b/libgo/go/reflect/all_test.go @@ -5864,7 +5864,7 @@ func clobber() { type funcLayoutTest struct { rcvr, t Type size, argsize, retOffset uintptr - stack []byte // pointer bitmap: 1 is pointer, 0 is scalar (or uninitialized) + stack []byte // pointer bitmap: 1 is pointer, 0 is scalar gc []byte } @@ -5886,7 +5886,7 @@ func init() { 6 * PtrSize, 4 * PtrSize, 4 * PtrSize, - []byte{1, 0, 1}, + []byte{1, 0, 1, 0, 1}, []byte{1, 0, 1, 0, 1}, }) diff --git a/libgo/go/reflect/makefunc_ffi.go b/libgo/go/reflect/makefunc_ffi.go index 2acf7bb..9d9cbde 100644 --- a/libgo/go/reflect/makefunc_ffi.go +++ b/libgo/go/reflect/makefunc_ffi.go @@ -33,7 +33,7 @@ func FFICallbackGo(results unsafe.Pointer, params unsafe.Pointer, impl *makeFunc ap := params for _, rt := range ftyp.in { p := unsafe_New(rt) - memmove(p, *(*unsafe.Pointer)(ap), rt.size) + typedmemmove(rt, p, *(*unsafe.Pointer)(ap)) v := Value{rt, p, flag(rt.Kind()) | flagIndir} in = append(in, v) ap = (unsafe.Pointer)(uintptr(ap) + ptrSize) @@ -59,7 +59,7 @@ func FFICallbackGo(results unsafe.Pointer, params unsafe.Pointer, impl *makeFunc if v.flag&flagIndir == 0 && (v.kind() == Ptr || v.kind() == UnsafePointer) { *(*unsafe.Pointer)(addr) = v.ptr } else { - memmove(addr, v.ptr, typ.size) + typedmemmove(typ, addr, v.ptr) } off += typ.size } diff --git a/libgo/go/reflect/value.go b/libgo/go/reflect/value.go index 5ddd30d..9f05744 100644 --- a/libgo/go/reflect/value.go +++ b/libgo/go/reflect/value.go @@ -323,7 +323,7 @@ var callGC bool // for testing; see TestCallMethodJump func (v Value) call(op string, in []Value) []Value { // Get function pointer, type. - t := v.typ + t := (*funcType)(unsafe.Pointer(v.typ)) var ( fn unsafe.Pointer rcvr Value @@ -472,7 +472,7 @@ func (v Value) call(op string, in []Value) []Value { // The return value rcvrtype gives the method's actual receiver type. // The return value t gives the method type signature (without the receiver). // The return value fn is a pointer to the method code. -func methodReceiver(op string, v Value, methodIndex int) (rcvrtype, t *rtype, fn unsafe.Pointer) { +func methodReceiver(op string, v Value, methodIndex int) (rcvrtype *rtype, t *funcType, fn unsafe.Pointer) { i := methodIndex if v.typ.Kind() == Interface { tt := (*interfaceType)(unsafe.Pointer(v.typ)) @@ -489,7 +489,7 @@ func methodReceiver(op string, v Value, methodIndex int) (rcvrtype, t *rtype, fn } rcvrtype = iface.itab.typ fn = unsafe.Pointer(&iface.itab.fun[i]) - t = m.typ + t = (*funcType)(unsafe.Pointer(m.typ)) } else { rcvrtype = v.typ ms := v.typ.exportedMethods() @@ -501,7 +501,7 @@ func methodReceiver(op string, v Value, methodIndex int) (rcvrtype, t *rtype, fn panic("reflect: " + op + " of unexported method") } fn = unsafe.Pointer(&m.tfn) - t = m.mtyp + t = (*funcType)(unsafe.Pointer(m.mtyp)) } return } @@ -2399,10 +2399,14 @@ func mapiternext(it unsafe.Pointer) //go:noescape func maplen(m unsafe.Pointer) int -func call(typ *rtype, fnaddr unsafe.Pointer, isInterface bool, isMethod bool, params *unsafe.Pointer, results *unsafe.Pointer) +func call(typ *funcType, fnaddr unsafe.Pointer, isInterface bool, isMethod bool, params *unsafe.Pointer, results *unsafe.Pointer) func ifaceE2I(t *rtype, src interface{}, dst unsafe.Pointer) +// memmove copies size bytes to dst from src. No write barriers are used. +//go:noescape +func memmove(dst, src unsafe.Pointer, size uintptr) + // typedmemmove copies a value of type t to dst from src. //go:noescape func typedmemmove(t *rtype, dst, src unsafe.Pointer) @@ -2412,10 +2416,6 @@ func typedmemmove(t *rtype, dst, src unsafe.Pointer) //go:noescape func typedslicecopy(elemType *rtype, dst, src sliceHeader) int -//go:noescape -//extern memmove -func memmove(adst, asrc unsafe.Pointer, n uintptr) - // Dummy annotation marking that the value x escapes, // for use in cases where the reflect code is so clever that // the compiler cannot follow. diff --git a/libgo/go/runtime/chan.go b/libgo/go/runtime/chan.go index 88a8944..cb369ef 100644 --- a/libgo/go/runtime/chan.go +++ b/libgo/go/runtime/chan.go @@ -102,7 +102,7 @@ func makechan(t *chantype, size int) *hchan { // Queue or element size is zero. c = (*hchan)(mallocgc(hchanSize, nil, true)) // Race detector uses this location for synchronization. - c.buf = unsafe.Pointer(c) + c.buf = c.raceaddr() case elem.kind&kindNoPointers != 0: // Elements do not contain pointers. // Allocate hchan and buf in one call. @@ -166,7 +166,7 @@ func chansend(c *hchan, ep unsafe.Pointer, block bool, callerpc uintptr) bool { } if raceenabled { - racereadpc(unsafe.Pointer(c), callerpc, funcPC(chansend)) + racereadpc(c.raceaddr(), callerpc, funcPC(chansend)) } // Fast path: check for failed non-blocking operation without acquiring the lock. @@ -352,8 +352,8 @@ func closechan(c *hchan) { if raceenabled { callerpc := getcallerpc() - racewritepc(unsafe.Pointer(c), callerpc, funcPC(closechan)) - racerelease(unsafe.Pointer(c)) + racewritepc(c.raceaddr(), callerpc, funcPC(closechan)) + racerelease(c.raceaddr()) } c.closed = 1 @@ -376,7 +376,7 @@ func closechan(c *hchan) { gp := sg.g gp.param = nil if raceenabled { - raceacquireg(gp, unsafe.Pointer(c)) + raceacquireg(gp, c.raceaddr()) } gp.schedlink.set(glist) glist = gp @@ -395,7 +395,7 @@ func closechan(c *hchan) { gp := sg.g gp.param = nil if raceenabled { - raceacquireg(gp, unsafe.Pointer(c)) + raceacquireg(gp, c.raceaddr()) } gp.schedlink.set(glist) glist = gp @@ -477,7 +477,7 @@ func chanrecv(c *hchan, ep unsafe.Pointer, block bool) (selected, received bool) if c.closed != 0 && c.qcount == 0 { if raceenabled { - raceacquire(unsafe.Pointer(c)) + raceacquire(c.raceaddr()) } unlock(&c.lock) if ep != nil { @@ -755,6 +755,15 @@ func (q *waitq) dequeue() *sudog { } } +func (c *hchan) raceaddr() unsafe.Pointer { + // Treat read-like and write-like operations on the channel to + // happen at this address. Avoid using the address of qcount + // or dataqsiz, because the len() and cap() builtins read + // those addresses, and we don't want them racing with + // operations like close(). + return unsafe.Pointer(&c.buf) +} + func racesync(c *hchan, sg *sudog) { racerelease(chanbuf(c, 0)) raceacquireg(sg.g, chanbuf(c, 0)) diff --git a/libgo/go/runtime/mbarrier.go b/libgo/go/runtime/mbarrier.go index 24e5865..4871315 100644 --- a/libgo/go/runtime/mbarrier.go +++ b/libgo/go/runtime/mbarrier.go @@ -309,6 +309,19 @@ func typedmemclr(typ *_type, ptr unsafe.Pointer) { memclrNoHeapPointers(ptr, typ.size) } +//go:linkname reflect_typedmemclr reflect.typedmemclr +func reflect_typedmemclr(typ *_type, ptr unsafe.Pointer) { + typedmemclr(typ, ptr) +} + +//go:linkname reflect_typedmemclrpartial reflect.typedmemclrpartial +func reflect_typedmemclrpartial(typ *_type, ptr unsafe.Pointer, off, size uintptr) { + if typ.kind&kindNoPointers == 0 { + bulkBarrierPreWrite(uintptr(ptr), 0, size) + } + memclrNoHeapPointers(ptr, size) +} + // memclrHasPointers clears n bytes of typed memory starting at ptr. // The caller must ensure that the type of the object at ptr has // pointers, usually by checking typ.kind&kindNoPointers. However, ptr diff --git a/libgo/go/runtime/os_darwin.go b/libgo/go/runtime/os_darwin.go index 9597633..235f794 100644 --- a/libgo/go/runtime/os_darwin.go +++ b/libgo/go/runtime/os_darwin.go @@ -34,6 +34,10 @@ func semacreate(mp *m) { //go:nosplit func semasleep(ns int64) int32 { + var start int64 + if ns >= 0 { + start = nanotime() + } mp := getg().m pthread_mutex_lock(&mp.mutex) for { @@ -43,8 +47,13 @@ func semasleep(ns int64) int32 { return 0 } if ns >= 0 { + spent := nanotime() - start + if spent >= ns { + pthread_mutex_unlock(&mp.mutex) + return -1 + } var t timespec - t.set_nsec(ns) + t.set_nsec(ns - spent) err := pthread_cond_timedwait_relative_np(&mp.cond, &mp.mutex, &t) if err == _ETIMEDOUT { pthread_mutex_unlock(&mp.mutex) diff --git a/libgo/go/runtime/os_netbsd.go b/libgo/go/runtime/os_netbsd.go index ea47e5c..16a1192 100644 --- a/libgo/go/runtime/os_netbsd.go +++ b/libgo/go/runtime/os_netbsd.go @@ -29,15 +29,9 @@ func semacreate(mp *m) { //go:nosplit func semasleep(ns int64) int32 { _g_ := getg() - - // Compute sleep deadline. - var tsp *timespec - var ts timespec + var deadline int64 if ns >= 0 { - var nsec int32 - ts.set_sec(int64(timediv(ns, 1000000000, &nsec))) - ts.set_nsec(nsec) - tsp = &ts + deadline = nanotime() + ns } for { @@ -50,18 +44,21 @@ func semasleep(ns int64) int32 { } // Sleep until unparked by semawakeup or timeout. + var tsp *timespec + var ts timespec + if ns >= 0 { + wait := deadline - nanotime() + if wait <= 0 { + return -1 + } + var nsec int32 + ts.set_sec(timediv(wait, 1000000000, &nsec)) + ts.set_nsec(nsec) + tsp = &ts + } ret := lwp_park(_CLOCK_MONOTONIC, _TIMER_RELTIME, tsp, 0, unsafe.Pointer(&_g_.m.waitsemacount), nil) if ret == _ETIMEDOUT { return -1 - } else if ret == _EINTR && ns >= 0 { - // Avoid sleeping forever if we keep getting - // interrupted (for example by the profiling - // timer). It would be if tsp upon return had the - // remaining time to sleep, but this is good enough. - var nsec int32 - ns /= 2 - ts.set_sec(timediv(ns, 1000000000, &nsec)) - ts.set_nsec(nsec) } } } diff --git a/libgo/go/runtime/select.go b/libgo/go/runtime/select.go index 39c12da..fb8373f 100644 --- a/libgo/go/runtime/select.go +++ b/libgo/go/runtime/select.go @@ -426,7 +426,7 @@ rclose: typedmemclr(c.elemtype, cas.elem) } if raceenabled { - raceacquire(unsafe.Pointer(c)) + raceacquire(c.raceaddr()) } goto retc diff --git a/libgo/go/runtime/trace/annotation.go b/libgo/go/runtime/trace/annotation.go index 3545ef3..d5a7d00 100644 --- a/libgo/go/runtime/trace/annotation.go +++ b/libgo/go/runtime/trace/annotation.go @@ -24,13 +24,13 @@ type traceContextKey struct{} // If the end function is called multiple times, only the first // call is used in the latency measurement. // -// ctx, task := trace.NewTask(ctx, "awesome task") -// trace.WithRegion(ctx, prepWork) +// ctx, task := trace.NewTask(ctx, "awesomeTask") +// trace.WithRegion(ctx, "preparation", prepWork) // // preparation of the task // go func() { // continue processing the task in a separate goroutine. // defer task.End() -// trace.WithRegion(ctx, remainingWork) -// } +// trace.WithRegion(ctx, "remainingWork", remainingWork) +// }() func NewTask(pctx context.Context, taskType string) (ctx context.Context, task *Task) { pid := fromContext(pctx).id id := newID() diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 06718b5..12dee3a 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,26 @@ +2018-10-08 Jonathan Wakely <jwakely@redhat.com> + + PR libstdc++/87538 + * testsuite/experimental/functional/87538.cc: New test. + + PR libstdc++/87538 + * include/std/functional (_Not_fn::operator()): Check value of + __is_nothrow_invocable as well. + * testsuite/20_util/function_objects/not_fn/87538.cc: New test. + +2018-10-08 François Dumont <fdumont@gcc.gnu.org> + + * include/debug/list (list<>::cbegin()): Use C++11 direct + initialization. + (list<>::cend()): Likewise. + (list<>::emplace<>(const_iterator, _Args&&...)): Likewise. + (list<>::insert(const_iterator, initializer_list<>)): Likewise. + (list<>::insert(const_iterator, size_type, const _Tp&)): Likewise. + (list<>::erase(const_iterator, const_iterator)): Ensure consistent + iterator comparisons. + (list<>::splice(const_iterator, list&&, const_iterator, + const_iterator)): Likewise. + 2018-10-05 François Dumont <fdumont@gcc.gnu.org> * include/bits/stl_tree.h diff --git a/libstdc++-v3/include/debug/list b/libstdc++-v3/include/debug/list index 8add1d5..879e117 100644 --- a/libstdc++-v3/include/debug/list +++ b/libstdc++-v3/include/debug/list @@ -244,11 +244,11 @@ namespace __debug #if __cplusplus >= 201103L const_iterator cbegin() const noexcept - { return const_iterator(_Base::begin(), this); } + { return { _Base::begin(), this }; } const_iterator cend() const noexcept - { return const_iterator(_Base::end(), this); } + { return { _Base::end(), this }; } const_reverse_iterator crbegin() const noexcept @@ -405,8 +405,8 @@ namespace __debug emplace(const_iterator __position, _Args&&... __args) { __glibcxx_check_insert(__position); - return iterator(_Base::emplace(__position.base(), - std::forward<_Args>(__args)...), this); + return { _Base::emplace(__position.base(), + std::forward<_Args>(__args)...), this }; } #endif @@ -430,7 +430,7 @@ namespace __debug insert(const_iterator __p, initializer_list<value_type> __l) { __glibcxx_check_insert(__p); - return iterator(_Base::insert(__p.base(), __l), this); + return { _Base::insert(__p.base(), __l), this }; } #endif @@ -439,7 +439,7 @@ namespace __debug insert(const_iterator __position, size_type __n, const _Tp& __x) { __glibcxx_check_insert(__position); - return iterator(_Base::insert(__position.base(), __n, __x), this); + return { _Base::insert(__position.base(), __n, __x), this }; } #else void @@ -465,7 +465,7 @@ namespace __debug _Base::insert(__position.base(), __gnu_debug::__unsafe(__first), __gnu_debug::__unsafe(__last)), - this + this }; else return { _Base::insert(__position.base(), __first, __last), this }; @@ -521,15 +521,17 @@ namespace __debug // _GLIBCXX_RESOLVE_LIB_DEFECTS // 151. can't currently clear() empty container __glibcxx_check_erase_range(__first, __last); - for (_Base_const_iterator __victim = __first.base(); + for (__decltype(__first.base()) __victim = __first.base(); __victim != __last.base(); ++__victim) { - _GLIBCXX_DEBUG_VERIFY(__victim != _Base::end(), - _M_message(__gnu_debug::__msg_valid_range) - ._M_iterator(__first, "position") - ._M_iterator(__last, "last")); + _GLIBCXX_DEBUG_VERIFY( + __victim != __first._M_get_sequence()->_M_base().end(), + _M_message(__gnu_debug::__msg_valid_range) + ._M_iterator(__first, "position") + ._M_iterator(__last, "last")); this->_M_invalidate_if(_Equal(__victim)); } + return iterator(_Base::erase(__first.base(), __last.base()), this); } @@ -586,7 +588,7 @@ namespace __debug ._M_iterator(__i, "__i")); _GLIBCXX_DEBUG_VERIFY(__i._M_attached_to(std::__addressof(__x)), _M_message(__gnu_debug::__msg_splice_other) - ._M_iterator(__i, "__i")._M_sequence(__x, "__x")); + ._M_iterator(__i, "__i")._M_sequence(__x, "__x")); // _GLIBCXX_RESOLVE_LIB_DEFECTS // 250. splicing invalidates iterators @@ -620,19 +622,21 @@ namespace __debug // We used to perform the splice_alloc check: not anymore, redundant // after implementing the relevant bits of N1599. - for (_Base_const_iterator __tmp = __first.base(); + for (__decltype(__first.base()) __tmp = __first.base(); __tmp != __last.base(); ++__tmp) { - _GLIBCXX_DEBUG_VERIFY(__tmp != _Base::end(), - _M_message(__gnu_debug::__msg_valid_range) - ._M_iterator(__first, "first") - ._M_iterator(__last, "last")); + _GLIBCXX_DEBUG_VERIFY( + __tmp != __first._M_get_sequence()->_M_base().end(), + _M_message(__gnu_debug::__msg_valid_range) + ._M_iterator(__first, "first") + ._M_iterator(__last, "last")); _GLIBCXX_DEBUG_VERIFY(std::__addressof(__x) != this || __tmp != __position.base(), _M_message(__gnu_debug::__msg_splice_overlap) ._M_iterator(__tmp, "position") ._M_iterator(__first, "first") ._M_iterator(__last, "last")); + // _GLIBCXX_RESOLVE_LIB_DEFECTS // 250. splicing invalidates iterators this->_M_transfer_from_if(__x, _Equal(__tmp)); diff --git a/libstdc++-v3/include/std/functional b/libstdc++-v3/include/std/functional index 2b46ba8..093528b 100644 --- a/libstdc++-v3/include/std/functional +++ b/libstdc++-v3/include/std/functional @@ -864,7 +864,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename... _Args> \ decltype(_S_not<__inv_res_t<_Fn _QUALS, _Args...>>()) \ operator()(_Args&&... __args) _QUALS \ - noexcept(noexcept(_S_not<__inv_res_t<_Fn _QUALS, _Args...>>())) \ + noexcept(__is_nothrow_invocable<_Fn _QUALS, _Args...>::value \ + && noexcept(_S_not<__inv_res_t<_Fn _QUALS, _Args...>>())) \ { \ return !std::__invoke(std::forward< _Fn _QUALS >(_M_fn), \ std::forward<_Args>(__args)...); \ diff --git a/libstdc++-v3/testsuite/20_util/function_objects/not_fn/87538.cc b/libstdc++-v3/testsuite/20_util/function_objects/not_fn/87538.cc new file mode 100644 index 0000000..7f4f0df --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/function_objects/not_fn/87538.cc @@ -0,0 +1,49 @@ +// Copyright (C) 2018 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// { dg-options "-std=gnu++17" } +// { dg-do run { target c++17 } } + +#include <functional> +#include <testsuite_hooks.h> + +struct N { + int operator()(int i) { if (i == 0) throw -1; return i; } +}; + +void +test01() +{ + N n; + auto not_n = std::not_fn(n); + static_assert( !noexcept(not_n(1)) ); + VERIFY(not_n(1) == 0); + int exception = 0; + try { + not_n(0); + } + catch (int e) { + exception = e; + } + VERIFY(exception == -1); +} + +int +main() +{ + test01(); +} diff --git a/libstdc++-v3/testsuite/experimental/functional/87538.cc b/libstdc++-v3/testsuite/experimental/functional/87538.cc new file mode 100644 index 0000000..1ee9ecd --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/functional/87538.cc @@ -0,0 +1,48 @@ +// Copyright (C) 2018 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// { dg-do run { target c++14 } } + +#include <experimental/functional> +#include <testsuite_hooks.h> + +struct N { + int operator()(int i) { if (i == 0) throw -1; return i; } +}; + +void +test01() +{ + N n; + auto not_n = std::experimental::not_fn(n); + static_assert( !noexcept(not_n(1)), "can throw" ); + VERIFY(not_n(1) == 0); + int exception = 0; + try { + not_n(0); + } + catch (int e) { + exception = e; + } + VERIFY(exception == -1); +} + +int +main() +{ + test01(); +} |