Merge branch 'master' into devel/sphinx
This commit is contained in:
commit
9fce2fbb1d
|
@ -1,3 +1,29 @@
|
|||
2022-08-08 Andrew MacLeod <amacleod@redhat.com>
|
||||
|
||||
PR tree-optimization/106556
|
||||
* gimple-range-gori.cc (gori_compute::condexpr_adjust): Use the
|
||||
type of the cond_expr operands being evaluted.
|
||||
|
||||
2022-08-08 Tom Honermann <tom@honermann.net>
|
||||
|
||||
* ginclude/stdatomic.h (atomic_char8_t,
|
||||
ATOMIC_CHAR8_T_LOCK_FREE): New typedef and macro.
|
||||
|
||||
2022-08-08 Andrew Pinski <apinski@marvell.com>
|
||||
|
||||
PR middle-end/103645
|
||||
* gimplify.cc (gimplify_init_constructor): Don't build/add
|
||||
gimple assignment of an empty type.
|
||||
|
||||
2022-08-08 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR lto/106540
|
||||
PR lto/106334
|
||||
* dwarf2out.cc (dwarf2out_register_external_die): Restore
|
||||
original assert.
|
||||
* lto-streamer-in.cc (lto_read_tree_1): Use lto_input_tree_1
|
||||
to input DECL_INITIAL, avoiding to commit drefs.
|
||||
|
||||
2022-08-07 Roger Sayle <roger@nextmovesoftware.com>
|
||||
|
||||
* config/i386/i386.md (*cmp<dwi>_doubleword): Change predicate
|
||||
|
|
|
@ -1 +1 @@
|
|||
20220808
|
||||
20220809
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
2022-08-08 Tom Honermann <tom@honermann.net>
|
||||
|
||||
PR preprocessor/106426
|
||||
* c-opts.cc (c_common_post_options): Assign cpp_opts->unsigned_utf8char
|
||||
subject to -fchar8_t, -fsigned-char, and/or -funsigned-char.
|
||||
|
||||
2022-08-08 Tom Honermann <tom@honermann.net>
|
||||
|
||||
* c-lex.cc (lex_string, lex_charconst): Use char8_t as the type
|
||||
of CPP_UTF8CHAR and CPP_UTF8STRING when char8_t support is
|
||||
enabled.
|
||||
* c-opts.cc (c_common_post_options): Set flag_char8_t if
|
||||
targeting C2x.
|
||||
|
||||
2022-07-31 Lewis Hyatt <lhyatt@gmail.com>
|
||||
|
||||
PR c++/66290
|
||||
|
|
|
@ -1352,7 +1352,14 @@ lex_string (const cpp_token *tok, tree *valp, bool objc_string, bool translate)
|
|||
default:
|
||||
case CPP_STRING:
|
||||
case CPP_UTF8STRING:
|
||||
value = build_string (1, "");
|
||||
if (type == CPP_UTF8STRING && flag_char8_t)
|
||||
{
|
||||
value = build_string (TYPE_PRECISION (char8_type_node)
|
||||
/ TYPE_PRECISION (char_type_node),
|
||||
""); /* char8_t is 8 bits */
|
||||
}
|
||||
else
|
||||
value = build_string (1, "");
|
||||
break;
|
||||
case CPP_STRING16:
|
||||
value = build_string (TYPE_PRECISION (char16_type_node)
|
||||
|
@ -1425,9 +1432,7 @@ lex_charconst (const cpp_token *token)
|
|||
type = char16_type_node;
|
||||
else if (token->type == CPP_UTF8CHAR)
|
||||
{
|
||||
if (!c_dialect_cxx ())
|
||||
type = unsigned_char_type_node;
|
||||
else if (flag_char8_t)
|
||||
if (flag_char8_t)
|
||||
type = char8_type_node;
|
||||
else
|
||||
type = char_type_node;
|
||||
|
|
|
@ -1059,9 +1059,10 @@ c_common_post_options (const char **pfilename)
|
|||
if (flag_sized_deallocation == -1)
|
||||
flag_sized_deallocation = (cxx_dialect >= cxx14);
|
||||
|
||||
/* char8_t support is new in C++20. */
|
||||
/* char8_t support is implicitly enabled in C++20 and C2X. */
|
||||
if (flag_char8_t == -1)
|
||||
flag_char8_t = (cxx_dialect >= cxx20);
|
||||
flag_char8_t = (cxx_dialect >= cxx20) || flag_isoc2x;
|
||||
cpp_opts->unsigned_utf8char = flag_char8_t ? 1 : cpp_opts->unsigned_char;
|
||||
|
||||
if (flag_extern_tls_init)
|
||||
{
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
2022-08-08 Tom Honermann <tom@honermann.net>
|
||||
|
||||
* c-parser.cc (c_parser_string_literal): Use char8_t as the type
|
||||
of CPP_UTF8STRING when char8_t support is enabled.
|
||||
* c-typeck.cc (digest_init): Allow initialization of an array
|
||||
of character type by a string literal with type array of
|
||||
char8_t.
|
||||
|
||||
2022-08-01 David Malcolm <dmalcolm@redhat.com>
|
||||
|
||||
* c-typeck.cc (build_c_cast): Quote names of address spaces in
|
||||
|
|
|
@ -7447,7 +7447,14 @@ c_parser_string_literal (c_parser *parser, bool translate, bool wide_ok)
|
|||
default:
|
||||
case CPP_STRING:
|
||||
case CPP_UTF8STRING:
|
||||
value = build_string (1, "");
|
||||
if (type == CPP_UTF8STRING && flag_char8_t)
|
||||
{
|
||||
value = build_string (TYPE_PRECISION (char8_type_node)
|
||||
/ TYPE_PRECISION (char_type_node),
|
||||
""); /* char8_t is 8 bits */
|
||||
}
|
||||
else
|
||||
value = build_string (1, "");
|
||||
break;
|
||||
case CPP_STRING16:
|
||||
value = build_string (TYPE_PRECISION (char16_type_node)
|
||||
|
@ -7472,9 +7479,14 @@ c_parser_string_literal (c_parser *parser, bool translate, bool wide_ok)
|
|||
{
|
||||
default:
|
||||
case CPP_STRING:
|
||||
case CPP_UTF8STRING:
|
||||
TREE_TYPE (value) = char_array_type_node;
|
||||
break;
|
||||
case CPP_UTF8STRING:
|
||||
if (flag_char8_t)
|
||||
TREE_TYPE (value) = char8_array_type_node;
|
||||
else
|
||||
TREE_TYPE (value) = char_array_type_node;
|
||||
break;
|
||||
case CPP_STRING16:
|
||||
TREE_TYPE (value) = char16_array_type_node;
|
||||
break;
|
||||
|
|
|
@ -8056,7 +8056,7 @@ digest_init (location_t init_loc, tree type, tree init, tree origtype,
|
|||
|
||||
if (char_array)
|
||||
{
|
||||
if (typ2 != char_type_node)
|
||||
if (typ2 != char_type_node && typ2 != char8_type_node)
|
||||
incompat_string_cst = true;
|
||||
}
|
||||
else if (!comptypes (typ1, typ2))
|
||||
|
|
|
@ -2284,7 +2284,7 @@ gcn_function_value (const_tree valtype, const_tree, bool)
|
|||
&& GET_MODE_SIZE (mode) < 4)
|
||||
mode = SImode;
|
||||
|
||||
return gen_rtx_REG (mode, SGPR_REGNO (RETURN_VALUE_REG));
|
||||
return gen_rtx_REG (mode, RETURN_VALUE_REG);
|
||||
}
|
||||
|
||||
/* Implement TARGET_FUNCTION_VALUE_REGNO_P.
|
||||
|
@ -2308,7 +2308,9 @@ num_arg_regs (const function_arg_info &arg)
|
|||
return 0;
|
||||
|
||||
int size = arg.promoted_size_in_bytes ();
|
||||
return (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
|
||||
int regsize = UNITS_PER_WORD * (VECTOR_MODE_P (arg.mode)
|
||||
? GET_MODE_NUNITS (arg.mode) : 1);
|
||||
return (size + regsize - 1) / regsize;
|
||||
}
|
||||
|
||||
/* Implement TARGET_STRICT_ARGUMENT_NAMING.
|
||||
|
@ -2358,16 +2360,16 @@ gcn_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
|
|||
if (targetm.calls.must_pass_in_stack (arg))
|
||||
return 0;
|
||||
|
||||
/* Vector parameters are not supported yet. */
|
||||
if (VECTOR_MODE_P (arg.mode))
|
||||
return 0;
|
||||
|
||||
int reg_num = FIRST_PARM_REG + cum->num;
|
||||
int first_reg = (VECTOR_MODE_P (arg.mode)
|
||||
? FIRST_VPARM_REG : FIRST_PARM_REG);
|
||||
int cum_num = (VECTOR_MODE_P (arg.mode)
|
||||
? cum->vnum : cum->num);
|
||||
int reg_num = first_reg + cum_num;
|
||||
int num_regs = num_arg_regs (arg);
|
||||
if (num_regs > 0)
|
||||
while (reg_num % num_regs != 0)
|
||||
reg_num++;
|
||||
if (reg_num + num_regs <= FIRST_PARM_REG + NUM_PARM_REGS)
|
||||
if (reg_num + num_regs <= first_reg + NUM_PARM_REGS)
|
||||
return gen_rtx_REG (arg.mode, reg_num);
|
||||
}
|
||||
else
|
||||
|
@ -2419,11 +2421,15 @@ gcn_function_arg_advance (cumulative_args_t cum_v,
|
|||
if (!arg.named)
|
||||
return;
|
||||
|
||||
int first_reg = (VECTOR_MODE_P (arg.mode)
|
||||
? FIRST_VPARM_REG : FIRST_PARM_REG);
|
||||
int *cum_num = (VECTOR_MODE_P (arg.mode)
|
||||
? &cum->vnum : &cum->num);
|
||||
int num_regs = num_arg_regs (arg);
|
||||
if (num_regs > 0)
|
||||
while ((FIRST_PARM_REG + cum->num) % num_regs != 0)
|
||||
cum->num++;
|
||||
cum->num += num_regs;
|
||||
while ((first_reg + *cum_num) % num_regs != 0)
|
||||
(*cum_num)++;
|
||||
*cum_num += num_regs;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2454,14 +2460,18 @@ gcn_arg_partial_bytes (cumulative_args_t cum_v, const function_arg_info &arg)
|
|||
if (targetm.calls.must_pass_in_stack (arg))
|
||||
return 0;
|
||||
|
||||
if (cum->num >= NUM_PARM_REGS)
|
||||
int cum_num = (VECTOR_MODE_P (arg.mode) ? cum->vnum : cum->num);
|
||||
int regsize = UNITS_PER_WORD * (VECTOR_MODE_P (arg.mode)
|
||||
? GET_MODE_NUNITS (arg.mode) : 1);
|
||||
|
||||
if (cum_num >= NUM_PARM_REGS)
|
||||
return 0;
|
||||
|
||||
/* If the argument fits entirely in registers, return 0. */
|
||||
if (cum->num + num_arg_regs (arg) <= NUM_PARM_REGS)
|
||||
if (cum_num + num_arg_regs (arg) <= NUM_PARM_REGS)
|
||||
return 0;
|
||||
|
||||
return (NUM_PARM_REGS - cum->num) * UNITS_PER_WORD;
|
||||
return (NUM_PARM_REGS - cum_num) * regsize;
|
||||
}
|
||||
|
||||
/* A normal function which takes a pointer argument (to a scalar) may be
|
||||
|
@ -2549,14 +2559,11 @@ gcn_return_in_memory (const_tree type, const_tree ARG_UNUSED (fntype))
|
|||
if (AGGREGATE_TYPE_P (type))
|
||||
return true;
|
||||
|
||||
/* Vector return values are not supported yet. */
|
||||
if (VECTOR_TYPE_P (type))
|
||||
return true;
|
||||
|
||||
if (mode == BLKmode)
|
||||
return true;
|
||||
|
||||
if (size > 2 * UNITS_PER_WORD)
|
||||
if ((!VECTOR_TYPE_P (type) && size > 2 * UNITS_PER_WORD)
|
||||
|| size > 2 * UNITS_PER_WORD * 64)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
@ -3199,9 +3206,10 @@ gcn_expand_epilogue (void)
|
|||
emit_move_insn (kernarg_reg, retptr_mem);
|
||||
|
||||
rtx retval_mem = gen_rtx_MEM (SImode, kernarg_reg);
|
||||
rtx scalar_retval = gen_rtx_REG (SImode, FIRST_PARM_REG);
|
||||
set_mem_addr_space (retval_mem, ADDR_SPACE_SCALAR_FLAT);
|
||||
emit_move_insn (retval_mem,
|
||||
gen_rtx_REG (SImode, SGPR_REGNO (RETURN_VALUE_REG)));
|
||||
emit_move_insn (scalar_retval, gen_rtx_REG (SImode, RETURN_VALUE_REG));
|
||||
emit_move_insn (retval_mem, scalar_retval);
|
||||
}
|
||||
|
||||
emit_jump_insn (gen_gcn_return ());
|
||||
|
|
|
@ -138,7 +138,7 @@
|
|||
#define LINK_REGNUM 18
|
||||
#define EXEC_SAVE_REG 20
|
||||
#define CC_SAVE_REG 22
|
||||
#define RETURN_VALUE_REG 24 /* Must be divisible by 4. */
|
||||
#define RETURN_VALUE_REG 168 /* Must be divisible by 4. */
|
||||
#define STATIC_CHAIN_REGNUM 30
|
||||
#define WORK_ITEM_ID_Z_REG 162
|
||||
#define SOFT_ARG_REG 416
|
||||
|
@ -146,7 +146,8 @@
|
|||
#define DWARF_LINK_REGISTER 420
|
||||
#define FIRST_PSEUDO_REGISTER 421
|
||||
|
||||
#define FIRST_PARM_REG 24
|
||||
#define FIRST_PARM_REG (FIRST_SGPR_REG + 24)
|
||||
#define FIRST_VPARM_REG (FIRST_VGPR_REG + 8)
|
||||
#define NUM_PARM_REGS 6
|
||||
|
||||
/* There is no arg pointer. Just choose random fixed register that does
|
||||
|
@ -164,7 +165,8 @@
|
|||
#define CC_REG_P(X) (REG_P (X) && CC_REGNO_P (REGNO (X)))
|
||||
#define CC_REGNO_P(X) ((X) == SCC_REG || (X) == VCC_REG)
|
||||
#define FUNCTION_ARG_REGNO_P(N) \
|
||||
((N) >= FIRST_PARM_REG && (N) < (FIRST_PARM_REG + NUM_PARM_REGS))
|
||||
(((N) >= FIRST_PARM_REG && (N) < (FIRST_PARM_REG + NUM_PARM_REGS)) \
|
||||
|| ((N) >= FIRST_VPARM_REG && (N) < (FIRST_VPARM_REG + NUM_PARM_REGS)))
|
||||
|
||||
|
||||
#define FIXED_REGISTERS { \
|
||||
|
@ -550,6 +552,7 @@ typedef struct gcn_args
|
|||
tree fntype;
|
||||
struct gcn_kernel_args args;
|
||||
int num;
|
||||
int vnum;
|
||||
int offset;
|
||||
int alignment;
|
||||
} CUMULATIVE_ARGS;
|
||||
|
@ -653,7 +656,7 @@ enum gcn_builtin_codes
|
|||
}
|
||||
|
||||
/* This needs to match gcn_function_value. */
|
||||
#define LIBCALL_VALUE(MODE) gen_rtx_REG (MODE, SGPR_REGNO (RETURN_VALUE_REG))
|
||||
#define LIBCALL_VALUE(MODE) gen_rtx_REG (MODE, RETURN_VALUE_REG)
|
||||
|
||||
/* The s_ff0 and s_flbit instructions return -1 if no input bits are set. */
|
||||
#define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = -1, 2)
|
||||
|
|
|
@ -908,11 +908,11 @@
|
|||
{})
|
||||
|
||||
(define_insn "gcn_call_value"
|
||||
[(set (match_operand 0 "register_operand" "=Sg,Sg")
|
||||
(call (mem (match_operand 1 "immediate_operand" "Y,B"))
|
||||
[(set (match_operand 0 "register_operand" "=Sgv,Sgv")
|
||||
(call (mem (match_operand 1 "immediate_operand" " Y, B"))
|
||||
(match_operand 2 "const_int_operand")))
|
||||
(clobber (reg:DI LR_REGNUM))
|
||||
(clobber (match_scratch:DI 3 "=&Sg,X"))]
|
||||
(clobber (match_scratch:DI 3 "=&Sg, X"))]
|
||||
""
|
||||
"@
|
||||
s_getpc_b64\t%3\;s_add_u32\t%L3, %L3, %1@rel32@lo+4\;s_addc_u32\t%H3, %H3, %1@rel32@hi+4\;s_swappc_b64\ts[18:19], %3
|
||||
|
@ -921,11 +921,11 @@
|
|||
(set_attr "length" "24")])
|
||||
|
||||
(define_insn "gcn_call_value_indirect"
|
||||
[(set (match_operand 0 "register_operand" "=Sg")
|
||||
(call (mem (match_operand:DI 1 "register_operand" "Sg"))
|
||||
[(set (match_operand 0 "register_operand" "=Sgv")
|
||||
(call (mem (match_operand:DI 1 "register_operand" " Sg"))
|
||||
(match_operand 2 "" "")))
|
||||
(clobber (reg:DI LR_REGNUM))
|
||||
(clobber (match_scratch:DI 3 "=X"))]
|
||||
(clobber (match_scratch:DI 3 "= X"))]
|
||||
""
|
||||
"s_swappc_b64\ts[18:19], %1"
|
||||
[(set_attr "type" "sop1")
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2022-08-08 Iain Buclaw <ibuclaw@gdcproject.org>
|
||||
|
||||
PR d/106555
|
||||
* d-target.cc (Target::isReturnOnStack): Check for return type size.
|
||||
|
||||
2022-08-03 Iain Buclaw <ibuclaw@gdcproject.org>
|
||||
|
||||
* dmd/MERGE: Merge upstream dmd d7772a2369.
|
||||
|
|
|
@ -464,6 +464,8 @@ Target::isReturnOnStack (TypeFunction *tf, bool)
|
|||
return false;
|
||||
|
||||
Type *tn = tf->next->toBasetype ();
|
||||
if (tn->size () == SIZE_INVALID)
|
||||
return false;
|
||||
|
||||
return (tn->ty == TY::Tstruct || tn->ty == TY::Tsarray);
|
||||
}
|
||||
|
|
121
gcc/d/decl.cc
121
gcc/d/decl.cc
|
@ -828,6 +828,10 @@ public:
|
|||
if (global.errors)
|
||||
return;
|
||||
|
||||
/* Start generating code for this function. */
|
||||
gcc_assert (d->semanticRun == PASS::semantic3done);
|
||||
d->semanticRun = PASS::obj;
|
||||
|
||||
/* Duplicated FuncDeclarations map to the same symbol. Check if this
|
||||
is the one declaration which will be emitted. */
|
||||
tree fndecl = get_symbol_decl (d);
|
||||
|
@ -844,10 +848,6 @@ public:
|
|||
if (global.params.verbose)
|
||||
message ("function %s", d->toPrettyChars ());
|
||||
|
||||
/* Start generating code for this function. */
|
||||
gcc_assert (d->semanticRun == PASS::semantic3done);
|
||||
d->semanticRun = PASS::obj;
|
||||
|
||||
tree old_context = start_function (d);
|
||||
|
||||
tree parm_decl = NULL_TREE;
|
||||
|
@ -1020,13 +1020,103 @@ build_decl_tree (Dsymbol *d)
|
|||
input_location = saved_location;
|
||||
}
|
||||
|
||||
/* Returns true if function FD is defined or instantiated in a root module. */
|
||||
|
||||
static bool
|
||||
function_defined_in_root_p (FuncDeclaration *fd)
|
||||
{
|
||||
Module *md = fd->getModule ();
|
||||
if (md && md->isRoot ())
|
||||
return true;
|
||||
|
||||
TemplateInstance *ti = fd->isInstantiated ();
|
||||
if (ti && ti->minst && ti->minst->isRoot ())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Returns true if function FD always needs to be implicitly defined, such as
|
||||
it was declared `pragma(inline)'. */
|
||||
|
||||
static bool
|
||||
function_needs_inline_definition_p (FuncDeclaration *fd)
|
||||
{
|
||||
/* Function has already been defined. */
|
||||
if (!DECL_EXTERNAL (fd->csym))
|
||||
return false;
|
||||
|
||||
/* Non-inlineable functions are always external. */
|
||||
if (DECL_UNINLINABLE (fd->csym))
|
||||
return false;
|
||||
|
||||
/* No function body available for inlining. */
|
||||
if (!fd->fbody)
|
||||
return false;
|
||||
|
||||
/* Ignore functions that aren't decorated with `pragma(inline)'. */
|
||||
if (fd->inlining != PINLINE::always)
|
||||
return false;
|
||||
|
||||
/* These functions are tied to the module they are defined in. */
|
||||
if (fd->isFuncLiteralDeclaration ()
|
||||
|| fd->isUnitTestDeclaration ()
|
||||
|| fd->isFuncAliasDeclaration ()
|
||||
|| fd->isInvariantDeclaration ())
|
||||
return false;
|
||||
|
||||
/* Check whether function will be regularly defined later in the current
|
||||
translation unit. */
|
||||
if (function_defined_in_root_p (fd))
|
||||
return false;
|
||||
|
||||
/* Weak functions cannot be inlined. */
|
||||
if (lookup_attribute ("weak", DECL_ATTRIBUTES (fd->csym)))
|
||||
return false;
|
||||
|
||||
/* Naked functions cannot be inlined. */
|
||||
if (lookup_attribute ("naked", DECL_ATTRIBUTES (fd->csym)))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* If the variable or function declaration in DECL needs to be defined, call
|
||||
build_decl_tree on it now before returning its back-end symbol. */
|
||||
|
||||
static tree
|
||||
maybe_build_decl_tree (Declaration *decl)
|
||||
{
|
||||
gcc_assert (decl->csym != NULL_TREE);
|
||||
|
||||
/* Still running semantic analysis on declaration, or it has already had its
|
||||
code generated. */
|
||||
if (doing_semantic_analysis_p || decl->semanticRun >= PASS::obj)
|
||||
return decl->csym;
|
||||
|
||||
if (error_operand_p (decl->csym))
|
||||
return decl->csym;
|
||||
|
||||
if (FuncDeclaration *fd = decl->isFuncDeclaration ())
|
||||
{
|
||||
/* Externally defined inline functions need to be emitted. */
|
||||
if (function_needs_inline_definition_p (fd))
|
||||
{
|
||||
DECL_EXTERNAL (fd->csym) = 0;
|
||||
build_decl_tree (fd);
|
||||
}
|
||||
}
|
||||
|
||||
return decl->csym;
|
||||
}
|
||||
|
||||
/* Return the decl for the symbol, create it if it doesn't already exist. */
|
||||
|
||||
tree
|
||||
get_symbol_decl (Declaration *decl)
|
||||
{
|
||||
if (decl->csym)
|
||||
return decl->csym;
|
||||
return maybe_build_decl_tree (decl);
|
||||
|
||||
/* Deal with placeholder symbols immediately:
|
||||
SymbolDeclaration is used as a shell around an initializer symbol. */
|
||||
|
@ -1404,7 +1494,7 @@ get_symbol_decl (Declaration *decl)
|
|||
TREE_USED (decl->csym) = 1;
|
||||
d_keep (decl->csym);
|
||||
|
||||
return decl->csym;
|
||||
return maybe_build_decl_tree (decl);
|
||||
}
|
||||
|
||||
/* Returns a declaration for a VAR_DECL. Used to create compiler-generated
|
||||
|
@ -1895,15 +1985,8 @@ start_function (FuncDeclaration *fd)
|
|||
/* Function has been defined, check now whether we intend to send it to
|
||||
object file, or it really is extern. Such as inlinable functions from
|
||||
modules not in this compilation, or thunk aliases. */
|
||||
TemplateInstance *ti = fd->isInstantiated ();
|
||||
if (ti && ti->needsCodegen ())
|
||||
if (function_defined_in_root_p (fd))
|
||||
DECL_EXTERNAL (fndecl) = 0;
|
||||
else
|
||||
{
|
||||
Module *md = fd->getModule ();
|
||||
if (md && md->isRoot ())
|
||||
DECL_EXTERNAL (fndecl) = 0;
|
||||
}
|
||||
|
||||
DECL_INITIAL (fndecl) = error_mark_node;
|
||||
|
||||
|
@ -2422,16 +2505,16 @@ set_linkage_for_decl (tree decl)
|
|||
if (!TREE_PUBLIC (decl))
|
||||
return;
|
||||
|
||||
/* Don't need to give private or protected symbols a special linkage. */
|
||||
if ((TREE_PRIVATE (decl) || TREE_PROTECTED (decl))
|
||||
&& !DECL_INSTANTIATED (decl))
|
||||
return;
|
||||
|
||||
/* Functions declared as `pragma(inline, true)' can appear in multiple
|
||||
translation units. */
|
||||
if (TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl))
|
||||
return d_comdat_linkage (decl);
|
||||
|
||||
/* Don't need to give private or protected symbols a special linkage. */
|
||||
if ((TREE_PRIVATE (decl) || TREE_PROTECTED (decl))
|
||||
&& !DECL_INSTANTIATED (decl))
|
||||
return;
|
||||
|
||||
/* If all instantiations must go in COMDAT, give them that linkage.
|
||||
This also applies to other extern declarations, so that it is possible
|
||||
for them to override template declarations. */
|
||||
|
|
|
@ -14717,6 +14717,13 @@ optimizing.
|
|||
Maximum number of statements allowed in a block that needs to be
|
||||
duplicated when threading jumps.
|
||||
|
||||
@item max-jump-thread-paths
|
||||
The maximum number of paths to consider when searching for jump threading
|
||||
opportunities. When arriving at a block incoming edges are only considered
|
||||
if the number of paths to be searched sofar multiplied by the incoming
|
||||
edge degree does not exhaust the specified maximum number of paths to
|
||||
consider.
|
||||
|
||||
@item max-fields-for-field-sensitive
|
||||
Maximum number of fields in a structure treated in
|
||||
a field sensitive manner during pointer analysis.
|
||||
|
@ -15218,9 +15225,6 @@ Emit instrumentation calls to __tsan_func_entry() and __tsan_func_exit().
|
|||
Maximum number of instructions to copy when duplicating blocks on a
|
||||
finite state automaton jump thread path.
|
||||
|
||||
@item max-fsm-thread-length
|
||||
Maximum number of basic blocks on a jump thread path.
|
||||
|
||||
@item threader-debug
|
||||
threader-debug=[none|all] Enables verbose dumping of the threader solver.
|
||||
|
||||
|
|
|
@ -6069,12 +6069,7 @@ dwarf2out_register_external_die (tree decl, const char *sym,
|
|||
|
||||
if (!external_die_map)
|
||||
external_die_map = hash_map<tree, sym_off_pair>::create_ggc (1000);
|
||||
/* When we do tree merging during WPA or with -flto-partition=none we
|
||||
can end up re-using GC memory as there's currently no way to unregister
|
||||
external DIEs. Ideally we'd register them only after merging finished
|
||||
but allowing override here is easiest. See PR106334. */
|
||||
gcc_checking_assert (!(in_lto_p && !flag_wpa)
|
||||
|| !external_die_map->get (decl));
|
||||
gcc_checking_assert (!external_die_map->get (decl));
|
||||
sym_off_pair p = { IDENTIFIER_POINTER (get_identifier (sym)), off };
|
||||
external_die_map->put (decl, p);
|
||||
}
|
||||
|
|
|
@ -1398,16 +1398,17 @@ gori_compute::condexpr_adjust (vrange &r1, vrange &r2, gimple *, tree cond,
|
|||
}
|
||||
|
||||
// Now solve for SSA1 or SSA2 if they are in the dependency chain.
|
||||
Value_Range tmp (type);
|
||||
if (ssa1 && in_chain_p (ssa1, cond_name))
|
||||
{
|
||||
if (compute_operand_range (tmp, def_stmt, cond_true, ssa1, src))
|
||||
r1.intersect (tmp);
|
||||
Value_Range tmp1 (TREE_TYPE (ssa1));
|
||||
if (compute_operand_range (tmp1, def_stmt, cond_true, ssa1, src))
|
||||
r1.intersect (tmp1);
|
||||
}
|
||||
if (ssa2 && in_chain_p (ssa2, cond_name))
|
||||
{
|
||||
if (compute_operand_range (tmp, def_stmt, cond_false, ssa2, src))
|
||||
r2.intersect (tmp);
|
||||
Value_Range tmp2 (TREE_TYPE (ssa2));
|
||||
if (compute_operand_range (tmp2, def_stmt, cond_false, ssa2, src))
|
||||
r2.intersect (tmp2);
|
||||
}
|
||||
if (idx)
|
||||
{
|
||||
|
|
|
@ -5488,8 +5488,11 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
|
|||
if (ret == GS_ERROR)
|
||||
return GS_ERROR;
|
||||
/* If we have gimplified both sides of the initializer but have
|
||||
not emitted an assignment, do so now. */
|
||||
if (*expr_p)
|
||||
not emitted an assignment, do so now. */
|
||||
if (*expr_p
|
||||
/* If the type is an empty type, we don't need to emit the
|
||||
assignment. */
|
||||
&& !is_empty_type (TREE_TYPE (TREE_OPERAND (*expr_p, 0))))
|
||||
{
|
||||
tree lhs = TREE_OPERAND (*expr_p, 0);
|
||||
tree rhs = TREE_OPERAND (*expr_p, 1);
|
||||
|
|
|
@ -49,6 +49,9 @@ typedef _Atomic long atomic_long;
|
|||
typedef _Atomic unsigned long atomic_ulong;
|
||||
typedef _Atomic long long atomic_llong;
|
||||
typedef _Atomic unsigned long long atomic_ullong;
|
||||
#ifdef __CHAR8_TYPE__
|
||||
typedef _Atomic __CHAR8_TYPE__ atomic_char8_t;
|
||||
#endif
|
||||
typedef _Atomic __CHAR16_TYPE__ atomic_char16_t;
|
||||
typedef _Atomic __CHAR32_TYPE__ atomic_char32_t;
|
||||
typedef _Atomic __WCHAR_TYPE__ atomic_wchar_t;
|
||||
|
@ -97,6 +100,9 @@ extern void atomic_signal_fence (memory_order);
|
|||
|
||||
#define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE
|
||||
#define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE
|
||||
#ifdef __GCC_ATOMIC_CHAR8_T_LOCK_FREE
|
||||
#define ATOMIC_CHAR8_T_LOCK_FREE __GCC_ATOMIC_CHAR8_T_LOCK_FREE
|
||||
#endif
|
||||
#define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE
|
||||
#define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE
|
||||
#define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE
|
||||
|
|
|
@ -1699,11 +1699,14 @@ lto_read_tree_1 (class lto_input_block *ib, class data_in *data_in, tree expr)
|
|||
/* Read all the pointer fields in EXPR. */
|
||||
streamer_read_tree_body (ib, data_in, expr);
|
||||
|
||||
/* Read any LTO-specific data not read by the tree streamer. */
|
||||
/* Read any LTO-specific data not read by the tree streamer. Do not use
|
||||
stream_read_tree here since that flushes the dref_queue in mids of
|
||||
SCC reading. */
|
||||
if (DECL_P (expr)
|
||||
&& TREE_CODE (expr) != FUNCTION_DECL
|
||||
&& TREE_CODE (expr) != TRANSLATION_UNIT_DECL)
|
||||
DECL_INITIAL (expr) = stream_read_tree (ib, data_in);
|
||||
DECL_INITIAL (expr)
|
||||
= lto_input_tree_1 (ib, data_in, streamer_read_record_start (ib), 0);
|
||||
|
||||
/* Stream references to early generated DIEs. Keep in sync with the
|
||||
trees handled in dwarf2out_register_external_die. */
|
||||
|
|
|
@ -8617,7 +8617,7 @@ expand_omp_atomic_load (basic_block load_bb, tree addr,
|
|||
basic_block store_bb;
|
||||
location_t loc;
|
||||
gimple *stmt;
|
||||
tree decl, call, type, itype;
|
||||
tree decl, type, itype;
|
||||
|
||||
gsi = gsi_last_nondebug_bb (load_bb);
|
||||
stmt = gsi_stmt (gsi);
|
||||
|
@ -8637,23 +8637,33 @@ expand_omp_atomic_load (basic_block load_bb, tree addr,
|
|||
itype = TREE_TYPE (TREE_TYPE (decl));
|
||||
|
||||
enum omp_memory_order omo = gimple_omp_atomic_memory_order (stmt);
|
||||
tree mo = build_int_cst (NULL, omp_memory_order_to_memmodel (omo));
|
||||
call = build_call_expr_loc (loc, decl, 2, addr, mo);
|
||||
tree mo = build_int_cst (integer_type_node,
|
||||
omp_memory_order_to_memmodel (omo));
|
||||
gcall *call = gimple_build_call (decl, 2, addr, mo);
|
||||
gimple_set_location (call, loc);
|
||||
gimple_set_vuse (call, gimple_vuse (stmt));
|
||||
gimple *repl;
|
||||
if (!useless_type_conversion_p (type, itype))
|
||||
call = fold_build1_loc (loc, VIEW_CONVERT_EXPR, type, call);
|
||||
call = build2_loc (loc, MODIFY_EXPR, void_type_node, loaded_val, call);
|
||||
|
||||
force_gimple_operand_gsi (&gsi, call, true, NULL_TREE, true, GSI_SAME_STMT);
|
||||
gsi_remove (&gsi, true);
|
||||
{
|
||||
tree lhs = make_ssa_name (itype);
|
||||
gimple_call_set_lhs (call, lhs);
|
||||
gsi_insert_before (&gsi, call, GSI_SAME_STMT);
|
||||
repl = gimple_build_assign (loaded_val,
|
||||
build1 (VIEW_CONVERT_EXPR, type, lhs));
|
||||
gimple_set_location (repl, loc);
|
||||
}
|
||||
else
|
||||
{
|
||||
gimple_call_set_lhs (call, loaded_val);
|
||||
repl = call;
|
||||
}
|
||||
gsi_replace (&gsi, repl, true);
|
||||
|
||||
store_bb = single_succ (load_bb);
|
||||
gsi = gsi_last_nondebug_bb (store_bb);
|
||||
gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_ATOMIC_STORE);
|
||||
gsi_remove (&gsi, true);
|
||||
|
||||
if (gimple_in_ssa_p (cfun))
|
||||
update_ssa (TODO_update_ssa_no_phi);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -8669,7 +8679,7 @@ expand_omp_atomic_store (basic_block load_bb, tree addr,
|
|||
basic_block store_bb = single_succ (load_bb);
|
||||
location_t loc;
|
||||
gimple *stmt;
|
||||
tree decl, call, type, itype;
|
||||
tree decl, type, itype;
|
||||
machine_mode imode;
|
||||
bool exchange;
|
||||
|
||||
|
@ -8710,25 +8720,36 @@ expand_omp_atomic_store (basic_block load_bb, tree addr,
|
|||
if (!useless_type_conversion_p (itype, type))
|
||||
stored_val = fold_build1_loc (loc, VIEW_CONVERT_EXPR, itype, stored_val);
|
||||
enum omp_memory_order omo = gimple_omp_atomic_memory_order (stmt);
|
||||
tree mo = build_int_cst (NULL, omp_memory_order_to_memmodel (omo));
|
||||
call = build_call_expr_loc (loc, decl, 3, addr, stored_val, mo);
|
||||
tree mo = build_int_cst (integer_type_node,
|
||||
omp_memory_order_to_memmodel (omo));
|
||||
stored_val = force_gimple_operand_gsi (&gsi, stored_val, true, NULL_TREE,
|
||||
true, GSI_SAME_STMT);
|
||||
gcall *call = gimple_build_call (decl, 3, addr, stored_val, mo);
|
||||
gimple_set_location (call, loc);
|
||||
gimple_set_vuse (call, gimple_vuse (stmt));
|
||||
gimple_set_vdef (call, gimple_vdef (stmt));
|
||||
|
||||
gimple *repl = call;
|
||||
if (exchange)
|
||||
{
|
||||
if (!useless_type_conversion_p (type, itype))
|
||||
call = build1_loc (loc, VIEW_CONVERT_EXPR, type, call);
|
||||
call = build2_loc (loc, MODIFY_EXPR, void_type_node, loaded_val, call);
|
||||
{
|
||||
tree lhs = make_ssa_name (itype);
|
||||
gimple_call_set_lhs (call, lhs);
|
||||
gsi_insert_before (&gsi, call, GSI_SAME_STMT);
|
||||
repl = gimple_build_assign (loaded_val,
|
||||
build1 (VIEW_CONVERT_EXPR, type, lhs));
|
||||
gimple_set_location (repl, loc);
|
||||
}
|
||||
else
|
||||
gimple_call_set_lhs (call, loaded_val);
|
||||
}
|
||||
|
||||
force_gimple_operand_gsi (&gsi, call, true, NULL_TREE, true, GSI_SAME_STMT);
|
||||
gsi_remove (&gsi, true);
|
||||
gsi_replace (&gsi, repl, true);
|
||||
|
||||
/* Remove the GIMPLE_OMP_ATOMIC_LOAD that we verified above. */
|
||||
gsi = gsi_last_nondebug_bb (load_bb);
|
||||
gsi_remove (&gsi, true);
|
||||
|
||||
if (gimple_in_ssa_p (cfun))
|
||||
update_ssa (TODO_update_ssa_no_phi);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -8874,10 +8895,7 @@ expand_omp_atomic_fetch_op (basic_block load_bb,
|
|||
gsi_remove (&gsi, true);
|
||||
|
||||
if (gimple_in_ssa_p (cfun))
|
||||
{
|
||||
release_defs (stmt);
|
||||
update_ssa (TODO_update_ssa_no_phi);
|
||||
}
|
||||
release_defs (stmt);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -9333,16 +9351,16 @@ expand_omp_atomic_pipeline (basic_block load_bb, basic_block store_bb,
|
|||
}
|
||||
|
||||
/* Remove GIMPLE_OMP_ATOMIC_STORE. */
|
||||
stmt = gsi_stmt (si);
|
||||
gsi_remove (&si, true);
|
||||
if (gimple_in_ssa_p (cfun))
|
||||
release_defs (stmt);
|
||||
|
||||
class loop *loop = alloc_loop ();
|
||||
loop->header = loop_header;
|
||||
loop->latch = store_bb;
|
||||
add_loop (loop, loop_header->loop_father);
|
||||
|
||||
if (gimple_in_ssa_p (cfun))
|
||||
update_ssa (TODO_update_ssa_no_phi);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -9399,15 +9417,14 @@ expand_omp_atomic_mutex (basic_block load_bb, basic_block store_bb,
|
|||
gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_STORE);
|
||||
|
||||
stmt = gimple_build_assign (unshare_expr (mem), stored_val);
|
||||
gimple_set_vuse (stmt, gimple_vuse (gsi_stmt (si)));
|
||||
gimple_set_vdef (stmt, gimple_vdef (gsi_stmt (si)));
|
||||
gsi_insert_before (&si, stmt, GSI_SAME_STMT);
|
||||
|
||||
t = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_END);
|
||||
t = build_call_expr (t, 0);
|
||||
force_gimple_operand_gsi (&si, t, true, NULL_TREE, true, GSI_SAME_STMT);
|
||||
gsi_remove (&si, true);
|
||||
|
||||
if (gimple_in_ssa_p (cfun))
|
||||
update_ssa (TODO_update_ssa_no_phi);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -6241,10 +6241,10 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
|
|||
}
|
||||
|
||||
if (POINTER_TYPE_P (TREE_TYPE (x)))
|
||||
x = fold_build2 (POINTER_PLUS_EXPR,
|
||||
TREE_TYPE (x), x, t);
|
||||
x = fold_build_pointer_plus (x, t);
|
||||
else
|
||||
x = fold_build2 (PLUS_EXPR, TREE_TYPE (x), x, t);
|
||||
x = fold_build2 (PLUS_EXPR, TREE_TYPE (x), x,
|
||||
fold_convert (TREE_TYPE (x), t));
|
||||
}
|
||||
|
||||
if ((OMP_CLAUSE_CODE (c) != OMP_CLAUSE_LINEAR
|
||||
|
|
|
@ -498,10 +498,6 @@ The maximum number of nested indirect inlining performed by early inliner.
|
|||
Common Joined UInteger Var(param_max_fields_for_field_sensitive) Param
|
||||
Maximum number of fields in a structure before pointer analysis treats the structure as a single variable.
|
||||
|
||||
-param=max-fsm-thread-length=
|
||||
Common Joined UInteger Var(param_max_fsm_thread_length) Init(10) IntegerRange(1, 999999) Param Optimization
|
||||
Maximum number of basic blocks on a jump thread path.
|
||||
|
||||
-param=max-fsm-thread-path-insns=
|
||||
Common Joined UInteger Var(param_max_fsm_thread_path_insns) Init(100) IntegerRange(1, 999999) Param Optimization
|
||||
Maximum number of instructions to copy when duplicating blocks on a finite state automaton jump thread path.
|
||||
|
@ -582,6 +578,10 @@ Bound on the number of iterations the brute force # of iterations analysis algor
|
|||
Common Joined UInteger Var(param_max_jump_thread_duplication_stmts) Init(15) Param Optimization
|
||||
Maximum number of statements allowed in a block that needs to be duplicated when threading jumps.
|
||||
|
||||
-param=max-jump-thread-paths=
|
||||
Common Joined UInteger Var(param_max_jump_thread_paths) Init(64) IntegerRange(1, 65536) Param Optimization
|
||||
Search space limit for the backwards jump threader.
|
||||
|
||||
-param=max-last-value-rtl=
|
||||
Common Joined UInteger Var(param_max_last_value_rtl) Init(10000) Param Optimization
|
||||
The maximum number of RTL nodes that can be recorded as combiner's last value.
|
||||
|
|
|
@ -1,3 +1,40 @@
|
|||
2022-08-08 Andrew MacLeod <amacleod@redhat.com>
|
||||
|
||||
PR tree-optimization/106556
|
||||
* gfortran.dg/pr106556.f90: New.
|
||||
|
||||
2022-08-08 Tom Honermann <tom@honermann.net>
|
||||
|
||||
PR preprocessor/106426
|
||||
* g++.dg/ext/char8_t-char-literal-1.C: Check signedness of u8 literals.
|
||||
* g++.dg/ext/char8_t-char-literal-2.C: Check signedness of u8 literals.
|
||||
|
||||
2022-08-08 Tom Honermann <tom@honermann.net>
|
||||
|
||||
* gcc.dg/atomic/c2x-stdatomic-lockfree-char8_t.c: New test.
|
||||
* gcc.dg/atomic/gnu2x-stdatomic-lockfree-char8_t.c: New test.
|
||||
* gcc.dg/c11-utf8str-type.c: New test.
|
||||
* gcc.dg/c17-utf8str-type.c: New test.
|
||||
* gcc.dg/c2x-utf8str-type.c: New test.
|
||||
* gcc.dg/c2x-utf8str.c: New test.
|
||||
* gcc.dg/gnu2x-utf8str-type.c: New test.
|
||||
* gcc.dg/gnu2x-utf8str.c: New test.
|
||||
|
||||
2022-08-08 Iain Buclaw <ibuclaw@gdcproject.org>
|
||||
|
||||
PR d/106555
|
||||
* gdc.dg/imports/pr106555.d: New test.
|
||||
* gdc.dg/pr106555.d: New test.
|
||||
|
||||
2022-08-08 Andrew Pinski <apinski@marvell.com>
|
||||
|
||||
* gcc.dg/pr87052.c: Update d var to expect nothing.
|
||||
|
||||
2022-08-08 Andrew Pinski <apinski@marvell.com>
|
||||
|
||||
* gcc.dg/tree-ssa/pr93776.c: Moved to...
|
||||
* gcc.c-torture/compile/pr93776.c: ...here.
|
||||
|
||||
2022-08-07 Roger Sayle <roger@nextmovesoftware.com>
|
||||
|
||||
* gcc.target/i386/cmpti2.c: Add -mno-stv to dg-options.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Test that UTF-8 character literals have type char if -fchar8_t is not enabled.
|
||||
// { dg-do compile }
|
||||
// { dg-options "-std=c++17 -fno-char8_t" }
|
||||
// { dg-options "-std=c++17 -fsigned-char -fno-char8_t" }
|
||||
|
||||
template<typename T1, typename T2>
|
||||
struct is_same
|
||||
|
@ -10,3 +10,7 @@ template<typename T>
|
|||
{ static const bool value = true; };
|
||||
|
||||
static_assert(is_same<decltype(u8'x'), char>::value, "Error");
|
||||
|
||||
#if u8'\0' - 1 > 0
|
||||
#error "UTF-8 character literals not signed in preprocessor"
|
||||
#endif
|
||||
|
|
|
@ -10,3 +10,7 @@ template<typename T>
|
|||
{ static const bool value = true; };
|
||||
|
||||
static_assert(is_same<decltype(u8'x'), char8_t>::value, "Error");
|
||||
|
||||
#if u8'\0' - 1 < 0
|
||||
#error "UTF-8 character literals not unsigned in preprocessor"
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
/* PR middle-end/106492 */
|
||||
|
||||
template <typename T>
|
||||
struct S {
|
||||
T a : 12;
|
||||
S () : a(0)
|
||||
{
|
||||
#pragma omp for simd linear(a)
|
||||
for (int k = 0; k < 64; ++k)
|
||||
a++;
|
||||
}
|
||||
};
|
||||
struct U {
|
||||
int a : 12;
|
||||
U () : a(0)
|
||||
{
|
||||
#pragma omp for simd linear(a)
|
||||
for (int k = 0; k < 64; ++k)
|
||||
a++;
|
||||
}
|
||||
};
|
||||
|
||||
S<int> s;
|
||||
U u;
|
||||
|
||||
|
||||
template <typename T>
|
||||
struct Sptr {
|
||||
T a;
|
||||
Sptr (T init) : a(init)
|
||||
{
|
||||
#pragma omp for simd linear(a)
|
||||
for (int k = 0; k < 64; ++k)
|
||||
a++;
|
||||
}
|
||||
};
|
||||
struct Uptr {
|
||||
int *a;
|
||||
Uptr (int *init) : a(init)
|
||||
{
|
||||
#pragma omp for simd linear(a)
|
||||
for (int k = 0; k < 64; ++k)
|
||||
a++;
|
||||
}
|
||||
};
|
||||
|
||||
int i[1024];
|
||||
Sptr<int *> sptr(i);
|
||||
Uptr uptr(&i[100]);
|
|
@ -0,0 +1,42 @@
|
|||
/* Test atomic_is_lock_free for char8_t. */
|
||||
/* { dg-do run } */
|
||||
/* { dg-options "-std=c2x -pedantic-errors" } */
|
||||
|
||||
#include <stdatomic.h>
|
||||
#include <stdint.h>
|
||||
|
||||
extern void abort (void);
|
||||
|
||||
_Atomic __CHAR8_TYPE__ ac8a;
|
||||
atomic_char8_t ac8t;
|
||||
|
||||
#define CHECK_TYPE(MACRO, V1, V2) \
|
||||
do \
|
||||
{ \
|
||||
int r1 = MACRO; \
|
||||
int r2 = atomic_is_lock_free (&V1); \
|
||||
int r3 = atomic_is_lock_free (&V2); \
|
||||
if (r1 != 0 && r1 != 1 && r1 != 2) \
|
||||
abort (); \
|
||||
if (r2 != 0 && r2 != 1) \
|
||||
abort (); \
|
||||
if (r3 != 0 && r3 != 1) \
|
||||
abort (); \
|
||||
if (r1 == 2 && r2 != 1) \
|
||||
abort (); \
|
||||
if (r1 == 2 && r3 != 1) \
|
||||
abort (); \
|
||||
if (r1 == 0 && r2 != 0) \
|
||||
abort (); \
|
||||
if (r1 == 0 && r3 != 0) \
|
||||
abort (); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
CHECK_TYPE (ATOMIC_CHAR8_T_LOCK_FREE, ac8a, ac8t);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
/* Test atomic_is_lock_free for char8_t with -std=gnu2x. */
|
||||
/* { dg-do run } */
|
||||
/* { dg-options "-std=gnu2x -pedantic-errors" } */
|
||||
|
||||
#include "c2x-stdatomic-lockfree-char8_t.c"
|
|
@ -0,0 +1,6 @@
|
|||
/* Test C11 UTF-8 string literal type. */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-std=c11" } */
|
||||
|
||||
_Static_assert (_Generic (u8"text", char*: 1, default: 2) == 1, "UTF-8 string literals have an unexpected type");
|
||||
_Static_assert (_Generic (u8"x"[0], char: 1, default: 2) == 1, "UTF-8 string literal elements have an unexpected type");
|
|
@ -0,0 +1,6 @@
|
|||
/* Test C17 UTF-8 string literal type. */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-std=c17" } */
|
||||
|
||||
_Static_assert (_Generic (u8"text", char*: 1, default: 2) == 1, "UTF-8 string literals have an unexpected type");
|
||||
_Static_assert (_Generic (u8"x"[0], char: 1, default: 2) == 1, "UTF-8 string literal elements have an unexpected type");
|
|
@ -0,0 +1,6 @@
|
|||
/* Test C2X UTF-8 string literal type. */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-std=c2x" } */
|
||||
|
||||
_Static_assert (_Generic (u8"text", unsigned char*: 1, default: 2) == 1, "UTF-8 string literals have an unexpected type");
|
||||
_Static_assert (_Generic (u8"x"[0], unsigned char: 1, default: 2) == 1, "UTF-8 string literal elements have an unexpected type");
|
|
@ -0,0 +1,34 @@
|
|||
/* Test initialization by UTF-8 string literal in C2X. */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-require-effective-target wchar } */
|
||||
/* { dg-options "-std=c2x" } */
|
||||
|
||||
typedef __CHAR8_TYPE__ char8_t;
|
||||
typedef __CHAR16_TYPE__ char16_t;
|
||||
typedef __CHAR32_TYPE__ char32_t;
|
||||
typedef __WCHAR_TYPE__ wchar_t;
|
||||
|
||||
/* Test that char, signed char, unsigned char, and char8_t arrays can be
|
||||
initialized by a UTF-8 string literal. */
|
||||
const char cbuf1[] = u8"text";
|
||||
const char cbuf2[] = { u8"text" };
|
||||
const signed char scbuf1[] = u8"text";
|
||||
const signed char scbuf2[] = { u8"text" };
|
||||
const unsigned char ucbuf1[] = u8"text";
|
||||
const unsigned char ucbuf2[] = { u8"text" };
|
||||
const char8_t c8buf1[] = u8"text";
|
||||
const char8_t c8buf2[] = { u8"text" };
|
||||
|
||||
/* Test that a diagnostic is issued for attempted initialization of
|
||||
other character types by a UTF-8 string literal. */
|
||||
const char16_t c16buf1[] = u8"text"; /* { dg-error "from a string literal with type array of .unsigned char." } */
|
||||
const char16_t c16buf2[] = { u8"text" }; /* { dg-error "from a string literal with type array of .unsigned char." } */
|
||||
const char32_t c32buf1[] = u8"text"; /* { dg-error "from a string literal with type array of .unsigned char." } */
|
||||
const char32_t c32buf2[] = { u8"text" }; /* { dg-error "from a string literal with type array of .unsigned char." } */
|
||||
const wchar_t wbuf1[] = u8"text"; /* { dg-error "from a string literal with type array of .unsigned char." } */
|
||||
const wchar_t wbuf2[] = { u8"text" }; /* { dg-error "from a string literal with type array of .unsigned char." } */
|
||||
|
||||
/* Test that char8_t arrays can be initialized by an ordinary string
|
||||
literal. */
|
||||
const char8_t c8buf3[] = "text";
|
||||
const char8_t c8buf4[] = { "text" };
|
|
@ -0,0 +1,5 @@
|
|||
/* Test C2X UTF-8 string literal type with -std=gnu2x. */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-std=gnu2x" } */
|
||||
|
||||
#include "c2x-utf8str-type.c"
|
|
@ -0,0 +1,34 @@
|
|||
/* Test initialization by UTF-8 string literal in C2X with -std=gnu2x. */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-require-effective-target wchar } */
|
||||
/* { dg-options "-std=gnu2x" } */
|
||||
|
||||
typedef __CHAR8_TYPE__ char8_t;
|
||||
typedef __CHAR16_TYPE__ char16_t;
|
||||
typedef __CHAR32_TYPE__ char32_t;
|
||||
typedef __WCHAR_TYPE__ wchar_t;
|
||||
|
||||
/* Test that char, signed char, unsigned char, and char8_t arrays can be
|
||||
initialized by a UTF-8 string literal. */
|
||||
const char cbuf1[] = u8"text";
|
||||
const char cbuf2[] = { u8"text" };
|
||||
const signed char scbuf1[] = u8"text";
|
||||
const signed char scbuf2[] = { u8"text" };
|
||||
const unsigned char ucbuf1[] = u8"text";
|
||||
const unsigned char ucbuf2[] = { u8"text" };
|
||||
const char8_t c8buf1[] = u8"text";
|
||||
const char8_t c8buf2[] = { u8"text" };
|
||||
|
||||
/* Test that a diagnostic is issued for attempted initialization of
|
||||
other character types by a UTF-8 string literal. */
|
||||
const char16_t c16buf1[] = u8"text"; /* { dg-error "from a string literal with type array of .unsigned char." } */
|
||||
const char16_t c16buf2[] = { u8"text" }; /* { dg-error "from a string literal with type array of .unsigned char." } */
|
||||
const char32_t c32buf1[] = u8"text"; /* { dg-error "from a string literal with type array of .unsigned char." } */
|
||||
const char32_t c32buf2[] = { u8"text" }; /* { dg-error "from a string literal with type array of .unsigned char." } */
|
||||
const wchar_t wbuf1[] = u8"text"; /* { dg-error "from a string literal with type array of .unsigned char." } */
|
||||
const wchar_t wbuf2[] = { u8"text" }; /* { dg-error "from a string literal with type array of .unsigned char." } */
|
||||
|
||||
/* Test that char8_t arrays can be initialized by an ordinary string
|
||||
literal. */
|
||||
const char8_t c8buf3[] = "text";
|
||||
const char8_t c8buf4[] = { "text" };
|
|
@ -23,8 +23,7 @@ void test (void)
|
|||
|
||||
const char d[0] = { };
|
||||
|
||||
/* Expect the following:
|
||||
d = ""; */
|
||||
/* Expect nothing. */
|
||||
|
||||
const char e[0] = "";
|
||||
|
||||
|
@ -36,6 +35,7 @@ void test (void)
|
|||
/* { dg-final { scan-tree-dump-times "a = \"\\\\x00ab\";" 1 "gimple" } }
|
||||
{ dg-final { scan-tree-dump-times "b = \"a\\\\x00bc\";" 1 "gimple" } }
|
||||
{ dg-final { scan-tree-dump-times "c = \"\";" 1 "gimple" } }
|
||||
{ dg-final { scan-tree-dump-times "d = { *};" 1 "gimple" } }
|
||||
{ dg-final { scan-tree-dump-times "d = " 1 "gimple" } }
|
||||
{ dg-final { scan-tree-dump-times "d = {CLOBBER\\(eol\\)}" 1 "gimple" } }
|
||||
{ dg-final { scan-tree-dump-times "e = " 1 "gimple" } }
|
||||
{ dg-final { scan-tree-dump-times "e = {CLOBBER\\(eol\\)}" 1 "gimple" } } */
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
to change decisions in switch expansion which in turn can expose new
|
||||
jump threading opportunities. Skip the later tests on aarch64. */
|
||||
/* { dg-final { scan-tree-dump-not "Jumps threaded" "dom3" { target { ! aarch64*-*-* } } } } */
|
||||
/* { dg-final { scan-tree-dump "Jumps threaded: 8" "thread2" { target { ! aarch64*-*-* } } } } */
|
||||
/* { dg-final { scan-tree-dump "Jumps threaded: 9" "thread2" { target { ! aarch64*-*-* } } } } */
|
||||
/* { dg-final { scan-tree-dump "Jumps threaded: 18" "thread2" { target { aarch64*-*-* } } } } */
|
||||
|
||||
enum STATE {
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -fdump-tree-threadfull1-details" } */
|
||||
|
||||
int res;
|
||||
void foo (int a, int b, int c, int d, int e)
|
||||
{
|
||||
if (a > 100)
|
||||
res = 3;
|
||||
if (b != 5)
|
||||
res = 5;
|
||||
if (c == 29)
|
||||
res = 7;
|
||||
if (d < 2)
|
||||
res = 9;
|
||||
/* Accounting whoes makes this not catched. */
|
||||
#if 0
|
||||
if (e != 37)
|
||||
res = 11;
|
||||
#endif
|
||||
if (a < 10)
|
||||
res = 13;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump "SUCCESS" "threadfull1" } } */
|
|
@ -0,0 +1,7 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -fdump-tree-threadfull1-details --param max-jump-thread-paths=15" } */
|
||||
|
||||
#include "ssa-thread-16.c"
|
||||
|
||||
/* With limiting the search space we should no longer consider this path. */
|
||||
/* { dg-final { scan-tree-dump-not "SUCCESS" "threadfull1" } } */
|
|
@ -0,0 +1,10 @@
|
|||
module imports.pr106555;
|
||||
struct S106555
|
||||
{
|
||||
int[] f106555;
|
||||
int max106555;
|
||||
this(int)
|
||||
{
|
||||
f106555.length = max106555;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106555
|
||||
// { dg-do compile }
|
||||
// { dg-additional-options "-O2" }
|
||||
// { dg-additional-sources "imports/pr106555.d" }
|
|
@ -0,0 +1,12 @@
|
|||
module imports.pr106563math;
|
||||
|
||||
T nextPow2(T)(const T val)
|
||||
{
|
||||
return powIntegralImpl(val);
|
||||
}
|
||||
|
||||
pragma(inline, true)
|
||||
T powIntegralImpl(T)(T)
|
||||
{
|
||||
return 1;
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
module imports.pr106563regex;
|
||||
import imports.pr106563uni;
|
||||
|
||||
struct CharMatcher
|
||||
{
|
||||
typeof(MultiArray!().length) trie;
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
module imports.pr106563uni;
|
||||
|
||||
struct MultiArray()
|
||||
{
|
||||
@property length()
|
||||
{
|
||||
return spaceFor!0();
|
||||
}
|
||||
}
|
||||
|
||||
size_t spaceFor(size_t bits)()
|
||||
{
|
||||
import imports.pr106563math;
|
||||
return nextPow2(bits);
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106563
|
||||
// { dg-do link }
|
||||
// { dg-additional-files "imports/pr106563math.d imports/pr106563regex.d imports/pr106563uni.d" }
|
||||
// { dg-additional-options "-I[srcdir] -fno-druntime" }
|
||||
import imports.pr106563math;
|
||||
import imports.pr106563regex;
|
||||
|
||||
auto requireSize()(size_t size)
|
||||
{
|
||||
return nextPow2(size);
|
||||
}
|
||||
|
||||
extern(C) int main()
|
||||
{
|
||||
return cast(int)requireSize(0);
|
||||
}
|
|
@ -19,6 +19,15 @@
|
|||
# Load support procs.
|
||||
load_lib gdc-dg.exp
|
||||
|
||||
# Helper function allows adding tests that use imports/*, but don't compile
|
||||
# the sources in with dg-additional-sources.
|
||||
global testdir
|
||||
set testdir $srcdir/$subdir
|
||||
proc srcdir {} {
|
||||
global testdir
|
||||
return $testdir
|
||||
}
|
||||
|
||||
# The default option list can be overridden by
|
||||
# TORTURE_OPTIONS="{ { list1 } ... { listN } }"
|
||||
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
! { dg-do compile }
|
||||
! { dg-options "-O1 -fnon-call-exceptions -ftree-loop-if-convert" }
|
||||
|
||||
|
||||
program p
|
||||
real :: a(2)
|
||||
|
||||
a(:) = 1.0
|
||||
if (minloc (a, dim = 1).ne.1) STOP 1
|
||||
end
|
|
@ -3082,7 +3082,7 @@ gen_parallel_loop (class loop *loop,
|
|||
profile_probability::unlikely (),
|
||||
profile_probability::likely (),
|
||||
profile_probability::unlikely (), true);
|
||||
update_ssa (TODO_update_ssa);
|
||||
update_ssa (TODO_update_ssa_no_phi);
|
||||
free_original_copy_tables ();
|
||||
}
|
||||
|
||||
|
|
|
@ -90,7 +90,7 @@ private:
|
|||
bool debug_counter ();
|
||||
edge maybe_register_path ();
|
||||
void maybe_register_path_dump (edge taken_edge);
|
||||
void find_paths_to_names (basic_block bb, bitmap imports);
|
||||
void find_paths_to_names (basic_block bb, bitmap imports, unsigned);
|
||||
edge find_taken_edge (const vec<basic_block> &path);
|
||||
edge find_taken_edge_cond (const vec<basic_block> &path, gcond *);
|
||||
edge find_taken_edge_switch (const vec<basic_block> &path, gswitch *);
|
||||
|
@ -337,9 +337,12 @@ back_threader::find_taken_edge_cond (const vec<basic_block> &path,
|
|||
// INTERESTING bitmap, and register any such paths.
|
||||
//
|
||||
// BB is the current path being processed.
|
||||
//
|
||||
// OVERALL_PATHS is the search space up to this block
|
||||
|
||||
void
|
||||
back_threader::find_paths_to_names (basic_block bb, bitmap interesting)
|
||||
back_threader::find_paths_to_names (basic_block bb, bitmap interesting,
|
||||
unsigned overall_paths)
|
||||
{
|
||||
if (m_visited_bbs.add (bb))
|
||||
return;
|
||||
|
@ -352,8 +355,10 @@ back_threader::find_paths_to_names (basic_block bb, bitmap interesting)
|
|||
|| maybe_register_path ()))
|
||||
;
|
||||
|
||||
// Continue looking for ways to extend the path
|
||||
else
|
||||
// Continue looking for ways to extend the path but limit the
|
||||
// search space along a branch
|
||||
else if ((overall_paths = overall_paths * EDGE_COUNT (bb->preds))
|
||||
<= (unsigned)param_max_jump_thread_paths)
|
||||
{
|
||||
// For further greedy searching we want to remove interesting
|
||||
// names defined in BB but add ones on the PHI edges for the
|
||||
|
@ -407,7 +412,7 @@ back_threader::find_paths_to_names (basic_block bb, bitmap interesting)
|
|||
unwind.quick_push (def);
|
||||
}
|
||||
}
|
||||
find_paths_to_names (e->src, new_interesting);
|
||||
find_paths_to_names (e->src, new_interesting, overall_paths);
|
||||
// Restore new_interesting. We leave m_imports alone since
|
||||
// we do not prune defs in BB from it and separately keeping
|
||||
// track of which bits to unwind isn't worth the trouble.
|
||||
|
@ -417,6 +422,9 @@ back_threader::find_paths_to_names (basic_block bb, bitmap interesting)
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
fprintf (dump_file, " FAIL: Search space limit %d reached.\n",
|
||||
param_max_jump_thread_paths);
|
||||
|
||||
// Reset things to their original state.
|
||||
m_path.pop ();
|
||||
|
@ -447,7 +455,7 @@ back_threader::find_paths (basic_block bb, tree name)
|
|||
|
||||
auto_bitmap interesting;
|
||||
bitmap_copy (interesting, m_imports);
|
||||
find_paths_to_names (bb, interesting);
|
||||
find_paths_to_names (bb, interesting, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -561,15 +569,6 @@ back_threader_profitability::profitable_path_p (const vec<basic_block> &m_path,
|
|||
if (m_path.length () <= 1)
|
||||
return false;
|
||||
|
||||
if (m_path.length () > (unsigned) param_max_fsm_thread_length)
|
||||
{
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
fprintf (dump_file, " FAIL: Jump-thread path not considered: "
|
||||
"the number of basic blocks on the path "
|
||||
"exceeds PARAM_MAX_FSM_THREAD_LENGTH.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
int n_insns = 0;
|
||||
gimple_stmt_iterator gsi;
|
||||
loop_p loop = m_path[0]->loop_father;
|
||||
|
|
|
@ -1,3 +1,15 @@
|
|||
2022-08-08 Tamar Christina <tamar.christina@arm.com>
|
||||
|
||||
PR target/102218
|
||||
* config/arm/host-config.h (pre_seq_barrier, post_seq_barrier,
|
||||
pre_post_seq_barrier): Require barrier on __ATOMIC_SEQ_CST.
|
||||
|
||||
2022-08-08 Tamar Christina <tamar.christina@arm.com>
|
||||
|
||||
PR target/102218
|
||||
* config/aarch64/aarch64-config.h: New file.
|
||||
* config/aarch64/host-config.h: New file.
|
||||
|
||||
2022-06-02 David Malcolm <dmalcolm@redhat.com>
|
||||
|
||||
* testsuite/lib/libatomic.exp: Add load_gcc_lib of scansarif.exp.
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
/* Copyright (C) 2022 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Atomic Library (libatomic).
|
||||
|
||||
Libatomic 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.
|
||||
|
||||
Libatomic 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.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
/* Copyright (C) 2022 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Atomic Library (libatomic).
|
||||
|
||||
Libatomic 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.
|
||||
|
||||
Libatomic 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.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Avoiding the DMB (or kernel helper) can be a good thing. */
|
||||
#define WANT_SPECIALCASE_RELAXED
|
||||
|
||||
/* Glibc, at least, uses acq_rel in its pthread mutex
|
||||
implementation. If the user is asking for seq_cst,
|
||||
this is insufficient. */
|
||||
|
||||
static inline void __attribute__((always_inline, artificial))
|
||||
pre_seq_barrier(int model)
|
||||
{
|
||||
if (model == __ATOMIC_SEQ_CST)
|
||||
__atomic_thread_fence (__ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
static inline void __attribute__((always_inline, artificial))
|
||||
post_seq_barrier(int model)
|
||||
{
|
||||
pre_seq_barrier(model);
|
||||
}
|
||||
|
||||
#define pre_post_seq_barrier 1
|
||||
|
||||
#include_next <host-config.h>
|
|
@ -1,4 +1,23 @@
|
|||
/* Avoiding the DMB (or kernel helper) can be a good thing. */
|
||||
#define WANT_SPECIALCASE_RELAXED
|
||||
|
||||
/* Glibc, at least, uses acq_rel in its pthread mutex
|
||||
implementation. If the user is asking for seq_cst,
|
||||
this is insufficient. */
|
||||
|
||||
static inline void __attribute__((always_inline, artificial))
|
||||
pre_seq_barrier(int model)
|
||||
{
|
||||
if (model == __ATOMIC_SEQ_CST)
|
||||
__atomic_thread_fence (__ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
static inline void __attribute__((always_inline, artificial))
|
||||
post_seq_barrier(int model)
|
||||
{
|
||||
pre_seq_barrier(model);
|
||||
}
|
||||
|
||||
#define pre_post_seq_barrier 1
|
||||
|
||||
#include_next <host-config.h>
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
2022-08-08 Tom Honermann <tom@honermann.net>
|
||||
|
||||
PR preprocessor/106426
|
||||
* charset.cc (narrow_str_to_charconst): Set signedness of CPP_UTF8CHAR
|
||||
literals based on unsigned_utf8char.
|
||||
* include/cpplib.h (cpp_options): Add unsigned_utf8char.
|
||||
* init.cc (cpp_create_reader): Initialize unsigned_utf8char.
|
||||
|
||||
2022-07-15 Jonathan Wakely <jwakely@redhat.com>
|
||||
|
||||
* include/line-map.h (label_text::take_or_copy): Remove.
|
||||
|
|
|
@ -1960,8 +1960,8 @@ narrow_str_to_charconst (cpp_reader *pfile, cpp_string str,
|
|||
/* Multichar constants are of type int and therefore signed. */
|
||||
if (i > 1)
|
||||
unsigned_p = 0;
|
||||
else if (type == CPP_UTF8CHAR && !CPP_OPTION (pfile, cplusplus))
|
||||
unsigned_p = 1;
|
||||
else if (type == CPP_UTF8CHAR)
|
||||
unsigned_p = CPP_OPTION (pfile, unsigned_utf8char);
|
||||
else
|
||||
unsigned_p = CPP_OPTION (pfile, unsigned_char);
|
||||
|
||||
|
|
|
@ -581,8 +581,8 @@ struct cpp_options
|
|||
ints and target wide characters, respectively. */
|
||||
size_t precision, char_precision, int_precision, wchar_precision;
|
||||
|
||||
/* True means chars (wide chars) are unsigned. */
|
||||
bool unsigned_char, unsigned_wchar;
|
||||
/* True means chars (wide chars, UTF-8 chars) are unsigned. */
|
||||
bool unsigned_char, unsigned_wchar, unsigned_utf8char;
|
||||
|
||||
/* True if the most significant byte in a word has the lowest
|
||||
address in memory. */
|
||||
|
|
|
@ -231,6 +231,7 @@ cpp_create_reader (enum c_lang lang, cpp_hash_table *table,
|
|||
CPP_OPTION (pfile, int_precision) = CHAR_BIT * sizeof (int);
|
||||
CPP_OPTION (pfile, unsigned_char) = 0;
|
||||
CPP_OPTION (pfile, unsigned_wchar) = 1;
|
||||
CPP_OPTION (pfile, unsigned_utf8char) = 1;
|
||||
CPP_OPTION (pfile, bytes_big_endian) = 1; /* does not matter */
|
||||
|
||||
/* Default to no charset conversion. */
|
||||
|
|
|
@ -1,3 +1,21 @@
|
|||
2022-08-08 François Dumont <fdumont@gcc.gnu.org>
|
||||
|
||||
* include/debug/formatter.h (__singular_value_init): New _Iterator_state enum entry.
|
||||
(_Parameter<>(const _Safe_iterator<>&, const char*, _Is_iterator)): Check if iterator
|
||||
parameter is value-initialized.
|
||||
(_Parameter<>(const _Safe_local_iterator<>&, const char*, _Is_iterator)): Likewise.
|
||||
* include/debug/safe_iterator.h (_Safe_iterator<>::_M_value_initialized()): New. Adapt
|
||||
checks.
|
||||
* include/debug/safe_local_iterator.h (_Safe_local_iterator<>::_M_value_initialized()): New.
|
||||
Adapt checks.
|
||||
* src/c++11/debug.cc (_Safe_iterator_base::_M_reset): Do not reset _M_version.
|
||||
(print_field(PrintContext&, const _Parameter&, const char*)): Adapt state_names.
|
||||
* testsuite/23_containers/deque/debug/iterator1_neg.cc: New test.
|
||||
* testsuite/23_containers/deque/debug/iterator2_neg.cc: New test.
|
||||
* testsuite/23_containers/forward_list/debug/iterator1_neg.cc: New test.
|
||||
* testsuite/23_containers/forward_list/debug/iterator2_neg.cc: New test.
|
||||
* testsuite/23_containers/forward_list/debug/iterator3_neg.cc: New test.
|
||||
|
||||
2022-08-05 Jonathan Wakely <jwakely@redhat.com>
|
||||
|
||||
* include/experimental/scope (__cpp_lib_experimental_scope):
|
||||
|
|
|
@ -185,6 +185,7 @@ namespace __gnu_debug
|
|||
__rbegin, // dereferenceable, and at the reverse-beginning
|
||||
__rmiddle, // reverse-dereferenceable, not at the reverse-beginning
|
||||
__rend, // reverse-past-the-end
|
||||
__singular_value_init, // singular, value initialized
|
||||
__last_state
|
||||
};
|
||||
|
||||
|
@ -280,7 +281,12 @@ namespace __gnu_debug
|
|||
_M_variant._M_iterator._M_seq_type = _GLIBCXX_TYPEID(_Sequence);
|
||||
|
||||
if (__it._M_singular())
|
||||
_M_variant._M_iterator._M_state = __singular;
|
||||
{
|
||||
if (__it._M_value_initialized())
|
||||
_M_variant._M_iterator._M_state = __singular_value_init;
|
||||
else
|
||||
_M_variant._M_iterator._M_state = __singular;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (__it._M_is_before_begin())
|
||||
|
@ -308,7 +314,12 @@ namespace __gnu_debug
|
|||
_M_variant._M_iterator._M_seq_type = _GLIBCXX_TYPEID(_Sequence);
|
||||
|
||||
if (__it._M_singular())
|
||||
_M_variant._M_iterator._M_state = __singular;
|
||||
{
|
||||
if (__it._M_value_initialized())
|
||||
_M_variant._M_iterator._M_state = __singular_value_init;
|
||||
else
|
||||
_M_variant._M_iterator._M_state = __singular;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (__it._M_is_end())
|
||||
|
|
|
@ -41,8 +41,8 @@
|
|||
|
||||
#define _GLIBCXX_DEBUG_VERIFY_OPERANDS(_Lhs, _Rhs, _BadMsgId, _DiffMsgId) \
|
||||
_GLIBCXX_DEBUG_VERIFY(!_Lhs._M_singular() && !_Rhs._M_singular() \
|
||||
|| (_Lhs.base() == _Iterator() \
|
||||
&& _Rhs.base() == _Iterator()), \
|
||||
|| (_Lhs._M_value_initialized() \
|
||||
&& _Rhs._M_value_initialized()), \
|
||||
_M_message(_BadMsgId) \
|
||||
._M_iterator(_Lhs, #_Lhs) \
|
||||
._M_iterator(_Rhs, #_Rhs)); \
|
||||
|
@ -177,7 +177,7 @@ namespace __gnu_debug
|
|||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// DR 408. Is vector<reverse_iterator<char*> > forbidden?
|
||||
_GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
|
||||
|| __x.base() == _Iterator(),
|
||||
|| __x._M_value_initialized(),
|
||||
_M_message(__msg_init_copy_singular)
|
||||
._M_iterator(*this, "this")
|
||||
._M_iterator(__x, "other"));
|
||||
|
@ -193,7 +193,7 @@ namespace __gnu_debug
|
|||
: _Iter_base()
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
|
||||
|| __x.base() == _Iterator(),
|
||||
|| __x._M_value_initialized(),
|
||||
_M_message(__msg_init_copy_singular)
|
||||
._M_iterator(*this, "this")
|
||||
._M_iterator(__x, "other"));
|
||||
|
@ -220,7 +220,7 @@ namespace __gnu_debug
|
|||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// DR 408. Is vector<reverse_iterator<char*> > forbidden?
|
||||
_GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
|
||||
|| __x.base() == _MutableIterator(),
|
||||
|| __x._M_value_initialized(),
|
||||
_M_message(__msg_init_const_singular)
|
||||
._M_iterator(*this, "this")
|
||||
._M_iterator(__x, "other"));
|
||||
|
@ -236,7 +236,7 @@ namespace __gnu_debug
|
|||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// DR 408. Is vector<reverse_iterator<char*> > forbidden?
|
||||
_GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
|
||||
|| __x.base() == _Iterator(),
|
||||
|| __x._M_value_initialized(),
|
||||
_M_message(__msg_copy_singular)
|
||||
._M_iterator(*this, "this")
|
||||
._M_iterator(__x, "other"));
|
||||
|
@ -266,7 +266,7 @@ namespace __gnu_debug
|
|||
operator=(_Safe_iterator&& __x) noexcept
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
|
||||
|| __x.base() == _Iterator(),
|
||||
|| __x._M_value_initialized(),
|
||||
_M_message(__msg_copy_singular)
|
||||
._M_iterator(*this, "this")
|
||||
._M_iterator(__x, "other"));
|
||||
|
@ -405,6 +405,11 @@ namespace __gnu_debug
|
|||
_M_incrementable() const
|
||||
{ return !this->_M_singular() && !_M_is_end(); }
|
||||
|
||||
/// Is the iterator value-initialized?
|
||||
bool
|
||||
_M_value_initialized() const
|
||||
{ return _M_version == 0 && base() == _Iter_base(); }
|
||||
|
||||
// Can we advance the iterator @p __n steps (@p __n may be negative)
|
||||
bool
|
||||
_M_can_advance(difference_type __n, bool __strict = false) const;
|
||||
|
|
|
@ -33,8 +33,8 @@
|
|||
|
||||
#define _GLIBCXX_DEBUG_VERIFY_OPERANDS(_Lhs, _Rhs) \
|
||||
_GLIBCXX_DEBUG_VERIFY(!_Lhs._M_singular() && !_Rhs._M_singular() \
|
||||
|| (_Lhs.base() == _Iterator{} \
|
||||
&& _Rhs.base() == _Iterator{}), \
|
||||
|| (_Lhs._M_value_initialized() \
|
||||
&& _Rhs._M_value_initialized()), \
|
||||
_M_message(__msg_iter_compare_bad) \
|
||||
._M_iterator(_Lhs, "lhs") \
|
||||
._M_iterator(_Rhs, "rhs")); \
|
||||
|
@ -127,7 +127,7 @@ namespace __gnu_debug
|
|||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// DR 408. Is vector<reverse_iterator<char*> > forbidden?
|
||||
_GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
|
||||
|| __x.base() == _Iterator(),
|
||||
|| __x._M_value_initialized(),
|
||||
_M_message(__msg_init_copy_singular)
|
||||
._M_iterator(*this, "this")
|
||||
._M_iterator(__x, "other"));
|
||||
|
@ -142,7 +142,7 @@ namespace __gnu_debug
|
|||
: _Iter_base()
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
|
||||
|| __x.base() == _Iterator(),
|
||||
|| __x._M_value_initialized(),
|
||||
_M_message(__msg_init_copy_singular)
|
||||
._M_iterator(*this, "this")
|
||||
._M_iterator(__x, "other"));
|
||||
|
@ -167,7 +167,7 @@ namespace __gnu_debug
|
|||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// DR 408. Is vector<reverse_iterator<char*> > forbidden?
|
||||
_GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
|
||||
|| __x.base() == _MutableIterator(),
|
||||
|| __x._M_value_initialized(),
|
||||
_M_message(__msg_init_const_singular)
|
||||
._M_iterator(*this, "this")
|
||||
._M_iterator(__x, "other"));
|
||||
|
@ -183,7 +183,7 @@ namespace __gnu_debug
|
|||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// DR 408. Is vector<reverse_iterator<char*> > forbidden?
|
||||
_GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
|
||||
|| __x.base() == _Iterator(),
|
||||
|| __x._M_value_initialized(),
|
||||
_M_message(__msg_copy_singular)
|
||||
._M_iterator(*this, "this")
|
||||
._M_iterator(__x, "other"));
|
||||
|
@ -212,7 +212,7 @@ namespace __gnu_debug
|
|||
operator=(_Safe_local_iterator&& __x) noexcept
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
|
||||
|| __x.base() == _Iterator(),
|
||||
|| __x._M_value_initialized(),
|
||||
_M_message(__msg_copy_singular)
|
||||
._M_iterator(*this, "this")
|
||||
._M_iterator(__x, "other"));
|
||||
|
@ -343,6 +343,11 @@ namespace __gnu_debug
|
|||
_M_incrementable() const
|
||||
{ return !this->_M_singular() && !_M_is_end(); }
|
||||
|
||||
/// Is the iterator value-initialized?
|
||||
bool
|
||||
_M_value_initialized() const
|
||||
{ return _M_version == 0 && base() == _Iter_base{}; }
|
||||
|
||||
// Is the iterator range [*this, __rhs) valid?
|
||||
bool
|
||||
_M_valid_range(const _Safe_local_iterator& __rhs,
|
||||
|
|
|
@ -426,7 +426,9 @@ namespace __gnu_debug
|
|||
_M_reset() throw ()
|
||||
{
|
||||
__atomic_store_n(&_M_sequence, (_Safe_sequence_base*)0, __ATOMIC_RELEASE);
|
||||
_M_version = 0;
|
||||
// Do not reset version, so that a detached iterator does not look like a
|
||||
// value-initialized one.
|
||||
// _M_version = 0;
|
||||
_M_prior = 0;
|
||||
_M_next = 0;
|
||||
}
|
||||
|
@ -767,7 +769,8 @@ namespace
|
|||
"before-begin",
|
||||
"dereferenceable (start-of-reverse-sequence)",
|
||||
"dereferenceable (reverse)",
|
||||
"past-the-reverse-end"
|
||||
"past-the-reverse-end",
|
||||
"singular (value-initialized)"
|
||||
};
|
||||
print_word(ctx, state_names[iterator._M_state]);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
// Copyright (C) 2022 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 { xfail *-*-* } }
|
||||
// { dg-require-debug-mode "" }
|
||||
|
||||
#include <deque>
|
||||
|
||||
void test01()
|
||||
{
|
||||
typedef typename std::deque<int>::iterator It;
|
||||
std::deque<int> dq;
|
||||
dq.push_back(1);
|
||||
|
||||
It it = It();
|
||||
(void)(dq.begin() != it);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
// Copyright (C) 2022 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 { xfail *-*-* } }
|
||||
// { dg-require-debug-mode "" }
|
||||
|
||||
#include <deque>
|
||||
|
||||
void test01()
|
||||
{
|
||||
typedef typename std::deque<int>::iterator It;
|
||||
It it;
|
||||
{
|
||||
std::deque<int> dq;
|
||||
it = dq.begin();
|
||||
}
|
||||
|
||||
It value_init_it = It();
|
||||
(void)(it != value_init_it);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
// Copyright (C) 2022 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 { xfail *-*-* } }
|
||||
// { dg-require-debug-mode "" }
|
||||
|
||||
#include <forward_list>
|
||||
|
||||
void test01()
|
||||
{
|
||||
typedef typename std::forward_list<int>::iterator It;
|
||||
std::forward_list<int> fl;
|
||||
fl.push_front(1);
|
||||
|
||||
It it = It();
|
||||
(void)(fl.begin() != it);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
// Copyright (C) 2022 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++11 xfail *-*-* } }
|
||||
// { dg-require-debug-mode "" }
|
||||
|
||||
#include <forward_list>
|
||||
|
||||
void test01()
|
||||
{
|
||||
typedef typename std::forward_list<int>::iterator It;
|
||||
It it;
|
||||
{
|
||||
std::forward_list<int> fl;
|
||||
it = fl.begin();
|
||||
}
|
||||
|
||||
It value_init_it{};
|
||||
(void)(it != value_init_it);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
// Copyright (C) 2022 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 { xfail *-*-* } }
|
||||
// { dg-require-debug-mode "" }
|
||||
|
||||
#include <forward_list>
|
||||
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
void test01()
|
||||
{
|
||||
typedef typename std::forward_list<int>::iterator It;
|
||||
It end1, end2;
|
||||
|
||||
{
|
||||
std::forward_list<int> fl;
|
||||
fl.push_front(1);
|
||||
|
||||
end1 = end2 = fl.end();
|
||||
VERIFY( end1 == end2 );
|
||||
}
|
||||
|
||||
(void)(end1 == end2);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue