aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xcontrib/filter-clang-warnings.py35
-rw-r--r--gcc/c-family/c-attribs.cc44
-rw-r--r--gcc/c-family/c-gimplify.cc28
-rw-r--r--gcc/c-family/c-ubsan.cc316
-rw-r--r--gcc/c-family/c.opt4
-rw-r--r--gcc/c-family/c.opt.urls3
-rw-r--r--gcc/c/c-decl.cc91
-rw-r--r--gcc/c/c-typeck.cc60
-rw-r--r--gcc/config/aarch64/aarch64.md13
-rw-r--r--gcc/config/s390/s390.md6
-rw-r--r--gcc/config/s390/vector.md25
-rw-r--r--gcc/config/s390/vx-builtins.md21
-rw-r--r--gcc/config/xtensa/xtensa.cc21
-rw-r--r--gcc/cp/decl.cc6
-rw-r--r--gcc/cp/parser.cc12
-rw-r--r--gcc/doc/extend.texi41
-rw-r--r--gcc/doc/invoke.texi18
-rw-r--r--gcc/testsuite/g++.dg/concepts/auto7a.C1
-rw-r--r--gcc/testsuite/g++.dg/concepts/auto7b.C10
-rw-r--r--gcc/testsuite/g++.dg/concepts/auto7c.C12
-rw-r--r--gcc/testsuite/g++.dg/concepts/pr67249.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/pr67249a.C7
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic-a.C15
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic.C4
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/pr85076.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/concepts-pr67210.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/concepts-pr67210a.C11
-rw-r--r--gcc/testsuite/g++.target/aarch64/pr119498.C19
-rw-r--r--gcc/testsuite/gcc.dg/flex-array-counted-by.c2
-rw-r--r--gcc/testsuite/gcc.dg/pointer-counted-by-1.c34
-rw-r--r--gcc/testsuite/gcc.dg/pointer-counted-by-2.c10
-rw-r--r--gcc/testsuite/gcc.dg/pointer-counted-by-3.c127
-rw-r--r--gcc/testsuite/gcc.dg/pointer-counted-by-4-char.c6
-rw-r--r--gcc/testsuite/gcc.dg/pointer-counted-by-4-float.c6
-rw-r--r--gcc/testsuite/gcc.dg/pointer-counted-by-4-struct.c10
-rw-r--r--gcc/testsuite/gcc.dg/pointer-counted-by-4-union.c10
-rw-r--r--gcc/testsuite/gcc.dg/pointer-counted-by-4.c77
-rw-r--r--gcc/testsuite/gcc.dg/pointer-counted-by-5.c56
-rw-r--r--gcc/testsuite/gcc.dg/pointer-counted-by-6.c56
-rw-r--r--gcc/testsuite/gcc.dg/pointer-counted-by-7.c32
-rw-r--r--gcc/testsuite/gcc.dg/pointer-counted-by.c111
-rw-r--r--gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-2.c51
-rw-r--r--gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-3.c42
-rw-r--r--gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-4.c42
-rw-r--r--gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-5.c40
-rw-r--r--gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds.c46
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr120817.c3
-rw-r--r--gcc/testsuite/gcc.target/aarch64/popcnt13.c24
-rw-r--r--gcc/testsuite/gcc.target/aarch64/popcnt9.c2
-rw-r--r--gcc/testsuite/gcc.target/s390/fminmax-1.c77
-rw-r--r--gcc/testsuite/gcc.target/s390/fminmax-2.c29
-rw-r--r--gcc/testsuite/gcc.target/xtensa/pr120888-1.c11
-rw-r--r--gcc/testsuite/gcc.target/xtensa/pr120888-2.c11
-rw-r--r--gcc/testsuite/lib/scanasm.exp2
-rw-r--r--gcc/tree-object-size.cc19
-rw-r--r--gcc/value-range.h6
-rw-r--r--libstdc++-v3/include/bits/chrono_io.h61
-rw-r--r--libstdc++-v3/include/bits/stl_iterator.h30
-rw-r--r--libstdc++-v3/include/std/mdspan2
-rw-r--r--libstdc++-v3/testsuite/ext/verify_neg.cc28
-rw-r--r--libstdc++-v3/testsuite/std/time/format/format.cc7
-rw-r--r--libstdc++-v3/testsuite/std/time/format/pr117214_custom_timeput.cc37
-rw-r--r--libstdc++-v3/testsuite/util/testsuite_hooks.h17
63 files changed, 606 insertions, 1347 deletions
diff --git a/contrib/filter-clang-warnings.py b/contrib/filter-clang-warnings.py
index 2ea7c71..b1b881e 100755
--- a/contrib/filter-clang-warnings.py
+++ b/contrib/filter-clang-warnings.py
@@ -41,22 +41,43 @@ def skip_warning(filename, message):
'-Wignored-attributes', '-Wgnu-zero-variadic-macro-arguments',
'-Wformat-security', '-Wundefined-internal',
'-Wunknown-warning-option', '-Wc++20-extensions',
- '-Wbitwise-instead-of-logical', 'egrep is obsolescent'],
+ '-Wbitwise-instead-of-logical', 'egrep is obsolescent',
+ '-Woverloaded-shift-op-parentheses',
+ '-Wunused-function', '-Wunneeded-internal-declaration',
+ '-Wvla-cxx-extension', '-Wunused-command-line-argument'],
+
+ 'diagnostic-path-output.cc': ['m_logical_loc_mgr'],
+ 'fold-const-call.cc': ['-Wreturn-type'],
+ 'gimple-match': ['-Wunused-', '-Wtautological-compare'],
+ 'generic-match': ['-Wunused-', '-Wtautological-compare'],
+ 'genautomata.cc': ['-Wstring-plus-int'],
+ # Perhaps revisit when ATTR_FNSPEC_DECONST_WATERMARK ifdef case is
+ # made default or removed:
+ 'ipa-strub.cc': ['-Wunused-but-set-variable'],
'insn-modes.cc': ['-Wshift-count-overflow'],
'insn-emit.cc': ['-Wtautological-compare'],
'insn-attrtab.cc': ['-Wparentheses-equality'],
- 'gimple-match.cc': ['-Wunused-', '-Wtautological-compare'],
- 'generic-match.cc': ['-Wunused-', '-Wtautological-compare'],
+ 'omp-builtins.def': ['-Wc++11-narrowing'],
+ 'wide-int.h': ['-Wnontrivial-memcall'],
'i386.md': ['-Wparentheses-equality', '-Wtautological-compare',
'-Wtautological-overlap-compare'],
'sse.md': ['-Wparentheses-equality', '-Wtautological-compare',
'-Wconstant-logical-operand'],
'mmx.md': ['-Wtautological-compare'],
- 'genautomata.cc': ['-Wstring-plus-int'],
- 'fold-const-call.cc': ['-Wreturn-type'],
- 'gfortran.texi': [''],
- 'libtool': [''],
'lex.cc': ['-Wc++20-attribute-extensions'],
+ # Perhaps remove once PR 120960 is resolved:
+ 'analyzer/ana-state-to-diagnostic-state.h': ['-Wunused-private-field'],
+ 'analyzer/sm.cc': ['-Wunused-parameter'],
+ 'c-family/c-format.cc': ['-Wunused-private-field'],
+ 'm2/gm2-compiler-boot': ['-Wunused-'],
+ # Rust peopel promised to clean these warnings too
+ 'rust/': ['-Wunused-private-field'],
+ 'libiberty/sha1.c': ['-Wc23-extensions'],
+ 'avr-mmcu.texi': [''],
+ 'gfortran.texi': [''],
+ 'install.texi': [''],
+ 'libgccjit.texi': [''],
+ 'libtool': ['']
}
for name, ignore in ignores.items():
diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc
index ea04ed7..5d7a31f 100644
--- a/gcc/c-family/c-attribs.cc
+++ b/gcc/c-family/c-attribs.cc
@@ -2906,53 +2906,22 @@ handle_counted_by_attribute (tree *node, tree name,
" declaration %q+D", name, decl);
*no_add_attrs = true;
}
- /* This attribute only applies to a field with array type or pointer type. */
- else if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE
- && TREE_CODE (TREE_TYPE (decl)) != POINTER_TYPE)
+ /* This attribute only applies to field with array type. */
+ else if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE)
{
error_at (DECL_SOURCE_LOCATION (decl),
- "%qE attribute is not allowed for a non-array"
- " or non-pointer field", name);
+ "%qE attribute is not allowed for a non-array field",
+ name);
*no_add_attrs = true;
}
/* This attribute only applies to a C99 flexible array member type. */
- else if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
- && !c_flexible_array_member_type_p (TREE_TYPE (decl)))
+ else if (! c_flexible_array_member_type_p (TREE_TYPE (decl)))
{
error_at (DECL_SOURCE_LOCATION (decl),
"%qE attribute is not allowed for a non-flexible"
" array member field", name);
*no_add_attrs = true;
}
- /* This attribute cannot be applied to a pointer to void type. */
- else if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
- && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == VOID_TYPE)
- {
- error_at (DECL_SOURCE_LOCATION (decl),
- "%qE attribute is not allowed for a pointer to void",
- name);
- *no_add_attrs = true;
- }
- /* This attribute cannot be applied to a pointer to function type. */
- else if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
- && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == FUNCTION_TYPE)
- {
- error_at (DECL_SOURCE_LOCATION (decl),
- "%qE attribute is not allowed for a pointer to"
- " function", name);
- *no_add_attrs = true;
- }
- /* This attribute cannot be applied to a pointer to structure or union
- with flexible array member. */
- else if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
- && RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_TYPE (decl)))
- && TYPE_INCLUDES_FLEXARRAY (TREE_TYPE (TREE_TYPE (decl))))
- {
- error_at (DECL_SOURCE_LOCATION (decl),
- "%qE attribute is not allowed for a pointer to"
- " structure or union with flexible array member", name);
- *no_add_attrs = true;
- }
/* The argument should be an identifier. */
else if (TREE_CODE (argval) != IDENTIFIER_NODE)
{
@@ -2961,8 +2930,7 @@ handle_counted_by_attribute (tree *node, tree name,
*no_add_attrs = true;
}
/* Issue error when there is a counted_by attribute with a different
- field as the argument for the same flexible array member or
- pointer field. */
+ field as the argument for the same flexible array member field. */
else if (old_counted_by != NULL_TREE)
{
tree old_fieldname = TREE_VALUE (TREE_VALUE (old_counted_by));
diff --git a/gcc/c-family/c-gimplify.cc b/gcc/c-family/c-gimplify.cc
index e905059..c6fb764 100644
--- a/gcc/c-family/c-gimplify.cc
+++ b/gcc/c-family/c-gimplify.cc
@@ -66,20 +66,6 @@ along with GCC; see the file COPYING3. If not see
walk back up, we check that they fit our constraints, and copy them
into temporaries if not. */
-
-/* Check whether TP is an address computation whose base is a call to
- .ACCESS_WITH_SIZE. */
-
-static bool
-is_address_with_access_with_size (tree tp)
-{
- if (TREE_CODE (tp) == POINTER_PLUS_EXPR
- && (TREE_CODE (TREE_OPERAND (tp, 0)) == INDIRECT_REF)
- && (is_access_with_size_p (TREE_OPERAND (TREE_OPERAND (tp, 0), 0))))
- return true;
- return false;
-}
-
/* Callback for c_genericize. */
static tree
@@ -135,20 +121,6 @@ ubsan_walk_array_refs_r (tree *tp, int *walk_subtrees, void *data)
walk_tree (&TREE_OPERAND (*tp, 1), ubsan_walk_array_refs_r, pset, pset);
walk_tree (&TREE_OPERAND (*tp, 0), ubsan_walk_array_refs_r, pset, pset);
}
- else if (TREE_CODE (*tp) == INDIRECT_REF
- && is_address_with_access_with_size (TREE_OPERAND (*tp, 0)))
- {
- ubsan_maybe_instrument_array_ref (&TREE_OPERAND (*tp, 0), false);
- /* Make sure ubsan_maybe_instrument_array_ref is not called again on
- the POINTER_PLUS_EXPR, so ensure it is not walked again and walk
- its subtrees manually. */
- tree aref = TREE_OPERAND (*tp, 0);
- pset->add (aref);
- *walk_subtrees = 0;
- walk_tree (&TREE_OPERAND (aref, 0), ubsan_walk_array_refs_r, pset, pset);
- }
- else if (is_address_with_access_with_size (*tp))
- ubsan_maybe_instrument_array_ref (tp, true);
return NULL_TREE;
}
diff --git a/gcc/c-family/c-ubsan.cc b/gcc/c-family/c-ubsan.cc
index 38514a4..78b7868 100644
--- a/gcc/c-family/c-ubsan.cc
+++ b/gcc/c-family/c-ubsan.cc
@@ -554,322 +554,38 @@ ubsan_instrument_bounds (location_t loc, tree array, tree *index,
*index, bound);
}
-
-/* Instrument array bounds for the pointer array address which is
- an INDIRECT_REF to the call to .ACCESS_WITH_SIZE. We create special
- builtin, that gets expanded in the sanopt pass, and make an array
- dimention of it. POINTER_ADDR is the pointer array's base address.
- *INDEX is an index to the array.
- IGNORE_OFF_BY_ONE is true if the POINTER_ADDR is not inside an
- INDIRECT_REF.
- Return NULL_TREE if no instrumentation is emitted. */
-
-tree
-ubsan_instrument_bounds_pointer_address (location_t loc, tree pointer_addr,
- tree *index,
- bool ignore_off_by_one)
-{
- gcc_assert (TREE_CODE (pointer_addr) == INDIRECT_REF);
- tree call = TREE_OPERAND (pointer_addr, 0);
- if (!is_access_with_size_p (call))
- return NULL_TREE;
- tree bound = get_bound_from_access_with_size (call);
-
- if (ignore_off_by_one)
- bound = fold_build2 (PLUS_EXPR, TREE_TYPE (bound), bound,
- build_int_cst (TREE_TYPE (bound),
- 1));
-
- /* Don't emit instrumentation in the most common cases. */
- tree idx = NULL_TREE;
- if (TREE_CODE (*index) == INTEGER_CST)
- idx = *index;
- else if (TREE_CODE (*index) == BIT_AND_EXPR
- && TREE_CODE (TREE_OPERAND (*index, 1)) == INTEGER_CST)
- idx = TREE_OPERAND (*index, 1);
- if (idx
- && TREE_CODE (bound) == INTEGER_CST
- && tree_int_cst_sgn (idx) >= 0
- && tree_int_cst_lt (idx, bound))
- return NULL_TREE;
-
- *index = save_expr (*index);
-
- /* Create an array_type for the corresponding pointer array. */
- tree itype = build_range_type (sizetype, size_zero_node, NULL_TREE);
- /* The array's element type can be get from the return type of the call to
- .ACCESS_WITH_SIZE. */
- tree element_type = TREE_TYPE (TREE_TYPE (TREE_TYPE (call)));
- tree array_type = build_array_type (element_type, itype);
- /* Create a "(T *) 0" tree node to describe the array type. */
- tree zero_with_type = build_int_cst (build_pointer_type (array_type), 0);
- return build_call_expr_internal_loc (loc, IFN_UBSAN_BOUNDS,
- void_type_node, 3, zero_with_type,
- *index, bound);
-}
-
-/* This structure is to combine a factor with its parent and its position
- * in its parent tree. */
-struct factor_t
-{
- tree factor;
- tree parent; /* the parent tree of this factor. */
- int pos; /* the position of this factor in its parent tree. */
-};
-
-/* for a multiply expression like:
- ((long unsigned int) m * (long unsigned int) SAVE_EXPR <n>) * 4
-
- locate all the factors, the parents of the factor and the position of
- the factor in its parent, and put them to VEC_FACTORS. */
-
-static void
-get_factors_from_mul_expr (tree mult_expr, tree parent,
- int pos, auto_vec<factor_t> *vec_factors)
-{
- struct factor_t mult_factor = {0, 0, -1};
- mult_factor.factor = mult_expr;
- mult_factor.parent = parent;
- mult_factor.pos = pos;
-
- while (CONVERT_EXPR_CODE_P (TREE_CODE (mult_expr)))
- {
- mult_factor.parent = mult_expr;
- mult_factor.pos = 0;
- mult_expr = TREE_OPERAND (mult_expr, 0);
- mult_factor.factor = mult_expr;
- }
- if (TREE_CODE (mult_expr) != MULT_EXPR)
- vec_factors->safe_push (mult_factor);
- else
- {
- get_factors_from_mul_expr (TREE_OPERAND (mult_expr, 0), mult_expr,
- 0, vec_factors);
- get_factors_from_mul_expr (TREE_OPERAND (mult_expr, 1), mult_expr,
- 1, vec_factors);
- }
-}
-
-/* Given an OFFSET expression, and the ELEMENT_SIZE,
- get the index expression from OFFSET and return it.
- For example:
- OFFSET:
- ((long unsigned int) m * (long unsigned int) SAVE_EXPR <n>) * 4
- ELEMENT_SIZE:
- (sizetype) SAVE_EXPR <n> * 4
- get the index as (long unsigned int) m, and return it.
- The INDEX_P holds the pointer to the parent tree of the index,
- INDEX_N holds the position of the index in its parent. */
-
-static tree
-get_index_from_offset (tree offset, tree *index_p,
- int *index_n, tree element_size)
-{
- if (TREE_CODE (offset) != MULT_EXPR)
- return NULL_TREE;
-
- auto_vec<factor_t> e_factors, o_factors;
- get_factors_from_mul_expr (element_size, NULL, -1, &e_factors);
- get_factors_from_mul_expr (offset, *index_p, *index_n, &o_factors);
-
- if (e_factors.is_empty () || o_factors.is_empty ())
- return NULL_TREE;
-
- bool all_found = true;
- for (unsigned i = 0; i < e_factors.length (); i++)
- {
- factor_t e_size_factor = e_factors[i];
- bool found = false;
- for (unsigned j = 0; j < o_factors.length ();)
- {
- factor_t o_exp_factor = o_factors[j];
- if (operand_equal_p (e_size_factor.factor, o_exp_factor.factor))
- {
- o_factors.unordered_remove (j);
- found = true;
- break;
- }
- else
- j++;
- }
- if (!found)
- all_found = false;
- }
-
- if (!all_found)
- return NULL_TREE;
-
- if (o_factors.length () != 1)
- return NULL_TREE;
-
- *index_p = o_factors[0].parent;
- *index_n = o_factors[0].pos;
- return o_factors[0].factor;
-}
-
-/* For an pointer + offset computation expression, such as,
- *.ACCESS_WITH_SIZE (p->c, &p->b, 1, 0, -1, 0B)
- + (sizetype) ((long unsigned int) index * 4
- Return the index of this pointer array reference,
- set the parent tree of INDEX to *INDEX_P.
- set the operand position of the INDEX in the parent tree to *INDEX_N.
- If failed, return NULL_TREE. */
-
-static tree
-get_index_from_pointer_addr_expr (tree pointer, tree *index_p, int *index_n)
-{
- *index_p = NULL_TREE;
- *index_n = -1;
- if (TREE_CODE (TREE_OPERAND (pointer, 0)) != INDIRECT_REF)
- return NULL_TREE;
- tree call = TREE_OPERAND (TREE_OPERAND (pointer, 0), 0);
- if (!is_access_with_size_p (call))
- return NULL_TREE;
-
- /* Get the pointee type of the call to .ACCESS_WITH_SIZE.
- This should be the element type of the pointer array. */
- tree pointee_type = TREE_TYPE (TREE_TYPE (TREE_TYPE (call)));
- tree pointee_size = TYPE_SIZE_UNIT (pointee_type);
-
- tree index_exp = TREE_OPERAND (pointer, 1);
- *index_p = pointer;
- *index_n = 1;
-
- if (!(TREE_CODE (index_exp) != MULT_EXPR
- && tree_int_cst_equal (pointee_size, integer_one_node)))
- {
- while (CONVERT_EXPR_CODE_P (TREE_CODE (index_exp)))
- {
- *index_p = index_exp;
- *index_n = 0;
- index_exp = TREE_OPERAND (index_exp, 0);
- }
- index_exp = get_index_from_offset (index_exp, index_p,
- index_n, pointee_size);
-
- if (!index_exp)
- return NULL_TREE;
- }
-
- while (CONVERT_EXPR_CODE_P (TREE_CODE (index_exp)))
- {
- *index_p = index_exp;
- *index_n = 0;
- index_exp = TREE_OPERAND (index_exp, 0);
- }
-
- return index_exp;
-}
-
-/* Return TRUE when the EXPR is a pointer array address that could be
- instrumented.
- We only instrument an address computation similar as the following:
- *.ACCESS_WITH_SIZE (p->c, &p->b, 1, 0, -1, 0B)
- + (sizetype) ((long unsigned int) index * 4)
- if the EXPR is instrumentable, return TRUE and
- set the index to *INDEX.
- set the *.ACCESS_WITH_SIZE to *BASE.
- set the parent tree of INDEX to *INDEX_P.
- set the operand position of the INDEX in the parent tree to INDEX_N. */
-
-static bool
-is_instrumentable_pointer_array_address (tree expr, tree *base,
- tree *index, tree *index_p,
- int *index_n)
-{
- /* For a poiner array address as:
- (*.ACCESS_WITH_SIZE (p->c, &p->b, 1, 0, -1, 0B)
- + (sizetype) ((long unsigned int) index * 4)
- op0 is the call to *.ACCESS_WITH_SIZE;
- op1 is the index. */
- if (TREE_CODE (expr) != POINTER_PLUS_EXPR)
- return false;
-
- tree op0 = TREE_OPERAND (expr, 0);
- if (TREE_CODE (op0) != INDIRECT_REF)
- return false;
- if (!is_access_with_size_p (TREE_OPERAND (op0, 0)))
- return false;
- tree op1 = get_index_from_pointer_addr_expr (expr, index_p, index_n);
- if (op1 != NULL_TREE)
- {
- *base = op0;
- *index = op1;
- return true;
- }
- return false;
-}
-
-/* Return true iff T is an array or an indirect reference that was
- instrumented by SANITIZE_BOUNDS. */
+/* Return true iff T is an array that was instrumented by SANITIZE_BOUNDS. */
bool
-ubsan_array_ref_instrumented_p (tree t)
+ubsan_array_ref_instrumented_p (const_tree t)
{
- if (TREE_CODE (t) != ARRAY_REF
- && TREE_CODE (t) != MEM_REF)
+ if (TREE_CODE (t) != ARRAY_REF)
return false;
- bool is_array = (TREE_CODE (t) == ARRAY_REF);
- tree op0 = NULL_TREE;
- tree op1 = NULL_TREE;
- tree index_p = NULL_TREE;
- int index_n = 0;
- if (is_array)
- {
- op1 = TREE_OPERAND (t, 1);
- return TREE_CODE (op1) == COMPOUND_EXPR
- && TREE_CODE (TREE_OPERAND (op1, 0)) == CALL_EXPR
- && CALL_EXPR_FN (TREE_OPERAND (op1, 0)) == NULL_TREE
- && CALL_EXPR_IFN (TREE_OPERAND (op1, 0)) == IFN_UBSAN_BOUNDS;
- }
- else if (is_instrumentable_pointer_array_address (t, &op0, &op1,
- &index_p, &index_n))
- return TREE_CODE (op1) == COMPOUND_EXPR
- && TREE_CODE (TREE_OPERAND (op1, 0)) == CALL_EXPR
- && CALL_EXPR_FN (TREE_OPERAND (op1, 0)) == NULL_TREE
- && CALL_EXPR_IFN (TREE_OPERAND (op1, 0)) == IFN_UBSAN_BOUNDS;
-
- return false;
+ tree op1 = TREE_OPERAND (t, 1);
+ return TREE_CODE (op1) == COMPOUND_EXPR
+ && TREE_CODE (TREE_OPERAND (op1, 0)) == CALL_EXPR
+ && CALL_EXPR_FN (TREE_OPERAND (op1, 0)) == NULL_TREE
+ && CALL_EXPR_IFN (TREE_OPERAND (op1, 0)) == IFN_UBSAN_BOUNDS;
}
-/* Instrument an ARRAY_REF or an address computation whose base address is
- a call to .ACCESS_WITH_SIZE, if it hasn't already been instrumented.
- IGNORE_OFF_BY_ONE is true if the ARRAY_REF is inside a ADDR_EXPR, or the
- address computation is not inside a INDIRECT_REF. */
+/* Instrument an ARRAY_REF, if it hasn't already been instrumented.
+ IGNORE_OFF_BY_ONE is true if the ARRAY_REF is inside a ADDR_EXPR. */
void
ubsan_maybe_instrument_array_ref (tree *expr_p, bool ignore_off_by_one)
{
- tree e = NULL_TREE;
- tree op0 = NULL_TREE;
- tree op1 = NULL_TREE;
- tree index_p = NULL_TREE; /* the parent tree of INDEX. */
- int index_n = 0; /* the operand position of INDEX in the parent tree. */
-
if (!ubsan_array_ref_instrumented_p (*expr_p)
&& sanitize_flags_p (SANITIZE_BOUNDS | SANITIZE_BOUNDS_STRICT)
&& current_function_decl != NULL_TREE)
{
- if (TREE_CODE (*expr_p) == ARRAY_REF)
- {
- op0 = TREE_OPERAND (*expr_p, 0);
- op1 = TREE_OPERAND (*expr_p, 1);
- index_p = *expr_p;
- index_n = 1;
- e = ubsan_instrument_bounds (EXPR_LOCATION (*expr_p), op0,
- &op1, ignore_off_by_one);
- }
- else if (is_instrumentable_pointer_array_address (*expr_p, &op0, &op1,
- &index_p, &index_n))
- e = ubsan_instrument_bounds_pointer_address (EXPR_LOCATION (*expr_p),
- op0, &op1,
- ignore_off_by_one);
-
- /* Replace the original INDEX with the instrumented INDEX. */
+ tree op0 = TREE_OPERAND (*expr_p, 0);
+ tree op1 = TREE_OPERAND (*expr_p, 1);
+ tree e = ubsan_instrument_bounds (EXPR_LOCATION (*expr_p), op0, &op1,
+ ignore_off_by_one);
if (e != NULL_TREE)
- TREE_OPERAND (index_p, index_n)
- = build2 (COMPOUND_EXPR, TREE_TYPE (op1), e, op1);
+ TREE_OPERAND (*expr_p, 1) = build2 (COMPOUND_EXPR, TREE_TYPE (op1),
+ e, op1);
}
}
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 8af466d..6a55e71 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -397,6 +397,10 @@ Wassign-intercept
ObjC ObjC++ Var(warn_assign_intercept) Warning
Warn whenever an Objective-C assignment is being intercepted by the garbage collector.
+Wabbreviated-auto-in-template-arg
+C++ ObjC++ Warning Var(warn_abbev_auto_targ) Init(1)
+Diagnose a placeholder type in a template argument in a function parameter type.
+
Wbad-function-cast
C ObjC Var(warn_bad_function_cast) Warning
Warn about casting functions to incompatible types.
diff --git a/gcc/c-family/c.opt.urls b/gcc/c-family/c.opt.urls
index 65d1221..401e6e7 100644
--- a/gcc/c-family/c.opt.urls
+++ b/gcc/c-family/c.opt.urls
@@ -139,6 +139,9 @@ UrlSuffix(gcc/Warning-Options.html#index-Warray-parameter)
Wassign-intercept
UrlSuffix(gcc/Objective-C-and-Objective-C_002b_002b-Dialect-Options.html#index-Wassign-intercept)
+Wabbreviated-auto-in-template-arg
+UrlSuffix(gcc/C_002b_002b-Dialect-Options.html#index-Wabbreviated-auto-in-template-arg)
+
Wbad-function-cast
UrlSuffix(gcc/Warning-Options.html#index-Wbad-function-cast)
diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 7e1c197..8bbd6eb 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -9432,62 +9432,56 @@ c_update_type_canonical (tree t)
}
}
-/* Verify the argument of the counted_by attribute of each of the
- FIELDS_WITH_COUNTED_BY is a valid field of the containing structure,
- STRUCT_TYPE, Report error and remove the corresponding attribute
- when it's not. */
+/* Verify the argument of the counted_by attribute of the flexible array
+ member FIELD_DECL is a valid field of the containing structure,
+ STRUCT_TYPE, Report error and remove this attribute when it's not. */
static void
-verify_counted_by_attribute (tree struct_type,
- auto_vec<tree> *fields_with_counted_by)
+verify_counted_by_attribute (tree struct_type, tree field_decl)
{
- for (tree field_decl : *fields_with_counted_by)
- {
- tree attr_counted_by = lookup_attribute ("counted_by",
- DECL_ATTRIBUTES (field_decl));
+ tree attr_counted_by = lookup_attribute ("counted_by",
+ DECL_ATTRIBUTES (field_decl));
- if (!attr_counted_by)
- continue;
+ if (!attr_counted_by)
+ return;
+
+ /* If there is an counted_by attribute attached to the field,
+ verify it. */
- /* If there is an counted_by attribute attached to the field,
- verify it. */
+ tree fieldname = TREE_VALUE (TREE_VALUE (attr_counted_by));
- tree fieldname = TREE_VALUE (TREE_VALUE (attr_counted_by));
+ /* Verify the argument of the attrbute is a valid field of the
+ containing structure. */
- /* Verify the argument of the attrbute is a valid field of the
- containing structure. */
+ tree counted_by_field = lookup_field (struct_type, fieldname);
- tree counted_by_field = lookup_field (struct_type, fieldname);
+ /* Error when the field is not found in the containing structure and
+ remove the corresponding counted_by attribute from the field_decl. */
+ if (!counted_by_field)
+ {
+ error_at (DECL_SOURCE_LOCATION (field_decl),
+ "argument %qE to the %<counted_by%> attribute"
+ " is not a field declaration in the same structure"
+ " as %qD", fieldname, field_decl);
+ DECL_ATTRIBUTES (field_decl)
+ = remove_attribute ("counted_by", DECL_ATTRIBUTES (field_decl));
+ }
+ else
+ /* Error when the field is not with an integer type. */
+ {
+ while (TREE_CHAIN (counted_by_field))
+ counted_by_field = TREE_CHAIN (counted_by_field);
+ tree real_field = TREE_VALUE (counted_by_field);
- /* Error when the field is not found in the containing structure and
- remove the corresponding counted_by attribute from the field_decl. */
- if (!counted_by_field)
+ if (!INTEGRAL_TYPE_P (TREE_TYPE (real_field)))
{
error_at (DECL_SOURCE_LOCATION (field_decl),
"argument %qE to the %<counted_by%> attribute"
- " is not a field declaration in the same structure"
- " as %qD", fieldname, field_decl);
+ " is not a field declaration with an integer type",
+ fieldname);
DECL_ATTRIBUTES (field_decl)
= remove_attribute ("counted_by", DECL_ATTRIBUTES (field_decl));
}
- else
- /* Error when the field is not with an integer type. */
- {
- while (TREE_CHAIN (counted_by_field))
- counted_by_field = TREE_CHAIN (counted_by_field);
- tree real_field = TREE_VALUE (counted_by_field);
-
- if (!INTEGRAL_TYPE_P (TREE_TYPE (real_field)))
- {
- error_at (DECL_SOURCE_LOCATION (field_decl),
- "argument %qE to the %<counted_by%> attribute"
- " is not a field declaration with an integer type",
- fieldname);
- DECL_ATTRIBUTES (field_decl)
- = remove_attribute ("counted_by",
- DECL_ATTRIBUTES (field_decl));
- }
- }
}
}
@@ -9562,7 +9556,7 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
until now.) */
bool saw_named_field = false;
- auto_vec<tree> fields_with_counted_by;
+ tree counted_by_fam_field = NULL_TREE;
for (x = fieldlist; x; x = DECL_CHAIN (x))
{
/* Whether this field is the last field of the structure or union.
@@ -9643,16 +9637,9 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
record it here and do more verification later after the
whole structure is complete. */
if (lookup_attribute ("counted_by", DECL_ATTRIBUTES (x)))
- fields_with_counted_by.safe_push (x);
+ counted_by_fam_field = x;
}
- if (TREE_CODE (TREE_TYPE (x)) == POINTER_TYPE)
- /* If there is a counted_by attribute attached to this field,
- record it here and do more verification later after the
- whole structure is complete. */
- if (lookup_attribute ("counted_by", DECL_ATTRIBUTES (x)))
- fields_with_counted_by.safe_push (x);
-
if (pedantic && TREE_CODE (t) == RECORD_TYPE
&& flexible_array_type_p (TREE_TYPE (x)))
pedwarn (DECL_SOURCE_LOCATION (x), OPT_Wpedantic,
@@ -9951,8 +9938,8 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
struct_parse_info->struct_types.safe_push (t);
}
- if (fields_with_counted_by.length () > 0)
- verify_counted_by_attribute (t, &fields_with_counted_by);
+ if (counted_by_fam_field)
+ verify_counted_by_attribute (t, counted_by_fam_field);
return t;
}
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index 7948106..e24629b 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -2922,8 +2922,8 @@ should_suggest_deref_p (tree datum_type)
/* For a SUBDATUM field of a structure or union DATUM, generate a REF to
the object that represents its counted_by per the attribute counted_by
- attached to this field if it's a flexible array member or a pointer
- field, otherwise return NULL_TREE.
+ attached to this field if it's a flexible array member field, otherwise
+ return NULL_TREE.
Set COUNTED_BY_TYPE to the TYPE of the counted_by field.
For example, if:
@@ -2941,34 +2941,18 @@ should_suggest_deref_p (tree datum_type)
*/
static tree
-build_counted_by_ref (location_t loc, tree datum, tree subdatum,
- tree *counted_by_type)
+build_counted_by_ref (tree datum, tree subdatum, tree *counted_by_type)
{
tree type = TREE_TYPE (datum);
- tree sub_type = TREE_TYPE (subdatum);
- if (!c_flexible_array_member_type_p (sub_type)
- && TREE_CODE (sub_type) != POINTER_TYPE)
+ if (!c_flexible_array_member_type_p (TREE_TYPE (subdatum)))
return NULL_TREE;
- tree element_type = TREE_TYPE (sub_type);
-
tree attr_counted_by = lookup_attribute ("counted_by",
DECL_ATTRIBUTES (subdatum));
tree counted_by_ref = NULL_TREE;
*counted_by_type = NULL_TREE;
if (attr_counted_by)
{
- /* Issue error when the element_type is a structure or
- union including a flexible array member. */
- if (RECORD_OR_UNION_TYPE_P (element_type)
- && TYPE_INCLUDES_FLEXARRAY (element_type))
- {
- error_at (loc,
- "%<counted_by%> attribute is not allowed for a pointer to"
- " structure or union with flexible array member");
- return error_mark_node;
- }
-
tree field_id = TREE_VALUE (TREE_VALUE (attr_counted_by));
counted_by_ref
= build_component_ref (UNKNOWN_LOCATION,
@@ -2991,11 +2975,8 @@ build_counted_by_ref (location_t loc, tree datum, tree subdatum,
}
/* Given a COMPONENT_REF REF with the location LOC, the corresponding
- COUNTED_BY_REF, and the COUNTED_BY_TYPE, generate the corresponding
- call to the internal function .ACCESS_WITH_SIZE.
-
- Generate an INDIRECT_REF to a call to the internal function
- .ACCESS_WITH_SIZE.
+ COUNTED_BY_REF, and the COUNTED_BY_TYPE, generate an INDIRECT_REF
+ to a call to the internal function .ACCESS_WITH_SIZE.
REF
@@ -3005,15 +2986,17 @@ build_counted_by_ref (location_t loc, tree datum, tree subdatum,
(TYPE_OF_ARRAY *)0))
NOTE: The return type of this function is the POINTER type pointing
- to the original flexible array type or the original pointer type.
- Then the type of the INDIRECT_REF is the original flexible array type
- or the original pointer type.
+ to the original flexible array type.
+ Then the type of the INDIRECT_REF is the original flexible array type.
+
+ The type of the first argument of this function is a POINTER type
+ to the original flexible array type.
The 4th argument of the call is a constant 0 with the TYPE of the
object pointed by COUNTED_BY_REF.
- The 6th argument of the call is a constant 0 of the same TYPE as
- the return type of the call.
+ The 6th argument of the call is a constant 0 with the pointer TYPE
+ to the original flexible array type.
*/
static tree
@@ -3021,16 +3004,11 @@ build_access_with_size_for_counted_by (location_t loc, tree ref,
tree counted_by_ref,
tree counted_by_type)
{
- gcc_assert (c_flexible_array_member_type_p (TREE_TYPE (ref))
- || TREE_CODE (TREE_TYPE (ref)) == POINTER_TYPE);
- bool is_fam = c_flexible_array_member_type_p (TREE_TYPE (ref));
- tree first_param = is_fam ? array_to_pointer_conversion (loc, ref)
- : build_unary_op (loc, ADDR_EXPR, ref, false);
-
- /* The result type of the call is a pointer to the original type
- of the ref. */
+ gcc_assert (c_flexible_array_member_type_p (TREE_TYPE (ref)));
+ /* The result type of the call is a pointer to the flexible array type. */
tree result_type = c_build_pointer_type (TREE_TYPE (ref));
- first_param = c_fully_fold (first_param, false, NULL);
+ tree first_param
+ = c_fully_fold (array_to_pointer_conversion (loc, ref), false, NULL);
tree second_param
= c_fully_fold (counted_by_ref, false, NULL);
@@ -3043,7 +3021,7 @@ build_access_with_size_for_counted_by (location_t loc, tree ref,
build_int_cst (counted_by_type, 0),
build_int_cst (integer_type_node, -1),
build_int_cst (result_type, 0));
- /* Wrap the call with an INDIRECT_REF with the original type of the ref. */
+ /* Wrap the call with an INDIRECT_REF with the flexible array type. */
call = build1 (INDIRECT_REF, TREE_TYPE (ref), call);
SET_EXPR_LOCATION (call, loc);
return call;
@@ -3061,7 +3039,7 @@ handle_counted_by_for_component_ref (location_t loc, tree ref)
tree datum = TREE_OPERAND (ref, 0);
tree subdatum = TREE_OPERAND (ref, 1);
tree counted_by_type = NULL_TREE;
- tree counted_by_ref = build_counted_by_ref (loc, datum, subdatum,
+ tree counted_by_ref = build_counted_by_ref (datum, subdatum,
&counted_by_type);
if (counted_by_ref)
ref = build_access_with_size_for_counted_by (loc, ref,
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 509ef4c..27efc91 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -5771,6 +5771,19 @@
(match_operand:TI 1 "register_operand")]
"TARGET_SIMD && !TARGET_CSSC"
{
+ /* For SVE we can do popcount on DImode chunks of the TImode argument
+ and then use a cheap ADDP reduction. The SVE CNT instruction requires
+ materializing a PTRUE so don't do this if optimizing for size. */
+ if (TARGET_SVE && !optimize_function_for_size_p (cfun))
+ {
+ rtx v = gen_reg_rtx (V2DImode);
+ rtx v1 = gen_reg_rtx (V2DImode);
+ emit_move_insn (v, gen_lowpart (V2DImode, operands[1]));
+ rtx p = aarch64_ptrue_reg (VNx2BImode, 16);
+ emit_insn (gen_aarch64_pred_popcountv2di (v1, p, v));
+ emit_insn (gen_reduc_plus_scal_v2di (operands[0], v1));
+ DONE;
+ }
rtx v = gen_reg_rtx (V16QImode);
rtx v1 = gen_reg_rtx (V16QImode);
emit_move_insn (v, gen_lowpart (V16QImode, operands[1]));
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index 440ce93..f6db36e 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -238,9 +238,6 @@
UNSPEC_VEC_MSUM
- UNSPEC_VEC_VFMIN
- UNSPEC_VEC_VFMAX
-
UNSPEC_VEC_VBLEND
UNSPEC_VEC_VEVAL
UNSPEC_VEC_VGEM
@@ -253,6 +250,9 @@
UNSPEC_NNPA_VCFN_V8HI
UNSPEC_NNPA_VCNF_V8HI
+
+ UNSPEC_FMAX
+ UNSPEC_FMIN
])
;;
diff --git a/gcc/config/s390/vector.md b/gcc/config/s390/vector.md
index 7c706ec..26753c0 100644
--- a/gcc/config/s390/vector.md
+++ b/gcc/config/s390/vector.md
@@ -89,6 +89,13 @@
(define_mode_iterator VF_HW [(V4SF "TARGET_VXE") V2DF (V1TF "TARGET_VXE")
(TF "TARGET_VXE")])
+; FP scalar and vector modes
+(define_mode_iterator VFT_BFP [SF DF
+ (V1SF "TARGET_VXE") (V2SF "TARGET_VXE") (V4SF "TARGET_VXE")
+ V1DF V2DF
+ (V1TF "TARGET_VXE") (TF "TARGET_VXE")])
+
+
(define_mode_iterator V_8 [V1QI])
(define_mode_iterator V_16 [V2QI V1HI])
(define_mode_iterator V_32 [V4QI V2HI V1SI V1SF])
@@ -3602,3 +3609,21 @@
(umul_highpart:VIT_HW_VXE3_DT (match_operand:VIT_HW_VXE3_DT 1 "register_operand")
(match_operand:VIT_HW_VXE3_DT 2 "register_operand")))]
"TARGET_VX")
+
+; fmax
+(define_expand "fmax<mode>3"
+ [(set (match_operand:VFT_BFP 0 "register_operand")
+ (unspec:VFT_BFP [(match_operand:VFT_BFP 1 "register_operand")
+ (match_operand:VFT_BFP 2 "register_operand")
+ (const_int 4)]
+ UNSPEC_FMAX))]
+ "TARGET_VXE")
+
+; fmin
+(define_expand "fmin<mode>3"
+ [(set (match_operand:VFT_BFP 0 "register_operand")
+ (unspec:VFT_BFP [(match_operand:VFT_BFP 1 "register_operand")
+ (match_operand:VFT_BFP 2 "register_operand")
+ (const_int 4)]
+ UNSPEC_FMIN))]
+ "TARGET_VXE")
diff --git a/gcc/config/s390/vx-builtins.md b/gcc/config/s390/vx-builtins.md
index 9e5d18b..9b89b13 100644
--- a/gcc/config/s390/vx-builtins.md
+++ b/gcc/config/s390/vx-builtins.md
@@ -2134,23 +2134,22 @@
"<vw>fche<sdx>bs\t%v2,%v0,%v1"
[(set_attr "op_type" "VRR")])
-
(define_insn "vfmin<mode>"
- [(set (match_operand:VF_HW 0 "register_operand" "=v")
- (unspec:VF_HW [(match_operand:VF_HW 1 "register_operand" "v")
- (match_operand:VF_HW 2 "register_operand" "v")
- (match_operand:QI 3 "const_mask_operand" "C")]
- UNSPEC_VEC_VFMIN))]
+ [(set (match_operand:VFT_BFP 0 "register_operand" "=v")
+ (unspec:VFT_BFP [(match_operand:VFT_BFP 1 "register_operand" "v")
+ (match_operand:VFT_BFP 2 "register_operand" "v")
+ (match_operand:QI 3 "const_mask_operand" "C")]
+ UNSPEC_FMIN))]
"TARGET_VXE"
"<vw>fmin<sdx>b\t%v0,%v1,%v2,%b3"
[(set_attr "op_type" "VRR")])
(define_insn "vfmax<mode>"
- [(set (match_operand:VF_HW 0 "register_operand" "=v")
- (unspec:VF_HW [(match_operand:VF_HW 1 "register_operand" "v")
- (match_operand:VF_HW 2 "register_operand" "v")
- (match_operand:QI 3 "const_mask_operand" "C")]
- UNSPEC_VEC_VFMAX))]
+ [(set (match_operand:VFT_BFP 0 "register_operand" "=v")
+ (unspec:VFT_BFP [(match_operand:VFT_BFP 1 "register_operand" "v")
+ (match_operand:VFT_BFP 2 "register_operand" "v")
+ (match_operand:QI 3 "const_mask_operand" "C")]
+ UNSPEC_FMAX))]
"TARGET_VXE"
"<vw>fmax<sdx>b\t%v0,%v1,%v2,%b3"
[(set_attr "op_type" "VRR")])
diff --git a/gcc/config/xtensa/xtensa.cc b/gcc/config/xtensa/xtensa.cc
index 92a2364..8c43a69 100644
--- a/gcc/config/xtensa/xtensa.cc
+++ b/gcc/config/xtensa/xtensa.cc
@@ -159,6 +159,10 @@ static void xtensa_asm_trampoline_template (FILE *);
static void xtensa_trampoline_init (rtx, tree, rtx);
static bool xtensa_output_addr_const_extra (FILE *, rtx);
static bool xtensa_cannot_force_const_mem (machine_mode, rtx);
+static machine_mode xtensa_promote_function_mode (const_tree,
+ machine_mode,
+ int *, const_tree,
+ int);
static reg_class_t xtensa_preferred_reload_class (rtx, reg_class_t);
static reg_class_t xtensa_preferred_output_reload_class (rtx, reg_class_t);
@@ -235,9 +239,7 @@ static HARD_REG_SET xtensa_zero_call_used_regs (HARD_REG_SET);
#define TARGET_EXPAND_BUILTIN_VA_START xtensa_va_start
#undef TARGET_PROMOTE_FUNCTION_MODE
-#define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
-#undef TARGET_PROMOTE_PROTOTYPES
-#define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
+#define TARGET_PROMOTE_FUNCTION_MODE xtensa_promote_function_mode
#undef TARGET_RETURN_IN_MEMORY
#define TARGET_RETURN_IN_MEMORY xtensa_return_in_memory
@@ -4801,6 +4803,19 @@ xtensa_insn_cost (rtx_insn *insn, bool speed)
return pattern_cost (PATTERN (insn), speed);
}
+/* Worker function for TARGET_PROMOTE_FUNCTION_MODE. */
+
+static machine_mode
+xtensa_promote_function_mode (const_tree type, machine_mode mode,
+ int *punsignedp, const_tree, int)
+{
+ if (GET_MODE_CLASS (mode) == MODE_INT
+ && GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
+ return SImode;
+
+ return promote_mode (type, mode, punsignedp);
+}
+
/* Worker function for TARGET_RETURN_IN_MEMORY. */
static bool
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 83c8e28..be26bd3 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -2014,8 +2014,10 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden)
}
/* For function versions, params and types match, but they
are not ambiguous. */
- else if ((!DECL_FUNCTION_VERSIONED (newdecl)
- && !DECL_FUNCTION_VERSIONED (olddecl))
+ else if (((!DECL_FUNCTION_VERSIONED (newdecl)
+ && !DECL_FUNCTION_VERSIONED (olddecl))
+ || !same_type_p (fndecl_declared_return_type (newdecl),
+ fndecl_declared_return_type (olddecl)))
/* Let constrained hidden friends coexist for now, we'll
check satisfaction later. */
&& !member_like_constrained_friend_p (newdecl)
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index 44a7832..239e6f9 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -21021,9 +21021,6 @@ cp_parser_simple_type_specifier (cp_parser* parser,
"only available with "
"%<-std=c++14%> or %<-std=gnu++14%>");
}
- else if (parser->in_template_argument_list_p)
- error_at (token->location,
- "use of %<auto%> in template argument");
else if (!flag_concepts)
pedwarn (token->location, OPT_Wc__20_extensions,
"use of %<auto%> in parameter declaration "
@@ -21033,6 +21030,11 @@ cp_parser_simple_type_specifier (cp_parser* parser,
"use of %<auto%> in parameter declaration "
"only available with "
"%<-std=c++14%> or %<-std=gnu++14%>");
+
+ if (parser->in_template_argument_list_p)
+ permerror_opt (token->location,
+ OPT_Wabbreviated_auto_in_template_arg,
+ "use of %<auto%> in template argument");
}
else
type = make_auto ();
@@ -21479,6 +21481,10 @@ cp_parser_placeholder_type_specifier (cp_parser *parser, location_t loc,
error_at (loc, "cannot declare a parameter with %<decltype(auto)%>");
return error_mark_node;
}
+ if (parser->in_template_argument_list_p)
+ permerror_opt (placeholder->location,
+ OPT_Wabbreviated_auto_in_template_arg,
+ "use of %<auto%> in template argument");
tree parm = build_constrained_parameter (con, proto, args);
return synthesize_implicit_template_parm (parser, parm);
}
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index a119ad3..8c29e24 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -7138,11 +7138,9 @@ The @code{aligned} attribute can also be used for functions
@cindex @code{counted_by} variable attribute
@item counted_by (@var{count})
The @code{counted_by} attribute may be attached to the C99 flexible array
-member, or a pointer field of a structure. It indicates that the number
-of the elements of the array that is held by the flexible array member
-field, or is pointed to by the pointer field, is given by the field
-"@var{count}" in the same structure as the flexible array member or the
-pointer field.
+member of a structure. It indicates that the number of the elements of the
+array is given by the field "@var{count}" in the same structure as the
+flexible array member.
This attribute is available only in C for now.
In C++ this attribute is ignored.
@@ -7163,22 +7161,8 @@ struct P @{
@end smallexample
@noindent
-specifies that the @code{array} is a flexible array member whose number
-of elements is given by the field @code{count} in the same structure.
-
-@smallexample
-struct PP @{
- size_t count2;
- char other1;
- char *array2 __attribute__ ((counted_by (count2)));
- int other2;
-@} *pp;
-@end smallexample
-
-@noindent
-specifies that the @code{array2} is an array that is pointed by the
-pointer field, and its number of elements is given by the field
-@code{count2} in the same structure.
+specifies that the @code{array} is a flexible array member whose number of
+elements is given by the field @code{count} in the same structure.
The field that represents the number of the elements should have an
integer type. Otherwise, the compiler reports an error and ignores
@@ -7187,12 +7171,6 @@ the attribute.
When the field that represents the number of the elements is assigned a
negative integer value, the compiler treats the value as zero.
-The @code{counted_by} attribute is not allowed for a pointer to @code{void},
-a pointer to function, or a pointer to a structure or union that includes
-a flexible array member. However, it is allowed for a pointer to
-non-void incomplete structure or union types, as long as the type could
-be completed before the first reference to the pointer.
-
An explicit @code{counted_by} annotation defines a relationship between
two objects, @code{p->array} and @code{p->count}, and there are the
following requirements on the relationship between this pair:
@@ -7208,13 +7186,6 @@ available all the time. This relationship must hold even after any of
these related objects are updated during the program.
@end itemize
-In addition to the above requirements, there is one more requirement
-between this pair if and only if @code{p->array} is an array that is
-pointed by the pointer field:
-
-@code{p->array} and @code{p->count} can only be changed by changing the
-whole structure at the same time.
-
It's the programmer's responsibility to make sure the above requirements to
be kept all the time. Otherwise the compiler reports warnings and
the results of the array bound sanitizer and the
@@ -7236,8 +7207,6 @@ In the above, @code{ref1} uses @code{val1} as the number of the elements in
@code{p->array}, and @code{ref2} uses @code{val2} as the number of elements
in @code{p->array}.
-Note, however, the above feature is not valid for the pointer field.
-
@cindex @code{alloc_size} variable attribute
@item alloc_size (@var{position})
@itemx alloc_size (@var{position-1}, @var{position-2})
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 7640e7d..74f5ee2 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -3816,6 +3816,23 @@ Warn when a type with an ABI tag is used in a context that does not
have that ABI tag. See @ref{C++ Attributes} for more information
about ABI tags.
+@opindex Wabbreviated-auto-in-template-arg
+@opindex Wno-abbreviated-auto-in-template-arg
+@item -Wno-abbreviated-auto-in-template-arg
+Disable the error for an @code{auto} placeholder type used within a
+template argument list to declare a C++20 abbreviated function
+template, e.g.
+
+@smallexample
+void f(S<auto>);
+@end smallexample
+
+This feature was proposed in the Concepts TS, but was not adopted into
+C++20; in the standard, a placeholder in a parameter declaration must
+appear as a decl-specifier. The error can also be reduced to a
+warning by @option{-fpermissive} or
+@option{-Wno-error=abbreviated-auto-in-template-arg}.
+
@opindex Wcomma-subscript
@opindex Wno-comma-subscript
@item -Wcomma-subscript @r{(C++ and Objective-C++ only)}
@@ -6443,6 +6460,7 @@ only by this flag, but it also downgrades some C and C++ diagnostics
that have their own flag:
@gccoptlist{
+-Wabbreviated-auto-in-template-arg @r{(C++ and Objective-C++ only)}
-Wdeclaration-missing-parameter-type @r{(C and Objective-C only)}
-Wimplicit-function-declaration @r{(C and Objective-C only)}
-Wimplicit-int @r{(C and Objective-C only)}
diff --git a/gcc/testsuite/g++.dg/concepts/auto7a.C b/gcc/testsuite/g++.dg/concepts/auto7a.C
index 88868f4..f36038d 100644
--- a/gcc/testsuite/g++.dg/concepts/auto7a.C
+++ b/gcc/testsuite/g++.dg/concepts/auto7a.C
@@ -2,6 +2,7 @@
template <class T> struct A { };
void f(A<auto> a) { } // { dg-error "auto. in template argument" }
+// { dg-message "in parameter declaration" "" { target c++17_down } .-1 }
int main()
{
f(A<int>());
diff --git a/gcc/testsuite/g++.dg/concepts/auto7b.C b/gcc/testsuite/g++.dg/concepts/auto7b.C
new file mode 100644
index 0000000..874192c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/concepts/auto7b.C
@@ -0,0 +1,10 @@
+// PR c++/120917
+// { dg-do compile { target c++14 } }
+// { dg-additional-options "-fconcepts -Wno-abbreviated-auto-in-template-arg" }
+
+template <class T> struct A { };
+void f(A<auto> a) { }
+int main()
+{
+ f(A<int>());
+}
diff --git a/gcc/testsuite/g++.dg/concepts/auto7c.C b/gcc/testsuite/g++.dg/concepts/auto7c.C
new file mode 100644
index 0000000..5b16027
--- /dev/null
+++ b/gcc/testsuite/g++.dg/concepts/auto7c.C
@@ -0,0 +1,12 @@
+// { dg-do compile { target c++17 } }
+// { dg-additional-options -fconcepts }
+
+template <class T>
+concept True = true;
+
+template <class T> struct A { };
+void f(A<True auto> a) { } // { dg-error "use of .auto. in template argument" }
+int main()
+{
+ f(A<int>());
+}
diff --git a/gcc/testsuite/g++.dg/concepts/pr67249.C b/gcc/testsuite/g++.dg/concepts/pr67249.C
index e0f8d5a..e97183d 100644
--- a/gcc/testsuite/g++.dg/concepts/pr67249.C
+++ b/gcc/testsuite/g++.dg/concepts/pr67249.C
@@ -4,4 +4,4 @@
template<class T> concept C1 = true;
template<class A, class B> struct Pair {};
// We used to test "Pair<auto, C1 >".
-void f(Pair<C1 auto, C1 auto>);
+void f(Pair<C1 auto, C1 auto>); // { dg-error "auto" }
diff --git a/gcc/testsuite/g++.dg/concepts/pr67249a.C b/gcc/testsuite/g++.dg/concepts/pr67249a.C
new file mode 100644
index 0000000..cb5d90e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/concepts/pr67249a.C
@@ -0,0 +1,7 @@
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts -Wno-abbreviated-auto-in-template-arg" }
+
+template<class T> concept C1 = true;
+template<class A, class B> struct Pair {};
+// We used to test "Pair<auto, C1 >".
+void f(Pair<C1 auto, C1 auto>);
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic-a.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic-a.C
new file mode 100644
index 0000000..557ecb9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic-a.C
@@ -0,0 +1,15 @@
+// Basic generic lambda test
+// { dg-do run { target c++14 } }
+// { dg-additional-options -Wno-abbreviated-auto-in-template-arg }
+
+template <typename T, typename U> struct pair {};
+template <typename... T> struct tuple {};
+
+int main()
+{
+ auto a = [] (auto, pair<auto,auto> v) { return sizeof (v); };
+ auto b = [] (auto, pair<pair<auto,auto>,auto>... v) { return sizeof... (v); };
+
+ a(1, pair<int, float>());
+ b(2, pair<pair<short,char>, double>(), pair<pair<float,long>, int>());
+}
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic.C
index 6d2d250..971f58f 100644
--- a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic.C
+++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic.C
@@ -6,8 +6,8 @@ template <typename... T> struct tuple {};
int main()
{
- auto a = [] (auto, pair<auto,auto> v) { return sizeof (v); };
- auto b = [] (auto, pair<pair<auto,auto>,auto>... v) { return sizeof... (v); };
+ auto a = [] (auto, pair<auto,auto> v) { return sizeof (v); }; // { dg-error "auto" }
+ auto b = [] (auto, pair<pair<auto,auto>,auto>... v) { return sizeof... (v); }; // { dg-error "auto" }
a(1, pair<int, float>());
b(2, pair<pair<short,char>, double>(), pair<pair<float,long>, int>());
diff --git a/gcc/testsuite/g++.dg/cpp1y/pr85076.C b/gcc/testsuite/g++.dg/cpp1y/pr85076.C
index 6d54dea..b68143b 100644
--- a/gcc/testsuite/g++.dg/cpp1y/pr85076.C
+++ b/gcc/testsuite/g++.dg/cpp1y/pr85076.C
@@ -3,4 +3,4 @@
template<typename> struct A*; // { dg-error "expected unqualified-id before" }
-auto a = [](A<auto>) {}; // { dg-error "is not a template|has incomplete type" }
+auto a = [](A<auto>) {}; // { dg-error "is not a template|has incomplete type|auto" }
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67210.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67210.C
index a31750e..baddc1c 100644
--- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67210.C
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67210.C
@@ -7,4 +7,4 @@ concept C = true;
template <class T>
struct A {};
-void f(A<C<int> auto >) {}
+void f(A<C<int> auto >) {} // { dg-error "auto" }
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67210a.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67210a.C
new file mode 100644
index 0000000..1d63a84
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67210a.C
@@ -0,0 +1,11 @@
+// PR c++/67210
+// { dg-do compile { target c++20 } }
+// { dg-additional-options -Wno-abbreviated-auto-in-template-arg }
+
+template <class T, class U>
+concept C = true;
+
+template <class T>
+struct A {};
+
+void f(A<C<int> auto >) {}
diff --git a/gcc/testsuite/g++.target/aarch64/pr119498.C b/gcc/testsuite/g++.target/aarch64/pr119498.C
new file mode 100644
index 0000000..03f1659
--- /dev/null
+++ b/gcc/testsuite/g++.target/aarch64/pr119498.C
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-require-ifunc "" } */
+/* { dg-options "-O0" } */
+/* { dg-additional-options "-Wno-experimental-fmv-target" } */
+
+__attribute__ ((target_version ("default"))) int
+foo ();
+
+__attribute__ ((target_version ("default"))) int
+foo () { return 1; } /* { dg-message "old declaration" } */
+
+__attribute__ ((target_version ("dotprod"))) float
+foo () { return 3; } /* { dg-error "ambiguating new declaration" } */
+
+__attribute__ ((target_version ("sve"))) int
+foo2 () { return 1; } /* { dg-message "old declaration" } */
+
+__attribute__ ((target_version ("dotprod"))) float
+foo2 () { return 3; } /* { dg-error "ambiguating new declaration of" } */
diff --git a/gcc/testsuite/gcc.dg/flex-array-counted-by.c b/gcc/testsuite/gcc.dg/flex-array-counted-by.c
index 4fa91ff..16eb2c6 100644
--- a/gcc/testsuite/gcc.dg/flex-array-counted-by.c
+++ b/gcc/testsuite/gcc.dg/flex-array-counted-by.c
@@ -10,7 +10,7 @@ int x __attribute ((counted_by (size))); /* { dg-error "attribute is not allowed
struct trailing {
int count;
- int field __attribute ((counted_by (count))); /* { dg-error "attribute is not allowed for a non-array or non-pointer field" } */
+ int field __attribute ((counted_by (count))); /* { dg-error "attribute is not allowed for a non-array field" } */
};
struct trailing_1 {
diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by-1.c b/gcc/testsuite/gcc.dg/pointer-counted-by-1.c
deleted file mode 100644
index 395af34..0000000
--- a/gcc/testsuite/gcc.dg/pointer-counted-by-1.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/* More testing the correct usage of attribute counted_by for pointer field. */
-/* { dg-do compile } */
-/* { dg-options "-O0" } */
-
-typedef struct item1 Item1;
-typedef union item2 Item2;
-
-struct pointer_array {
- int count1;
- Item1 *array_1 __attribute__ ((counted_by (count1)));
- Item2 *array_2 __attribute__ ((counted_by (count2)));
- int count2;
-} *pointer_data;
-
-struct item1 {
- int a;
- float b[];
-};
-
-union item2 {
- int c;
- float d[];
-};
-
-void foo ()
-{
- pointer_data
- = (struct pointer_array *) __builtin_malloc (sizeof (struct pointer_array));
- pointer_data->array_1 /* { dg-error "attribute is not allowed for a pointer to structure or union with flexible array member" } */
- = (Item1 *) __builtin_malloc (sizeof (Item1) + 3 * sizeof (float));
- pointer_data->array_2 /* { dg-error "attribute is not allowed for a pointer to structure or union with flexible array member" } */
- = (Item2 *) __builtin_malloc (sizeof (Item2) + 3 * sizeof (float));
- return;
-}
diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by-2.c b/gcc/testsuite/gcc.dg/pointer-counted-by-2.c
deleted file mode 100644
index 1f4a278..0000000
--- a/gcc/testsuite/gcc.dg/pointer-counted-by-2.c
+++ /dev/null
@@ -1,10 +0,0 @@
-/* Testing the correct usage of attribute counted_by for pointer: _BitInt */
-/* { dg-do compile { target bitint } } */
-/* { dg-options "-O2 -std=c23" } */
-
-struct pointer_array {
- _BitInt(24) count;
- int *array __attribute__ ((counted_by (count)));
- int *array1 __attribute__ ((counted_by (count1)));
- _BitInt(24) count1;
-};
diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by-3.c b/gcc/testsuite/gcc.dg/pointer-counted-by-3.c
deleted file mode 100644
index 7005609..0000000
--- a/gcc/testsuite/gcc.dg/pointer-counted-by-3.c
+++ /dev/null
@@ -1,127 +0,0 @@
- /* Testing the correct usage of attribute counted_by for pointer in c23,
- multiple definitions of the same tag in same or different scopes.
- { dg-do compile }
- { dg-options "-std=c23" }
- */
-
-/* Allowed redefinitions of the same struct in the same scope, with the
- same counted_by attribute. */
-struct f {
- int b;
- int c;
- int *a __attribute__ ((counted_by (b))); };
-struct f {
- int b;
- int c;
- int *a __attribute__ ((counted_by (b))); };
-struct f {
- int b;
- int c;
- int *a; }; /* { dg-error "redefinition of struct or union" } */
-
-/* Error when the counted_by attribute is defined differently. */
-struct f {
- int b;
- int c;
- int *a __attribute__ ((counted_by (c))); }; /* { dg-error "redefinition of struct or union" } */
-
-struct h {
- int b;
- int c;
- int *a __attribute__ ((counted_by (b))); } p;
-
-void test (void)
-{
- struct h {
- int b;
- int c;
- int *a __attribute__ ((counted_by (b))); } x;
-
- p = x;
-}
-
-void test1 (void)
-{
- struct h {
- int b;
- int c;
- int *a __attribute__ ((counted_by (c))); } y;
-
- p = y; /* { dg-error "incompatible types when assigning to type" } */
-}
-
-struct nested_f {
- struct {
- union {
- int b;
- float f;
- };
- int n;
- };
- char *c __attribute__ ((counted_by (b)));
-};
-
-struct nested_f {
- struct {
- union {
- int b;
- float f;
- };
- int n;
- };
- char *c __attribute__ ((counted_by (b)));
-};
-
-struct nested_f {
- struct {
- union {
- int b;
- float f;
- };
- int n;
- };
- char *c __attribute__ ((counted_by (n)));
-}; /* { dg-error "redefinition of struct or union" } */
-
-struct nested_h {
- struct {
- union {
- int b;
- float f;
- };
- int n;
- };
- char *c __attribute__ ((counted_by (b)));
-} nested_p;
-
-void test_2 (void)
-{
-struct nested_h {
- struct {
- union {
- int b;
- float f;
- };
- int n;
- };
- char *c __attribute__ ((counted_by (b)));
-} nested_x;
-
- nested_p = nested_x;
-}
-
-void test_3 (void)
-{
-struct nested_h {
- struct {
- union {
- int b;
- float f;
- };
- int n;
- };
- char *c __attribute__ ((counted_by (n)));
-} nested_y;
-
- nested_p = nested_y; /* { dg-error "incompatible types when assigning to type" } */
-}
diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by-4-char.c b/gcc/testsuite/gcc.dg/pointer-counted-by-4-char.c
deleted file mode 100644
index c404e5b..0000000
--- a/gcc/testsuite/gcc.dg/pointer-counted-by-4-char.c
+++ /dev/null
@@ -1,6 +0,0 @@
-/* Test the attribute counted_by for pointer field and its usage in
- * __builtin_dynamic_object_size. */
-/* { dg-do run } */
-/* { dg-options "-O2" } */
-#define PTR_TYPE char
-#include "pointer-counted-by-4.c"
diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by-4-float.c b/gcc/testsuite/gcc.dg/pointer-counted-by-4-float.c
deleted file mode 100644
index 383d8fb..0000000
--- a/gcc/testsuite/gcc.dg/pointer-counted-by-4-float.c
+++ /dev/null
@@ -1,6 +0,0 @@
-/* Test the attribute counted_by for pointer field and its usage in
- * __builtin_dynamic_object_size. */
-/* { dg-do run } */
-/* { dg-options "-O2" } */
-#define PTR_TYPE float
-#include "pointer-counted-by-4.c"
diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by-4-struct.c b/gcc/testsuite/gcc.dg/pointer-counted-by-4-struct.c
deleted file mode 100644
index 50246d2..0000000
--- a/gcc/testsuite/gcc.dg/pointer-counted-by-4-struct.c
+++ /dev/null
@@ -1,10 +0,0 @@
-/* Test the attribute counted_by for pointer field and its usage in
- * __builtin_dynamic_object_size. */
-/* { dg-do run } */
-/* { dg-options "-O2" } */
-struct A {
- int a;
- char *b;
-};
-#define PTR_TYPE struct A
-#include "pointer-counted-by-4.c"
diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by-4-union.c b/gcc/testsuite/gcc.dg/pointer-counted-by-4-union.c
deleted file mode 100644
index e786d99..0000000
--- a/gcc/testsuite/gcc.dg/pointer-counted-by-4-union.c
+++ /dev/null
@@ -1,10 +0,0 @@
-/* Test the attribute counted_by for pointer field and its usage in
- * __builtin_dynamic_object_size. */
-/* { dg-do run } */
-/* { dg-options "-O2" } */
-union A {
- int a;
- float b;
-};
-#define PTR_TYPE union A
-#include "pointer-counted-by-4.c"
diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by-4.c b/gcc/testsuite/gcc.dg/pointer-counted-by-4.c
deleted file mode 100644
index c4b3631..0000000
--- a/gcc/testsuite/gcc.dg/pointer-counted-by-4.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/* Test the attribute counted_by for pointer field and its usage in
- * __builtin_dynamic_object_size. */
-/* { dg-do run } */
-/* { dg-options "-O2" } */
-
-#include "builtin-object-size-common.h"
-#ifndef PTR_TYPE
-#define PTR_TYPE int
-#endif
-struct pointer_array {
- int b;
- PTR_TYPE *c;
-} *p_array;
-
-struct annotated {
- PTR_TYPE *c __attribute__ ((counted_by (b)));
- int b;
-} *p_array_annotated;
-
-struct nested_annotated {
- PTR_TYPE *c __attribute__ ((counted_by (b)));
- struct {
- union {
- int b;
- float f;
- };
- int n;
- };
-} *p_array_nested_annotated;
-
-void __attribute__((__noinline__)) setup (int normal_count, int attr_count)
-{
- p_array
- = (struct pointer_array *) malloc (sizeof (struct pointer_array));
- p_array->c = (PTR_TYPE *) malloc (sizeof (PTR_TYPE) * normal_count);
- p_array->b = normal_count;
-
- p_array_annotated
- = (struct annotated *) malloc (sizeof (struct annotated));
- p_array_annotated->c = (PTR_TYPE *) malloc (sizeof (PTR_TYPE) * attr_count);
- p_array_annotated->b = attr_count;
-
- p_array_nested_annotated
- = (struct nested_annotated *) malloc (sizeof (struct nested_annotated));
- p_array_nested_annotated->c = (PTR_TYPE *) malloc (sizeof (PTR_TYPE) * attr_count);
- p_array_nested_annotated->b = attr_count;
-
- return;
-}
-
-void __attribute__((__noinline__)) test ()
-{
- EXPECT(__builtin_dynamic_object_size(p_array->c, 1), -1);
- EXPECT(__builtin_dynamic_object_size(p_array_annotated->c, 1),
- p_array_annotated->b * sizeof (PTR_TYPE));
- EXPECT(__builtin_dynamic_object_size(p_array_nested_annotated->c, 1),
- p_array_nested_annotated->b * sizeof (PTR_TYPE));
-}
-
-void cleanup ()
-{
- free (p_array->c);
- free (p_array);
- free (p_array_annotated->c);
- free (p_array_annotated);
- free (p_array_nested_annotated->c);
- free (p_array_nested_annotated);
-}
-
-int main(int argc, char *argv[])
-{
- setup (10,10);
- test ();
- DONE ();
- cleanup ();
- return 0;
-}
diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by-5.c b/gcc/testsuite/gcc.dg/pointer-counted-by-5.c
deleted file mode 100644
index b43ffdf..0000000
--- a/gcc/testsuite/gcc.dg/pointer-counted-by-5.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/* Test the attribute counted_by for pointer fields and its usage in
- * __builtin_dynamic_object_size: when the counted_by field is negative. */
-/* { dg-do run } */
-/* { dg-options "-O2" } */
-
-#include "builtin-object-size-common.h"
-
-struct annotated {
- int b;
- int *c __attribute__ ((counted_by (b)));
-} *array_annotated;
-
-struct nested_annotated {
- int *c __attribute__ ((counted_by (b)));
- struct {
- union {
- int b;
- float f;
- };
- int n;
- };
-} *array_nested_annotated;
-
-void __attribute__((__noinline__)) setup (int attr_count)
-{
- array_annotated
- = (struct annotated *)malloc (sizeof (struct annotated));
- array_annotated->b = attr_count;
-
- array_nested_annotated
- = (struct nested_annotated *)malloc (sizeof (struct nested_annotated));
- array_nested_annotated->b = attr_count - 1;
-
- return;
-}
-
-void __attribute__((__noinline__)) test ()
-{
- EXPECT(__builtin_dynamic_object_size(array_annotated->c, 1), 0);
- EXPECT(__builtin_dynamic_object_size(array_nested_annotated->c, 1), 0);
-}
-
-void cleanup ()
-{
- free (array_annotated);
- free (array_nested_annotated);
-}
-
-int main(int argc, char *argv[])
-{
- setup (-10);
- test ();
- DONE ();
- cleanup ();
- return 0;
-}
diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by-6.c b/gcc/testsuite/gcc.dg/pointer-counted-by-6.c
deleted file mode 100644
index 355558c..0000000
--- a/gcc/testsuite/gcc.dg/pointer-counted-by-6.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/* Test the attribute counted_by for pointer fields and its usage in
- * __builtin_dynamic_object_size: when the type of the pointer
- * is casting to another type. */
-/* { dg-do run } */
-/* { dg-options "-O2" } */
-
-#include "builtin-object-size-common.h"
-
-typedef unsigned short u16;
-
-struct info {
- u16 data_len;
- char *data __attribute__((counted_by(data_len)));
-};
-
-struct foo {
- int a;
- int b;
-};
-
-static __attribute__((__noinline__))
-struct info *setup ()
-{
- struct info *p;
- size_t bytes = 3 * sizeof(struct foo);
-
- p = (struct info *) malloc (sizeof (struct info));
- p->data = (char *) malloc (bytes);
- p->data_len = bytes;
-
- return p;
-}
-
-static void
-__attribute__((__noinline__)) report (struct info *p)
-{
- struct foo *bar = (struct foo *)p->data;
- EXPECT(__builtin_dynamic_object_size((char *)(bar + 1), 1),
- sizeof (struct foo) * 2);
- EXPECT(__builtin_dynamic_object_size((char *)(bar + 2), 1),
- sizeof (struct foo));
-}
-
-void cleanup (struct info *p)
-{
- free (p->data);
- free (p);
-}
-
-int main(int argc, char *argv[])
-{
- struct info *p = setup();
- report(p);
- cleanup (p);
- return 0;
-}
diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by-7.c b/gcc/testsuite/gcc.dg/pointer-counted-by-7.c
deleted file mode 100644
index af1ab27..0000000
--- a/gcc/testsuite/gcc.dg/pointer-counted-by-7.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/* Additional test of the attribute counted_by for pointer field and its usage
- in __builtin_dynamic_object_size. */
-/* { dg-do run } */
-/* { dg-options "-O2" } */
-
-#include "builtin-object-size-common.h"
-
-struct annotated {
- int b;
- int *c __attribute__ ((counted_by (b)));
-};
-
-struct annotated __attribute__((__noinline__)) setup (int attr_count)
-{
- struct annotated p_array_annotated;
- p_array_annotated.c = (int *) malloc (sizeof (int) * attr_count);
- p_array_annotated.b = attr_count;
-
- return p_array_annotated;
-}
-
-int main(int argc, char *argv[])
-{
- struct annotated x = setup (10);
- int *p = x.c;
- x = setup (20);
- EXPECT(__builtin_dynamic_object_size (p, 1), 10 * sizeof (int));
- EXPECT(__builtin_dynamic_object_size (x.c, 1), 20 * sizeof (int));
- free (p);
- free (x.c);
- DONE ();
-}
diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by.c b/gcc/testsuite/gcc.dg/pointer-counted-by.c
deleted file mode 100644
index 0f18828..0000000
--- a/gcc/testsuite/gcc.dg/pointer-counted-by.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/* Testing the correct usage of attribute counted_by for pointer field.
- and also mixed pointer field and FMA field in the same structure. */
-/* { dg-do compile } */
-/* { dg-options "-O0" } */
-
-int size;
-int *x __attribute__ ((counted_by (size))); /* { dg-error "attribute is not allowed for a non-field declaration" } */
-
-struct pointer_array_0 {
- int count;
- int array __attribute__ ((counted_by (count))); /* { dg-error "attribute is not allowed for a non-array or non-pointer field" } */
- int other;
-};
-
-int count;
-struct pointer_array_1 {
- int other;
- int *array_1 __attribute__ ((counted_by (count))); /* { dg-error "attribute is not a field declaration in the same structure as" } */
- int array_fam[] __attribute__ ((counted_by (count))); /* { dg-error "attribute is not a field declaration in the same structure as" } */
-};
-
-struct pointer_array_2 {
- float count1;
- float count2;
- int *array_2 __attribute__ ((counted_by (count1))); /* { dg-error "attribute is not a field declaration with an integer type" } */
- int array_fam[] __attribute__ ((counted_by (count2))); /* { dg-error "attribute is not a field declaration with an integer type" } */
-};
-
-struct pointer_array_3 {
- int count;
- int *array_3 __attribute__ ((counted_by (count))) __attribute__ ((counted_by (count)));
-};
-
-struct pointer_array_4 {
- int count1;
- int count2;
- int *array_4 __attribute__ ((counted_by (count1))) __attribute__ ((counted_by (count2))); /* { dg-error "conflicts with previous declaration" } */
- float array_fam[] __attribute__ ((counted_by (count2))) __attribute__ ((counted_by (count1))); /* { dg-error "conflicts with previous declaration" } */
-};
-
-struct pointer_array_5 {
- _Bool count;
- int *array_5 __attribute__ ((counted_by (count)));
-};
-
-enum week {Mon, Tue, Wed};
-struct pointer_array_6 {
- enum week days;
- int *array_6 __attribute__ ((counted_by (days)));
-};
-
-struct pointer_array_7 {
- int count;
- void *array_7 __attribute__ ((counted_by (count))); /* { dg-error "attribute is not allowed for a pointer to void" } */
-};
-
-struct pointer_array_8 {
- int count;
- int (*fpr)(int,int) __attribute__ ((counted_by (count))); /* { dg-error "attribute is not allowed for a pointer to function" } */
-};
-
-struct item1 {
- int a;
- float b;
-};
-
-union item2 {
- char *a;
- int *b;
-};
-
-typedef struct item3 Item3;
-typedef union item4 Item4;
-
-struct item5 {
- int a;
- float b[];
-};
-
-/* Incomplete structure and union are allowed. */
-struct pointer_array_9 {
- int count1;
- int count2;
- int count3;
- struct item1 *array_1 __attribute__ ((counted_by (count1)));
- union item2 *array_2 __attribute__ ((counted_by (count2)));
- Item3 *array_3 __attribute__ ((counted_by (count3)));
- Item4 *array_4 __attribute__ ((counted_by (count4)));
- int count4;
- int count5;
- /* structure with flexible array member is not allowed. */
- struct item5 *array_5 __attribute__ ((counted_by (count5))); /* { dg-error "attribute is not allowed for a pointer to structure or union with flexible array member" } */
-};
-
-struct mixed_array {
- int count1;
- float *array_1 __attribute__ ((counted_by (count1)));
- float *array_2 __attribute__ ((counted_by (count1)));
- int count2;
- long *array_3 __attribute__ ((counted_by (count2)));
- long array_4[] __attribute__ ((counted_by (count2)));
-};
-
-struct mixed_array_2 {
- float *array_1 __attribute__ ((counted_by (count1)));
- int count1;
- float *array_2 __attribute__ ((counted_by (count1)));
- long *array_3 __attribute__ ((counted_by (count2)));
- int count2;
- long array_4[] __attribute__ ((counted_by (count2)));
-};
diff --git a/gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-2.c b/gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-2.c
deleted file mode 100644
index 0653ecc..0000000
--- a/gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-2.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/* Test the attribute counted_by for pointer fields and its usage in
- bounds sanitizer combined with VLA. */
-/* { dg-do run } */
-/* { dg-options "-fsanitize=bounds" } */
-/* { dg-output "index 11 out of bounds for type 'int \\\[\\\*\\\]\\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*index 20 out of bounds for type 'int \\\[\\\*\\\]\\\[\\\*\\\]\\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*index 11 out of bounds for type 'int \\\[\\\*\\\]\\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*index 10 out of bounds for type 'int \\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
-
-
-#include <stdlib.h>
-
-void __attribute__((__noinline__)) setup_and_test_vla (int n, int m)
-{
- struct foo {
- int n;
- int (*p)[n] __attribute__((counted_by(n)));
- } *f;
-
- f = (struct foo *) malloc (sizeof (struct foo));
- f->p = (int (*)[n]) malloc (m * sizeof (int[n]));
- f->n = m;
- f->p[m][n-1] = 1;
- free (f->p);
- free (f);
- return;
-}
-
-void __attribute__((__noinline__)) setup_and_test_vla_1 (int n1, int n2, int m)
-{
- struct foo {
- int n;
- int (*p)[n2][n1] __attribute__((counted_by(n)));
- } *f;
-
- f = (struct foo *) malloc (sizeof(struct foo));
- f->p = (int (*)[n2][n1]) malloc (m * sizeof (int[n2][n1]));
- f->n = m;
- f->p[m][n2][n1] = 1;
- free (f->p);
- free (f);
- return;
-}
-
-int main(int argc, char *argv[])
-{
- setup_and_test_vla (10, 11);
- setup_and_test_vla_1 (10, 11, 20);
- return 0;
-}
-
diff --git a/gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-3.c b/gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-3.c
deleted file mode 100644
index 731422d..0000000
--- a/gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-3.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Test the attribute counted_by for pointer fields and its usage in bounds
- sanitizer. when counted_by field is negative value. */
-/* { dg-do run } */
-/* { dg-options "-fsanitize=bounds" } */
-
-#include <stdlib.h>
-
-struct annotated {
- int b;
- int *c __attribute__ ((counted_by (b)));
-} *array_annotated;
-
-void __attribute__((__noinline__)) setup (int annotated_count)
-{
- array_annotated
- = (struct annotated *)malloc (sizeof (struct annotated));
- array_annotated->c = (int *) malloc (sizeof (int) * 10);
- array_annotated->b = annotated_count;
-
- return;
-}
-
-void __attribute__((__noinline__)) test (int annotated_index)
-{
- array_annotated->c[annotated_index] = 2;
-}
-
-void cleanup ()
-{
- free (array_annotated->c);
- free (array_annotated);
-}
-
-int main(int argc, char *argv[])
-{
- setup (-3);
- test (2);
- cleanup ();
- return 0;
-}
-
-/* { dg-output "25:21: runtime error: index 2 out of bounds for type" } */
diff --git a/gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-4.c b/gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-4.c
deleted file mode 100644
index 52f202f..0000000
--- a/gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-4.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Test the attribute counted_by for pointer fields and its usage in bounds
- sanitizer. when counted_by field is zero value. */
-/* { dg-do run } */
-/* { dg-options "-fsanitize=bounds" } */
-
-#include <stdlib.h>
-
-struct annotated {
- int b;
- int *c __attribute__ ((counted_by (b)));
-} *array_annotated;
-
-void __attribute__((__noinline__)) setup (int annotated_count)
-{
- array_annotated
- = (struct annotated *)malloc (sizeof (struct annotated));
- array_annotated->c = (int *)malloc (sizeof (int) * 10);
- array_annotated->b = annotated_count;
-
- return;
-}
-
-void __attribute__((__noinline__)) test (int annotated_index)
-{
- array_annotated->c[annotated_index] = 2;
-}
-
-void cleanup ()
-{
- free (array_annotated->c);
- free (array_annotated);
-}
-
-int main(int argc, char *argv[])
-{
- setup (0);
- test (1);
- cleanup ();
- return 0;
-}
-
-/* { dg-output "25:21: runtime error: index 1 out of bounds for type" } */
diff --git a/gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-5.c b/gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-5.c
deleted file mode 100644
index 8ad7572..0000000
--- a/gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-5.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/* Test the attribute counted_by for pointer fields and its usage in
- bounds sanitizer. */
-/* { dg-do run } */
-/* { dg-options "-fsanitize=bounds" } */
-
-#include <stdlib.h>
-
-struct annotated {
- int b;
- int *c __attribute__ ((counted_by (b)));
-} *p_array_annotated;
-
-void __attribute__((__noinline__)) setup (int annotated_count)
-{
- p_array_annotated
- = (struct annotated *)malloc (sizeof (struct annotated));
- p_array_annotated->c = (int *) malloc (annotated_count * sizeof (int));
- p_array_annotated->b = annotated_count;
-
- return;
-}
-
-void cleanup ()
-{
- free (p_array_annotated->c);
- free (p_array_annotated);
-}
-
-int main(int argc, char *argv[])
-{
- int i;
- setup (10);
- for (i = 0; i < 11; i++)
- p_array_annotated->c[i] = 2; // goes boom at i == 10
- cleanup ();
- return 0;
-}
-
-
-/* { dg-output "34:25: runtime error: index 10 out of bounds for type" } */
diff --git a/gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds.c b/gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds.c
deleted file mode 100644
index c5a1ac5..0000000
--- a/gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/* Test the attribute counted_by for pointer fields and its usage in
- bounds sanitizer. */
-/* { dg-do run } */
-/* { dg-options "-fsanitize=bounds" } */
-
-#include <stdlib.h>
-
-struct pointer_array {
- int b;
- int *c;
-} *p_array;
-
-struct annotated {
- int b;
- int *c __attribute__ ((counted_by (b)));
-} *p_array_annotated;
-
-void __attribute__((__noinline__)) setup (int normal_count, int annotated_count)
-{
- p_array
- = (struct pointer_array *) malloc (sizeof (struct pointer_array));
- p_array->c = (int *) malloc (normal_count * sizeof (int));
- p_array->b = normal_count;
-
- p_array_annotated
- = (struct annotated *) malloc (sizeof (struct annotated));
- p_array_annotated->c = (int *) malloc (annotated_count * sizeof (int));
- p_array_annotated->b = annotated_count;
-
- return;
-}
-
-void __attribute__((__noinline__)) test (int normal_index, int annotated_index)
-{
- p_array->c[normal_index] = 1;
- p_array_annotated->c[annotated_index] = 2;
-}
-
-int main(int argc, char *argv[])
-{
- setup (10, 10);
- test (10, 10);
- return 0;
-}
-
-/* { dg-output "36:23: runtime error: index 10 out of bounds for type" } */
diff --git a/gcc/testsuite/gcc.dg/vect/pr120817.c b/gcc/testsuite/gcc.dg/vect/pr120817.c
index d8f55c9..199189a 100644
--- a/gcc/testsuite/gcc.dg/vect/pr120817.c
+++ b/gcc/testsuite/gcc.dg/vect/pr120817.c
@@ -1,5 +1,6 @@
/* { dg-additional-options "-O1" } */
-/* { dg-additional-options "-mcpu=neoverse-n2" { target aarch64*-*-* } } */
+/* { dg-require-effective-target aarch64_sve_hw { target aarch64*-*-* } } */
+/* { dg-additional-options "-march=armv8-a+sve -mtune=neoverse-n2" { target aarch64*-*-* } } */
#include "tree-vect.h"
diff --git a/gcc/testsuite/gcc.target/aarch64/popcnt13.c b/gcc/testsuite/gcc.target/aarch64/popcnt13.c
new file mode 100644
index 0000000..2a30e98
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/popcnt13.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#pragma GCC target "+nocssc+sve"
+
+/*
+** h128:
+** ldr q([0-9]+), \[x0\]
+** ptrue p([0-9]+).b, vl16
+** cnt z([0-9]+).d, p\2/m, z\1.d
+** addp d([0-9]+), v\3.2d
+** fmov x0, d\4
+** ret
+*/
+
+unsigned h128 (const unsigned __int128 *a) {
+ return __builtin_popcountg (a[0]);
+}
+
+/* There should be only one POPCOUNT. */
+/* { dg-final { scan-tree-dump-times "POPCOUNT " 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-not " __builtin_popcount" "optimized" } } */
+
diff --git a/gcc/testsuite/gcc.target/aarch64/popcnt9.c b/gcc/testsuite/gcc.target/aarch64/popcnt9.c
index c778fc7..cfed8c5 100644
--- a/gcc/testsuite/gcc.target/aarch64/popcnt9.c
+++ b/gcc/testsuite/gcc.target/aarch64/popcnt9.c
@@ -3,7 +3,7 @@
/* { dg-final { check-function-bodies "**" "" } } */
/* PR target/113042 */
-#pragma GCC target "+nocssc"
+#pragma GCC target "+nocssc+nosve"
/*
** h128:
diff --git a/gcc/testsuite/gcc.target/s390/fminmax-1.c b/gcc/testsuite/gcc.target/s390/fminmax-1.c
new file mode 100644
index 0000000..df10905
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/fminmax-1.c
@@ -0,0 +1,77 @@
+/* Check fmin/fmax expanders for scalars on VXE targets. */
+
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=z14 -mzarch" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+/*
+** dofmaxl:
+** vl (%v.),0\(%r3\),3
+** vl (%v.),0\(%r4\),3
+** wfmaxxb (%v.),\1,\2,4
+** vst \3,0\(%r2\),3
+** br %r14
+*/
+long double
+dofmaxl (long double d1, long double d2)
+{
+ return __builtin_fmaxl (d1, d2);
+}
+
+/*
+** dofminl:
+** vl (%v.),0\(%r3\),3
+** vl (%v.),0\(%r4\),3
+** wfminxb (%v.),\1,\2,4
+** vst \3,0\(%r2\),3
+** br %r14
+*/
+long double
+dofminl (long double d1, long double d2)
+{
+ return __builtin_fminl (d1, d2);
+}
+
+/*
+** dofmax:
+** wfmaxdb %v0,%v0,%v2,4
+** br %r14
+*/
+double
+dofmax (double d1, double d2)
+{
+ return __builtin_fmax (d1, d2);
+}
+
+/*
+** dofmin:
+** wfmindb %v0,%v0,%v2,4
+** br %r14
+*/
+double
+dofmin (double d1, double d2)
+{
+ return __builtin_fmin (d1, d2);
+}
+
+/*
+** dofmaxf:
+** wfmaxsb %v0,%v0,%v2,4
+** br %r14
+*/
+float
+dofmaxf (float f1, float f2)
+{
+ return __builtin_fmaxf (f1, f2);
+}
+
+/*
+** dofminf:
+** wfminsb %v0,%v0,%v2,4
+** br %r14
+*/
+float
+dofminf (float f1, float f2)
+{
+ return __builtin_fminf (f1, f2);
+}
diff --git a/gcc/testsuite/gcc.target/s390/fminmax-2.c b/gcc/testsuite/gcc.target/s390/fminmax-2.c
new file mode 100644
index 0000000..ea37a0a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/fminmax-2.c
@@ -0,0 +1,29 @@
+/* Check fmin/fmax expanders for scalars on non-VXE targets. */
+
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=z13 -mzarch" } */
+/* { dg-final { scan-assembler-times "jg" 4 } } */
+
+double
+dofmax (double d1, double d2)
+{
+ return __builtin_fmax (d1, d2);
+}
+
+double
+dofmin (double d1, double d2)
+{
+ return __builtin_fmin (d1, d2);
+}
+
+float
+dofmaxf (float f1, float f2)
+{
+ return __builtin_fmaxf (f1, f2);
+}
+
+float
+dofminf (float f1, float f2)
+{
+ return __builtin_fminf (f1, f2);
+}
diff --git a/gcc/testsuite/gcc.target/xtensa/pr120888-1.c b/gcc/testsuite/gcc.target/xtensa/pr120888-1.c
new file mode 100644
index 0000000..f438e4c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/xtensa/pr120888-1.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-rtl-expand" } */
+
+void u8(unsigned char c);
+void cu8(unsigned char *p)
+{
+ u8(*p);
+}
+
+/* { dg-final { scan-rtl-dump "zero_extend" "expand" } } */
+/* { dg-final { scan-rtl-dump-not "sign_extend" "expand" } } */
diff --git a/gcc/testsuite/gcc.target/xtensa/pr120888-2.c b/gcc/testsuite/gcc.target/xtensa/pr120888-2.c
new file mode 100644
index 0000000..9b5caad
--- /dev/null
+++ b/gcc/testsuite/gcc.target/xtensa/pr120888-2.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-rtl-expand" } */
+
+void s8(signed char c);
+void cs8(signed char *p)
+{
+ s8(*p);
+}
+
+/* { dg-final { scan-rtl-dump "sign_extend" "expand" } } */
+/* { dg-final { scan-rtl-dump-not "zero_extend" "expand" } } */
diff --git a/gcc/testsuite/lib/scanasm.exp b/gcc/testsuite/lib/scanasm.exp
index 97935cb..a2311de 100644
--- a/gcc/testsuite/lib/scanasm.exp
+++ b/gcc/testsuite/lib/scanasm.exp
@@ -1109,6 +1109,8 @@ proc check-function-bodies { args } {
append function_regexp ".*"
} elseif { [regexp {^\.L} $line] } {
append function_regexp $line "\n"
+ } elseif { [regexp {^[0-9]+:} $line] } {
+ append function_regexp $line "\n"
} else {
append function_regexp $config(line_prefix) $line "\n"
}
diff --git a/gcc/tree-object-size.cc b/gcc/tree-object-size.cc
index a551f2b..2d13ab7 100644
--- a/gcc/tree-object-size.cc
+++ b/gcc/tree-object-size.cc
@@ -861,12 +861,10 @@ addr_object_size (struct object_size_info *osi, const_tree ptr,
4th argument TYPE_OF_SIZE: A constant 0 with its TYPE being the same as the TYPE
of the object referenced by REF_TO_SIZE
6th argument: A constant 0 with the pointer TYPE to the original flexible
- array type or pointer field type.
+ array type.
The size of the element can be retrived from the TYPE of the 6th argument
- of the call, which is the pointer to the original flexible array type or
- the type of the original pointer field. */
-
+ of the call, which is the pointer to the array type. */
static tree
access_with_size_object_size (const gcall *call, int object_size_type)
{
@@ -876,7 +874,7 @@ access_with_size_object_size (const gcall *call, int object_size_type)
gcc_assert (gimple_call_internal_p (call, IFN_ACCESS_WITH_SIZE));
/* The type of the 6th argument type is the pointer TYPE to the original
- flexible array type or to the original pointer type. */
+ flexible array type. */
tree pointer_to_array_type = TREE_TYPE (gimple_call_arg (call, 5));
gcc_assert (POINTER_TYPE_P (pointer_to_array_type));
tree element_type = TREE_TYPE (TREE_TYPE (pointer_to_array_type));
@@ -1944,17 +1942,6 @@ collect_object_sizes_for (struct object_size_info *osi, tree var)
if (TREE_CODE (rhs) == SSA_NAME
&& POINTER_TYPE_P (TREE_TYPE (rhs)))
reexamine = merge_object_sizes (osi, var, rhs);
- /* Handle the following stmt #2 to propagate the size from the
- stmt #1 to #3:
- 1 _1 = .ACCESS_WITH_SIZE (_3, _4, 1, 0, -1, 0B);
- 2 _5 = *_1;
- 3 _6 = __builtin_dynamic_object_size (_5, 1);
- */
- else if (TREE_CODE (rhs) == MEM_REF
- && POINTER_TYPE_P (TREE_TYPE (rhs))
- && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME
- && integer_zerop (TREE_OPERAND (rhs, 1)))
- reexamine = merge_object_sizes (osi, var, TREE_OPERAND (rhs, 0));
else
expr_object_size (osi, var, rhs);
}
diff --git a/gcc/value-range.h b/gcc/value-range.h
index 5c358f3..3bc02db 100644
--- a/gcc/value-range.h
+++ b/gcc/value-range.h
@@ -324,7 +324,7 @@ public:
virtual void update_bitmask (const class irange_bitmask &) override;
virtual irange_bitmask get_bitmask () const override;
- virtual void verify_range () const;
+ virtual void verify_range () const override;
protected:
void maybe_resize (int needed);
virtual void set (tree, tree, value_range_kind = VR_RANGE) override;
@@ -422,7 +422,7 @@ public:
bool contains_p (const wide_int &) const;
wide_int lower_bound () const;
wide_int upper_bound () const;
- virtual void verify_range () const;
+ virtual void verify_range () const final override;
irange_bitmask get_bitmask () const final override;
void update_bitmask (const irange_bitmask &) final override;
protected:
@@ -594,7 +594,7 @@ public:
bool nan_signbit_p (bool &signbit) const;
bool known_isnormal () const;
bool known_isdenormal_or_zero () const;
- virtual void verify_range () const;
+ virtual void verify_range () const override;
protected:
virtual bool contains_p (tree cst) const override;
virtual void set (tree, tree, value_range_kind = VR_RANGE) override;
diff --git a/libstdc++-v3/include/bits/chrono_io.h b/libstdc++-v3/include/bits/chrono_io.h
index 72cd569..75ee7e8 100644
--- a/libstdc++-v3/include/bits/chrono_io.h
+++ b/libstdc++-v3/include/bits/chrono_io.h
@@ -280,8 +280,8 @@ namespace __format
// in the format-spec, e.g. "{:L%a}" is localized and locale-specific,
// but "{:L}" is only localized and "{:%a}" is only locale-specific.
unsigned _M_locale_specific : 1;
- // Indicates that we are handling duration.
- unsigned _M_time_only : 1;
+ // Indicates that we are handling time_point.
+ unsigned _M_time_point : 1;
// Indicates that duration should be treated as floating point.
unsigned _M_floating_point_rep : 1;
// Indicate that duration uses user-defined representation.
@@ -693,8 +693,11 @@ namespace __format
__allowed_mods = _Mod_O;
break;
case 'j':
- __needed = __spec._M_time_only ? _HoursMinutesSeconds
- : _DayOfYear;
+ __needed = __parts & _DayOfYear;
+ // If we do not know day-of-year then we must have a duration,
+ // which is to be formatted as decimal number of days.
+ if (__needed == _None)
+ __needed = _HoursMinutesSeconds;
break;
case 'm':
__needed = _Month;
@@ -919,7 +922,13 @@ namespace __format
{
switch (__conv)
{
+ case 'a':
+ case 'A':
+ case 'b':
+ case 'B':
case 'c':
+ case 'h':
+ case 'p':
case 'r':
case 'x':
case 'X':
@@ -947,6 +956,32 @@ namespace __format
return __out;
}
+ void
+ _M_check_ok(const _ChronoData<_CharT>& __t, _CharT __conv) const
+ {
+ // n.b. for time point all date parts are computed, so
+ // they are always ok.
+ if (_M_spec._M_time_point || _M_spec._M_debug)
+ return;
+
+ switch (__conv)
+ {
+ case 'a':
+ case 'A':
+ if (!__t._M_weekday.ok()) [[unlikely]]
+ __throw_format_error("format error: invalid weekday");
+ return;
+ case 'b':
+ case 'h':
+ case 'B':
+ if (!__t._M_month.ok()) [[unlikely]]
+ __throw_format_error("format error: invalid month");
+ return;
+ default:
+ return;
+ }
+ }
+
template<typename _OutIter, typename _FormatContext>
_OutIter
_M_format_to(const _ChronoData<_CharT>& __t, _OutIter __out,
@@ -1003,6 +1038,8 @@ namespace __format
do
{
_CharT __c = *__first++;
+ _M_check_ok(__t, __c);
+
if (__use_locale_fmt && _S_localized_spec(__c, __mod)) [[unlikely]]
__out = _M_locale_fmt(std::move(__out), __fc.locale(),
__tm, __c, __mod);
@@ -1153,11 +1190,8 @@ namespace __format
{
// %a Locale's abbreviated weekday name.
// %A Locale's full weekday name.
- if (!__wd.ok())
+ if (_M_spec._M_debug && !__wd.ok())
{
- if (!_M_spec._M_debug)
- __throw_format_error("format error: invalid weekday");
-
_CharT __buf[3];
__out = __format::__write(std::move(__out),
_S_str_d1(__buf, __wd.c_encoding()));
@@ -1183,11 +1217,8 @@ namespace __format
{
// %b Locale's abbreviated month name.
// %B Locale's full month name.
- if (!__m.ok())
+ if (_M_spec._M_debug && !__m.ok())
{
- if (!_M_spec._M_debug)
- __throw_format_error("format error: invalid month");
-
_CharT __buf[3];
__out = __format::__write(std::move(__out),
_S_str_d1(__buf, (unsigned)__m));
@@ -1419,7 +1450,7 @@ namespace __format
_OutIter
_M_j(const _ChronoData<_CharT>& __t, _OutIter __out) const
{
- if (_M_spec._M_time_only)
+ if (!_M_spec._M_needs(_ChronoParts::_DayOfYear))
{
// Decimal number of days, without padding.
auto __d = chrono::floor<chrono::days>(__t._M_hours).count();
@@ -1766,7 +1797,7 @@ namespace __format
{
if (__n < 100) [[likely]]
return _S_two_digits(__n);
- return _S_str_d3(__buf, __n);
+ return _S_str_d3(__buf, __n);
}
// Returns decimal representation of __n, padded to 3 digits.
@@ -1811,7 +1842,7 @@ namespace __format
using enum _ChronoParts;
_ChronoSpec<_CharT> __res{};
- __res._M_time_only = (__parts & _Date) == 0;
+ __res._M_time_point = (__parts & _DateTime) == _DateTime;
__res._M_floating_point_rep = chrono::treat_as_floating_point_v<_Rep>;
__res._M_custom_rep = !is_arithmetic_v<_Rep>;
__res._M_prec = chrono::hh_mm_ss<_Duration>::fractional_width;
diff --git a/libstdc++-v3/include/bits/stl_iterator.h b/libstdc++-v3/include/bits/stl_iterator.h
index a7188f4..75e794f 100644
--- a/libstdc++-v3/include/bits/stl_iterator.h
+++ b/libstdc++-v3/include/bits/stl_iterator.h
@@ -1211,7 +1211,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#else
// Forward iterator requirements
template<typename _Iter>
- __attribute__((__always_inline__)) _GLIBCXX_NODISCARD
+ _GLIBCXX_NODISCARD __attribute__((__always_inline__))
friend
_GLIBCXX_CONSTEXPR
bool
@@ -1220,7 +1220,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX_NOEXCEPT
{ return __lhs.base() == __rhs.base(); }
- __attribute__((__always_inline__)) _GLIBCXX_NODISCARD
+ _GLIBCXX_NODISCARD __attribute__((__always_inline__))
friend
_GLIBCXX_CONSTEXPR
bool
@@ -1229,7 +1229,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return __lhs.base() == __rhs.base(); }
template<typename _Iter>
- __attribute__((__always_inline__)) _GLIBCXX_NODISCARD
+ _GLIBCXX_NODISCARD __attribute__((__always_inline__))
friend
_GLIBCXX_CONSTEXPR
bool
@@ -1238,7 +1238,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX_NOEXCEPT
{ return __lhs.base() != __rhs.base(); }
- __attribute__((__always_inline__)) _GLIBCXX_NODISCARD
+ _GLIBCXX_NODISCARD __attribute__((__always_inline__))
friend
_GLIBCXX_CONSTEXPR
bool
@@ -1248,15 +1248,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// Random access iterator requirements
template<typename _Iter>
+ _GLIBCXX_NODISCARD __attribute__((__always_inline__))
friend
- __attribute__((__always_inline__)) _GLIBCXX_NODISCARD _GLIBCXX_CONSTEXPR
+ _GLIBCXX_CONSTEXPR
inline bool
operator<(const __normal_iterator& __lhs,
const __normal_iterator<_Iter, _Container>& __rhs)
_GLIBCXX_NOEXCEPT
{ return __lhs.base() < __rhs.base(); }
- __attribute__((__always_inline__)) _GLIBCXX_NODISCARD
+ _GLIBCXX_NODISCARD __attribute__((__always_inline__))
friend
_GLIBCXX20_CONSTEXPR
bool
@@ -1265,15 +1266,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return __lhs.base() < __rhs.base(); }
template<typename _Iter>
+ _GLIBCXX_NODISCARD __attribute__((__always_inline__))
friend
- __attribute__((__always_inline__)) _GLIBCXX_NODISCARD _GLIBCXX_CONSTEXPR
+ _GLIBCXX_CONSTEXPR
bool
operator>(const __normal_iterator& __lhs,
const __normal_iterator<_Iter, _Container>& __rhs)
_GLIBCXX_NOEXCEPT
{ return __lhs.base() > __rhs.base(); }
- __attribute__((__always_inline__)) _GLIBCXX_NODISCARD
+ _GLIBCXX_NODISCARD __attribute__((__always_inline__))
friend
_GLIBCXX_CONSTEXPR
bool
@@ -1282,7 +1284,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return __lhs.base() > __rhs.base(); }
template<typename _Iter>
- __attribute__((__always_inline__)) _GLIBCXX_NODISCARD
+ _GLIBCXX_NODISCARD __attribute__((__always_inline__))
friend
_GLIBCXX_CONSTEXPR
bool
@@ -1291,7 +1293,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX_NOEXCEPT
{ return __lhs.base() <= __rhs.base(); }
- __attribute__((__always_inline__)) _GLIBCXX_NODISCARD
+ _GLIBCXX_NODISCARD __attribute__((__always_inline__))
friend
_GLIBCXX_CONSTEXPR
bool
@@ -1300,7 +1302,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return __lhs.base() <= __rhs.base(); }
template<typename _Iter>
- __attribute__((__always_inline__)) _GLIBCXX_NODISCARD
+ _GLIBCXX_NODISCARD __attribute__((__always_inline__))
friend
_GLIBCXX_CONSTEXPR
bool
@@ -1309,7 +1311,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX_NOEXCEPT
{ return __lhs.base() >= __rhs.base(); }
- __attribute__((__always_inline__)) _GLIBCXX_NODISCARD
+ _GLIBCXX_NODISCARD __attribute__((__always_inline__))
friend
_GLIBCXX_CONSTEXPR
bool
@@ -1341,7 +1343,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#endif
{ return __lhs.base() - __rhs.base(); }
- __attribute__((__always_inline__)) _GLIBCXX_NODISCARD
+ _GLIBCXX_NODISCARD __attribute__((__always_inline__))
friend
_GLIBCXX_CONSTEXPR
difference_type
@@ -1349,7 +1351,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX_NOEXCEPT
{ return __lhs.base() - __rhs.base(); }
- __attribute__((__always_inline__)) _GLIBCXX_NODISCARD
+ _GLIBCXX_NODISCARD __attribute__((__always_inline__))
friend
_GLIBCXX_CONSTEXPR
__normal_iterator
diff --git a/libstdc++-v3/include/std/mdspan b/libstdc++-v3/include/std/mdspan
index c72a640..4a06fb2 100644
--- a/libstdc++-v3/include/std/mdspan
+++ b/libstdc++-v3/include/std/mdspan
@@ -509,7 +509,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Layout, typename _Mapping>
concept __mapping_of =
- is_same_v<typename _Layout::mapping<typename _Mapping::extents_type>,
+ is_same_v<typename _Layout::template mapping<typename _Mapping::extents_type>,
_Mapping>;
template<typename _Mapping>
diff --git a/libstdc++-v3/testsuite/ext/verify_neg.cc b/libstdc++-v3/testsuite/ext/verify_neg.cc
new file mode 100644
index 0000000..ce03374
--- /dev/null
+++ b/libstdc++-v3/testsuite/ext/verify_neg.cc
@@ -0,0 +1,28 @@
+// { dg-do compile { target c++11 } }
+
+#include <testsuite_hooks.h>
+
+struct X { explicit operator void*() const { return nullptr; } };
+
+void
+test_VERIFY(int i)
+{
+ // This should not be parsed as a function type bool(bool(i)):
+ VERIFY( bool(i) );
+
+ // This should not produce warnings about lambda in unevaluated context:
+ VERIFY( []{ return 1; }() );
+
+ // Only one expression allowed:
+ VERIFY(1, 2); // { dg-error "in expansion of macro" }
+ // { dg-error "compound expression in functional cast" "" { target *-*-* } 0 }
+
+ // A scoped enum is not contextually convertible to bool:
+ enum class E { E0 };
+ VERIFY( E::E0 ); // { dg-error "could not convert" }
+
+ // explicit conversion to void* is not contextually convertible to bool:
+ X x;
+ VERIFY( x ); // { dg-error "in expansion of macro" }
+ // { dg-error "invalid cast .* to type 'bool'" "" { target *-*-* } 0 }
+}
diff --git a/libstdc++-v3/testsuite/std/time/format/format.cc b/libstdc++-v3/testsuite/std/time/format/format.cc
index d6e3583..00affb9 100644
--- a/libstdc++-v3/testsuite/std/time/format/format.cc
+++ b/libstdc++-v3/testsuite/std/time/format/format.cc
@@ -78,6 +78,13 @@ test_bad_format_strings()
VERIFY( not is_format_string_for("{:%OOy}", t) );
VERIFY( not is_format_string_for("{:%OEy}", t) );
VERIFY( not is_format_string_for("{:%EOy}", t) );
+
+ // weekday and month values for which ok() is false
+ VERIFY( not is_format_string_for("{:%a}", std::chrono::weekday(8)) );
+ VERIFY( not is_format_string_for("{:%A}", std::chrono::weekday(8)) );
+ VERIFY( not is_format_string_for("{:%b}", std::chrono::month(13)) );
+ VERIFY( not is_format_string_for("{:%h}", std::chrono::month(13)) );
+ VERIFY( not is_format_string_for("{:%B}", std::chrono::month(13)) );
}
template<typename I>
diff --git a/libstdc++-v3/testsuite/std/time/format/pr117214_custom_timeput.cc b/libstdc++-v3/testsuite/std/time/format/pr117214_custom_timeput.cc
new file mode 100644
index 0000000..03b9496
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/time/format/pr117214_custom_timeput.cc
@@ -0,0 +1,37 @@
+// { dg-do run { target c++20 } }
+
+#include <chrono>
+#include <format>
+#include <locale>
+#include <testsuite_hooks.h>
+
+struct custom_time_put : std::time_put<char>
+{
+ iter_type
+ do_put(iter_type out, std::ios_base& io, char_type fill, const tm* t,
+ char format, char modifier) const override
+ {
+ using Base = std::time_put<char>;
+
+ switch (format) {
+ case 'a': case 'A': case 'b': case 'h': case 'B': case 'p':
+ *out++ = '[';
+ *out++ = format;
+ *out++ = ']';
+ }
+ return Base::do_put(out, io, fill, t, format, modifier);
+ }
+};
+
+int main()
+{
+ using namespace std::chrono;
+ std::locale loc(std::locale::classic(), new custom_time_put);
+#define test(t, fmt, exp) VERIFY( std::format(loc, fmt, t) == exp )
+ test(Monday, "{:L%a}", "[a]Mon");
+ test(Monday, "{:L%A}", "[A]Monday");
+ test(January, "{:L%b}", "[b]Jan");
+ test(January, "{:L%h}", "[h]Jan");
+ test(January, "{:L%B}", "[B]January");
+ test(1h, "{:L%p}", "[p]AM");
+}
diff --git a/libstdc++-v3/testsuite/util/testsuite_hooks.h b/libstdc++-v3/testsuite/util/testsuite_hooks.h
index faa01ba..bf34fd1 100644
--- a/libstdc++-v3/testsuite/util/testsuite_hooks.h
+++ b/libstdc++-v3/testsuite/util/testsuite_hooks.h
@@ -58,16 +58,13 @@
# define _VERIFY_PRINT(S, F, L, P, C) __builtin_printf(S, F, L, P, C)
#endif
-#define VERIFY(fn) \
- do \
- { \
- if (! (fn)) \
- { \
- _VERIFY_PRINT("%s:%d: %s: Assertion '%s' failed.\n", \
- __FILE__, __LINE__, __PRETTY_FUNCTION__, #fn); \
- __builtin_abort(); \
- } \
- } while (false)
+#define VERIFY(...) \
+ ((void)((__VA_ARGS__) \
+ ? (void)(true ? true : bool(__VA_ARGS__)) \
+ : (_VERIFY_PRINT("%s:%d: %s: Assertion '%s' failed.\n", \
+ __FILE__, __LINE__, __PRETTY_FUNCTION__, \
+ #__VA_ARGS__), \
+ __builtin_abort())))
#ifdef _GLIBCXX_HAVE_UNISTD_H
# include <unistd.h>