[pushed] c++: default mem-init of array [PR103946]
In the patch for PR92385 I added asserts to see if we tried to make a vec_init of a vec_init, but didn't see any in regression testing. This testcase is one case, which seems reasonable: we create a VEC_INIT_EXPR for the aggregate initializer, and then again to express the actual initialization of the member. We already do similar collapsing of TARGET_EXPR. So let's just remove the asserts. PR c++/103946 gcc/cp/ChangeLog: * init.c (build_vec_init): Remove assert. * tree.c (build_vec_init_expr): Likewise. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/nsdmi-array1.C: New test. --- gcc/cp/init.c | 5 + gcc/cp/tree.c | 5 + gcc/testsuite/g++.dg/cpp0x/nsdmi-array1.C | 6 ++ 3 files changed, 8 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/nsdmi-array1.C diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 6226812b470..ccc4f5ece08 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -4369,10 +4369,7 @@ build_vec_init (tree base, tree maxindex, tree init, init = TARGET_EXPR_INITIAL (init); if (init && TREE_CODE (init) == VEC_INIT_EXPR) -{ - gcc_checking_assert (false); - init = VEC_INIT_EXPR_INIT (init); -} +init = VEC_INIT_EXPR_INIT (init); bool direct_init = false; if (from_array && init && BRACE_ENCLOSED_INITIALIZER_P (init) diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 4c1135ba386..d0c6490e42f 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -787,10 +787,7 @@ tree build_vec_init_expr (tree type, tree init, tsubst_flags_t complain) { if (init && TREE_CODE (init) == VEC_INIT_EXPR) -{ - gcc_checking_assert (false); - return init; -} +return init; tree elt_init; if (init && TREE_CODE (init) == CONSTRUCTOR diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-array1.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi-array1.C new file mode 100644 index 000..1ab14359b56 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi-array1.C @@ -0,0 +1,6 @@ +// PR c++/103946 +// { dg-do compile { target c++11 } } + +struct s1 { s1(); }; +class s2 { s1 f1[2]{}; }; +s2 a; base-commit: 75047f79550fd10a8f86f5c72deab10cde77 -- 2.27.0
Re: [PATCH] c++, match.pd: Evaluate in constant evaluation comparisons like + 12 == + 24 [PR89074]
On 1/7/22 07:06, Jakub Jelinek wrote: Hi! The match.pd address_comparison simplification can only handle ADDR_EXPR comparisons possibly converted to some other type (I wonder if we shouldn't restrict it in address_compare to casts to pointer types or pointer-sized integer types, I think we shouldn't optimize (short) () == (short) () because we really don't know whether it will be true or false). On GIMPLE, most of pointer to pointer casts are useless and optimized away and further we have in gimple_fold_stmt_to_constant_1 an optimization that folds p+ const_int into _REF[..., off] On GENERIC, we don't do that and e.g. for constant evaluation it could be pretty harmful if e.g. such pointers are dereferenced, because it can lose what exact field it was starting with etc., all it knows is the base and offset, type and alias set. Instead of teaching the match.pd address_compare about 3 extra variants where one or both compared operands are pointer_plus, this patch attempts to fold operands of comparisons similarly to gimple_fold_stmt_to_constant_1 before calling fold_binary on it. There is another thing though, while we do have (x p+ y) p+ z to x p+ (y + z) simplification which works on GIMPLE well because of the useless pointer conversions, on GENERIC we can have pointer casts in between and at that point we can end up with large expressions like ((type3) (((type2) ((type1) ( + 2) + 2) + 2) + 2)) etc. Pointer-plus doesn't really care what exact pointer type it has as long as it is a pointer, so the following match.pd simplification for GENERIC only (it is useless for GIMPLE) also moves the cast so that nested p+ can be simplified. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? LGTM. Note, I've noticed we don't really diagnose going out of bounds with pointer_plus (unlike e.g. with ARRAY_REF) during constant evaluation, I think another patch for cxx_eval_binary_expression with POINTER_PLUS will be needed. But it isn't clear to me what exactly it should do in case of subobjects. If we start with address of a whole var, (), I guess we should diagnose if the pointer_plus gets before start of the var (i.e. "negative") or 1 byte past the end of the var, but what if we start with or [3] ? For , shall we diagnose out of bounds of field (except perhaps flexible members? or the whole var? The field. And a flexible member has unknown bounds. For ARRAY_REFs, I assume we must at least strip all the outer ARRAY_REFs and so start with too, right? A strict reading suggests that we should complain about going outside the bounds of the inner array, but flattening multidimensional arrays as you suggest seems reasonable as well. 2022-01-07 Jakub Jelinek PR c++/89074 gcc/ * match.pd ((ptr) (x p+ y) p+ z -> (ptr) (x p+ (y + z))): New GENERIC simplification. gcc/cp/ * constexpr.c (cxx_maybe_fold_addr_pointer_plus): New function. (cxx_eval_binary_expression): Use it. gcc/testsuite/ * g++.dg/cpp1y/constexpr-89074-2.C: New test. * g++.dg/cpp1z/constexpr-89074-1.C: New test. --- gcc/match.pd.jj 2022-01-05 20:30:08.768806236 +0100 +++ gcc/match.pd2022-01-06 19:59:53.596114417 +0100 @@ -2143,6 +2143,11 @@ (define_operator_list SYNC_FETCH_AND_AND (simplify (pointer_plus (pointer_plus:s @0 @1) @3) (pointer_plus @0 (plus @1 @3))) +#if GENERIC +(simplify + (pointer_plus (convert:s (pointer_plus:s @0 @1)) @3) + (convert:type (pointer_plus @0 (plus @1 @3 +#endif /* Pattern match tem1 = (long) ptr1; --- gcc/cp/constexpr.c.jj 2022-01-03 10:40:48.403063535 +0100 +++ gcc/cp/constexpr.c 2022-01-06 20:47:44.596623219 +0100 @@ -3288,6 +3288,38 @@ cxx_fold_pointer_plus_expression (const return NULL_TREE; } +/* Try to fold expressions like + (struct S *) ([0].D.2378 + 12) + into + [(void *) + 12B] + This is something normally done by gimple_fold_stmt_to_constant_1 + on GIMPLE, but is undesirable on GENERIC if we are e.g. going to + dereference the address because some details are lost. + For pointer comparisons we want such folding though so that + match.pd address_compare optimization works. */ + +static tree +cxx_maybe_fold_addr_pointer_plus (tree t) +{ + while (CONVERT_EXPR_P (t) +&& POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0 +t = TREE_OPERAND (t, 0); + if (TREE_CODE (t) != POINTER_PLUS_EXPR) +return NULL_TREE; + tree op0 = TREE_OPERAND (t, 0); + tree op1 = TREE_OPERAND (t, 1); + if (TREE_CODE (op1) != INTEGER_CST) +return NULL_TREE; + while (CONVERT_EXPR_P (op0) +&& POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (op0, 0 +op0 = TREE_OPERAND (op0, 0); + if (TREE_CODE (op0) != ADDR_EXPR) +return NULL_TREE; + op1 = fold_convert (ptr_type_node, op1); + tree r = fold_build2 (MEM_REF, TREE_TYPE (TREE_TYPE (op0)), op0, op1); + return build1_loc (EXPR_LOCATION (t), ADDR_EXPR, TREE_TYPE (op0), r); +} + /* Subroutine of
[pushed] c++: destroying delete, throw in new-expr [PR100588]
The standard says that a destroying operator delete is preferred, but that only applies to the delete-expression, not the cleanup if a new-expression initialization throws. As a result of this patch, several of the destroying delete tests don't get EH cleanups, but I'm turning off the warning in cases where the initialization can't throw anyway. It's unclear what should happen if the class does not declare a non-deleting operator delete; a proposal in CWG was to call the global delete, which makes sense to me if the class doesn't declare its own operator new. If it does, we warn and don't call any deallocation function if initialization throws. Tested x86_64-pc-linux-gnu, applying to trunk. PR c++/100588 gcc/cp/ChangeLog: * call.c (build_op_delete_call): Ignore destroying delete if alloc_fn. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/destroying-delete6.C: New test. --- gcc/cp/call.c | 31 ++-- .../g++.dg/cpp2a/destroying-delete5.C | 4 +-- .../g++.dg/cpp2a/destroying-delete6.C | 36 +++ 3 files changed, 67 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp2a/destroying-delete6.C diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 7f7ee88deed..44fc6d0f695 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -7267,6 +7267,8 @@ build_op_delete_call (enum tree_code code, tree addr, tree size, tree oaddr = addr; addr = cp_convert (ptr_type_node, addr, complain); + tree excluded_destroying = NULL_TREE; + if (placement) { /* "A declaration of a placement deallocation function matches the @@ -7352,6 +7354,15 @@ build_op_delete_call (enum tree_code code, tree addr, tree size, dealloc_info di_elt; if (usual_deallocation_fn_p (elt, _elt)) { + /* If we're called for an EH cleanup in a new-expression, we can't + use a destroying delete; the exception was thrown before the + object was constructed. */ + if (alloc_fn && di_elt.destroying) + { + excluded_destroying = elt; + continue; + } + if (!fn) { fn = elt; @@ -7499,6 +7510,14 @@ build_op_delete_call (enum tree_code code, tree addr, tree size, return ret; } + /* If there's only a destroying delete that we can't use because the + object isn't constructed yet, and we used global new, use global + delete as well. */ + if (excluded_destroying + && DECL_NAMESPACE_SCOPE_P (alloc_fn)) +return build_op_delete_call (code, addr, size, true, placement, +alloc_fn, complain); + /* [expr.new] If no unambiguous matching deallocation function can be found, @@ -7508,8 +7527,16 @@ build_op_delete_call (enum tree_code code, tree addr, tree size, { if ((complain & tf_warning) && !placement) - warning (0, "no corresponding deallocation function for %qD", -alloc_fn); + { + bool w = warning (0, + "no corresponding deallocation function for %qD", + alloc_fn); + if (w && excluded_destroying) + inform (DECL_SOURCE_LOCATION (excluded_destroying), "destroying " + "delete %qD cannot be used to release the allocated memory" + " if the initialization throws because the object is not " + "constructed yet", excluded_destroying); + } return NULL_TREE; } diff --git a/gcc/testsuite/g++.dg/cpp2a/destroying-delete5.C b/gcc/testsuite/g++.dg/cpp2a/destroying-delete5.C index 553c964b9e9..6113d7f3d9e 100644 --- a/gcc/testsuite/g++.dg/cpp2a/destroying-delete5.C +++ b/gcc/testsuite/g++.dg/cpp2a/destroying-delete5.C @@ -18,7 +18,7 @@ void * Expression::operator new(std::size_t sz) int i; -void Expression::operator delete(Expression *p, std::destroying_delete_t) +void Expression::operator delete(Expression *p, std::destroying_delete_t) // { dg-message "destroying delete" } { Expression * e = p; ::i = e->i; @@ -28,7 +28,7 @@ void Expression::operator delete(Expression *p, std::destroying_delete_t) int main() { - auto p = new Expression(); + auto p = new Expression(); // { dg-warning "no corresponding dealloc" } p->i = 1; delete p; if (i != 1) diff --git a/gcc/testsuite/g++.dg/cpp2a/destroying-delete6.C b/gcc/testsuite/g++.dg/cpp2a/destroying-delete6.C new file mode 100644 index 000..be783738082 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/destroying-delete6.C @@ -0,0 +1,36 @@ +// PR c++/100588 +// { dg-do run { target c++20 } } + +extern "C" void abort (); +extern "C" int puts (const char *); +#include + +#ifndef DEBUG +#define puts(S) +#endif + +class A { + public: + A() { throw 42; } + ~A() { puts("A::~A"); } + + void operator delete(void* p) { +puts("regular
[PATCH 2/2]: C N2653 char8_t: New tests
This patch provides new tests for the core language and compiler dependent library changes proposed in WG14 N2653 [1] for C2x. Tested on Linux x86_64. gcc/testsuite/ChangeLog: 2021-05-31 Tom Honermann * gcc.dg/atomic/c2x-stdatomic-lockfree-char8_t.c: New test. * gcc.dg/atomic/gnu2x-stdatomic-lockfree-char8_t.c: New test. * gcc.dg/c2x-predefined-macros.c: New test. * gcc.dg/c2x-utf8str-type.c: New test. * gcc.dg/c2x-utf8str.c: New test. * gcc.dg/gnu2x-predefined-macros.c: New test. * gcc.dg/gnu2x-utf8str-type.c: New test. * gcc.dg/gnu2x-utf8str.c: New test. Tom. [1]: WG14 N2653 "char8_t: A type for UTF-8 characters and strings (Revision 1)" http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2653.htm commit f4eee2bf403b62714d1ccb4542b8c85dc552a411 Author: Tom Honermann Date: Sun Jan 2 00:26:17 2022 -0500 N2653 char8_t for C: New tests This change provides new tests for the core language and compiler dependent library changes proposed in WG14 N2653 for C. diff --git a/gcc/testsuite/gcc.dg/atomic/c2x-stdatomic-lockfree-char8_t.c b/gcc/testsuite/gcc.dg/atomic/c2x-stdatomic-lockfree-char8_t.c new file mode 100644 index 000..37ea4c8926c --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic/c2x-stdatomic-lockfree-char8_t.c @@ -0,0 +1,42 @@ +/* Test atomic_is_lock_free for char8_t. */ +/* { dg-do run } */ +/* { dg-options "-std=c2x -D_ISOC2X_SOURCE -pedantic-errors" } */ + +#include +#include + +extern void abort (void); + +_Atomic __CHAR8_TYPE__ ac8a; +atomic_char8_t ac8t; + +#define CHECK_TYPE(MACRO, V1, V2) \ + do \ +{ \ + int r1 = MACRO;\ + int r2 = atomic_is_lock_free (); \ + int r3 = atomic_is_lock_free (); \ + if (r1 != 0 && r1 != 1 && r1 != 2) \ + abort ();\ + if (r2 != 0 && r2 != 1) \ + abort ();\ + if (r3 != 0 && r3 != 1) \ + abort ();\ + if (r1 == 2 && r2 != 1) \ + abort ();\ + if (r1 == 2 && r3 != 1) \ + abort ();\ + if (r1 == 0 && r2 != 0) \ + abort ();\ + if (r1 == 0 && r3 != 0) \ + abort ();\ +} \ + while (0) + +int +main () +{ + CHECK_TYPE (ATOMIC_CHAR8_T_LOCK_FREE, ac8a, ac8t); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/atomic/gnu2x-stdatomic-lockfree-char8_t.c b/gcc/testsuite/gcc.dg/atomic/gnu2x-stdatomic-lockfree-char8_t.c new file mode 100644 index 000..a017b134817 --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic/gnu2x-stdatomic-lockfree-char8_t.c @@ -0,0 +1,5 @@ +/* Test atomic_is_lock_free for char8_t with -std=gnu2x. */ +/* { dg-do run } */ +/* { dg-options "-std=gnu2x -D_GNU_SOURCE -pedantic-errors" } */ + +#include "c2x-stdatomic-lockfree-char8_t.c" diff --git a/gcc/testsuite/gcc.dg/c2x-predefined-macros.c b/gcc/testsuite/gcc.dg/c2x-predefined-macros.c new file mode 100644 index 000..c88e51b54c5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c2x-predefined-macros.c @@ -0,0 +1,11 @@ +/* Test C2x predefined macros. */ +/* { dg-do compile } */ +/* { dg-options "-std=c2x" } */ + +#if !defined(__CHAR8_TYPE__) +# error __CHAR8_TYPE__ is not defined! +#endif + +#if !defined(__GCC_ATOMIC_CHAR8_T_LOCK_FREE) +# error __GCC_ATOMIC_CHAR8_T_LOCK_FREE is not defined! +#endif diff --git a/gcc/testsuite/gcc.dg/c2x-utf8str-type.c b/gcc/testsuite/gcc.dg/c2x-utf8str-type.c new file mode 100644 index 000..76559c0b19b --- /dev/null +++ b/gcc/testsuite/gcc.dg/c2x-utf8str-type.c @@ -0,0 +1,6 @@ +/* Test C2x UTF-8 string literal type. */ +/* { dg-do compile } */ +/* { dg-options "-std=c2x" } */ + +_Static_assert (_Generic (u8"text", char*: 1, unsigned char*: 2) == 2, "UTF-8 string literals have an unexpected type"); +_Static_assert (_Generic (u8"x"[0], char: 1, unsigned char: 2) == 2, "UTF-8 string literal elements have an unexpected type"); diff --git a/gcc/testsuite/gcc.dg/c2x-utf8str.c b/gcc/testsuite/gcc.dg/c2x-utf8str.c new file mode 100644 index 000..712482c6569 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c2x-utf8str.c @@ -0,0 +1,34 @@ +/* Test initialization by UTF-8 string literal in C2x. */ +/* { dg-do compile } */ +/* { dg-require-effective-target wchar } */ +/* { dg-options "-std=c2x" } */ + +typedef __CHAR8_TYPE__ char8_t; +typedef __CHAR16_TYPE__ char16_t; +typedef __CHAR32_TYPE__ char32_t; +typedef __WCHAR_TYPE__ wchar_t; + +/* Test that char, signed char, unsigned char, and char8_t arrays can be + initialized by a UTF-8 string literal. */ +const char cbuf1[] = u8"text"; +const char cbuf2[] = { u8"text" }; +const signed char scbuf1[] = u8"text"; +const signed char scbuf2[] = { u8"text" }; +const unsigned char ucbuf1[] = u8"text"; +const unsigned char ucbuf2[] = { u8"text" }; +const char8_t c8buf1[] = u8"text"; +const char8_t c8buf2[] = { u8"text" }; + +/* Test that a diagnostic is issued for attempted initialization of + other character types by a UTF-8 string literal. */ +const char16_t c16buf1[] = u8"text"; /* { dg-error "from
[PATCH 1/2]: C N2653 char8_t: Language support
This patch implements the core language and compiler dependent library changes proposed in WG14 N2653 [1] for C2x. The changes include: - Change of type for UTF-8 string literals from array of char to array of char8_t (unsigned char) when targeting C2x. - A new atomic_char8_t typedef. - A new ATOMIC_CHAR8_T_LOCK_FREE macro defined in terms of the existing __GCC_ATOMIC_CHAR8_T_LOCK_FREE predefined macro. Tested on Linux x86_64. gcc/ChangeLog: 2022-01-07 Tom Honermann * ginclude/stdatomic.h (atomic_char8_t, ATOMIC_CHAR8_T_LOCK_FREE): New typedef and macro. gcc/c/ChangeLog: 2022-01-07 Tom Honermann * c-parser.c (c_parser_string_literal): Use char8_t as the type of CPP_UTF8STRING when char8_t support is enabled. * c-typeck.c (digest_init): Allow initialization of an array of character type by a string literal with type array of char8_t. gcc/c-family/ChangeLog: 2022-01-07 Tom Honermann * c-lex.c (lex_string, lex_charconst): Use char8_t as the type of CPP_UTF8CHAR and CPP_UTF8STRING when char8_t support is enabled. * c-opts.c (c_common_post_options): Set flag_char8_t if targeting C2x. Tom. [1]: WG14 N2653 "char8_t: A type for UTF-8 characters and strings (Revision 1)" http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2653.htm commit c041cce5d262908349be3f1f2e361c824db15845 Author: Tom Honermann Date: Sat Jan 1 18:10:41 2022 -0500 N2653 char8_t for C: Language support This patch implements the core language and compiler dependent library changes proposed in WG14 N2653 for C2X. The changes include: - Change of type for UTF-8 string literals from array of const char to array of const char8_t (unsigned char). - A new atomic_char8_t typedef. - A new ATOMIC_CHAR8_T_LOCK_FREE macro defined in terms of the existing __GCC_ATOMIC_CHAR8_T_LOCK_FREE predefined macro. diff --git a/gcc/c-family/c-lex.c b/gcc/c-family/c-lex.c index 2651331e683..0b3debbb9bd 100644 --- a/gcc/c-family/c-lex.c +++ b/gcc/c-family/c-lex.c @@ -1352,7 +1352,14 @@ lex_string (const cpp_token *tok, tree *valp, bool objc_string, bool translate) default: case CPP_STRING: case CPP_UTF8STRING: - value = build_string (1, ""); + if (type == CPP_UTF8STRING && flag_char8_t) + { + value = build_string (TYPE_PRECISION (char8_type_node) +/ TYPE_PRECISION (char_type_node), +""); /* char8_t is 8 bits */ + } + else + value = build_string (1, ""); break; case CPP_STRING16: value = build_string (TYPE_PRECISION (char16_type_node) @@ -1425,10 +1432,10 @@ lex_charconst (const cpp_token *token) type = char16_type_node; else if (token->type == CPP_UTF8CHAR) { - if (!c_dialect_cxx ()) - type = unsigned_char_type_node; - else if (flag_char8_t) + if (flag_char8_t) type = char8_type_node; + else if (!c_dialect_cxx ()) + type = unsigned_char_type_node; else type = char_type_node; } diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c index 4c20e44f5b5..bd96e1319ad 100644 --- a/gcc/c-family/c-opts.c +++ b/gcc/c-family/c-opts.c @@ -1060,9 +1060,9 @@ c_common_post_options (const char **pfilename) if (flag_sized_deallocation == -1) flag_sized_deallocation = (cxx_dialect >= cxx14); - /* char8_t support is new in C++20. */ + /* char8_t support is implicitly enabled in C++20 and C2x. */ if (flag_char8_t == -1) -flag_char8_t = (cxx_dialect >= cxx20); +flag_char8_t = (cxx_dialect >= cxx20) || flag_isoc2x; if (flag_extern_tls_init) { diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index b09ad307acd..4239633e295 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -7439,7 +7439,14 @@ c_parser_string_literal (c_parser *parser, bool translate, bool wide_ok) default: case CPP_STRING: case CPP_UTF8STRING: - value = build_string (1, ""); + if (type == CPP_UTF8STRING && flag_char8_t) + { + value = build_string (TYPE_PRECISION (char8_type_node) +/ TYPE_PRECISION (char_type_node), +""); /* char8_t is 8 bits */ + } + else + value = build_string (1, ""); break; case CPP_STRING16: value = build_string (TYPE_PRECISION (char16_type_node) @@ -7464,9 +7471,14 @@ c_parser_string_literal (c_parser *parser, bool translate, bool wide_ok) { default: case CPP_STRING: -case CPP_UTF8STRING: TREE_TYPE (value) = char_array_type_node; break; +case CPP_UTF8STRING: + if (flag_char8_t) + TREE_TYPE (value) = char8_array_type_node; + else + TREE_TYPE (value) = char_array_type_node; + break; case CPP_STRING16: TREE_TYPE (value) = char16_array_type_node; break; diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index 78a6c68aaa6..b4eeea545a9 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -8028,7 +8028,7 @@ digest_init (location_t init_loc, tree type,
[PATCH 0/2]: C N2653 char8_t implementation
This series of patches implements the core language features for the WG14 N2653 [1] proposal to provide char8_t support in C. These changes are intended to align char8_t support in C with the support provided in C++20 via WG21 P0482R6 [2]. These patches addresses feedback provided in response to a previous submission [3][4]. These changes do not impact default gcc behavior. Per prior feedback by Joseph Myers, the existing -fchar8_t and -fno-char8_t options used to opt-in to or opt-out of char8_t support in C++ are NOT reused for C. Instead, the C related core language changes are enabled when targeting C2x. Note that N2653 has not yet been accepted by WG14 for C2x, but the patches enable these changes for C2x in order to avoid an additional language dialect flag (e.g., -fchar8_t). Patch 1: Language support Patch 2: New tests Tom. [1]: WG14 N2653 "char8_t: A type for UTF-8 characters and strings (Revision 1)" http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2653.htm [2]: WG21 P0482R6 "char8_t: A type for UTF-8 characters and strings (Revision 6)" https://wg21.link/p0482r6 [3]: [PATCH 0/3]: C N2653 char8_t implementation https://gcc.gnu.org/pipermail/gcc-patches/2021-June/572022.html [4]: [PATCH 1/3]: C N2653 char8_t: Language support https://gcc.gnu.org/pipermail/gcc-patches/2021-June/572023.html
[PATCH] C++ P0482R6 char8_t: declare std::c8rtomb and std::mbrtoc8 if provided by the C library
This patch completes implementation of the C++20 proposal P0482R6 [1] by adding declarations of std::c8rtomb() and std::mbrtoc8() in if provided by the C library in . This patch addresses feedback provided in response to a previous patch submission [2]. Autoconf changes determine if the C library declares c8rtomb and mbrtoc8 at global scope when uchar.h is included and compiled with either -fchar8_t or -std=c++20. New _GLIBCXX_USE_UCHAR_C8RTOMB_MBRTOC8_FCHAR8_T and _GLIBCXX_USE_UCHAR_C8RTOMB_MBRTOC8_CXX20 configuration macros reflect the probe results. The header declares these functions in the std namespace only if available and the _GLIBCXX_USE_CHAR8_T configuration macro is defined (by default it is defined if the C++20 __cpp_char8_t feature test macro is defined) Patches to glibc to implement c8rtomb and mbrtoc8 have been submitted [3]. New tests validate the presence of these declarations. The tests pass trivially if the C library does not provide these functions. Otherwise they ensure that the functions are declared when is included and either -fchar8_t or -std=c++20 is enabled. Tested on Linux x86_64. libstdc++-v3/ChangeLog: 2022-01-07 Tom Honermann * acinclude.m4 Define config macros if uchar.h provides c8rtomb() and mbrtoc8(). * config.h.in: Re-generate. * configure: Re-generate. * include/c_compatibility/uchar.h: Declare ::c8rtomb and ::mbrtoc8. * include/c_global/cuchar: Declare std::c8rtomb and std::mbrtoc8. * include/c_std/cuchar: Declare std::c8rtomb and std::mbrtoc8. * testsuite/21_strings/headers/cuchar/functions_std_cxx20.cc: New test. * testsuite/21_strings/headers/cuchar/functions_std_fchar8_t.cc: New test. Tom. [1]: WG21 P0482R6 "char8_t: A type for UTF-8 characters and strings (Revision 6)" https://wg21.link/p0482r6 [2]: [PATCH] C++ P0482R6 char8_t: declare std::c8rtomb and std::mbrtoc8 if provided by the C library https://gcc.gnu.org/pipermail/libstdc++/2021-June/052685.html [3]: "C++20 P0482R6 and C2X N2653" [Patch 0/3]: https://sourceware.org/pipermail/libc-alpha/2022-January/135061.html [Patch 1/3]: https://sourceware.org/pipermail/libc-alpha/2022-January/135062.html [Patch 2/3]: https://sourceware.org/pipermail/libc-alpha/2022-January/135063.html [Patch 3/3]: https://sourceware.org/pipermail/libc-alpha/2022-January/135064.html Tom. commit 3d40bc9bf5c79343ea5a6cc355539542f4b56c9b Author: Tom Honermann Date: Sat Jan 1 17:26:31 2022 -0500 P0482R6 char8_t: declare std::c8rtomb and std::mbrtoc8 if provided by the C library. This change completes implementation of the C++20 proposal P0482R6 by adding declarations of std::c8rtomb() and std::mbrtoc8() if provided by the C library. Autoconf changes determine if the C library declares c8rtomb and mbrtoc8 at global scope when uchar.h is included and compiled with either -fchar8_t or -std=c++20 enabled; new _GLIBCXX_USE_UCHAR_C8RTOMB_MBRTOC8_FCHAR8_T and _GLIBCXX_USE_UCHAR_C8RTOMB_MBRTOC8_CXX20 configuration macros are defined accordingly. The header declares these functions in the std namespace only if available and the _GLIBCXX_USE_CHAR8_T configuration macro is defined (by default it is defined if the C++20 __cpp_char8_t feature test macro is defined). New tests validate the presence of these declarations. The tests pass trivially if the C library does not provide these functions. Otherwise they ensure that the functions are declared when is included and either -fchar8_t or -std=c++20 is enabled. diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4 index 635168d7e25..85235005c7e 100644 --- a/libstdc++-v3/acinclude.m4 +++ b/libstdc++-v3/acinclude.m4 @@ -2039,6 +2039,50 @@ AC_DEFUN([GLIBCXX_CHECK_UCHAR_H], [ namespace std in .]) fi + CXXFLAGS="$CXXFLAGS -fchar8_t" + if test x"$ac_has_uchar_h" = x"yes"; then +AC_MSG_CHECKING([for c8rtomb and mbrtoc8 in with -fchar8_t]) +AC_TRY_COMPILE([#include + namespace test + { + using ::c8rtomb; + using ::mbrtoc8; + } + ], + [], [ac_uchar_c8rtomb_mbrtoc8_fchar8_t=yes], + [ac_uchar_c8rtomb_mbrtoc8_fchar8_t=no]) + else +ac_uchar_c8rtomb_mbrtoc8_fchar8_t=no + fi + AC_MSG_RESULT($ac_uchar_c8rtomb_mbrtoc8_fchar8_t) + if test x"$ac_uchar_c8rtomb_mbrtoc8_fchar8_t" = x"yes"; then +AC_DEFINE(_GLIBCXX_USE_UCHAR_C8RTOMB_MBRTOC8_FCHAR8_T, 1, + [Define if c8rtomb and mbrtoc8 functions in should be + imported into namespace std in for -fchar8_t.]) + fi + + CXXFLAGS="$CXXFLAGS -std=c++20" + if test x"$ac_has_uchar_h" = x"yes"; then +AC_MSG_CHECKING([for c8rtomb and mbrtoc8 in with -std=c++20]) +AC_TRY_COMPILE([#include + namespace test + { + using ::c8rtomb; + using ::mbrtoc8; + } + ], + [],
[PATCH] PR 102935, Fix pr101384-1.c code generation test.
Fix pr101384-1.c code generation test. Add support for the compiler using XXSPLTIB reg,255 to load all 1's into a register on power9 and above instead of using VSPLTI{B,H,W} reg,-1. gcc/testsuite/ 2022-01-07 Michael Meissner PR testsuite/102935 * gcc.target/powerpc/pr101384-1.c: Update insn regexp for power9 and power10. --- gcc/testsuite/gcc.target/powerpc/pr101384-1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/testsuite/gcc.target/powerpc/pr101384-1.c b/gcc/testsuite/gcc.target/powerpc/pr101384-1.c index 627d7d76721..41cf84bf8bc 100644 --- a/gcc/testsuite/gcc.target/powerpc/pr101384-1.c +++ b/gcc/testsuite/gcc.target/powerpc/pr101384-1.c @@ -2,7 +2,7 @@ /* { dg-do compile { target le } } */ /* { dg-options "-O2 -maltivec" } */ /* { dg-require-effective-target powerpc_altivec_ok } */ -/* { dg-final { scan-assembler-times {\mvspltis[whb] [^\n\r]*,-1\M} 9 } } */ +/* { dg-final { scan-assembler-times {\mvspltis[whb] [^\n\r]*,-1\M|\mxxspltib[^\n\r]*,255\M} 9 } } */ /* { dg-final { scan-assembler-times {\mvslw\M} 3 } } */ /* { dg-final { scan-assembler-times {\mvslh\M} 3 } } */ /* { dg-final { scan-assembler-times {\mvslb\M} 3 } } */ -- 2.33.1 -- Michael Meissner, IBM PO Box 98, Ayer, Massachusetts, USA, 01432 email: meiss...@linux.ibm.com
[committed] analyzer: add logging of aliasing
Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu. Pushed to trunk as 11a2ff8d981110e1562caf7d98e41c1ff2e76056. gcc/analyzer/ChangeLog: * engine.cc (impl_run_checkers): Pass logger to engine ctor. * region-model-manager.cc (region_model_manager::region_model_manager): Add logger param and use it to initialize m_logger. * region-model.cc (engine::engine): New. * region-model.h (region_model_manager::region_model_manager): Add logger param. (region_model_manager::get_logger): New. (region_model_manager::m_logger): New field. (engine::engine): New. * store.cc (store_manager::get_logger): New. (store::set_value): Log scope. Log when marking a cluster as unknown due to possible aliasing. * store.h (store_manager::get_logger): New decl. --- gcc/analyzer/engine.cc | 2 +- gcc/analyzer/region-model-manager.cc | 5 +++-- gcc/analyzer/region-model.cc | 7 +++ gcc/analyzer/region-model.h | 7 ++- gcc/analyzer/store.cc| 21 + gcc/analyzer/store.h | 2 ++ 6 files changed, 40 insertions(+), 4 deletions(-) diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc index 0d456a14639..346b65973b2 100644 --- a/gcc/analyzer/engine.cc +++ b/gcc/analyzer/engine.cc @@ -5329,7 +5329,7 @@ impl_run_checkers (logger *logger) FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node) node->get_untransformed_body (); - engine eng; + engine eng (logger); /* Create the supergraph. */ supergraph sg (logger); diff --git a/gcc/analyzer/region-model-manager.cc b/gcc/analyzer/region-model-manager.cc index 19e1a93b89e..998bbe7858c 100644 --- a/gcc/analyzer/region-model-manager.cc +++ b/gcc/analyzer/region-model-manager.cc @@ -66,8 +66,9 @@ namespace ana { /* region_model_manager's ctor. */ -region_model_manager::region_model_manager () -: m_next_region_id (0), +region_model_manager::region_model_manager (logger *logger) +: m_logger (logger), + m_next_region_id (0), m_root_region (alloc_region_id ()), m_stack_region (alloc_region_id (), _root_region), m_heap_region (alloc_region_id (), _root_region), diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc index cb86d79c99d..8708a91551d 100644 --- a/gcc/analyzer/region-model.cc +++ b/gcc/analyzer/region-model.cc @@ -3965,6 +3965,13 @@ rejected_ranges_constraint::dump_to_pp (pretty_printer *pp) const /* class engine. */ +/* engine's ctor. */ + +engine::engine (logger *logger) +: m_mgr (logger) +{ +} + /* Dump the managed objects by class to LOGGER, and the per-class totals. */ void diff --git a/gcc/analyzer/region-model.h b/gcc/analyzer/region-model.h index 669f1c748ce..b1fa4fc82af 100644 --- a/gcc/analyzer/region-model.h +++ b/gcc/analyzer/region-model.h @@ -240,7 +240,7 @@ namespace ana { class region_model_manager { public: - region_model_manager (); + region_model_manager (logger *logger = NULL); ~region_model_manager (); /* svalue consolidation. */ @@ -335,6 +335,8 @@ public: void enable_complexity_check (void) { m_check_complexity = true; } void disable_complexity_check (void) { m_check_complexity = false; } + logger *get_logger () const { return m_logger; } + private: bool too_complex_p (const complexity ) const; bool reject_if_too_complex (svalue *sval); @@ -358,6 +360,8 @@ private: const svalue *maybe_fold_asm_output_svalue (tree type, const vec ); + logger *m_logger; + unsigned m_next_region_id; root_region m_root_region; stack_region m_stack_region; @@ -1080,6 +1084,7 @@ private: class engine { public: + engine (logger *logger = NULL); region_model_manager *get_model_manager () { return _mgr; } void log_stats (logger *logger) const; diff --git a/gcc/analyzer/store.cc b/gcc/analyzer/store.cc index 3f91b6107a9..ade6dec624d 100644 --- a/gcc/analyzer/store.cc +++ b/gcc/analyzer/store.cc @@ -1987,6 +1987,12 @@ binding_cluster::maybe_get_simple_value (store_manager *mgr) const /* class store_manager. */ +logger * +store_manager::get_logger () const +{ + return m_mgr->get_logger (); +} + /* binding consolidation. */ const concrete_binding * @@ -2353,6 +2359,9 @@ store::set_value (store_manager *mgr, const region *lhs_reg, const svalue *rhs_sval, uncertainty_t *uncertainty) { + logger *logger = mgr->get_logger (); + LOG_SCOPE (logger); + remove_overlapping_bindings (mgr, lhs_reg); rhs_sval = simplify_for_binding (rhs_sval); @@ -2405,6 +2414,18 @@ store::set_value (store_manager *mgr, const region *lhs_reg, gcc_unreachable (); case tristate::TS_UNKNOWN: + if (logger) + { + pretty_printer *pp = logger->get_printer (); + logger->start_log_line (); +
[committed] analyzer: implement __analyzer_dump_escaped
PR analyzer/103546 seems to involve an issue in how the analyzer tracks which decls have escaped, so this patch adds a way to directly test this from DejaGnu. Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu. Pushed to trunk as r12-6377-g4409152a4acaec5b58a93996088d0df9aaa779b8. gcc/analyzer/ChangeLog: * region-model-impl-calls.cc (cmp_decls): New. (cmp_decls_ptr_ptr): New. (region_model::impl_call_analyzer_dump_escaped): New. * region-model.cc (region_model::on_stmt_pre): Handle __analyzer_dump_escaped. * region-model.h (region_model::impl_call_analyzer_dump_escaped): New decl. * store.h (binding_cluster::get_base_region): New accessor. gcc/ChangeLog: * doc/analyzer.texi (Special Functions for Debugging the Analyzer): Document __analyzer_dump_escaped. gcc/testsuite/ChangeLog: * gcc.dg/analyzer/analyzer-decls.h (__analyzer_dump_escaped): New decl. * gcc.dg/analyzer/escaping-1.c: New test. --- gcc/analyzer/region-model-impl-calls.cc | 69 +++ gcc/analyzer/region-model.cc | 2 + gcc/analyzer/region-model.h | 1 + gcc/analyzer/store.h | 2 + gcc/doc/analyzer.texi | 8 +++ .../gcc.dg/analyzer/analyzer-decls.h | 3 + gcc/testsuite/gcc.dg/analyzer/escaping-1.c| 27 7 files changed, 112 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/analyzer/escaping-1.c diff --git a/gcc/analyzer/region-model-impl-calls.cc b/gcc/analyzer/region-model-impl-calls.cc index 9063acd6be5..c20058ec778 100644 --- a/gcc/analyzer/region-model-impl-calls.cc +++ b/gcc/analyzer/region-model-impl-calls.cc @@ -264,6 +264,75 @@ region_model::impl_call_analyzer_dump_capacity (const gcall *call, warning_at (call->location, 0, "capacity: %qs", desc.m_buffer); } +/* Compare D1 and D2 using their names, and then IDs to order them. */ + +static int +cmp_decls (tree d1, tree d2) +{ + gcc_assert (DECL_P (d1)); + gcc_assert (DECL_P (d2)); + if (DECL_NAME (d1) && DECL_NAME (d2)) +if (int cmp = strcmp (IDENTIFIER_POINTER (DECL_NAME (d1)), + IDENTIFIER_POINTER (DECL_NAME (d2 + return cmp; + return (int)DECL_UID (d1) - (int)DECL_UID (d2); +} + +/* Comparator for use by vec::qsort, + using their names, and then IDs to order them. */ + +static int +cmp_decls_ptr_ptr (const void *p1, const void *p2) +{ + tree const *d1 = (tree const *)p1; + tree const *d2 = (tree const *)p2; + + return cmp_decls (*d1, *d2); +} + +/* Handle a call to "__analyzer_dump_escaped". + + Emit a warning giving the number of decls that have escaped, followed + by a comma-separated list of their names, in alphabetical order. + + This is for use when debugging, and may be of use in DejaGnu tests. */ + +void +region_model::impl_call_analyzer_dump_escaped (const gcall *call) +{ + auto_vec escaped_decls; + for (auto iter : m_store) +{ + const binding_cluster *c = iter.second; + if (!c->escaped_p ()) + continue; + if (tree decl = c->get_base_region ()->maybe_get_decl ()) + escaped_decls.safe_push (decl); +} + + /* Sort them into deterministic order; alphabetical is + probably most user-friendly. */ + escaped_decls.qsort (cmp_decls_ptr_ptr); + + pretty_printer pp; + pp_format_decoder () = default_tree_printer; + pp_show_color () = pp_show_color (global_dc->printer); + bool first = true; + for (auto iter : escaped_decls) +{ + if (first) + first = false; + else + pp_string (, ", "); + pp_printf (, "%qD", iter); +} + /* Print the number to make it easier to write DejaGnu tests for + the "nothing has escaped" case. */ + warning_at (call->location, 0, "escaped: %i: %s", + escaped_decls.length (), + pp_formatted_text ()); +} + /* Handle a call to "__analyzer_eval" by evaluating the input and dumping as a dummy warning, so that test cases can use dg-warning to validate the result (and so unexpected warnings will diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc index b7371948873..cb86d79c99d 100644 --- a/gcc/analyzer/region-model.cc +++ b/gcc/analyzer/region-model.cc @@ -999,6 +999,8 @@ region_model::on_stmt_pre (const gimple *stmt, impl_call_analyzer_describe (call, ctxt); else if (is_special_named_call_p (call, "__analyzer_dump_capacity", 1)) impl_call_analyzer_dump_capacity (call, ctxt); + else if (is_special_named_call_p (call, "__analyzer_dump_escaped", 0)) + impl_call_analyzer_dump_escaped (call); else if (is_special_named_call_p (call, "__analyzer_dump_path", 0)) { /* Handle the builtin "__analyzer_dump_path" by queuing a diff --git a/gcc/analyzer/region-model.h b/gcc/analyzer/region-model.h index 8e35be1f180..669f1c748ce 100644 ---
[committed] analyzer: add region::is_named_decl_p
This patch adds a debug function that I've found handy when debugging a problem with handling the decl yy_buffer_stack" in PR analyzer/103546. Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu. Pushed to trunk as r12-6376-gc1b7d28a5987e74232b7f054849f8bd8ccc7e7de. gcc/analyzer/ChangeLog: * region.cc (region::is_named_decl_p): New. * region.h (region::is_named_decl_p): New decl. gcc/ChangeLog: * doc/analyzer.texi (Other Debugging Techniques): Document region::is_named_decl_p. --- gcc/analyzer/region.cc | 14 ++ gcc/analyzer/region.h | 2 ++ gcc/doc/analyzer.texi | 10 ++ 3 files changed, 26 insertions(+) diff --git a/gcc/analyzer/region.cc b/gcc/analyzer/region.cc index befcaa495cd..161e7e1fb10 100644 --- a/gcc/analyzer/region.cc +++ b/gcc/analyzer/region.cc @@ -638,6 +638,20 @@ region::symbolic_for_unknown_ptr_p () const return false; } +/* Return true if this is a region for a decl with name DECL_NAME. + Intended for use when debugging (for assertions and conditional + breakpoints). */ + +DEBUG_FUNCTION bool +region::is_named_decl_p (const char *decl_name) const +{ + if (tree decl = maybe_get_decl ()) +if (DECL_NAME (decl) + && !strcmp (IDENTIFIER_POINTER (DECL_NAME (decl)), decl_name)) + return true; + return false; +} + /* region's ctor. */ region::region (complexity c, unsigned id, const region *parent, tree type) diff --git a/gcc/analyzer/region.h b/gcc/analyzer/region.h index fbb50a1817a..d97bbc1e3f1 100644 --- a/gcc/analyzer/region.h +++ b/gcc/analyzer/region.h @@ -189,6 +189,8 @@ public: const complexity _complexity () const { return m_complexity; } + bool is_named_decl_p (const char *decl_name) const; + protected: region (complexity c, unsigned id, const region *parent, tree type); diff --git a/gcc/doc/analyzer.texi b/gcc/doc/analyzer.texi index 657798101c2..62faac44d7f 100644 --- a/gcc/doc/analyzer.texi +++ b/gcc/doc/analyzer.texi @@ -545,3 +545,13 @@ and the exploded graph in compressed JSON form. One approach when tracking down where a particular bogus state is introduced into the @code{exploded_graph} is to add custom code to @code{program_state::validate}. + +The debug function @code{region::is_named_decl_p} can be used when debugging, +such as for assertions and conditional breakpoints. For example, when +tracking down a bug in handling a decl called @code{yy_buffer_stack}, I +temporarily added a: +@smallexample + gcc_assert (!m_base_region->is_named_decl_p ("yy_buffer_stack")); +@end smallexample +to @code{binding_cluster::mark_as_escaped} to trap a point where +@code{yy_buffer_stack} was mistakenly being treated as having escaped. -- 2.26.3
Re: [Patch][V2]Enable -Wuninitialized + -ftrivial-auto-var-init for address taken variables
> On Jan 5, 2022, at 10:59 AM, Qing Zhao via Gcc-patches > wrote: > > Hi, Richard, > > Thanks a lot for the review and questions. > See my reply embedded below: > > >> On Jan 5, 2022, at 4:33 AM, Richard Biener >> wrote: >> >> On Thu, Dec 16, 2021 at 5:00 PM Qing Zhao wrote: >>> >>> Hi, >>> >>> This is the 2nd version of the patch. >>> The original patch is at: >>> >>> https://gcc.gnu.org/pipermail/gcc-patches/2021-December/586341.html >>> >>> In addition to resolve the two issues mentioned in the original patch, >>> This patch also can be used as a very good workaround for the issue in >>> PR103720 >>> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103720 >>> >>> And as I checked, the patch can fix all the bogus uninitialized warnings >>> when >>> building kernel with -O2 + -ftrivial-auto-var-init=zero + -Wuninitialized. >>> >>> So, this is a very important patch that need to be included into gcc12. >>> >>> Compared to the 1st patch, the major changes are to resolve Martin’s >>> comments on >>> tree-ssa-uninit.c >>> >>> 1. Add some meaningful temporaries to break the long expression to make it >>>Readable. And also add comments to explain the purpose of the statement; >>> >>> 2. Resolve the memory leakage of the dynamically created string. >>> >>> The patch has been bootstrapped and regressing tested on both x86 and >>> aarch64, no issues. >>> Okay for commit? >> >> tree decl_name >> += build_string_literal (IDENTIFIER_LENGTH (DECL_NAME (decl)) + 1, >> + IDENTIFIER_POINTER (DECL_NAME (decl))); >> >> you need to deal with DECL_NAME being NULL. > > Okay. > Usually under what situation, the decl_name will be NULL? Anyway, I made the following change in gimplify.c to address this concern: [opc@qinzhao-ol8u3-x86 gcc]$ git diff diff --git a/gcc/gimplify.c b/gcc/gimplify.c index cc6b643312e..a9714c9f9c4 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -1764,9 +1764,12 @@ gimple_add_init_for_auto_var (tree decl, tree init_type_node = build_int_cst (integer_type_node, (int) init_type); + const char *decl_name_str = DECL_NAME (decl) + ? IDENTIFIER_POINTER (DECL_NAME (decl)) + : ""; tree decl_name -= build_string_literal (IDENTIFIER_LENGTH (DECL_NAME (decl)) + 1, - IDENTIFIER_POINTER (DECL_NAME (decl))); += build_string_literal (strlen (decl_name_str) + 1, + decl_name_str); Let me know if you see any issue with this solution. > >> It's also a bit awkward >> to build another >> copy of all decl names :/ > > Yes, this is awkward. But it might be unavoidable for address taken variables > since the original variable might be completely deleted by optimizations. > See the details at: > https://gcc.gnu.org/pipermail/gcc-patches/2021-August/577431.html > > We had a previous discussion on this issue, and the idea of adding this 3rd > argument with the name of the variable was proposed by you at that time. -:) > And I think that’s a good solution to this problem. > > >> The changes in the uninit warning are also >> quite ugly, refactoring >> things to always pass down a name / location pair might improve that >> (but I'd like to >> understand the case to fix first). > > I will try this idea to see whether it will work. Martin Sebor raised the similar concern and similar suggestions in the previous round of review, and I tried to pass the name string and use “%qs” consistently. However, that didn’t work since there are some special cases that %qD handles specially other than %qs. There were multiple testing cases failed after the change. In order to resolve the regression, we have to copy multiple details from the handling of “%D” to uninit warning. Please see: https://gcc.gnu.org/pipermail/gcc-patches/2021-December/586814.html For more details. > >> >> + /* The LHS of the call is a temporary variable, we use it as a >> +placeholder to record the information on whether the warning >> +has been issued or not. */ >> + repl_var = gimple_call_lhs (def_stmt); >> >> this seems to be a change that can be done independently? > > The major purpose of this “repl_var” is used to record the info whether the > warning has been issued for the variable or not, then avoid emitting it again > later. > Since the original variable has been completely deleted by optimization, we > have to use this “repl_var” for a placeholder to record such info. >> >> + /* Ignore the call to .DEFERRED_INIT that define the original >> +var itself. */ >> + if (is_gimple_assign (context)) >> + { >> + if (TREE_CODE (gimple_assign_lhs (context)) == VAR_DECL) >> + lhs_var = gimple_assign_lhs (context); >> + else if (TREE_CODE (gimple_assign_lhs (context)) == SSA_NAME) >> + lhs_var = SSA_NAME_VAR
[pushed] c++: check delete access with trivial init [PR20040]
Apparently we need to check the accessibility of the deallocation function even if there is no initialization. Tested x86_64-pc-linux-gnu, applying to trunk. PR c++/20040 gcc/cp/ChangeLog: * init.c (build_new_1): Also build pointer cleanup if TYPE_GETS_DELETE. * cp-tree.h (TYPE_GETS_VEC_DELETE): New. gcc/testsuite/ChangeLog: * g++.dg/init/delete4.C: New test. --- gcc/cp/cp-tree.h| 1 + gcc/cp/init.c | 142 +++- gcc/testsuite/g++.dg/init/delete4.C | 14 +++ 3 files changed, 89 insertions(+), 68 deletions(-) create mode 100644 gcc/testsuite/g++.dg/init/delete4.C diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index e204182da97..f8225c18a48 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -2395,6 +2395,7 @@ struct GTY(()) lang_type { /* Nonzero for _CLASSTYPE means that operator delete is defined. */ #define TYPE_GETS_DELETE(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->gets_delete) #define TYPE_GETS_REG_DELETE(NODE) (TYPE_GETS_DELETE (NODE) & 1) +#define TYPE_GETS_VEC_DELETE(NODE) (TYPE_GETS_DELETE (NODE) & 2) /* Nonzero if `new NODE[x]' should cause the allocation of extra storage to indicate how many array elements are in use. */ diff --git a/gcc/cp/init.c b/gcc/cp/init.c index c932699ffa6..6226812b470 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -3316,6 +3316,12 @@ build_new_1 (vec **placement, tree type, tree nelts, ? TYPE_HAS_ARRAY_NEW_OPERATOR (elt_type) : TYPE_HAS_NEW_OPERATOR (elt_type)); + bool member_delete_p = (!globally_qualified_p + && CLASS_TYPE_P (elt_type) + && (array_p + ? TYPE_GETS_VEC_DELETE (elt_type) + : TYPE_GETS_REG_DELETE (elt_type))); + if (member_new_p) { /* Use a class-specific operator new. */ @@ -3473,7 +3479,7 @@ build_new_1 (vec **placement, tree type, tree nelts, /* In the simple case, we can stop now. */ pointer_type = build_pointer_type (type); - if (!cookie_size && !is_initialized) + if (!cookie_size && !is_initialized && !member_delete_p) return build_nop (pointer_type, alloc_call); /* Store the result of the allocation call in a variable so that we can @@ -3700,77 +3706,77 @@ build_new_1 (vec **placement, tree type, tree nelts, if (init_expr == error_mark_node) return error_mark_node; - - /* If any part of the object initialization terminates by throwing an -exception and a suitable deallocation function can be found, the -deallocation function is called to free the memory in which the -object was being constructed, after which the exception continues -to propagate in the context of the new-expression. If no -unambiguous matching deallocation function can be found, -propagating the exception does not cause the object's memory to be -freed. */ - if (flag_exceptions) - { - enum tree_code dcode = array_p ? VEC_DELETE_EXPR : DELETE_EXPR; - tree cleanup; - - /* The Standard is unclear here, but the right thing to do -is to use the same method for finding deallocation -functions that we use for finding allocation functions. */ - cleanup = (build_op_delete_call -(dcode, - alloc_node, - size, - globally_qualified_p, - placement_allocation_fn_p ? alloc_call : NULL_TREE, - alloc_fn, - complain)); - - if (cleanup && !processing_template_decl) - /* Ack! First we allocate the memory. Then we set our sentry - variable to true, and expand a cleanup that deletes the - memory if sentry is true. Then we run the constructor, and - finally clear the sentry. - - We need to do this because we allocate the space first, so - if there are any temporaries with cleanups in the - constructor args, we need this EH region to extend until - end of full-expression to preserve nesting. - - We used to try to evaluate the args first to avoid this, but - since C++17 [expr.new] says that "The invocation of the - allocation function is sequenced before the evaluations of - expressions in the new-initializer." */ - { - tree end, sentry, begin; - - begin = get_target_expr (boolean_true_node); - CLEANUP_EH_ONLY (begin) = 1; - - sentry = TARGET_EXPR_SLOT (begin); - - /* CLEANUP is compiler-generated, so no diagnostics. */ - suppress_warning (cleanup); - - TARGET_EXPR_CLEANUP (begin) - = build3 (COND_EXPR, void_type_node, sentry, -
Re: [power-ieee128] OPEN CONV
On Fri, Jan 07, 2022 at 10:40:50PM +0100, Thomas Koenig wrote: > One thing that one has to watch out for is a big-endian IBM long double > file, so the byte swapping will have to be done before assigning > the value. I've tried to handle that right, i.e. on unformatted read with byte-swapping and r16 <-> r17 conversions first do byte-swapping and then r16 <-> r17 conversions, while for unformatted writes first r16 <-> r17 conversions and then byte-swapping. Jakub
Re: [power-ieee128] OPEN CONV
On 07.01.22 20:52, Jakub Jelinek wrote: Here is completely untested patch that implements something, but doesn't implement the gcc option stuff, nor the CONVERT= syntax to supply multiple conversion options nor done anything about env var nor any testcases. But it tries to have the native/swap/big/little choice orthogonal from native/r16_ieee/r16_ibm with r16_ieee and r16_ibm only supported on ppc64le-linux. For INQUIRE it has the so far perhaps manageable set of possibilities handled so that it uses string literals and doesn't have to construct those strings at runtime (haven't studied how it would need to be done). I'm afraid I don't know that stuff enough to move forward from this. That looks like the direction to go. I will take it from there and see if I can find some hours over the weekend to work on something. Unfortunately, my daytime job will kick in again on Monday :-) One thing that one has to watch out for is a big-endian IBM long double file, so the byte swapping will have to be done before assigning the value. Best regards Thomas
Re: [power-ieee128] RFH: LTO broken
Hi Jakub, So, the following patch adds -fbuilding-libgfortran option and uses it together with TARGET_GLIBC_M* checks to decide whether to use libquadmath APIs (for the IEEE quad kind=16 if -fbuilding-libgfortran and not glibc or glibc is older than 2.32) or glibc 2.32 APIs (otherwise). This way, libgfortran uses solely the libquadmath APIs on glibc < 2.32 and __*ieee128 APIs on glibc 2.32, while user code always uses the latter. Ok for power-ieee128? OK! Best regards Thomas
[PATCH] PR 103763, Fix fold-vec-splat-floatdouble on power10.
Fix fold-vec-splat-floatdouble testsuite failure on power10 When I added support for generating XXSPLTIDP on December 15th, 2021, I missed updating the fold-vec-splat-floatdouble.c test to add to the regex for the instructions generated. This patch fixes that. gcc/testsuite/ 2022-01-07 Michael Meissner PR testsuite/103763 * gcc.target/powerpc/fold-vec-splat-floatdouble.c: Fix insn regex on power10. --- .../gcc.target/powerpc/fold-vec-splat-floatdouble.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/gcc/testsuite/gcc.target/powerpc/fold-vec-splat-floatdouble.c b/gcc/testsuite/gcc.target/powerpc/fold-vec-splat-floatdouble.c index b95fa324633..01f1b0dadf3 100644 --- a/gcc/testsuite/gcc.target/powerpc/fold-vec-splat-floatdouble.c +++ b/gcc/testsuite/gcc.target/powerpc/fold-vec-splat-floatdouble.c @@ -21,12 +21,11 @@ vector double test_dc () { const vector double y = { 3.0, 5.0 }; return vec_splat (y, 0b1); } /* If the source vector is a known constant, we will generate a load or possibly - XXSPLTIW. */ -/* { dg-final { scan-assembler-times {\mlvx\M|\mlxvd2x\M|\mlxv\M|\mplxv\M|\mxxspltiw\M} 2 } } */ + XXSPLTIW/XXSPLTIDP. */ +/* { dg-final { scan-assembler-times {\mlvx\M|\mlxvd2x\M|\mlxv\M|\mplxv\M|\mxxspltiw\M|\mxxspltidp\M} 2 } } */ /* For float types, we generate a splat. */ /* { dg-final { scan-assembler-times {\mvspltw\M|\mxxspltw\M} 3 } } */ /* For double types, we will generate xxpermdi instructions. */ /* { dg-final { scan-assembler-times "xxpermdi" 2 } } */ - -- 2.33.1 -- Michael Meissner, IBM PO Box 98, Ayer, Massachusetts, USA, 01432 email: meiss...@linux.ibm.com
Re: [Patch, fortran] PR103366 - [9/10/11/12 Regression] ICE in gfc_conv_gfc_desc_to_cfi_desc, at fortran/trans-expr.c:5647
Hi Paul, Am 07.01.22 um 14:42 schrieb Paul Richard Thomas via Fortran: I doubt that this is a regression on 9-11 branches since the testcase compiles correctly on each of my copies of these branches. IMHO it is rather more likely to have been caused by 64f9623765da3306b0ab6a47997dc5d62c2ea261, which introduced this new form of gfc_conv_gfc_desc_to_cfi_desc. The patch is self-explanatory. OK for mainline? I do not have a copy of F2017; but I can find your comment in the F2018 document. OK with this change. Thanks for the patch! Harald Paul Fortran: Match unlimited polymorphic argument to assumed type [PR103366]. 2022-01-07 Paul Thomas gcc/fortran PR fortran/103366 * trans-expr.c (gfc_conv_gfc_desc_to_cfi_desc): Allow unlimited polymorphic actual argument passed to assumed type formal. gcc/testsuite/ PR fortran/103366 * gfortran.dg/pr103366.f90: New test.
Re: [PATCH] rs6000: Add optimizations for _mm_sad_epu8
On Fri, Jan 7, 2022 at 3:57 PM Paul A. Clarke wrote: > > On Fri, Jan 07, 2022 at 02:40:51PM -0500, David Edelsohn via Gcc-patches > wrote: > > +#ifdef __LITTLE_ENDIAN__ > > + /* Sum across four integers with two integer results. */ > > + asm ("vsum2sws %0,%1,%2" : "=v" (result) : "v" (vsum), "v" (zero)); > > + /* Note: vec_sum2s could be used here, but on little-endian, vector > > + shifts are added that are not needed for this use-case. > > + A vector shift to correctly position the 32-bit integer results > > + (currently at [0] and [2]) to [1] and [3] would then need to be > > + swapped back again since the desired results are two 64-bit > > + integers ([1]|[0] and [3]|[2]). Thus, no shift is performed. */ > > +#else > >/* Sum across four integers with two integer results. */ > >result = vec_sum2s (vsum, (__vector signed int) zero); > > > > If little-endian adds shifts to correct for the position and > > big-endian does not, why not use the inline asm without the shifts for > > both? It seems confusing to add the inline asm only for LE instead of > > always using it with the appropriate comment. > > > > It's a good and valuable optimization for LE. Fewer variants are less > > fragile, easier to test and easier to maintain. If you're going to go > > to the trouble of using inline asm for LE, use it for both. > > BE (only) _does_ need a shift as seen on the next two lines after the > code snippet above: > /* Sum across four integers with two integer results. */ > result = vec_sum2s (vsum, (__vector signed int) zero); > /* Rotate the sums into the correct position. */ > result = vec_sld (result, result, 6); > > So, when using {vec_sum2s;vec_sld}: > - LE gets an implicit shift in vec_sum2s which just needs to be undone > by the vec_sld, and those shifts don't "cancel out" and get removed > by GCC. > - BE does not get any implicit shifts, but needs one that comes from > vec_sld. > > Are you saying use the asm(vsum2sws) and then conditionally call > vec_sld on BE only? > > I viewed this change as a temporary bandage unless and until GCC can > remove the unnecessary swaps. It seems like the preferred code is > vec_sum2s/vec_sld, not the asm, but that currently is suboptimal for LE. Nevermind. I thought that these patches had not been reviewed. Thanks, David
Re: [PATCH] rs6000: Add optimizations for _mm_sad_epu8
On Fri, Jan 07, 2022 at 02:40:51PM -0500, David Edelsohn via Gcc-patches wrote: > +#ifdef __LITTLE_ENDIAN__ > + /* Sum across four integers with two integer results. */ > + asm ("vsum2sws %0,%1,%2" : "=v" (result) : "v" (vsum), "v" (zero)); > + /* Note: vec_sum2s could be used here, but on little-endian, vector > + shifts are added that are not needed for this use-case. > + A vector shift to correctly position the 32-bit integer results > + (currently at [0] and [2]) to [1] and [3] would then need to be > + swapped back again since the desired results are two 64-bit > + integers ([1]|[0] and [3]|[2]). Thus, no shift is performed. */ > +#else >/* Sum across four integers with two integer results. */ >result = vec_sum2s (vsum, (__vector signed int) zero); > > If little-endian adds shifts to correct for the position and > big-endian does not, why not use the inline asm without the shifts for > both? It seems confusing to add the inline asm only for LE instead of > always using it with the appropriate comment. > > It's a good and valuable optimization for LE. Fewer variants are less > fragile, easier to test and easier to maintain. If you're going to go > to the trouble of using inline asm for LE, use it for both. BE (only) _does_ need a shift as seen on the next two lines after the code snippet above: /* Sum across four integers with two integer results. */ result = vec_sum2s (vsum, (__vector signed int) zero); /* Rotate the sums into the correct position. */ result = vec_sld (result, result, 6); So, when using {vec_sum2s;vec_sld}: - LE gets an implicit shift in vec_sum2s which just needs to be undone by the vec_sld, and those shifts don't "cancel out" and get removed by GCC. - BE does not get any implicit shifts, but needs one that comes from vec_sld. Are you saying use the asm(vsum2sws) and then conditionally call vec_sld on BE only? I viewed this change as a temporary bandage unless and until GCC can remove the unnecessary swaps. It seems like the preferred code is vec_sum2s/vec_sld, not the asm, but that currently is suboptimal for LE. PC
Re: [PATCH] rs6000: Add Power10 optimization for most _mm_movemask*
On Fri, Jan 7, 2022 at 3:35 PM Paul A. Clarke wrote: > > On Fri, Jan 07, 2022 at 02:23:14PM -0500, David Edelsohn wrote: > > > Power10 ISA added `vextract*` instructions which are realized in the > > > `vec_extractm` instrinsic. > > > > > > Use `vec_extractm` for `_mm_movemask_ps`, `_mm_movemask_pd`, and > > > `_mm_movemask_epi8` compatibility intrinsics, when `_ARCH_PWR10`. > > > > > > 2021-10-21 Paul A. Clarke > > > > > > gcc > > > * config/rs6000/xmmintrin.h (_mm_movemask_ps): Use vec_extractm > > > when _ARCH_PWR10. > > > * config/rs6000/emmintrin.h (_mm_movemask_pd): Likewise. > > > (_mm_movemask_epi8): Likewise. > > > --- > > > Tested on Power10 powerpc64le-linux (compiled with and without > > > `-mcpu=power10`). > > > > > > OK for trunk? > > > > This is okay modulo > > > > > + return vec_extractm ((__v16qu) __A); > > > > Should the above be __v16qi like x86? > > That would match x86 better, but we don't have a function signature > for vec_extractm which accepts a signed type. Okay, nevermind. I thought that vec_extractm also allowed signed. Thanks, David
Re: [PATCH] rs6000: Add Power10 optimization for _mm_blendv*
On Fri, Jan 7, 2022 at 3:32 PM Paul A. Clarke wrote: > > On Fri, Jan 07, 2022 at 02:15:22PM -0500, David Edelsohn wrote: > > > Power10 ISA added `xxblendv*` instructions which are realized in the > > > `vec_blendv` instrinsic. > > > > > > Use `vec_blendv` for `_mm_blendv_epi8`, `_mm_blendv_ps`, and > > > `_mm_blendv_pd` compatibility intrinsics, when `_ARCH_PWR10`. > > > > > > Also, copy a test from i386 for testing `_mm_blendv_ps`. > > > This should have come with commit > > > ed04cf6d73e233c74c4e55c27f1cbd89ae4710e8, > > > but was inadvertently omitted. > > > > > > 2021-10-20 Paul A. Clarke > > > > > > gcc > > > * config/rs6000/smmintrin.h (_mm_blendv_epi8): Use vec_blendv > > > when _ARCH_PWR10. > > > (_mm_blendv_ps): Likewise. > > > (_mm_blendv_pd): Likewise. > > > > > > gcc/testsuite > > > * gcc.target/powerpc/sse4_1-blendvps.c: Copy from gcc.target/i386, > > > adjust dg directives to suit. > > > --- > > > Tested on Power10 powerpc64le-linux (compiled with and without > > > `-mcpu=power10`). > > > > > > OK for trunk? > > > > This is okay modulo > > > > > + return (__m128i) vec_blendv ((__v16qu) __A, (__v16qu) __B, (__v16qu) > > > __mask); > > > > Should the above be __v16qi like x86? > > That does arguably match the types involved (epi8) better. > > Shall I change the original implementation as well (4 lines later)? > > > return (__m128i) vec_sel ((__v16qi) __A, (__v16qi) __B, __lmask); vec_blendv supports the signed type, so it seems that the function should use that type, unless unsigned is preferred because PowerPC defaults to unsigned char. I wasn't going to recommend changing the existing code because I don't know how the signed type interacts with the other builtins. Thanks, David
Re: [PATCH] rs6000: Add Power10 optimization for most _mm_movemask*
On Fri, Jan 07, 2022 at 02:23:14PM -0500, David Edelsohn wrote: > > Power10 ISA added `vextract*` instructions which are realized in the > > `vec_extractm` instrinsic. > > > > Use `vec_extractm` for `_mm_movemask_ps`, `_mm_movemask_pd`, and > > `_mm_movemask_epi8` compatibility intrinsics, when `_ARCH_PWR10`. > > > > 2021-10-21 Paul A. Clarke > > > > gcc > > * config/rs6000/xmmintrin.h (_mm_movemask_ps): Use vec_extractm > > when _ARCH_PWR10. > > * config/rs6000/emmintrin.h (_mm_movemask_pd): Likewise. > > (_mm_movemask_epi8): Likewise. > > --- > > Tested on Power10 powerpc64le-linux (compiled with and without > > `-mcpu=power10`). > > > > OK for trunk? > > This is okay modulo > > > + return vec_extractm ((__v16qu) __A); > > Should the above be __v16qi like x86? That would match x86 better, but we don't have a function signature for vec_extractm which accepts a signed type. PC
Re: [PATCH] rs6000: Add Power10 optimization for _mm_blendv*
On Fri, Jan 07, 2022 at 02:15:22PM -0500, David Edelsohn wrote: > > Power10 ISA added `xxblendv*` instructions which are realized in the > > `vec_blendv` instrinsic. > > > > Use `vec_blendv` for `_mm_blendv_epi8`, `_mm_blendv_ps`, and > > `_mm_blendv_pd` compatibility intrinsics, when `_ARCH_PWR10`. > > > > Also, copy a test from i386 for testing `_mm_blendv_ps`. > > This should have come with commit ed04cf6d73e233c74c4e55c27f1cbd89ae4710e8, > > but was inadvertently omitted. > > > > 2021-10-20 Paul A. Clarke > > > > gcc > > * config/rs6000/smmintrin.h (_mm_blendv_epi8): Use vec_blendv > > when _ARCH_PWR10. > > (_mm_blendv_ps): Likewise. > > (_mm_blendv_pd): Likewise. > > > > gcc/testsuite > > * gcc.target/powerpc/sse4_1-blendvps.c: Copy from gcc.target/i386, > > adjust dg directives to suit. > > --- > > Tested on Power10 powerpc64le-linux (compiled with and without > > `-mcpu=power10`). > > > > OK for trunk? > > This is okay modulo > > > + return (__m128i) vec_blendv ((__v16qu) __A, (__v16qu) __B, (__v16qu) > > __mask); > > Should the above be __v16qi like x86? That does arguably match the types involved (epi8) better. Shall I change the original implementation as well (4 lines later)? > return (__m128i) vec_sel ((__v16qi) __A, (__v16qi) __B, __lmask); PC
Re: [PATCH v4] c-format: Add -Wformat-int-precision option [PR80060]
On Fri, 7 Jan 2022, Daniil Stas via Gcc-patches wrote: > > > @@ -4248,7 +4248,7 @@ check_format_types (const substring_loc > > > _loc, && (!pedantic || i < 2) > > > && char_type_flag) > > > continue; > > > - if (types->scalar_identity_flag > > > + if ((types->scalar_identity_flag || > > > !warn_format_int_precision) && (TREE_CODE (cur_type) == TREE_CODE This makes the option apply to all types, not just integer types. Thus, it means a test such as void f (void) { __builtin_printf ("%f", 0.0f64); } is not diagnosed with -Wformat -Wno-format-int-precision. Given the option name, I don't think it should affect diagnosing that test (and there should be such a test added to the testsuite to verify that it doesn't affect diagnostics for non-integer types). -- Joseph S. Myers jos...@codesourcery.com
Re: [power-ieee128] OPEN CONV
On Fri, Jan 07, 2022 at 11:26:15AM +0100, Thomas Koenig wrote: > In > > https://gcc.gnu.org/pipermail/fortran/2021-October/056895.html > > I made a suggestion how how the format could look like. I used > a plus sign instead of a comma because I thought the environment > variable should follow the same syntax as the CONVERT specifier, > and I did not want to think about having commas in there :-) > > Thinking about this again after some time, I think the syntax of > the environment variable would be clearer if the keywords for > the two conversions were separate, so somethig like > > big_endian;r16_ieee;r16_ibm:10-20; > > for the environment variable and > > CONVERT="big_endian,r16_ibm" > > would probably be better. Here is completely untested patch that implements something, but doesn't implement the gcc option stuff, nor the CONVERT= syntax to supply multiple conversion options nor done anything about env var nor any testcases. But it tries to have the native/swap/big/little choice orthogonal from native/r16_ieee/r16_ibm with r16_ieee and r16_ibm only supported on ppc64le-linux. For INQUIRE it has the so far perhaps manageable set of possibilities handled so that it uses string literals and doesn't have to construct those strings at runtime (haven't studied how it would need to be done). I'm afraid I don't know that stuff enough to move forward from this. --- gcc/fortran/libgfortran.h.jj2022-01-07 18:41:55.473722388 +0100 +++ gcc/fortran/libgfortran.h 2022-01-07 19:14:23.881784305 +0100 @@ -86,14 +86,16 @@ along with GCC; see the file COPYING3. #define GFC_INVALID_UNIT -3 /* Possible values for the CONVERT I/O specifier. */ -/* Keep in sync with GFC_FLAG_CONVERT_* in gcc/flags.h. */ +/* Keep in sync with GFC_FLAG_CONVERT_* in gcc/flag-types.h. */ typedef enum { GFC_CONVERT_NONE = -1, GFC_CONVERT_NATIVE = 0, GFC_CONVERT_SWAP, GFC_CONVERT_BIG, - GFC_CONVERT_LITTLE + GFC_CONVERT_LITTLE, + GFC_CONVERT_R16_IEEE = 4, + GFC_CONVERT_R16_IBM = 8 } unit_convert; --- gcc/flag-types.h.jj 2022-01-07 18:41:55.452722678 +0100 +++ gcc/flag-types.h2022-01-07 19:13:55.953170776 +0100 @@ -424,7 +424,9 @@ enum gfc_convert GFC_FLAG_CONVERT_NATIVE = 0, GFC_FLAG_CONVERT_SWAP, GFC_FLAG_CONVERT_BIG, - GFC_FLAG_CONVERT_LITTLE + GFC_FLAG_CONVERT_LITTLE, + GFC_FLAG_CONVERT_R16_IEEE = 4, + GFC_FLAG_CONVERT_R16_IBM = 8 }; --- libgfortran/io/open.c.jj2022-01-07 18:41:56.078714031 +0100 +++ libgfortran/io/open.c 2022-01-07 19:19:11.582780100 +0100 @@ -153,6 +153,10 @@ static const st_option convert_opt[] = { "swap", GFC_CONVERT_SWAP}, { "big_endian", GFC_CONVERT_BIG}, { "little_endian", GFC_CONVERT_LITTLE}, +#ifdef HAVE_GFC_REAL_17 + { "r16_ieee", GFC_CONVERT_R16_IEEE}, + { "r16_ibm", GFC_CONVERT_R16_IBM}, +#endif { NULL, 0} }; @@ -820,7 +824,14 @@ st_open (st_parameter_open *opp) else conv = compile_options.convert; } - + + flags.convert = 0; + +#ifdef HAVE_GFC_REAL_17 + flags.convert = conv & (GFC_CONVERT_R16_IEEE | GFC_CONVERT_R16_IBM); + conv &= ~(GFC_CONVERT_R16_IEEE | GFC_CONVERT_R16_IBM); +#endif + switch (conv) { case GFC_CONVERT_NATIVE: @@ -840,7 +851,7 @@ st_open (st_parameter_open *opp) break; } - flags.convert = conv; + flags.convert |= conv; if (flags.position != POSITION_UNSPECIFIED && flags.access == ACCESS_DIRECT) --- libgfortran/io/transfer.c.jj2022-01-07 18:41:56.080714003 +0100 +++ libgfortran/io/transfer.c 2022-01-07 20:43:36.146920392 +0100 @@ -1126,7 +1126,11 @@ unformatted_read (st_parameter_dt *dtp, size *= GFC_SIZE_OF_CHAR_KIND(kind); read_block_direct (dtp, dest, size * nelems); - if (unlikely (dtp->u.p.current_unit->flags.convert == GFC_CONVERT_SWAP) + int convert = dtp->u.p.current_unit->flags.convert; +#ifdef HAVE_GFC_REAL_17 + convert &= ~(GFC_CONVERT_R16_IEEE | GFC_CONVERT_R16_IBM); +#endif + if (unlikely (convert == GFC_CONVERT_SWAP) && kind != 1) { /* Handle wide chracters. */ @@ -1144,6 +1148,48 @@ unformatted_read (st_parameter_dt *dtp, } bswap_array (dest, dest, size, nelems); } +#ifdef HAVE_GFC_REAL_17 + if ((dtp->u.p.current_unit->flags.convert & GFC_CONVERT_R16_IEEE) + && kind == 16 + && (type == BT_REAL || type == BT_COMPLEX)) +{ + if (type == BT_COMPLEX && size == 32) + { + nelems *= 2; + size /= 2; + } + char *pd = dest; + for (size_t i = 0; i < nelems; i++) + { + GFC_REAL_16 r16; + GFC_REAL_17 r17; + memcpy (, pd, 16); + r16 = r17; + memcpy (pd, , 16); + pd += size; + } +} + else if ((dtp->u.p.current_unit->flags.convert & GFC_CONVERT_R16_IBM) + && kind == 17 + && (type == BT_REAL || type == BT_COMPLEX)) +{ + if (type == BT_COMPLEX && size == 32) + { + nelems *= 2; + size /= 2; + } +
[PATCH] i386: Robustify V2QI and V4QI move patterns
Add sse2 isa attribute where needed and remove where not needed. 2022-01-07 Uroš Bizjak gcc/ChangeLog: * config/i386/mmx.md (*move_internal): Add isa attribute. (*movv2qi_internal): Remve sse2 requirement for alternatives 4,5. Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}. Pushed to master. Uros. diff --git a/gcc/config/i386/mmx.md b/gcc/config/i386/mmx.md index 8e0a6490b7b..4fc3e00f100 100644 --- a/gcc/config/i386/mmx.md +++ b/gcc/config/i386/mmx.md @@ -285,7 +285,12 @@ gcc_unreachable (); } } - [(set (attr "type") + [(set (attr "isa") + (cond [(eq_attr "alternative" "6,7") + (const_string "sse2") + ] + (const_string "*"))) + (set (attr "type") (cond [(eq_attr "alternative" "2") (const_string "sselog1") (eq_attr "alternative" "3,4,5,6,7") @@ -306,12 +311,15 @@ (const_string "V4SF") (match_test "TARGET_AVX") (const_string "TI") -(match_test "optimize_function_for_size_p (cfun)") +(ior (not (match_test "TARGET_SSE2")) + (match_test "optimize_function_for_size_p (cfun)")) (const_string "V4SF") ] (const_string "TI")) + (and (eq_attr "alternative" "4,5") -(match_test "mode == V2HFmode")) +(ior (match_test "mode == V2HFmode") + (not (match_test "TARGET_SSE2" (const_string "SF") ] (const_string "SI"))) @@ -401,7 +409,7 @@ } } [(set (attr "isa") - (cond [(eq_attr "alternative" "4,5,6,8,9") + (cond [(eq_attr "alternative" "6,8,9") (const_string "sse2") (eq_attr "alternative" "7") (const_string "sse4")
Re: [PATCH] rs6000: Add optimizations for _mm_sad_epu8
+#ifdef __LITTLE_ENDIAN__ + /* Sum across four integers with two integer results. */ + asm ("vsum2sws %0,%1,%2" : "=v" (result) : "v" (vsum), "v" (zero)); + /* Note: vec_sum2s could be used here, but on little-endian, vector + shifts are added that are not needed for this use-case. + A vector shift to correctly position the 32-bit integer results + (currently at [0] and [2]) to [1] and [3] would then need to be + swapped back again since the desired results are two 64-bit + integers ([1]|[0] and [3]|[2]). Thus, no shift is performed. */ +#else /* Sum across four integers with two integer results. */ result = vec_sum2s (vsum, (__vector signed int) zero); If little-endian adds shifts to correct for the position and big-endian does not, why not use the inline asm without the shifts for both? It seems confusing to add the inline asm only for LE instead of always using it with the appropriate comment. It's a good and valuable optimization for LE. Fewer variants are less fragile, easier to test and easier to maintain. If you're going to go to the trouble of using inline asm for LE, use it for both. Thanks, David
Re: [PATCH] rs6000: Add Power10 optimization for most _mm_movemask*
> Power10 ISA added `vextract*` instructions which are realized in the > `vec_extractm` instrinsic. > > Use `vec_extractm` for `_mm_movemask_ps`, `_mm_movemask_pd`, and > `_mm_movemask_epi8` compatibility intrinsics, when `_ARCH_PWR10`. > > 2021-10-21 Paul A. Clarke > > gcc > * config/rs6000/xmmintrin.h (_mm_movemask_ps): Use vec_extractm > when _ARCH_PWR10. > * config/rs6000/emmintrin.h (_mm_movemask_pd): Likewise. > (_mm_movemask_epi8): Likewise. > --- > Tested on Power10 powerpc64le-linux (compiled with and without > `-mcpu=power10`). > > OK for trunk? This is okay modulo > + return vec_extractm ((__v16qu) __A); Should the above be __v16qi like x86? Thanks, David
Re: [PATCH] rs6000: Add Power10 optimization for _mm_blendv*
> Power10 ISA added `xxblendv*` instructions which are realized in the > `vec_blendv` instrinsic. > > Use `vec_blendv` for `_mm_blendv_epi8`, `_mm_blendv_ps`, and > `_mm_blendv_pd` compatibility intrinsics, when `_ARCH_PWR10`. > > Also, copy a test from i386 for testing `_mm_blendv_ps`. > This should have come with commit ed04cf6d73e233c74c4e55c27f1cbd89ae4710e8, > but was inadvertently omitted. > > 2021-10-20 Paul A. Clarke > > gcc > * config/rs6000/smmintrin.h (_mm_blendv_epi8): Use vec_blendv > when _ARCH_PWR10. > (_mm_blendv_ps): Likewise. > (_mm_blendv_pd): Likewise. > > gcc/testsuite > * gcc.target/powerpc/sse4_1-blendvps.c: Copy from gcc.target/i386, > adjust dg directives to suit. > --- > Tested on Power10 powerpc64le-linux (compiled with and without > `-mcpu=power10`). > > OK for trunk? This is okay modulo > + return (__m128i) vec_blendv ((__v16qu) __A, (__v16qu) __B, (__v16qu) > __mask); Should the above be __v16qi like x86? Thanks, David
[PATCH] [12/11/10] Fix invalid format warnings on Windows
Mingw32 targets use ms_printf format for printf, but mingw-w64 when configured for UCRT uses gnu_format (via stdio.h). GCC then checks both formats, which means that one cannot print a 64-bit integer without a warning. All these lines issue a warning: printf("Hello %"PRIu64"\n", x); // 1 printf("Hello %I64u\n", x); // 2 printf("Hello %llu\n", x); // 3 because each of them violates one of the formats. This causes trouble particularly for systems that turn warnings into errors or otherwise require no warnings (leading to the use of -Wno-format or of various printf replacements). Also, one gets a warning twice if the format string violates both formats. These issues have been reported as PR 95130 and PR 92292: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95130 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92292 This patch fixes these issues following the suggestion of Joseph Myers, it disables the built in format in case there are additional ones. It applies to GCC 12, 11, 10 and fixes the example above as tested on cross compilers built on Linux. I've also verified that R built using a 10.3 native compiler with the patch applied builds and passes its tests. I've updated the patch based on advice and comments from Martin Liska and Martin Storsjo. Could this or a variant of please be accepted to 12/11/10? Thanks Tomas gcc/c-family/ChangeLog: * c-common.c (check_function_arguments): Pass also function declaration to check_function_format. * c-common.h (check_function_format): Extra argument - function declaration. * c-format.c (check_function_format): For builtin functions with a built in format and at least one more, do not check the first one. diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 13341fa315e..be4d8400447 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -6057,7 +6057,7 @@ check_function_arguments (location_t loc, const_tree fndecl, const_tree fntype, /* Check for errors in format strings. */ if (warn_format || warn_suggest_attribute_format) - check_function_format (fntype, TYPE_ATTRIBUTES (fntype), nargs, argarray, + check_function_format (fndecl, fntype, TYPE_ATTRIBUTES (fntype), nargs, argarray, arglocs); if (warn_format) diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index 8b7bf35e888..ee370eafbbc 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -856,7 +856,7 @@ extern void check_function_arguments_recurse (void (*) unsigned HOST_WIDE_INT); extern bool check_builtin_function_arguments (location_t, vec, tree, tree, int, tree *); -extern void check_function_format (const_tree, tree, int, tree *, +extern void check_function_format (const_tree, const_tree, tree, int, tree *, vec *); extern bool attribute_fallthrough_p (tree); extern tree handle_format_attribute (tree *, tree, tree, int, bool *); diff --git a/gcc/c-family/c-format.c b/gcc/c-family/c-format.c index afa77810a5c..8155ee8c6f2 100644 --- a/gcc/c-family/c-format.c +++ b/gcc/c-family/c-format.c @@ -1160,12 +1160,13 @@ decode_format_type (const char *s, bool *is_raw /* = NULL */) attribute themselves. */ void -check_function_format (const_tree fntype, tree attrs, int nargs, +check_function_format (const_tree fndecl, const_tree fntype, tree attrs, int nargs, tree *argarray, vec *arglocs) { - tree a; + tree a, aa; tree atname = get_identifier ("format"); + int skipped_default_format = 0; /* See if this function has any format attributes. */ for (a = attrs; a; a = TREE_CHAIN (a)) @@ -1176,6 +1177,58 @@ check_function_format (const_tree fntype, tree attrs, int nargs, function_format_info info; decode_format_attr (fntype, atname, TREE_VALUE (a), , /*validated=*/true); + + /* Mingw32 targets have traditionally used ms_printf format for the + printf function, and this format is built in GCC. But nowadays, + if mingw-w64 is configured to target UCRT, the printf function + uses the gnu_printf format (specified in the stdio.h header). This + causes GCC to check both formats, which means that there is no way + to e.g. print a long long unsigned without a warning (ms_printf + warns for %llu and gnu_printf warns for %I64u). Also, GCC would warn + twice about the same issue when both formats are violated, e.g. + for %lu used to print long long unsigned. + + Hence, if there are multiple format specifiers, we skip the first + one. See PR 95130, PR 92292. */ + + if (!skipped_default_format && fndecl) + { + for(aa = TREE_CHAIN (a); aa; aa = TREE_CHAIN(aa)) + { + if (is_attribute_p ("format", get_attribute_name (aa)) && + fndecl && fndecl_built_in_p (fndecl,
Re: [PATCH][GCC11] PR tree-optimization/103603 - Directly resolve range_of_stmt dependencies. (Port of PR 103231/103464)
On 12/7/21 15:19, Andrew MacLeod wrote: The following patch is a slight rework of the 2 patches which flatten rangers call stack. It needed some tweaking since some of the routines have changed name or been adjusted. This has been bootstrapped on x86_64-pc-linux-gnu with no regressions. OK for gcc-11 release branch? Andrew ping. I don't think anyone OK'd this. Andrew
Re: [PING^3 PATCH] rs6000: Add Power10 optimization for _mm_blendv*
On Thu, Nov 18, 2021 at 08:25:35PM -0600, Paul A. Clarke via Gcc-patches wrote: > On Mon, Nov 08, 2021 at 11:42:27AM -0600, Paul A. Clarke via Gcc-patches > wrote: > > Gentle ping... > > Gentle re-ping. Gentle re-re-ping. > > On Wed, Oct 20, 2021 at 08:42:07PM -0500, Paul A. Clarke via Gcc-patches > > wrote: > > > Power10 ISA added `xxblendv*` instructions which are realized in the > > > `vec_blendv` instrinsic. > > > > > > Use `vec_blendv` for `_mm_blendv_epi8`, `_mm_blendv_ps`, and > > > `_mm_blendv_pd` compatibility intrinsics, when `_ARCH_PWR10`. > > > > > > Also, copy a test from i386 for testing `_mm_blendv_ps`. > > > This should have come with commit > > > ed04cf6d73e233c74c4e55c27f1cbd89ae4710e8, > > > but was inadvertently omitted. > > > > > > 2021-10-20 Paul A. Clarke > > > > > > gcc > > > * config/rs6000/smmintrin.h (_mm_blendv_epi8): Use vec_blendv > > > when _ARCH_PWR10. > > > (_mm_blendv_ps): Likewise. > > > (_mm_blendv_pd): Likewise. > > > > > > gcc/testsuite > > > * gcc.target/powerpc/sse4_1-blendvps.c: Copy from gcc.target/i386, > > > adjust dg directives to suit. > > > --- > > > Tested on Power10 powerpc64le-linux (compiled with and without > > > `-mcpu=power10`). > > > > > > OK for trunk? > > > > > > gcc/config/rs6000/smmintrin.h | 12 > > > .../gcc.target/powerpc/sse4_1-blendvps.c | 65 +++ > > > 2 files changed, 77 insertions(+) > > > create mode 100644 gcc/testsuite/gcc.target/powerpc/sse4_1-blendvps.c > > > > > > diff --git a/gcc/config/rs6000/smmintrin.h b/gcc/config/rs6000/smmintrin.h > > > index b732fbca7b09..5d87fd7b6f61 100644 > > > --- a/gcc/config/rs6000/smmintrin.h > > > +++ b/gcc/config/rs6000/smmintrin.h > > > @@ -113,9 +113,13 @@ _mm_blend_epi16 (__m128i __A, __m128i __B, const int > > > __imm8) > > > extern __inline __m128i __attribute__((__gnu_inline__, > > > __always_inline__, __artificial__)) > > > _mm_blendv_epi8 (__m128i __A, __m128i __B, __m128i __mask) > > > { > > > +#ifdef _ARCH_PWR10 > > > + return (__m128i) vec_blendv ((__v16qu) __A, (__v16qu) __B, (__v16qu) > > > __mask); > > > +#else > > >const __v16qu __seven = vec_splats ((unsigned char) 0x07); > > >__v16qu __lmask = vec_sra ((__v16qu) __mask, __seven); > > >return (__m128i) vec_sel ((__v16qu) __A, (__v16qu) __B, __lmask); > > > +#endif > > > } > > > > > > __inline __m128 > > > @@ -149,9 +153,13 @@ __inline __m128 > > > __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) > > > _mm_blendv_ps (__m128 __A, __m128 __B, __m128 __mask) > > > { > > > +#ifdef _ARCH_PWR10 > > > + return (__m128) vec_blendv ((__v4sf) __A, (__v4sf) __B, (__v4su) > > > __mask); > > > +#else > > >const __v4si __zero = {0}; > > >const __vector __bool int __boolmask = vec_cmplt ((__v4si) __mask, > > > __zero); > > >return (__m128) vec_sel ((__v4su) __A, (__v4su) __B, (__v4su) > > > __boolmask); > > > +#endif > > > } > > > > > > __inline __m128d > > > @@ -174,9 +182,13 @@ __inline __m128d > > > __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) > > > _mm_blendv_pd (__m128d __A, __m128d __B, __m128d __mask) > > > { > > > +#ifdef _ARCH_PWR10 > > > + return (__m128d) vec_blendv ((__v2df) __A, (__v2df) __B, (__v2du) > > > __mask); > > > +#else > > >const __v2di __zero = {0}; > > >const __vector __bool long long __boolmask = vec_cmplt ((__v2di) > > > __mask, __zero); > > >return (__m128d) vec_sel ((__v2du) __A, (__v2du) __B, (__v2du) > > > __boolmask); > > > +#endif > > > } > > > #endif > > > > > > diff --git a/gcc/testsuite/gcc.target/powerpc/sse4_1-blendvps.c > > > b/gcc/testsuite/gcc.target/powerpc/sse4_1-blendvps.c > > > new file mode 100644 > > > index ..8fcb55383047 > > > --- /dev/null > > > +++ b/gcc/testsuite/gcc.target/powerpc/sse4_1-blendvps.c > > > @@ -0,0 +1,65 @@ > > > +/* { dg-do run } */ > > > +/* { dg-require-effective-target p8vector_hw } */ > > > +/* { dg-options "-O2 -mpower8-vector -Wno-psabi" } */ > > > + > > > +#include "sse4_1-check.h" > > > + > > > +#include > > > +#include > > > + > > > +#define NUM 20 > > > + > > > +static void > > > +init_blendvps (float *src1, float *src2, float *mask) > > > +{ > > > + int i, msk, sign = 1; > > > + > > > + msk = -1; > > > + for (i = 0; i < NUM * 4; i++) > > > +{ > > > + if((i % 4) == 0) > > > + msk++; > > > + src1[i] = i* (i + 1) * sign; > > > + src2[i] = (i + 20) * sign; > > > + mask[i] = (i + 120) * i; > > > + if( (msk & (1 << (i % 4 > > > + mask[i] = -mask[i]; > > > + sign = -sign; > > > +} > > > +} > > > + > > > +static int > > > +check_blendvps (__m128 *dst, float *src1, float *src2, > > > + float *mask) > > > +{ > > > + float tmp[4]; > > > + int j; > > > + > > > + memcpy ([0], src1, sizeof (tmp)); > > > + for (j = 0; j < 4; j++) > > > +if (mask [j] < 0.0) > > > + tmp[j] = src2[j]; > > > + > > > + return memcmp (dst, [0],
Re: [power-ieee128] RFH: LTO broken
On Fri, Jan 07, 2022 at 03:25:57PM +0100, Thomas Koenig wrote: > > > 00251038 06ad0015 R_PPC64_JMP_SLOT > > > __cabsieee128 + 0 > > > All these should for POWER_IEEE128 use atan2q@QUADMATH_1.0 etc. > > > > So, seems all these come from f951 compiled sources. > > For user code, I think the agreement was if you want to use successfully > > -mabi=ieeelongdouble, you need glibc 2.32 or later, which is why the Fortran > > FE doesn't conditionalize on whether glibc 2.32 is available or not and just > > emits __WHATEVERieee128 entrypoints. > > That was the idea, I think. > > > But for Fortran compiled sources in libgfortran, we need to use > > __WHATEVERieee128 only if glibc 2.32 or later and WHATEVERq (from > > libquadmath) otherwise. > > I guess easiest would be to do this always in the FE, but we need to > > determine in the FE if the target is glibc 2.32 or later. > > Instead of determining this in the front end, maybe we can add > an option (documented, but marked as useful as only for internal > use and with no guarantee that it will remain) and use that option > when compiling libgfortran. We apparently have already TARGET_GLIBC_MAJOR and TARGET_GLIBC_MINOR target macros, and e.g. libgcc or D testsuite uses internal options like -fbuilding-libgcc. So, the following patch adds -fbuilding-libgfortran option and uses it together with TARGET_GLIBC_M* checks to decide whether to use libquadmath APIs (for the IEEE quad kind=16 if -fbuilding-libgfortran and not glibc or glibc is older than 2.32) or glibc 2.32 APIs (otherwise). This way, libgfortran uses solely the libquadmath APIs on glibc < 2.32 and __*ieee128 APIs on glibc 2.32, while user code always uses the latter. Ok for power-ieee128? 2022-01-07 Jakub Jelinek gcc/fortran/ * trans-types.c (gfc_init_kinds): When setting abi_kind to 17, if not targetting glibc 2.32 or later and -fbuilding-libgfortran, set gfc_real16_is_float128 and c_float128 in gfc_real_kinds. (gfc_build_real_type): Don't set c_long_double if c_float128 is already set. * trans-intrinsic.c (builtin_decl_for_precision): Don't use long_double_built_in if gfc_real16_is_float128 and long_double_type_node == gfc_float128_type_node. * lang.opt (fbuilding-libgfortran): New undocumented option. libgfortran/ * Makefile.am (AM_FCFLAGS): Add -fbuilding-libgfortran after -fallow-leading-underscore. * Makefile.in: Regenerated. --- gcc/fortran/trans-types.c.jj2022-01-04 10:27:56.498322942 + +++ gcc/fortran/trans-types.c 2022-01-07 16:19:06.737066905 + @@ -516,7 +516,16 @@ gfc_init_kinds (void) { for (int i = 0; i < r_index; ++i) if (gfc_real_kinds[i].kind == 16) - gfc_real_kinds[i].abi_kind = 17; + { + gfc_real_kinds[i].abi_kind = 17; + if (flag_building_libgfortran + && (TARGET_GLIBC_MAJOR < 2 + || (TARGET_GLIBC_MAJOR == 2 && TARGET_GLIBC_MINOR < 32))) + { + gfc_real16_is_float128 = true; + gfc_real_kinds[i].c_float128 = 1; + } + } } /* Choose the default integer kind. We choose 4 unless the user directs us @@ -859,7 +868,7 @@ gfc_build_real_type (gfc_real_info *info info->c_float = 1; if (mode_precision == DOUBLE_TYPE_SIZE) info->c_double = 1; - if (mode_precision == LONG_DOUBLE_TYPE_SIZE) + if (mode_precision == LONG_DOUBLE_TYPE_SIZE && !info->c_float128) info->c_long_double = 1; if (mode_precision != LONG_DOUBLE_TYPE_SIZE && mode_precision == 128) { --- gcc/fortran/trans-intrinsic.c.jj2022-01-07 09:39:10.222157644 + +++ gcc/fortran/trans-intrinsic.c 2022-01-07 13:57:35.451495059 + @@ -154,7 +154,9 @@ builtin_decl_for_precision (enum built_i i = m->float_built_in; else if (precision == TYPE_PRECISION (double_type_node)) i = m->double_built_in; - else if (precision == TYPE_PRECISION (long_double_type_node)) + else if (precision == TYPE_PRECISION (long_double_type_node) + && (!gfc_real16_is_float128 + || long_double_type_node != gfc_float128_type_node)) i = m->long_double_built_in; else if (precision == TYPE_PRECISION (gfc_float128_type_node)) { --- gcc/fortran/lang.opt.jj 2021-12-31 11:00:15.042190365 + +++ gcc/fortran/lang.opt2022-01-07 16:18:17.685995005 + @@ -413,6 +413,9 @@ fblas-matmul-limit= Fortran RejectNegative Joined UInteger Var(flag_blas_matmul_limit) Init(30) -fblas-matmul-limit=Size of the smallest matrix for which matmul will use BLAS. +fbuilding-libgfortran +Fortran Undocumented Var(flag_building_libgfortran) + fcheck-array-temporaries Fortran Produce a warning at runtime if a array temporary has been created for a procedure argument. --- libgfortran/Makefile.am.jj 2022-01-04 10:27:56.498322942 + +++ libgfortran/Makefile.am
[Ada] Read directory in Ada.Directories.Start_Search rather than Get_Next_Entry
The Ada.Directories directory search function is changed so the contents of the directory is now read in Start_Search instead of in Get_Next_Entry. Start_Search now stores the result of the directory search in the search object, with Get_Next_Entry returning results from the search object. This differs from the prior implementation where Get_Next_Entry would query the directory directly for the next item using the POSIX readdir function. The problem with building Get_Next_Entry around the readdir function is POSIX does not specify the behavior of readdir when files are added or removed from the directory being read. For example: on most systems, deleting files from the folder being read does not impact readdir. However, some systems, like RTEMS and HFS+ volumes on macOS, will return NULL instead of the next item in the directory if the current item returned by readdir is deleted. To avoid this issue, the contents of the directory is read in Start_Search and the user is given a copy of these results. Consequently, any subsequent modification to the directory does not affect the ability to iterate through the results. This approach is the same taken by the popular fts C functions. Tested on x86_64-pc-linux-gnu, committed on trunk gcc/ada/ * libgnat/a-direct.adb (Search_Data): Remove type. (Directory_Vectors): New package instantiation. (Search_State): New type. (Fetch_Next_Entry): Remove. (Close): Remove. (Finalize): Rewritten. (Full_Name): Ditto. (Get_Next_Entry): Return next entry from Search results vector rather than querying the directory directly using readdir. (Kind): Rewritten. (Modification_Time): Rewritten. (More_Entries): Use Search state cursor to determine if more entries are available for users to read. (Simple_Name): Rewritten. (Size): Rewritten. (Start_Search_Internal): Rewritten to load the contents of the directory that matches the pattern and filter into the search object. * libgnat/a-direct.ads (Search_Type): New type. (Search_Ptr): Ditto. (Directory_Entry_Type): Rewritten to support new Start_Search procedure. * libgnat/s-filatt.ads (File_Length_Attr): New function. patch.diff.gz Description: application/gzip
[Ada] Fix the check of the 'Old prefix
The check did miss the part of Ada 2022 RM 6.1.1 (27/5) that the use of an entity declared within the postcondition expression is allowed if it's declared within the prefix itself. Tested on x86_64-pc-linux-gnu, committed on trunk gcc/ada/ * sem_attr.adb (Check_Reference): Fix condition.diff --git a/gcc/ada/sem_attr.adb b/gcc/ada/sem_attr.adb --- a/gcc/ada/sem_attr.adb +++ b/gcc/ada/sem_attr.adb @@ -5151,11 +5151,14 @@ package body Sem_Attr is -- Entities mentioned within the prefix of attribute 'Old must -- be global to the related postcondition. If this is not the -- case, then the scope of the local entity is nested within - -- that of the subprogram. + -- that of the subprogram. Moreover, we need to know whether + -- Entity (Nod) occurs in the tree rooted at the prefix to + -- ensure the entity is not declared within then prefix itself. elsif Is_Entity_Name (Nod) and then Present (Entity (Nod)) and then Scope_Within (Scope (Entity (Nod)), Subp_Id) + and then not In_Subtree (Entity (Nod), P) then Error_Attr ("prefix of attribute % cannot reference local entities",
[Ada] Fix uses of pragma Unreferenced in MinGW runtime unit
GNAT now emits more warnings about pragma Unreferenced. Tested on x86_64-pc-linux-gnu, committed on trunk gcc/ada/ * libgnarl/s-taprop__mingw.adb (Timed_Sleep): Remove "pragma Unreferenced" for Result. (Timed_Delay): Likewise.diff --git a/gcc/ada/libgnarl/s-taprop__mingw.adb b/gcc/ada/libgnarl/s-taprop__mingw.adb --- a/gcc/ada/libgnarl/s-taprop__mingw.adb +++ b/gcc/ada/libgnarl/s-taprop__mingw.adb @@ -559,7 +559,6 @@ package body System.Task_Primitives.Operations is Abs_Time : Duration; Result : Integer; - pragma Unreferenced (Result); Local_Timedout : Boolean; @@ -615,7 +614,6 @@ package body System.Task_Primitives.Operations is Timedout : Boolean; Result : Integer; - pragma Unreferenced (Timedout, Result); begin Write_Lock (Self_ID);
[Ada] Fix layout of pragma Inline in generated AST unit
Make the generated nmake.ads unit look more like it was written with GNAT style rules in mind; semantics is unaffected. Cleanup related to fix of default initialization in multi-dimensional arrays, which used to explicitly call the Nmake.Make_Null routine. Tested on x86_64-pc-linux-gnu, committed on trunk gcc/ada/ * gen_il-gen.adb (Put_Make_Decls): Put pragma Inline in a dedicated line, so that the current indentation is taken into account.diff --git a/gcc/ada/gen_il-gen.adb b/gcc/ada/gen_il-gen.adb --- a/gcc/ada/gen_il-gen.adb +++ b/gcc/ada/gen_il-gen.adb @@ -2472,7 +2472,8 @@ package body Gen_IL.Gen is for T in First_Concrete (Root) .. Last_Concrete (Root) loop if T not in N_Unused_At_Start | N_Unused_At_End then Put_Make_Spec (S, Root, T); - Put (S, ";" & LF & "pragma " & Inline & " (Make_" & + Put (S, ";" & LF); + Put (S, "pragma " & Inline & " (Make_" & Image_Sans_N (T) & ");" & LF & LF); end if; end loop;
[Ada] Fix style in expansion of multi-dimensional array aggregates
Cleanup; semantics is unaffected. Tested on x86_64-pc-linux-gnu, committed on trunk gcc/ada/ * exp_aggr.adb (Build_Array_Aggr_Code): Fix inconsistent style in comments and code.diff --git a/gcc/ada/exp_aggr.adb b/gcc/ada/exp_aggr.adb --- a/gcc/ada/exp_aggr.adb +++ b/gcc/ada/exp_aggr.adb @@ -1021,7 +1021,7 @@ package body Exp_Aggr is -- 2. If the aggregate contains positional elements we - -- (a) translate the positional elements in a series of assignments + -- (a) Translate the positional elements in a series of assignments -- (b) Generate a final loop to cover the others choice if any. -- Note that this final loop has to be a while loop since the case @@ -1032,7 +1032,7 @@ package body Exp_Aggr is -- cannot be handled by a for loop. Thus for the following - -- array (L .. H) := (.. positional elements.., others =>E); + -- array (L .. H) := (.. positional elements.., others => E); -- we always generate something like: @@ -2063,11 +2063,9 @@ package body Exp_Aggr is -- Construct "for L_J in Index_Base range L .. H" L_Iteration_Scheme := - Make_Iteration_Scheme - (Loc, + Make_Iteration_Scheme (Loc, Loop_Parameter_Specification => -Make_Loop_Parameter_Specification - (Loc, +Make_Loop_Parameter_Specification (Loc, Defining_Identifier => L_J, Discrete_Subtype_Definition => L_Range));
[Ada] Crash in class-wide pre/postconditions
The compiler may crash processing a class-wide pre/postcondition that has dispatching calls using the Object.Operation notation. Tested on x86_64-pc-linux-gnu, committed on trunk gcc/ada/ * atree.ads (Traverse_Func_With_Parent): New generic subprogram. (Traverse_Proc_With_Parent): Likewise. * atree.adb (Parents_Stack): New table used to traverse trees passing the parent field of each node. (Internal_Traverse_With_Parent): New generic subprogram. (Traverse_Func_With_Parent): Likewise. (Traverse_Proc_With_Parent): Likewise. * contracts.adb (Fix_Parents): New subprogram. (Restore_Original_Selected_Component): Enhanced to fix the parent field of restored nodes. (Inherit_Condition): Adding assertions to check the parent field of inherited conditions and to ensure that the built inherited condition has no reference to the formals of the parent subprogram. * sem_util.ads, sem_util.adb (Check_Parents): New subprogram.diff --git a/gcc/ada/atree.adb b/gcc/ada/atree.adb --- a/gcc/ada/atree.adb +++ b/gcc/ada/atree.adb @@ -88,6 +88,23 @@ package body Atree is Table_Increment => Alloc.Node_Offsets_Increment, Table_Name => "Orig_Nodes"); + -- + -- Parent Stack -- + -- + + -- A separate table is used to traverse trees. It passes the parent field + -- of each node to the called process subprogram. It is defined global to + -- avoid adding performance overhead if allocated each time the traversal + -- functions are invoked. + + package Parents_Stack is new Table.Table + (Table_Component_Type => Node_Id, + Table_Index_Type => Nat, + Table_Low_Bound => 1, + Table_Initial=> 256, + Table_Increment => 100, + Table_Name => "Parents_Stack"); + -- -- Paren_Count Handling -- -- @@ -135,6 +152,20 @@ package body Atree is -- Fix up parent pointers for the children of Fix_Node after a copy, -- setting them to Fix_Node when they pointed to Ref_Node. + generic + with function Process +(Parent_Node : Node_Id; + Node: Node_Id) return Traverse_Result is <>; + function Internal_Traverse_With_Parent + (Node : Node_Id) return Traverse_Final_Result; + pragma Inline (Internal_Traverse_With_Parent); + -- Internal function that provides a functionality similar to Traverse_Func + -- but extended to pass the Parent node to the called Process subprogram; + -- delegates to Traverse_Func_With_Parent the initialization of the stack + -- data structure which stores the parent nodes (cf. Parents_Stack). + -- ??? Could we factorize the common code of Internal_Traverse_Func and + -- Traverse_Func? + procedure Mark_New_Ghost_Node (N : Node_Or_Entity_Id); -- Mark arbitrary node or entity N as Ghost when it is created within a -- Ghost region. @@ -2322,6 +2353,167 @@ package body Atree is return Size_In_Slots (N) - N_Head; end Size_In_Slots_Dynamic; + --- + -- Internal_Traverse_With_Parent -- + --- + + function Internal_Traverse_With_Parent + (Node : Node_Id) return Traverse_Final_Result + is + Tail_Recursion_Counter : Natural := 0; + + procedure Pop_Parents; + -- Pop enclosing nodes of tail recursion plus the current parent. + + function Traverse_Field (Fld : Union_Id) return Traverse_Final_Result; + -- Fld is one of the Traversed fields of Nod, which is necessarily a + -- Node_Id or List_Id. It is traversed, and the result is the result of + -- this traversal. + + - + -- Pop_Parents -- + - + + procedure Pop_Parents is + begin + -- Pop the enclosing nodes of the tail recursion + + for J in 1 .. Tail_Recursion_Counter loop +Parents_Stack.Decrement_Last; + end loop; + + -- Pop the current node + + pragma Assert (Parents_Stack.Table (Parents_Stack.Last) = Node); + Parents_Stack.Decrement_Last; + end Pop_Parents; + + + -- Traverse_Field -- + + + function Traverse_Field (Fld : Union_Id) return Traverse_Final_Result is + begin + if Fld /= Union_Id (Empty) then + +-- Descendant is a node + +if Fld in Node_Range then + return Internal_Traverse_With_Parent (Node_Id (Fld)); + +-- Descendant is a list + +elsif Fld in List_Range then + declare + Elmt : Node_Id := First (List_Id (Fld)); + begin + while Present (Elmt) loop + if Internal_Traverse_With_Parent (Elmt) = Abandon then +
[Ada] More default initialization for multi-dim array aggregates
Expansion of multi-dimensional array aggregates with boxes (e.g. "(others => (others => <>))" only applied default initialization to components of a scalar type with Default_Value aspect and of an access type (which are initialized by default to null). Now default initialization is applied to components of all types that require default initialization (e.g. because of pragma Normalize_Scalars), except for those with pragma Suppress_Initialization. Tested on x86_64-pc-linux-gnu, committed on trunk gcc/ada/ * exp_aggr.adb (Gen_Assign): Remove explicit initialization for components of access types. (Get_Assoc_Expr): Enable initialization for components of all types that require simple initialization.diff --git a/gcc/ada/exp_aggr.adb b/gcc/ada/exp_aggr.adb --- a/gcc/ada/exp_aggr.adb +++ b/gcc/ada/exp_aggr.adb @@ -1872,12 +1872,6 @@ package body Exp_Aggr is Set_Etype (Indexed_Comp, Ctype); Append_To (Stmts, Make_Invariant_Call (Indexed_Comp)); end if; - -elsif Is_Access_Type (Ctype) then - Append_To (Stmts, - Make_Assignment_Statement (Loc, - Name => New_Copy_Tree (Indexed_Comp), - Expression => Make_Null (Loc))); end if; if Needs_Finalization (Ctype) then @@ -2212,15 +2206,10 @@ package body Exp_Aggr is begin if Box_Present (Assoc) then -if Is_Scalar_Type (Ctype) then - if Present (Default_Aspect_Component_Value (Typ)) then - return Default_Aspect_Component_Value (Typ); - elsif Present (Default_Aspect_Value (Ctype)) then - return Default_Aspect_Value (Ctype); - else - return Empty; - end if; - +if Present (Default_Aspect_Component_Value (Typ)) then + return Default_Aspect_Component_Value (Typ); +elsif Needs_Simple_Initialization (Ctype) then + return Get_Simple_Init_Val (Ctype, N); else return Empty; end if;
[Ada] Cleanup and modification of unreferenced warnings
This patch modifies the behavior of pragma Unreferenced to be consistent in its behavior, by counting all variables specified as "Out" actual parameters as being referenced instead of only the first "Out" parameter. Additionally, much related duplicated has been removed. Tested on x86_64-pc-linux-gnu, committed on trunk gcc/ada/ * comperr.adb (Delete_SCIL_Files): Replace unnecessary Unreferenced pragma with specific pragma Warnings. * doc/gnat_rm/implementation_defined_pragmas.rst (Unreferenced): Add documentation for new behavior. * gnat_rm.texi: Regenerate. * erroutc.adb (Set_At): Remove useless assignment. * exp_ch2.adb (In_Assignment_Context): Deleted. (Is_Object_Renaming_Name): Replace calls to Is_LHS with calls to Known_To_Be_Assigned. (Expand_Current_Value): Replace calls to May_Be_Lvalue with calls to Known_To_Be_Assigned. (Expand_Entry_Paramter): Replace calls to In_Assignment_Context with calls to Known_To_Be_Assigned. * exp_ch4.adb (Expand_N_Op_Rem): Remove unnecessary Unreferenced pragma. * exp_imgv.adb (Build_Enumeration_Image_Tables): Default initialize S_N. * ghost.adb (Check_Ghost_Policy): Replace call to May_Be_Lvalue with call to Known_To_Be_Assigned. * lib-xref.adb (Is_On_LHS): Deleted. (OK_To_Set_Referenced): Rewrite subprogram to encompass the new pragma Unreferenced behavior. (Process_Deferred_References): Replace call to Is_LHS with call to Known_To_Be_Assigned. * libgnarl/s-taasde.adb, libgnarl/s-tasren.adb, libgnarl/s-tpobop.adb, libgnat/a-calend.adb, libgnat/a-calfor.adb, libgnat/a-cbdlli.adb, libgnat/a-cbhama.adb, libgnat/a-cbhase.adb, libgnat/a-cbmutr.adb, libgnat/a-cborma.adb, libgnat/a-cborse.adb, libgnat/a-cdlili.adb, libgnat/a-cfhama.adb, libgnat/a-cforse.adb, libgnat/a-cidlli.adb, libgnat/a-cihama.adb, libgnat/a-cihase.adb, libgnat/a-cimutr.adb, libgnat/a-ciorma.adb, libgnat/a-ciormu.adb, libgnat/a-ciorse.adb, libgnat/a-cohama.adb, libgnat/a-cohase.adb, libgnat/a-comutr.adb, libgnat/a-convec.adb, libgnat/a-coorma.adb, libgnat/a-coormu.adb, libgnat/a-coorse.adb, libgnat/a-crdlli.adb, libgnat/a-tigeau.adb, libgnat/a-wtgeau.adb, libgnat/a-ztgeau.adb, libgnat/g-calend.adb, libgnat/g-comlin.adb, libgnat/g-expect.adb, libgnat/g-mbflra.adb, libgnat/g-spipat.adb, libgnat/s-fatgen.adb, libgnat/s-fileio.adb, libgnat/s-os_lib.adb, libgnat/s-regpat.adb, libgnat/s-valued.adb, libgnat/s-valuer.adb: Remove unnecessary Unreferenced pragmas * sem_ch10.adb (Process_Spec_Clauses): Remove useless assignments. * sem_ch13.adb (Validate_Literal_Aspect): Default initialize I. * sem_ch3.adb (Build_Derived_Concurrent_Type): Default initialize Corr_Decl. * sem_ch8.adb (Undefined): Replace calls to Is_LHS with calls to Known_To_Be_Assigned. (In_Abstract_View_Pragma): Likewise. * sem_eval.adb (Eval_Selected_Component): Replace calls to Is_LHS with calls to Known_To_Be_Assigned. * sem_res.adb (Init_Component): Replace calls to May_Be_Lvalue with calls to Known_To_Be_Assigned. * sem_util.adb, sem_util.ads (End_Label_Loc): Default initialize Owner. (Explain_Limited_Type): Default initialize Expr_Func. (Find_Actual): Modified to handle entry families. (Is_LHS): Deleted. (May_Be_Lvalue): Deleted. (Known_To_Be_Assigned): Modified and improved to handle all cases. * sem_warn.adb (Traverse_Result): Replace calls to May_Be_Lvalue with calls to Known_To_Be_Assigned. (Check_Ref): Modify error on unreferenced out parameters to take into account different warning flags. patch.diff.gz Description: application/gzip
[Ada] Spurious error caused by order of interfaces in full view
The frontend reports a spurious error when the order of interfaces differ between the full view and the partial view of a private type defined in a generic unit. Tested on x86_64-pc-linux-gnu, committed on trunk gcc/ada/ * sem_ch3.adb (Reorder_Interfaces): When the conflicting interface is identified we just replace the interface in the list of interfaces of the tagged type (instead of adding a duplicate to the list of interfaces).diff --git a/gcc/ada/sem_ch3.adb b/gcc/ada/sem_ch3.adb --- a/gcc/ada/sem_ch3.adb +++ b/gcc/ada/sem_ch3.adb @@ -17272,7 +17272,6 @@ package body Sem_Ch3 is -- append the full view's original parent to the interface list, -- recursively call Derived_Type_Definition on the full type, and -- return True. If a match is not found, return False. --- ??? This seems broken in the case of generic packages. -- Reorder_Interfaces -- @@ -17281,6 +17280,7 @@ package body Sem_Ch3 is function Reorder_Interfaces return Boolean is Iface : Node_Id; New_Iface : Node_Id; + begin Iface := First (Interface_List (Def)); while Present (Iface) loop @@ -17290,7 +17290,7 @@ package body Sem_Ch3 is New_Iface := Make_Identifier (Sloc (N), Chars (Parent_Type)); - Append (New_Iface, Interface_List (Def)); + Rewrite (Iface, New_Iface); -- Analyze the transformed code
[Ada] Fix __gnat_kill on Windows
Terminate process only on terminating signals. Tested on x86_64-pc-linux-gnu, committed on trunk gcc/ada/ * adaint.c (__gnat_kill): Terminate process only in case of SIGKILL, SIGINT, SIGBREAK, SIGTERM, SIGABRT. Do not call OpenProcess if not going to terminate process.diff --git a/gcc/ada/adaint.c b/gcc/ada/adaint.c --- a/gcc/ada/adaint.c +++ b/gcc/ada/adaint.c @@ -3559,13 +3559,21 @@ void __gnat_kill (int pid, int sig, int close ATTRIBUTE_UNUSED) { #if defined(_WIN32) - HANDLE h = OpenProcess (PROCESS_ALL_ACCESS, FALSE, pid); - if (h == NULL) -return; + HANDLE h; - TerminateProcess (h, sig); + switch (sig) { +case 9: // SIGKILL is not declared in Windows headers +case SIGINT: +case SIGBREAK: +case SIGTERM: +case SIGABRT: + h = OpenProcess (PROCESS_ALL_ACCESS, FALSE, pid); + if (h != NULL) { +TerminateProcess (h, sig); +CloseHandle (h); + } + } - CloseHandle (h); #elif defined (__vxworks) /* Not implemented */ #else
[Ada] Fix a couple of issues with pragma Inspection_Point
The first issue is that the pragma may require the address of the objects subject to it to have their address taken, like Asm_Input and Asm_Output, so these objects need to be specifically marked. The second issue is that the detection of unfrozen objects was not robust enough and would miss objects that are explicit arguments of the pragma. Tested on x86_64-pc-linux-gnu, committed on trunk gcc/ada/ * exp_prag.adb (Expand_Pragma_Inspection_Point): Do a single pass over the arguments of the pragma. Set the Address_Taken flag on them and use the Has_Delayed_Freeze flag to spot those which have their elaboration delayed. Reuse the location variable Loc.diff --git a/gcc/ada/exp_prag.adb b/gcc/ada/exp_prag.adb --- a/gcc/ada/exp_prag.adb +++ b/gcc/ada/exp_prag.adb @@ -2354,12 +2354,13 @@ package body Exp_Prag is procedure Expand_Pragma_Inspection_Point (N : Node_Id) is Loc : constant Source_Ptr := Sloc (N); + A : List_Id; Assoc : Node_Id; - S : Entity_Id; E : Entity_Id; + Rip : Boolean; + S : Entity_Id; - Remove_Inspection_Point : Boolean := False; begin if No (Pragma_Argument_Associations (N)) then A := New_List; @@ -2389,45 +2390,47 @@ package body Exp_Prag is Set_Pragma_Argument_Associations (N, A); end if; - -- Expand the arguments of the pragma. Expanding an entity reference - -- is a noop, except in a protected operation, where a reference may - -- have to be transformed into a reference to the corresponding prival. - -- Are there other pragmas that may require this ??? + -- Process the arguments of the pragma and expand them. Expanding an + -- entity reference is a noop, except in a protected operation, where + -- a reference may have to be transformed into a reference to the + -- corresponding prival. Are there other pragmas that require this ??? + Rip := False; Assoc := First (Pragma_Argument_Associations (N)); while Present (Assoc) loop - Expand (Expression (Assoc)); - Next (Assoc); - end loop; + -- The back end may need to take the address of the object - -- If any of the references have a freeze node, it must appear before - -- pragma Inspection_Point, otherwise the entity won't be available when - -- Gigi processes Inspection_Point. - -- When this requirement isn't met, turn the pragma into a no-op. + Set_Address_Taken (Entity (Expression (Assoc))); - Assoc := First (Pragma_Argument_Associations (N)); - while Present (Assoc) loop + Expand (Expression (Assoc)); + + -- If any of the objects have a freeze node, it must appear before + -- pragma Inspection_Point, otherwise the entity won't be elaborated + -- when Gigi processes the pragma. - if Present (Freeze_Node (Entity (Expression (Assoc and then - not Is_Frozen (Entity (Expression (Assoc))) + if Has_Delayed_Freeze (Entity (Expression (Assoc))) + and then not Is_Frozen (Entity (Expression (Assoc))) then -Error_Msg_NE ("??inspection point references unfrozen object &", - Assoc, - Entity (Expression (Assoc))); -Remove_Inspection_Point := True; +Error_Msg_NE + ("??inspection point references unfrozen object &", + Assoc, + Entity (Expression (Assoc))); +Rip := True; end if; Next (Assoc); end loop; - if Remove_Inspection_Point then + -- When the above requirement isn't met, turn the pragma into a no-op + + if Rip then Error_Msg_N ("\pragma will be ignored", N); -- We can't just remove the pragma from the tree as it might be -- iterated over by the caller. Turn it into a null statement -- instead. - Rewrite (N, Make_Null_Statement (Sloc (N))); + Rewrite (N, Make_Null_Statement (Loc)); end if; end Expand_Pragma_Inspection_Point;
[Ada] Remove repeated routines for printing AST in Mixed_Case
Code cleanup; behaviour is unaffected. Tested on x86_64-pc-linux-gnu, committed on trunk gcc/ada/ * osint.adb (To_Lower): Clarify that only To_Lower function causes bootstrap issues; fix style. * treepr.adb (Print_Str_Mixed_Case): Reuse existing case conversion routine. (To_Mixed): Rename from Capitalize; reuse System.Case_Util procedure and explain the bootstrap issue.diff --git a/gcc/ada/osint.adb b/gcc/ada/osint.adb --- a/gcc/ada/osint.adb +++ b/gcc/ada/osint.adb @@ -1061,7 +1061,8 @@ package body Osint is function File_Names_Equal (File1, File2 : String) return Boolean is function To_Lower (A : String) return String; - -- For bootstrap reasons, we cannot use To_Lower from System.Case_Util + -- For bootstrap reasons, we cannot use To_Lower function from + -- System.Case_Util. -- -- To_Lower -- @@ -1074,6 +1075,8 @@ package body Osint is return Result; end To_Lower; + -- Start of processing for File_Names_Equal + begin if File_Names_Case_Sensitive then return File1 = File2; diff --git a/gcc/ada/treepr.adb b/gcc/ada/treepr.adb --- a/gcc/ada/treepr.adb +++ b/gcc/ada/treepr.adb @@ -25,7 +25,6 @@ with Aspects; use Aspects; with Atree;use Atree; -with Csets;use Csets; with Debug;use Debug; with Einfo;use Einfo; with Einfo.Entities; use Einfo.Entities; @@ -45,6 +44,7 @@ with Snames; use Snames; with Sinput; use Sinput; with Stand;use Stand; with Stringt; use Stringt; +with System.Case_Util; use System.Case_Util; with SCIL_LL; use SCIL_LL; with Uintp;use Uintp; with Urealp; use Urealp; @@ -135,9 +135,9 @@ package body Treepr is function From_Union is new Unchecked_Conversion (Union_Id, Uint); function From_Union is new Unchecked_Conversion (Union_Id, Ureal); - function Capitalize (S : String) return String; - procedure Capitalize (S : in out String); - -- Turns an identifier into Mixed_Case + function To_Mixed (S : String) return String; + -- Turns an identifier into Mixed_Case. For bootstrap reasons, we cannot + -- use To_Mixed function from System.Case_Util. function Image (F : Node_Or_Entity_Field) return String; @@ -255,35 +255,6 @@ package body Treepr is -- descendants are to be printed. Prefix_Str is to be added to all -- printed lines. - - -- Capitalize -- - - - procedure Capitalize (S : in out String) is - Cap : Boolean := True; - begin - for J in S'Range loop - declare -Old : constant Character := S (J); - begin -if Cap then - S (J) := Fold_Upper (S (J)); -else - S (J) := Fold_Lower (S (J)); -end if; - -Cap := Old = '_'; - end; - end loop; - end Capitalize; - - function Capitalize (S : String) return String is - begin - return Result : String (S'Range) := S do - Capitalize (Result); - end return; - end Capitalize; - -- -- Hash -- -- @@ -400,7 +371,7 @@ package body Treepr is when others => declare - Result : constant String := Capitalize (F'Img); + Result : constant String := To_Mixed (F'Img); begin return Result (3 .. Result'Last); -- Remove "F_" end; @@ -1713,22 +1684,8 @@ package body Treepr is -- procedure Print_Str_Mixed_Case (S : String) is - Ucase : Boolean; - begin - if Phase = Printing then - Ucase := True; - - for J in S'Range loop -if Ucase then - Write_Char (S (J)); -else - Write_Char (Fold_Lower (S (J))); -end if; - -Ucase := (S (J) = '_'); - end loop; - end if; + Print_Str (To_Mixed (S)); end Print_Str_Mixed_Case; @@ -1862,6 +1819,17 @@ package body Treepr is Next_Serial_Number := Next_Serial_Number + 1; end Set_Serial_Number; + -- + -- To_Mixed -- + -- + + function To_Mixed (S : String) return String is + begin + return Result : String (S'Range) := S do + To_Mixed (Result); + end return; + end To_Mixed; + --- -- Tree_Dump -- ---
[Ada] Simplify traversal in hooking of transient scopes
Subprogram calls can be detected with just Traverse_Func, we don't need a separate global variable or a Traverse_Proc (which is a wrapper for Traverse_Func with a yet another variable). Cleanup related to handling of transient scopes in various routines for (pre)analysis and resolution. Semantics is unaffected. Tested on x86_64-pc-linux-gnu, committed on trunk gcc/ada/ * exp_ch7.adb (Process_Transients_In_Scope): Remove unnecessary initialization of Must_Hook; change Detect_Subprogram_Call from function to procedure; adapt caller.diff --git a/gcc/ada/exp_ch7.adb b/gcc/ada/exp_ch7.adb --- a/gcc/ada/exp_ch7.adb +++ b/gcc/ada/exp_ch7.adb @@ -6188,15 +6188,15 @@ package body Exp_Ch7 is Last_Object : Node_Id; Related_Node : Node_Id) is - Must_Hook : Boolean := False; + Must_Hook : Boolean; -- Flag denoting whether the context requires transient object -- export to the outer finalizer. function Is_Subprogram_Call (N : Node_Id) return Traverse_Result; - -- Determine whether an arbitrary node denotes a subprogram call + -- Return Abandon if arbitrary node denotes a subprogram call - procedure Detect_Subprogram_Call is - new Traverse_Proc (Is_Subprogram_Call); + function Has_Subprogram_Call is + new Traverse_Func (Is_Subprogram_Call); procedure Process_Transient_In_Scope (Obj_Decl : Node_Id; @@ -6216,7 +6216,6 @@ package body Exp_Ch7 is -- A regular procedure or function call if Nkind (N) in N_Subprogram_Call then - Must_Hook := True; return Abandon; -- Special cases @@ -6226,20 +6225,13 @@ package body Exp_Ch7 is -- of the call. elsif Is_Rewrite_Substitution (N) then - Detect_Subprogram_Call (Original_Node (N)); - - if Must_Hook then - return Abandon; - else - return OK; - end if; + return Has_Subprogram_Call (Original_Node (N)); -- Generalized indexing always involves a function call elsif Nkind (N) = N_Indexed_Component and then Present (Generalized_Indexing (N)) then - Must_Hook := True; return Abandon; -- Keep searching @@ -6476,8 +6468,8 @@ package body Exp_Ch7 is -- due to the possibility of abnormal call termination. else -Detect_Subprogram_Call (N); -Blk_Ins := Last_Object; +Must_Hook := Has_Subprogram_Call (N) = Abandon; +Blk_Ins := Last_Object; end if; if Clean then
[Ada] Remove extra space before THEN keywords
Style cleanup; semantics is unaffected. Offending occurrences found with: $ grep "[A-Za-z0-9\)]+ +then$" -C 3 and reviewed manually, because some of them were due to explicit layout. Tested on x86_64-pc-linux-gnu, committed on trunk gcc/ada/ * exp_ch5.adb, exp_disp.adb, exp_util.adb, par-ch4.adb, sem_ch13.adb: Remove extra space before THEN that occurs at the end of a line.diff --git a/gcc/ada/exp_ch5.adb b/gcc/ada/exp_ch5.adb --- a/gcc/ada/exp_ch5.adb +++ b/gcc/ada/exp_ch5.adb @@ -2664,7 +2664,7 @@ package body Exp_Ch5 is Rewrite (Lhs, OK_Convert_To (Base_Type (Typ), Lhs)); Apply_Discriminant_Check (Rhs, Typ, Lhs); - elsif Is_Array_Type (Typ) and then Is_Constrained (Typ) then + elsif Is_Array_Type (Typ) and then Is_Constrained (Typ) then Rewrite (Rhs, OK_Convert_To (Base_Type (Typ), Rhs)); Rewrite (Lhs, OK_Convert_To (Base_Type (Typ), Lhs)); Apply_Length_Check (Rhs, Typ); diff --git a/gcc/ada/exp_disp.adb b/gcc/ada/exp_disp.adb --- a/gcc/ada/exp_disp.adb +++ b/gcc/ada/exp_disp.adb @@ -4615,7 +4615,7 @@ package body Exp_Disp is -- case concerning the need for this check, and this topic may -- go back to the ARG. - if not Is_Abstract_Subprogram (Prim) then + if not Is_Abstract_Subprogram (Prim) then Formal := First_Formal (Prim); while Present (Formal) loop Check_Premature_Freezing (Prim, Typ, Etype (Formal)); diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb --- a/gcc/ada/exp_util.adb +++ b/gcc/ada/exp_util.adb @@ -3752,7 +3752,7 @@ package body Exp_Util is -- Anonymous arrays in object declarations have no explicit declaration -- so use the related object declaration as the insertion point. - elsif Is_Itype (Work_Typ) and then Is_Array_Type (Work_Typ) then + elsif Is_Itype (Work_Typ) and then Is_Array_Type (Work_Typ) then Typ_Decl := Associated_Node_For_Itype (Work_Typ); -- Derived types with the full view as parent do not have a partial diff --git a/gcc/ada/par-ch4.adb b/gcc/ada/par-ch4.adb --- a/gcc/ada/par-ch4.adb +++ b/gcc/ada/par-ch4.adb @@ -2968,7 +2968,7 @@ package body Ch4 is Save_Scan_State (Scan_State); Scan; -- past FOR - if Token = Tok_All or else Token = Tok_Some then + if Token = Tok_All or else Token = Tok_Some then Restore_Scan_State (Scan_State); -- To FOR Node1 := P_Quantified_Expression; diff --git a/gcc/ada/sem_ch13.adb b/gcc/ada/sem_ch13.adb --- a/gcc/ada/sem_ch13.adb +++ b/gcc/ada/sem_ch13.adb @@ -16005,7 +16005,7 @@ package body Sem_Ch13 is function Valid_Empty (E : Entity_Id) return Boolean is begin - if Etype (E) /= Typ or else Scope (E) /= Scope (Typ) then + if Etype (E) /= Typ or else Scope (E) /= Scope (Typ) then return False; elsif Ekind (E) = E_Constant then
[Ada] Fix exit status of GNAT.Expect.Close call on running process
Fix exit status processing logic in __gnat_waitpid. Fix GNAT.Expect.Interrupt on Windows. It was terminating the calling process. Tested on x86_64-pc-linux-gnu, committed on trunk gcc/ada/ * expect.c (__gnat_waitpid): Use macros WIFEXITED, WEXITSTATUS, WIFSIGNALED, WTERMSIG, WIFSTOPPED, WSTOPSIG to get exit status or signal that caused the child process to terminate/stop. Do not process exit status in case of error in waitpid call. * adaint.c (__gnat_kill): Use of GenerateConsoleCtrlEvent is removed in Windows variant as it actually is not working and was terminating the calling process. Set signal number into exit code parameter of TerminateProcess to work the same like in Linux.diff --git a/gcc/ada/adaint.c b/gcc/ada/adaint.c --- a/gcc/ada/adaint.c +++ b/gcc/ada/adaint.c @@ -3562,18 +3562,8 @@ __gnat_kill (int pid, int sig, int close ATTRIBUTE_UNUSED) HANDLE h = OpenProcess (PROCESS_ALL_ACCESS, FALSE, pid); if (h == NULL) return; - if (sig == 9) -{ - TerminateProcess (h, 1); -} - else if (sig == SIGINT) -GenerateConsoleCtrlEvent (CTRL_C_EVENT, pid); - else if (sig == SIGBREAK) -GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT, pid); - /* ??? The last two alternatives don't really work. SIGBREAK requires setting - up process groups at start time which we don't do; treating SIGINT is just - not possible apparently. So we really only support signal 9. Fortunately - that's all we use in GNAT.Expect */ + + TerminateProcess (h, sig); CloseHandle (h); #elif defined (__vxworks) diff --git a/gcc/ada/expect.c b/gcc/ada/expect.c --- a/gcc/ada/expect.c +++ b/gcc/ada/expect.c @@ -345,8 +345,17 @@ __gnat_waitpid (int pid) { int status = 0; - waitpid (pid, , 0); - status = WEXITSTATUS (status); + if (waitpid (pid, , 0) == -1) { + return -1; + } + + if WIFEXITED (status) { + status = WEXITSTATUS (status); + } else if WIFSIGNALED (status) { + status = WTERMSIG (status); + } else if WIFSTOPPED (status) { + status = WSTOPSIG (status); + } return status; }
[Ada] Remove explicit expansion of block with general case statement
When a general case statements is rewritten into a block, it is enough to call Analyze on this block node, because analysis of non-expressions automatically triggers expansion. Cleanup originating from investigating many variants of routines for (pre)analysis and resolution. Tested on x86_64-pc-linux-gnu, committed on trunk gcc/ada/ * exp_ch5.adb (Expand_N_Case_Statement): Remove explicit expansion.diff --git a/gcc/ada/exp_ch5.adb b/gcc/ada/exp_ch5.adb --- a/gcc/ada/exp_ch5.adb +++ b/gcc/ada/exp_ch5.adb @@ -39,7 +39,6 @@ with Exp_Dbug; use Exp_Dbug; with Exp_Pakd; use Exp_Pakd; with Exp_Tss;use Exp_Tss; with Exp_Util; use Exp_Util; -with Expander; use Expander; with Inline; use Inline; with Namet; use Namet; with Nlists; use Nlists; @@ -3876,7 +3875,6 @@ package body Exp_Ch5 is if Extensions_Allowed and then not Is_Discrete_Type (Etype (Expr)) then Rewrite (N, Expand_General_Case_Statement); Analyze (N); - Expand (N); return; end if;
[Ada] Update -gnatwr doc for import of parent package
This construct is now flagged with -gnatwr. Tested on x86_64-pc-linux-gnu, committed on trunk gcc/ada/ * doc/gnat_ugn/building_executable_programs_with_gnat.rst: Update -gnatwr documentation. * gnat_ugn.texi: Regenerate.diff --git a/gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst b/gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst --- a/gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst +++ b/gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst @@ -3703,6 +3703,8 @@ of the pragma in the :title:`GNAT_Reference_manual`). * Comparison of an object or (unary or binary) operation of boolean type to an explicit True value. + * Import of parent package. + The default is that warnings for redundant constructs are not given. diff --git a/gcc/ada/gnat_ugn.texi b/gcc/ada/gnat_ugn.texi --- a/gcc/ada/gnat_ugn.texi +++ b/gcc/ada/gnat_ugn.texi @@ -11974,6 +11974,9 @@ to be non-negative @item Comparison of an object or (unary or binary) operation of boolean type to an explicit True value. + +@item +Import of parent package. @end itemize The default is that warnings for redundant constructs are not given. @@ -29241,8 +29244,8 @@ to permit their use in free software. @printindex ge -@anchor{gnat_ugn/gnat_utility_programs switches-related-to-project-files}@w{ } @anchor{cf}@w{ } +@anchor{gnat_ugn/gnat_utility_programs switches-related-to-project-files}@w{ } @c %**end of body @bye
[Ada] Fix comment about subprogram unnesting and unconstrained arrays
The original code for subprogram unnesting used 'Access for unconstrained arrays. This was recently changed to 'Unchecked_Access for GNAT-to-LLVM, but a reference to 'Access still appears in the comment. Tested on x86_64-pc-linux-gnu, committed on trunk gcc/ada/ * exp_unst.adb (Unnest_Subprogram): Sync comment with the current code.diff --git a/gcc/ada/exp_unst.adb b/gcc/ada/exp_unst.adb --- a/gcc/ada/exp_unst.adb +++ b/gcc/ada/exp_unst.adb @@ -2093,7 +2093,8 @@ package body Exp_Unst is -- Build and insert the assignment: --ARECn.nam := nam'Address - -- or else 'Access for unconstrained array + -- or else 'Unchecked_Access for + -- unconstrained array. if Needs_Fat_Pointer (Ent) then Attr := Name_Unchecked_Access;
[Ada] Fix inconsistent quoting in messages about compile-time errors
In some messages of the form "XXX_Error will be raised at run time" the XXX_Error was enclosed in quotes, in other it was not. Now all messages of this form are emitted without quotes. Note: in messages emitted from routine Possible_Local_Raise we still quote names of exceptions, but there indeed any exception name can appear and quotes seem to be the right choice. Tested on x86_64-pc-linux-gnu, committed on trunk gcc/ada/ * exp_ch4.adb (Raise_Accessibility_Error): Move exception name to the message string; move << control characters to the end, for consistency. * sem_ch6.adb (Analyze_Function_Return): Likewise. * sem_util.adb (Compile_Time_Constraint_Error): Likewise. * gcc-interface/decl.c (gnat_to_gnu_entity): Remove quotes around Storage_Error. * gcc-interface/trans.c (gnat_to_gnu): Remove quotes around Constraint_Error. gcc/testsuite/ * gnat.dg/aggr26.adb: Update expected error message.diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb --- a/gcc/ada/exp_ch4.adb +++ b/gcc/ada/exp_ch4.adb @@ -11885,8 +11885,8 @@ package body Exp_Ch4 is Reason => PE_Accessibility_Check_Failed)); Set_Etype (N, Target_Type); - Error_Msg_N ("< (others => 0)); -- { dg-warning "\"Storage_Error\" will be raised at run time" } +H : array (Positive) of Row := (others => (others => 0)); -- { dg-warning "Storage_Error will be raised at run time" } begin null;
[Ada] Consistent suppression for warnings inside null loops
Warnings for nodes inside null loops were suppressed if posted with Error_Msg_NLE and emitted if posted with other error-reporting routines. This was inconsistent and error-prone. Part of removing quotes around exception names in messages, because messages without quotes will be now emitted by Error_Msg and not by Error_Msg_NLE. Tested on x86_64-pc-linux-gnu, committed on trunk gcc/ada/ * errout.adb (Error_Msg): Move warning suppression code from Error_Msg_NLE (Error_Msg_NLE): Warning suppression is now done by the internal call to Error_Msg.diff --git a/gcc/ada/errout.adb b/gcc/ada/errout.adb --- a/gcc/ada/errout.adb +++ b/gcc/ada/errout.adb @@ -440,6 +440,28 @@ package body Errout is and then Warnings_Detected >= Maximum_Messages then return; + + -- Suppress warnings inside a loop that is known to be null or is + -- probably null (i.e. when loop executes only if invalid values + -- present). In either case warnings in the loop are likely to be junk. + + elsif Is_Warning_Msg and then Present (N) then + + declare +P : Node_Id; + + begin +P := Parent (N); +while Present (P) loop + if Nkind (P) = N_Loop_Statement + and then Suppress_Loop_Warnings (P) + then + return; + end if; + + P := Parent (P); +end loop; + end; end if; -- The idea at this stage is that we have two kinds of messages @@ -1490,26 +1512,6 @@ package body Errout is Last_Killed := True; return; end if; - - -- Suppress if inside loop that is known to be null or is probably - -- null (case where loop executes only if invalid values present). - -- In either case warnings in the loop are likely to be junk. - - declare -P : Node_Id; - - begin -P := Parent (N); -while Present (P) loop - if Nkind (P) = N_Loop_Statement - and then Suppress_Loop_Warnings (P) - then - return; - end if; - - P := Parent (P); -end loop; - end; end if; -- Test for message to be output
[Ada] Remove unnecessary guard for inserting non-empty list
Calls to Insert_List_After and Insert_List_Before applied to empty lists do nothing, so there is no need to explicitly guard against such calls. Code cleanup; semantics is unaffected. Tested on x86_64-pc-linux-gnu, committed on trunk gcc/ada/ * exp_ch3.adb (Expand_N_Object_Declaration): Remove unnecessary guards. * exp_ch4.adb (Expand_N_If_Expression): Likewise; clarify comment. * exp_ch5.adb (Expand_N_If_Statement, Expand_Iterator_Loop_Over_Container): Likewise. * exp_ch9.adb (Expand_N_Task_Type_Declaration): Remove redundant guard. * freeze.adb (Freeze_All_Ent): Reduce scope of a local variable.diff --git a/gcc/ada/exp_ch3.adb b/gcc/ada/exp_ch3.adb --- a/gcc/ada/exp_ch3.adb +++ b/gcc/ada/exp_ch3.adb @@ -6908,9 +6908,7 @@ package body Exp_Ch3 is New_Nodes := Make_DT (Base_Typ, N); end if; -if not Is_Empty_List (New_Nodes) then - Insert_List_Before (N, New_Nodes); -end if; +Insert_List_Before (N, New_Nodes); end; end if; diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb --- a/gcc/ada/exp_ch4.adb +++ b/gcc/ada/exp_ch4.adb @@ -6198,18 +6198,10 @@ package body Exp_Ch4 is Set_Sloc (Parent (N), Loc); end if; - -- Make sure Then_Actions and Else_Actions are appropriately moved - -- to the new if statement. + -- Move Then_Actions and Else_Actions, if any, to the new if statement - if Present (Then_Actions (N)) then - Insert_List_Before - (First (Then_Statements (New_If)), Then_Actions (N)); - end if; - - if Present (Else_Actions (N)) then - Insert_List_Before - (First (Else_Statements (New_If)), Else_Actions (N)); - end if; + Insert_List_Before (First (Then_Statements (New_If)), Then_Actions (N)); + Insert_List_Before (First (Else_Statements (New_If)), Else_Actions (N)); Insert_Action (N, Decl); Insert_Action (N, New_If); diff --git a/gcc/ada/exp_ch5.adb b/gcc/ada/exp_ch5.adb --- a/gcc/ada/exp_ch5.adb +++ b/gcc/ada/exp_ch5.adb @@ -4559,9 +4559,7 @@ package body Exp_Ch5 is Set_Else_Statements (N, New_List (New_If)); - if Present (Condition_Actions (E)) then - Insert_List_Before (New_If, Condition_Actions (E)); - end if; + Insert_List_Before (New_If, Condition_Actions (E)); Remove (E); @@ -5455,9 +5453,7 @@ package body Exp_Ch5 is -- Condition_Actions of the iterator. Insert them now at the head of -- the loop. - if Present (Condition_Actions (Isc)) then - Insert_List_Before (N, Condition_Actions (Isc)); - end if; + Insert_List_Before (N, Condition_Actions (Isc)); Rewrite (N, New_Loop); Analyze (N); diff --git a/gcc/ada/exp_ch9.adb b/gcc/ada/exp_ch9.adb --- a/gcc/ada/exp_ch9.adb +++ b/gcc/ada/exp_ch9.adb @@ -12516,13 +12516,7 @@ package body Exp_Ch9 is -- procedure for this corresponding record type and we won't get it -- in time if we don't freeze now. - declare -L : constant List_Id := Freeze_Entity (Rec_Ent, N); - begin -if Is_Non_Empty_List (L) then - Insert_List_After (Body_Decl, L); -end if; - end; + Insert_List_After (Body_Decl, List => Freeze_Entity (Rec_Ent, N)); end if; -- Complete the expansion of access types to the current task type, if diff --git a/gcc/ada/freeze.adb b/gcc/ada/freeze.adb --- a/gcc/ada/freeze.adb +++ b/gcc/ada/freeze.adb @@ -2354,7 +2354,6 @@ package body Freeze is procedure Freeze_All_Ent (From : Entity_Id; After : in out Node_Id) is E : Entity_Id; Flist : List_Id; - Lastn : Node_Id; procedure Process_Flist; -- If freeze nodes are present, insert and analyze, and reset cursor @@ -2365,6 +2364,7 @@ package body Freeze is --- procedure Process_Flist is +Lastn : Node_Id; begin if Is_Non_Empty_List (Flist) then Lastn := Next (After);
[Ada] Remove unnecessary guards for appending non-empty lists
Calls to Append_List and Append_List_To applied with empty lists do nothing, so there is no need to explicitly guard against such calls. Tested on x86_64-pc-linux-gnu, committed on trunk gcc/ada/ * exp_ch3.adb (Build_Init_Procedure): Remove unnecessary guard. * exp_disp.adb (Make_DT): Likewise. * sem_ch12.adb (Analyze_Associations): Likewise.diff --git a/gcc/ada/exp_ch3.adb b/gcc/ada/exp_ch3.adb --- a/gcc/ada/exp_ch3.adb +++ b/gcc/ada/exp_ch3.adb @@ -2885,9 +2885,7 @@ package body Exp_Ch3 is Fixed_Comps=> False, Variable_Comps => True); - if Is_Non_Empty_List (Init_Tags_List) then - Append_List_To (Body_Stmts, Init_Tags_List); - end if; + Append_List_To (Body_Stmts, Init_Tags_List); end if; end if; diff --git a/gcc/ada/exp_disp.adb b/gcc/ada/exp_disp.adb --- a/gcc/ada/exp_disp.adb +++ b/gcc/ada/exp_disp.adb @@ -6379,9 +6379,7 @@ package body Exp_Disp is New_List (New_Occurrence_Of (DT_Ptr, Loc; end if; - if not Is_Empty_List (Elab_Code) then - Append_List_To (Result, Elab_Code); - end if; + Append_List_To (Result, Elab_Code); -- Populate the two auxiliary tables used for dispatching asynchronous, -- conditional and timed selects for synchronized types that implement diff --git a/gcc/ada/sem_ch12.adb b/gcc/ada/sem_ch12.adb --- a/gcc/ada/sem_ch12.adb +++ b/gcc/ada/sem_ch12.adb @@ -2248,9 +2248,7 @@ package body Sem_Ch12 is -- explicit box associations for the formals that are covered by an -- Others_Choice. - if not Is_Empty_List (Default_Formals) then - Append_List (Default_Formals, Formals); - end if; + Append_List (Default_Formals, Formals); return Assoc_List; end Analyze_Associations;
[Ada] Check scalar range in arrays constructed by concatenation
When concatenating scalars, we should check their range as in the following example: type uint8 is range 0 .. 255; type Array_Type is array (Positive range <>) of uint8; Array_1 : Array_Type := 42 & 256; This commit leads to emitting: - a warning if a constraint error is expected but the scalar fits in the base type. - an error if it does not fit in the base type Tested on x86_64-pc-linux-gnu, committed on trunk gcc/ada/ * sem_res.adb (Resolve_Op_Concat_Arg): Check range when concatenating scalars.diff --git a/gcc/ada/sem_res.adb b/gcc/ada/sem_res.adb --- a/gcc/ada/sem_res.adb +++ b/gcc/ada/sem_res.adb @@ -10185,7 +10185,7 @@ package body Sem_Res is ("\\interpretation as call yields&", Arg, Typ); Error_Msg_NE ("\\interpretation as indexing of call yields&", - Arg, Component_Type (Typ)); + Arg, Ctyp); else Error_Msg_N ("ambiguous operand for concatenation!", Arg); @@ -10208,10 +10208,30 @@ package body Sem_Res is end; end if; -Resolve (Arg, Component_Type (Typ)); +Resolve (Arg, Ctyp); if Nkind (Arg) = N_String_Literal then - Set_Etype (Arg, Component_Type (Typ)); + Set_Etype (Arg, Ctyp); + +elsif Is_Scalar_Type (Etype (Arg)) + and then Compile_Time_Known_Value (Arg) +then + -- Determine if the out-of-range violation constitutes a + -- warning or an error according to the expression base type, + -- according to Ada 2022 RM 4.9 (35/2). + + if Is_Out_Of_Range (Arg, Base_Type (Ctyp)) then + Apply_Compile_Time_Constraint_Error +(Arg, "value not in range of}", CE_Range_Check_Failed, + Ent => Base_Type (Ctyp), + Typ => Base_Type (Ctyp)); + + elsif Is_Out_Of_Range (Arg, Ctyp) then + Apply_Compile_Time_Constraint_Error +(Arg, "value not in range of}??", CE_Range_Check_Failed, + Ent => Ctyp, + Typ => Ctyp); + end if; end if; if Arg = Left_Opnd (N) then
[Ada] treepr: print value only for discrete types
Follow-on to previous change "Print value of static expression". Print only if the type is discrete. Tested on x86_64-pc-linux-gnu, committed on trunk gcc/ada/ * treepr.adb (Print_Node_Ref): Change "not Is_Array_Type" to "Is_Discrete_Type".diff --git a/gcc/ada/treepr.adb b/gcc/ada/treepr.adb --- a/gcc/ada/treepr.adb +++ b/gcc/ada/treepr.adb @@ -1643,13 +1643,13 @@ package body Treepr is end if; end if; - -- If this is an integer-like expression whose value is known, print - -- that value. + -- If this is a discrete expression whose value is known, print that + -- value. if Nkind (N) in N_Subexpr and then Compile_Time_Known_Value (N) and then Present (Etype (N)) - and then not Is_Array_Type (Etype (N)) + and then Is_Discrete_Type (Etype (N)) then if Is_Entity_Name (N) -- e.g. enumeration literal or else Nkind (N) in N_Integer_Literal
[Ada] Use non-internal representation for access subprograms if UC to Address
If we have an Unchecked_Conversion between an access to subprogram and System.Address, we want to try to use a thin subprogram pointer. Try to do this automatically as much as possible and add one to the RTS. Tested on x86_64-pc-linux-gnu, committed on trunk gcc/ada/ * libgnat/g-spipat.ads (Boolean_Func, Natural_Func, VString_Func): Mark as Favor_Top_Level. * sem_ch13.adb (Validate_Unchecked_Conversion): Avoid using internal representation if Unchecked_Conversion between an access to subprogram and System.Address within the same unit.diff --git a/gcc/ada/libgnat/g-spipat.ads b/gcc/ada/libgnat/g-spipat.ads --- a/gcc/ada/libgnat/g-spipat.ads +++ b/gcc/ada/libgnat/g-spipat.ads @@ -654,19 +654,19 @@ package GNAT.Spitbol.Patterns is -- operations for constructing patterns that can be used in the pattern -- matching operations provided. - type Boolean_Func is access function return Boolean; + type Boolean_Func is access function return Boolean with Favor_Top_Level; -- General Boolean function type. When this type is used as a formal -- parameter type in this package, it indicates a deferred predicate -- pattern. The function will be called when the pattern element is -- matched and failure signalled if False is returned. - type Natural_Func is access function return Natural; + type Natural_Func is access function return Natural with Favor_Top_Level; -- General Natural function type. When this type is used as a formal -- parameter type in this package, it indicates a deferred pattern. -- The function will be called when the pattern element is matched -- to obtain the currently referenced Natural value. - type VString_Func is access function return VString; + type VString_Func is access function return VString with Favor_Top_Level; -- General VString function type. When this type is used as a formal -- parameter type in this package, it indicates a deferred pattern. -- The function will be called when the pattern element is matched diff --git a/gcc/ada/sem_ch13.adb b/gcc/ada/sem_ch13.adb --- a/gcc/ada/sem_ch13.adb +++ b/gcc/ada/sem_ch13.adb @@ -17546,6 +17546,22 @@ package body Sem_Ch13 is Set_No_Strict_Aliasing (Implementation_Base_Type (Target)); end if; + -- If the unchecked conversion is between Address and an access + -- subprogram type, show that we shouldn't use an internal + -- representation for the access subprogram type. + + if Is_Access_Subprogram_Type (Target) +and then Is_Descendant_Of_Address (Source) +and then In_Same_Source_Unit (Target, N) + then + Set_Can_Use_Internal_Rep (Target, False); + elsif Is_Access_Subprogram_Type (Source) +and then Is_Descendant_Of_Address (Target) +and then In_Same_Source_Unit (Source, N) + then + Set_Can_Use_Internal_Rep (Source, False); + end if; + -- Generate N_Validate_Unchecked_Conversion node for back end in case -- the back end needs to perform special validation checks.
[Ada] treepr: Print value of static expression
When printing a node, if it happens to be an integer-like expression whose value is known, print that value. This makes debugging a little easier. Tested on x86_64-pc-linux-gnu, committed on trunk gcc/ada/ * treepr.adb (Print_Node_Ref): Print the value if available.diff --git a/gcc/ada/treepr.adb b/gcc/ada/treepr.adb --- a/gcc/ada/treepr.adb +++ b/gcc/ada/treepr.adb @@ -37,6 +37,7 @@ with Namet;use Namet; with Nlists; use Nlists; with Output; use Output; with Seinfo; use Seinfo; +with Sem_Eval; use Sem_Eval; with Sinfo;use Sinfo; with Sinfo.Nodes; use Sinfo.Nodes; with Sinfo.Utils; use Sinfo.Utils; @@ -1642,6 +1643,24 @@ package body Treepr is end if; end if; + -- If this is an integer-like expression whose value is known, print + -- that value. + + if Nkind (N) in N_Subexpr + and then Compile_Time_Known_Value (N) + and then Present (Etype (N)) + and then not Is_Array_Type (Etype (N)) + then +if Is_Entity_Name (N) -- e.g. enumeration literal + or else Nkind (N) in N_Integer_Literal + | N_Character_Literal + | N_Unchecked_Type_Conversion +then + Print_Str (" val = "); + UI_Write (Expr_Value (N)); +end if; + end if; + if Nkind (N) in N_Entity then Write_Str (" (Entity_Id="); else
[Ada] Add an option to Get_Fullest_View to not recurse
This option is used by GNAT LLVM. Tested on x86_64-pc-linux-gnu, committed on trunk gcc/ada/ * sem_util.ads, sem_util.adb (Get_Fullest_View): Add option to not recurse and return the next-most-fullest view.diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb --- a/gcc/ada/sem_util.adb +++ b/gcc/ada/sem_util.adb @@ -10926,7 +10926,12 @@ package body Sem_Util is -- function Get_Fullest_View - (E : Entity_Id; Include_PAT : Boolean := True) return Entity_Id is + (E : Entity_Id; + Include_PAT : Boolean := True; + Recurse : Boolean := True) return Entity_Id + is + New_E : Entity_Id := Empty; + begin -- Prevent cascaded errors @@ -10934,47 +10939,45 @@ package body Sem_Util is return E; end if; - -- Strictly speaking, the recursion below isn't necessary, but - -- it's both simplest and safest. + -- Look at each kind of entity to see where we may need to go deeper. case Ekind (E) is when Incomplete_Kind => if From_Limited_With (E) then - return Get_Fullest_View (Non_Limited_View (E), Include_PAT); + New_E := Non_Limited_View (E); elsif Present (Full_View (E)) then - return Get_Fullest_View (Full_View (E), Include_PAT); + New_E := Full_View (E); elsif Ekind (E) = E_Incomplete_Subtype then - return Get_Fullest_View (Etype (E)); + New_E := Etype (E); end if; when Private_Kind => if Present (Underlying_Full_View (E)) then - return - Get_Fullest_View (Underlying_Full_View (E), Include_PAT); + New_E := Underlying_Full_View (E); elsif Present (Full_View (E)) then - return Get_Fullest_View (Full_View (E), Include_PAT); + New_E := Full_View (E); elsif Etype (E) /= E then - return Get_Fullest_View (Etype (E), Include_PAT); + New_E := Etype (E); end if; when Array_Kind => if Include_PAT and then Present (Packed_Array_Impl_Type (E)) then - return Get_Fullest_View (Packed_Array_Impl_Type (E)); + New_E := Packed_Array_Impl_Type (E); end if; when E_Record_Subtype => if Present (Cloned_Subtype (E)) then - return Get_Fullest_View (Cloned_Subtype (E), Include_PAT); + New_E := Cloned_Subtype (E); end if; when E_Class_Wide_Type => -return Get_Fullest_View (Root_Type (E), Include_PAT); +New_E := Root_Type (E); when E_Class_Wide_Subtype => if Present (Equivalent_Type (E)) then - return Get_Fullest_View (Equivalent_Type (E), Include_PAT); + New_E := Equivalent_Type (E); elsif Present (Cloned_Subtype (E)) then - return Get_Fullest_View (Cloned_Subtype (E), Include_PAT); + New_E := Cloned_Subtype (E); end if; when E_Protected_Subtype @@ -10983,25 +10986,29 @@ package body Sem_Util is | E_Task_Type => if Present (Corresponding_Record_Type (E)) then - return Get_Fullest_View (Corresponding_Record_Type (E), -Include_PAT); + New_E := Corresponding_Record_Type (E); end if; when E_Access_Protected_Subprogram_Type | E_Anonymous_Access_Protected_Subprogram_Type => if Present (Equivalent_Type (E)) then - return Get_Fullest_View (Equivalent_Type (E), Include_PAT); + New_E := Equivalent_Type (E); end if; when E_Access_Subtype => -return Get_Fullest_View (Base_Type (E), Include_PAT); +New_E := Base_Type (E); when others => null; end case; - return E; + -- If we found a fuller view, either return it or recurse. Otherwise, + -- return our input. + + return (ifNo (New_E) then E + elsif Recurse then Get_Fullest_View (New_E, Include_PAT, Recurse) + else New_E); end Get_Fullest_View; diff --git a/gcc/ada/sem_util.ads b/gcc/ada/sem_util.ads --- a/gcc/ada/sem_util.ads +++ b/gcc/ada/sem_util.ads @@ -1354,10 +1354,13 @@ package Sem_Util is --CRec_Typ - the corresponding record type of the full views function Get_Fullest_View - (E : Entity_Id; Include_PAT : Boolean := True) return Entity_Id; + (E : Entity_Id; + Include_PAT : Boolean := True; + Recurse : Boolean := True) return Entity_Id; -- Get the fullest possible view of E, looking through private, limited, -- packed array and other implementation types. If
[Ada] Warn on import of parent package
There is no need to say "with P;" in package P.Q. This patch adds a warning for that case. We also remove with clauses in our own code that trigger the warning. Tested on x86_64-pc-linux-gnu, committed on trunk gcc/ada/ * sem_ch10.adb (Check_Redundant_Withs): Add a warning if a library unit with's its own ancestor. Note that this warning is not triggered for something like "with P.R;" in P.Q, because there the "with P;" is considered implicit. * fname-sf.adb, libgnarl/s-stusta.adb, libgnarl/s-tasdeb.ads, libgnat/a-calfor.adb, libgnat/a-tiboio.adb, libgnat/a-wwboio.adb, libgnat/a-zzboio.adb, libgnat/i-cobol.adb, libgnat/s-bitops.adb, libgnat/s-bitops.ads, libgnat/s-direio.adb, libgnat/s-dwalin.adb, libgnat/s-geveop.adb, libgnat/s-mmosin__unix.adb, libgnat/s-os_lib.adb, libgnat/s-os_lib.ads, libgnat/s-pooglo.ads, libgnat/s-secsta.adb, libgnat/s-shasto.adb, libgnat/s-stausa.ads, libgnat/s-stratt.ads, libgnat/s-ststop.adb: Remove with of parent. * sinfo.ads: Minor comment fix.diff --git a/gcc/ada/fname-sf.adb b/gcc/ada/fname-sf.adb --- a/gcc/ada/fname-sf.adb +++ b/gcc/ada/fname-sf.adb @@ -24,7 +24,6 @@ -- with Casing;use Casing; -with Fname; use Fname; with Fname.UF; use Fname.UF; with SFN_Scan; use SFN_Scan; with Osint; use Osint; diff --git a/gcc/ada/libgnarl/s-stusta.adb b/gcc/ada/libgnarl/s-stusta.adb --- a/gcc/ada/libgnarl/s-stusta.adb +++ b/gcc/ada/libgnarl/s-stusta.adb @@ -29,8 +29,6 @@ -- -- -- -with System.Stack_Usage; - -- This is why this package is part of GNARL: with System.Tasking.Debug; diff --git a/gcc/ada/libgnarl/s-tasdeb.ads b/gcc/ada/libgnarl/s-tasdeb.ads --- a/gcc/ada/libgnarl/s-tasdeb.ads +++ b/gcc/ada/libgnarl/s-tasdeb.ads @@ -32,7 +32,6 @@ -- This package encapsulates all direct interfaces to task debugging services -- that are needed by gdb with gnat mode. -with System.Tasking; with System.OS_Interface; package System.Tasking.Debug is diff --git a/gcc/ada/libgnat/a-calfor.adb b/gcc/ada/libgnat/a-calfor.adb --- a/gcc/ada/libgnat/a-calfor.adb +++ b/gcc/ada/libgnat/a-calfor.adb @@ -29,7 +29,6 @@ -- -- -- -with Ada.Calendar;use Ada.Calendar; with Ada.Calendar.Time_Zones; use Ada.Calendar.Time_Zones; package body Ada.Calendar.Formatting is diff --git a/gcc/ada/libgnat/a-tiboio.adb b/gcc/ada/libgnat/a-tiboio.adb --- a/gcc/ada/libgnat/a-tiboio.adb +++ b/gcc/ada/libgnat/a-tiboio.adb @@ -29,7 +29,6 @@ -- -- -- -with Ada.Text_IO; use Ada.Text_IO; with Ada.Unchecked_Deallocation; package body Ada.Text_IO.Bounded_IO is diff --git a/gcc/ada/libgnat/a-wwboio.adb b/gcc/ada/libgnat/a-wwboio.adb --- a/gcc/ada/libgnat/a-wwboio.adb +++ b/gcc/ada/libgnat/a-wwboio.adb @@ -29,7 +29,6 @@ -- -- -- -with Ada.Wide_Text_IO; use Ada.Wide_Text_IO; with Ada.Unchecked_Deallocation; package body Ada.Wide_Text_IO.Wide_Bounded_IO is diff --git a/gcc/ada/libgnat/a-zzboio.adb b/gcc/ada/libgnat/a-zzboio.adb --- a/gcc/ada/libgnat/a-zzboio.adb +++ b/gcc/ada/libgnat/a-zzboio.adb @@ -29,7 +29,6 @@ -- -- -- -with Ada.Wide_Wide_Text_IO; use Ada.Wide_Wide_Text_IO; with Ada.Unchecked_Deallocation; package body Ada.Wide_Wide_Text_IO.Wide_Wide_Bounded_IO is diff --git a/gcc/ada/libgnat/i-cobol.adb b/gcc/ada/libgnat/i-cobol.adb --- a/gcc/ada/libgnat/i-cobol.adb +++ b/gcc/ada/libgnat/i-cobol.adb @@ -34,8 +34,7 @@ -- particular COBOL format is completely contained in the private part of -- the spec. -with Interfaces; use Interfaces; -with System; use System; +with System; use System; with Ada.Unchecked_Conversion; package body Interfaces.COBOL is diff --git a/gcc/ada/libgnat/s-bitops.adb b/gcc/ada/libgnat/s-bitops.adb --- a/gcc/ada/libgnat/s-bitops.adb +++ b/gcc/ada/libgnat/s-bitops.adb @@ -29,8 +29,7 @@ -- -- -- -with System; use System; -with System.Unsigned_Types; use System.Unsigned_Types; +with
[Ada] Small cleanup of osint-m.adb
We remove the "pragma Elaborate_All (Osint)", because it is no longer needed. That allows us to remove the "with Osint" (i.e. with of our own parent). Tested on x86_64-pc-linux-gnu, committed on trunk gcc/ada/ * osint-m.adb: Remove with_clause and pragma.diff --git a/gcc/ada/osint-m.adb b/gcc/ada/osint-m.adb --- a/gcc/ada/osint-m.adb +++ b/gcc/ada/osint-m.adb @@ -23,17 +23,6 @@ -- -- -- -with Osint; - -pragma Elaborate_All (Osint); --- This pragma is needed because of the call to Set_Program in the --- elaboration of the package. We cannot rely on the static model --- of elaboration since the compiler is routinely compiled with --- checks off (-gnatp), and with older versions of the compiler --- (up to and including most 5.04 wavefronts), -gnatp suppresses --- the static elaboration check mechanisms. It could be removed --- one day, but there really is no need to do so. - package body Osint.M is ---
Re: [PATCH v4] c-format: Add -Wformat-int-precision option [PR80060]
On Tue, 21 Dec 2021 00:43:24 +0200 Daniil Stas wrote: > On Sat, 27 Nov 2021 22:18:23 + > Daniil Stas wrote: > > > This option is enabled by default when -Wformat option is enabled. A > > user can specify -Wno-format-int-precision to disable emitting > > warnings when passing an argument of an incompatible integer type to > > a 'd', 'i', 'b', 'B', 'o', 'u', 'x', or 'X' conversion specifier > > when it has the same precision as the expected type. > > > > Signed-off-by: Daniil Stas > > > > gcc/c-family/ChangeLog: > > > > * c-format.c (check_format_types): Don't emit warnings when > > passing an argument of an incompatible integer type to > > a 'd', 'i', 'b', 'B', 'o', 'u', 'x', or 'X' conversion > > specifier when it has the same precision as the expected > > type if -Wno-format-int-precision option is specified. > > * c.opt: Add -Wformat-int-precision option. > > > > gcc/ChangeLog: > > > > * doc/invoke.texi: Add -Wformat-int-precision option > > description. > > > > gcc/testsuite/ChangeLog: > > > > * c-c++-common/Wformat-int-precision-1.c: New test. > > * c-c++-common/Wformat-int-precision-2.c: New test. > > --- > > Changes for v4: > > - Added 'b' and 'B' format specifiers to the option descriptions. > > > > Changes for v3: > > - Added additional @code{} derictives to the documentation where > > needed. > > - Changed tests to run on "! long_neq_int" target instead of > > "lp64". > > - Added a test case to check that gcc still emits warnings for > > arguments with different precision even with > > -Wno-format-int-precision option enabled. > > > > Changes for v2: > > - Changed the option name to -Wformat-int-precision. > > - Changed the option description as was suggested by Martin. > > - Changed Wformat-int-precision-2.c to use dg-bogus instead of > > previous invalid syntax. > > > > gcc/c-family/c-format.c | 2 +- > > gcc/c-family/c.opt | 6 ++ > > gcc/doc/invoke.texi | 17 > > - .../c-c++-common/Wformat-int-precision-1.c | > > 7 +++ .../c-c++-common/Wformat-int-precision-2.c | 8 > > 5 files changed, 38 insertions(+), 2 deletions(-) > > create mode 100644 > > gcc/testsuite/c-c++-common/Wformat-int-precision-1.c create mode > > 100644 gcc/testsuite/c-c++-common/Wformat-int-precision-2.c > > > > diff --git a/gcc/c-family/c-format.c b/gcc/c-family/c-format.c > > index e735e092043..c66787f931f 100644 > > --- a/gcc/c-family/c-format.c > > +++ b/gcc/c-family/c-format.c > > @@ -4248,7 +4248,7 @@ check_format_types (const substring_loc > > _loc, && (!pedantic || i < 2) > > && char_type_flag) > > continue; > > - if (types->scalar_identity_flag > > + if ((types->scalar_identity_flag || > > !warn_format_int_precision) && (TREE_CODE (cur_type) == TREE_CODE > > (wanted_type) || (INTEGRAL_TYPE_P (cur_type) > > && INTEGRAL_TYPE_P (wanted_type))) > > diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt > > index 4b8a094b206..d7d952765c6 100644 > > --- a/gcc/c-family/c.opt > > +++ b/gcc/c-family/c.opt > > @@ -684,6 +684,12 @@ C ObjC C++ LTO ObjC++ Warning > > Alias(Wformat-overflow=, 1, 0) IntegerRange(0, 2) Warn about > > function calls with format strings that write past the end of the > > destination region. Same as -Wformat-overflow=1. > > +Wformat-int-precision > > +C ObjC C++ ObjC++ Var(warn_format_int_precision) Warning > > LangEnabledBy(C ObjC C++ ObjC++,Wformat=,warn_format >= 1, 0) +Warn > > when passing an argument of an incompatible integer type to a 'd', > > 'i', +'b', 'B', 'o', 'u', 'x', or 'X' conversion specifier even when > > it has the same +precision as the expected type. + > > Wformat-security > > C ObjC C++ ObjC++ Var(warn_format_security) Warning LangEnabledBy(C > > ObjC C++ ObjC++,Wformat=, warn_format >= 2, 0) Warn about possible > > security problems with format functions. diff --git > > a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index > > 3bddfbaae6a..94a7ad96c50 100644 --- a/gcc/doc/invoke.texi > > +++ b/gcc/doc/invoke.texi > > @@ -351,7 +351,7 @@ Objective-C and Objective-C++ Dialects}. > > -Werror -Werror=* -Wexpansion-to-defined -Wfatal-errors @gol > > -Wfloat-conversion -Wfloat-equal -Wformat -Wformat=2 @gol > > -Wno-format-contains-nul -Wno-format-extra-args @gol > > --Wformat-nonliteral -Wformat-overflow=@var{n} @gol > > +-Wformat-nonliteral -Wformat-overflow=@var{n} > > -Wformat-int-precision @gol -Wformat-security -Wformat-signedness > > -Wformat-truncation=@var{n} @gol -Wformat-y2k -Wframe-address @gol > > -Wframe-larger-than=@var{byte-size} -Wno-free-nonheap-object @gol > > @@ -6122,6 +6122,21 @@ If @option{-Wformat} is specified, also warn > > if the format string is not a string literal and so cannot be > > checked, unless the format function takes its format arguments as a > > @code{va_list}. > > +@item -Wformat-int-precision > >
Re: [PATCH] Fix alignment of stack slots for overaligned types [PR103500]
On Fri, Jan 7, 2022 at 7:20 AM Alex Coplan via Gcc-patches wrote: > > Hi Richard, > > Thanks for the review. > > On 20/12/2021 13:19, Richard Sandiford wrote: > > Alex Coplan via Gcc-patches writes: > > > Hi, > > > > > > This fixes PR103500 i.e. ensuring that stack slots for > > > passed-by-reference overaligned types are appropriately aligned. For the > > > testcase: > > > > > > typedef struct __attribute__((aligned(32))) { > > > long x,y; > > > } S; > > > S x; > > > void f(S); > > > void g(void) { f(x); } > > > > > > on AArch64, we currently generate (at -O2): > > > > > > g: > > > adrpx1, .LANCHOR0 > > > add x1, x1, :lo12:.LANCHOR0 > > > stp x29, x30, [sp, -48]! > > > mov x29, sp > > > ldp q0, q1, [x1] > > > add x0, sp, 16 > > > stp q0, q1, [sp, 16] > > > bl f > > > ldp x29, x30, [sp], 48 > > > ret > > > > > > so the stack slot for the passed-by-reference copy of the structure is > > > at sp + 16, and the sp is only guaranteed to be 16-byte aligned, so the > > > structure is only 16-byte aligned. The PCS requires the structure to be > > > 32-byte aligned. After this patch, we generate: > > > > > > g: > > > adrpx1, .LANCHOR0 > > > add x1, x1, :lo12:.LANCHOR0 > > > stp x29, x30, [sp, -64]! > > > mov x29, sp > > > add x0, sp, 47 > > > ldp q0, q1, [x1] > > > and x0, x0, -32 > > > stp q0, q1, [x0] > > > bl f > > > ldp x29, x30, [sp], 64 > > > ret > > > > > > i.e. we ensure 32-byte alignment for the struct. > > > > > > The approach taken here is similar to that in > > > function.c:assign_parm_setup_block where it handles the case for > > > DECL_ALIGN (parm) > MAX_SUPPORTED_STACK_ALIGNMENT. This in turn is > > > similar to the approach taken in cfgexpand.c:expand_stack_vars (where > > > the function calls get_dynamic_stack_size) which is the code that > > > handles the alignment for overaligned structures as addressable local > > > variables (see the related case discussed in the PR). > > > > A difference with the latter is that cfgexpand (AFAICT) always > > honours the DECL/TYPE_ALIGN, with LOCAL_DECL_ALIGNMENT supposedly > > only increasing the alignment for efficiency reasons (rather than > > decreasing it). > > > > So… > > > > > This patch also updates the aapcs64 test mentioned in the PR to avoid > > > the frontend folding away the alignment check. I've confirmed that the > > > execution test actually fails on aarch64-linux-gnu prior to the patch > > > being applied and passes afterwards. > > > > > > Bootstrapped and regtested on aarch64-linux-gnu, x86_64-linux-gnu, and > > > arm-linux-gnueabihf: no regressions. > > > > > > I'd appreciate any feedback. Is it OK for trunk? > > > > > > Thanks, > > > Alex > > > > > > gcc/ChangeLog: > > > > > > PR middle-end/103500 > > > * function.c (get_stack_local_alignment): Align BLKmode overaligned > > > types to the alignment required by the type. > > > (assign_stack_temp_for_type): Handle BLKmode overaligned stack > > > slots by allocating a larger-than-necessary buffer and aligning > > > the address within appropriately. > > > > > > gcc/testsuite/ChangeLog: > > > > > > PR middle-end/103500 > > > * gcc.target/aarch64/aapcs64/rec_align-8.c (test_pass_by_ref): > > > Prevent the frontend from folding our alignment check away by > > > using snprintf to store the pointer into a string and recovering > > > it with sscanf. > > > > > > diff --git a/gcc/function.c b/gcc/function.c > > > index 61b3bd036b8..5ed722ab959 100644 > > > --- a/gcc/function.c > > > +++ b/gcc/function.c > > > @@ -278,7 +278,9 @@ get_stack_local_alignment (tree type, machine_mode > > > mode) > > >unsigned int alignment; > > > > > >if (mode == BLKmode) > > > -alignment = BIGGEST_ALIGNMENT; > > > +alignment = (type && TYPE_ALIGN (type) > > > > MAX_SUPPORTED_STACK_ALIGNMENT) > > > + ? TYPE_ALIGN (type) > > > + : BIGGEST_ALIGNMENT; > > > > …I'm not sure about this calculation. Why do we only honour TYPE_ALIGN > > if it's greater than MAX_SUPPORTED_STACK_ALIGNMENT, and fall all the > > way back to BIGGEST_ALIGNMENT otherwise? It looks like on nvptx > > this would have the effect of honouring (say) 2048-byte alignment, > > but not 32-byte alignment (which falls between BIGGEST_ALIGNMENT > > and MAX_SUPPORTED_STACK_ALIGNMENT). > > So, to be honest, this was a bit of a bodge to try and work around > issues on x86. My original attempt at solving the PR used the more > obvious calculation you suggest below, i.e. the max of BIGGEST_ALIGNMENT > and TYPE_ALIGN (type). The problem with that is, on x86, > MAX_SUPPORTED_STACK_ALIGNMENT has a huge value (2^31). On x86, stack alignment limit is the limit of stack. You can align stack to any values on x86 as long as your stack allows it. >
Re: [PATCH] Fix alignment of stack slots for overaligned types [PR103500]
Hi Richard, Thanks for the review. On 20/12/2021 13:19, Richard Sandiford wrote: > Alex Coplan via Gcc-patches writes: > > Hi, > > > > This fixes PR103500 i.e. ensuring that stack slots for > > passed-by-reference overaligned types are appropriately aligned. For the > > testcase: > > > > typedef struct __attribute__((aligned(32))) { > > long x,y; > > } S; > > S x; > > void f(S); > > void g(void) { f(x); } > > > > on AArch64, we currently generate (at -O2): > > > > g: > > adrpx1, .LANCHOR0 > > add x1, x1, :lo12:.LANCHOR0 > > stp x29, x30, [sp, -48]! > > mov x29, sp > > ldp q0, q1, [x1] > > add x0, sp, 16 > > stp q0, q1, [sp, 16] > > bl f > > ldp x29, x30, [sp], 48 > > ret > > > > so the stack slot for the passed-by-reference copy of the structure is > > at sp + 16, and the sp is only guaranteed to be 16-byte aligned, so the > > structure is only 16-byte aligned. The PCS requires the structure to be > > 32-byte aligned. After this patch, we generate: > > > > g: > > adrpx1, .LANCHOR0 > > add x1, x1, :lo12:.LANCHOR0 > > stp x29, x30, [sp, -64]! > > mov x29, sp > > add x0, sp, 47 > > ldp q0, q1, [x1] > > and x0, x0, -32 > > stp q0, q1, [x0] > > bl f > > ldp x29, x30, [sp], 64 > > ret > > > > i.e. we ensure 32-byte alignment for the struct. > > > > The approach taken here is similar to that in > > function.c:assign_parm_setup_block where it handles the case for > > DECL_ALIGN (parm) > MAX_SUPPORTED_STACK_ALIGNMENT. This in turn is > > similar to the approach taken in cfgexpand.c:expand_stack_vars (where > > the function calls get_dynamic_stack_size) which is the code that > > handles the alignment for overaligned structures as addressable local > > variables (see the related case discussed in the PR). > > A difference with the latter is that cfgexpand (AFAICT) always > honours the DECL/TYPE_ALIGN, with LOCAL_DECL_ALIGNMENT supposedly > only increasing the alignment for efficiency reasons (rather than > decreasing it). > > So… > > > This patch also updates the aapcs64 test mentioned in the PR to avoid > > the frontend folding away the alignment check. I've confirmed that the > > execution test actually fails on aarch64-linux-gnu prior to the patch > > being applied and passes afterwards. > > > > Bootstrapped and regtested on aarch64-linux-gnu, x86_64-linux-gnu, and > > arm-linux-gnueabihf: no regressions. > > > > I'd appreciate any feedback. Is it OK for trunk? > > > > Thanks, > > Alex > > > > gcc/ChangeLog: > > > > PR middle-end/103500 > > * function.c (get_stack_local_alignment): Align BLKmode overaligned > > types to the alignment required by the type. > > (assign_stack_temp_for_type): Handle BLKmode overaligned stack > > slots by allocating a larger-than-necessary buffer and aligning > > the address within appropriately. > > > > gcc/testsuite/ChangeLog: > > > > PR middle-end/103500 > > * gcc.target/aarch64/aapcs64/rec_align-8.c (test_pass_by_ref): > > Prevent the frontend from folding our alignment check away by > > using snprintf to store the pointer into a string and recovering > > it with sscanf. > > > > diff --git a/gcc/function.c b/gcc/function.c > > index 61b3bd036b8..5ed722ab959 100644 > > --- a/gcc/function.c > > +++ b/gcc/function.c > > @@ -278,7 +278,9 @@ get_stack_local_alignment (tree type, machine_mode mode) > >unsigned int alignment; > > > >if (mode == BLKmode) > > -alignment = BIGGEST_ALIGNMENT; > > +alignment = (type && TYPE_ALIGN (type) > MAX_SUPPORTED_STACK_ALIGNMENT) > > + ? TYPE_ALIGN (type) > > + : BIGGEST_ALIGNMENT; > > …I'm not sure about this calculation. Why do we only honour TYPE_ALIGN > if it's greater than MAX_SUPPORTED_STACK_ALIGNMENT, and fall all the > way back to BIGGEST_ALIGNMENT otherwise? It looks like on nvptx > this would have the effect of honouring (say) 2048-byte alignment, > but not 32-byte alignment (which falls between BIGGEST_ALIGNMENT > and MAX_SUPPORTED_STACK_ALIGNMENT). So, to be honest, this was a bit of a bodge to try and work around issues on x86. My original attempt at solving the PR used the more obvious calculation you suggest below, i.e. the max of BIGGEST_ALIGNMENT and TYPE_ALIGN (type). The problem with that is, on x86, MAX_SUPPORTED_STACK_ALIGNMENT has a huge value (2^31). explow.c:get_dynamic_stack_size has: if (size_align % MAX_SUPPORTED_STACK_ALIGNMENT != 0) { size = round_push (size); [...] } *psize = size; so inevitably we end up calling round_push on x86 which in turn ends up going down the else branch: else { /* If crtl->preferred_stack_boundary might still grow, use virtual_preferred_stack_boundary_rtx instead. This will be substituted by the right value in vregs
Re: [committed] c++: Add testcase for recently fixed PR [PR69681]
On Fri, 7 Jan 2022, Jakub Jelinek wrote: > On Thu, Jan 06, 2022 at 10:44:09AM -0500, Patrick Palka via Gcc-patches wrote: > > Fixed ever since r12-6188. > > > > PR c++/69681 > > > > gcc/testsuite/ChangeLog: > > > > * g++.dg/cpp0x/constexpr-compare2.C: New test. > > Note, I've tested my > https://gcc.gnu.org/pipermail/gcc-patches/2022-January/587745.html > patch before you've committed this test, that patch makes it FAIL > again. > > The thing is that in address_compare now we make it all the way to > tree sz0 = DECL_SIZE_UNIT (base0); > tree sz1 = DECL_SIZE_UNIT (base1); > /* If sizes are unknown, e.g. VLA or not representable, punt. */ > if (!tree_fits_poly_int64_p (sz0) || !tree_fits_poly_int64_p (sz1)) > return 2; > which wants to check if one pointer is to a start of one object and > another pointer to the end of another one. But, base0 and base1 > are both FUNCTION_DECLs, and those seem to never have DECL_SIZE_UNIT > set on them, whether the functions are external or defined locally. > > We've already proven that base0 and base1 are different. Can we > with folding_initializer set (or even unset?) assume that if one > or both of the bases are FUNCTION_DECLs they will compare unequal > regardless if the other pointer is at the start or end of some > variable? For the !folding_initializer case, one thing is that > while we've dealt with aliases visible to the compiler already and > punted, there could again be aliases not visible to the compiler > etc. There is also a theoretical chance that .text section > with some functions in it could be immediately followed by .rodata > section with variables, but zero sized functions are rare and using > address arithmetics to get to the end of a function isn't something > we should support. Some functions and variables could be also > defined in assembly and could be adjacent... > So at least limiting it to folding_initializer would be wise, > but the question is what exactly should be valid and what should > be invalid in C++. > > So, thoughts on this? Not totally sure but since pointer arithmetic on a function pointer isn't a valid C++ constant expression, I suppose we could also restrict ourselves to the case where both offsets are 0. So probably returning 0 for FUNCTION_DECL if folding_initializer && ioff0 == 0 && ioff1 == 0 might be sufficient. Then again, I don't see why we'd want to treat functions differently from other decls when the offsets are 0, so perhaps we could relax this to folding_initializer && ioff0 == 0 && ioff1 == 0. > > > --- /dev/null > > +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-compare2.C > > @@ -0,0 +1,10 @@ > > +// PR c++/69681 > > +// { dg-do compile { target c++11 } } > > + > > +void f(); > > +void g(); > > +static_assert(f != g, ""); > > + > > +#if __cpp_constexpr >= 201603L > > +static_assert([]{} != []{}, ""); > > +#endif > > -- > > 2.34.1.493.ge83ba647f7 > > Jakub > >
Re: [PATCH 3/6] ira: Add ira_subloop_allocnos_can_differ_p
On 2022-01-06 09:47, Richard Sandiford wrote: color_pass has two instances of the same code for propagating non-cap assignments from parent loops to subloops. This patch adds a helper function for testing when such propagations are required for correctness and uses it to remove the duplicated code. A later patch will use this in ira-build.c too, which is why the function is exported to ira-int.h. No functional change intended. gcc/ PR rtl-optimization/98782 * ira-int.h (ira_subloop_allocnos_can_differ_p): New function, extracted from... * ira-color.c (color_pass): ...here. OK.
Re: [PATCH 2/6] ira: Add comments and fix move_spill_restore calculation
On 2022-01-06 09:46, Richard Sandiford wrote: This patch adds comments to describe each use of ira_loop_border_costs. I think this highlights that move_spill_restore was using the wrong cost in one case, which came from tranposing [0] and [1] in the original (pre-ira_loop_border_costs) ira_memory_move_cost expressions. The difference would only be noticeable on targets that distinguish between load and store costs. gcc/ PR rtl-optimization/98782 * ira-color.c (color_pass): Add comments to describe the spill costs. (move_spill_restore): Likewise. Fix reversed calculation. OK for me. Thank you for fixing the cost typo.
Re: [PATCH 1/6] ira: Add a ira_loop_border_costs class
On 2022-01-06 09:46, Richard Sandiford wrote: The final index into (ira_)memory_move_cost is 1 for loads and 0 for stores. Thus the combination: entry_freq * memory_cost[1] + exit_freq * memory_cost[0] is the cost of loading a register on entry to a loop and storing it back on exit from the loop. This is the cost to use if the register is successfully allocated within the loop but is spilled in the parent loop. Similarly: entry_freq * memory_cost[0] + exit_freq * memory_cost[1] is the cost of storing a register on entry to the loop and restoring it on exit from the loop. This is the cost to use if the register is spilled within the loop but is successfully allocated in the parent loop. The patch adds a helper class for calculating these values and mechanically replaces the existing instances. There is no attempt to editorialise the choice between using “spill inside” and “spill outside” costs. (I think one of them is the wrong way round, but a later patch deals with that.) No functional change intended. gcc/ PR rtl-optimization/98782 * ira-int.h (ira_loop_border_costs): New class. * ira-color.c (ira_loop_border_costs::ira_loop_border_costs): New constructor. (calculate_allocno_spill_cost): Use ira_loop_border_costs. (color_pass): Likewise. (move_spill_restore): Likewise. It is OK for me.
Re: [PATCH 0/6] ira: Fix performance regression in exchange2 [PR98782]
On 2022-01-06 09:45, Richard Sandiford wrote: This series of patches recovers the exchange2 performance lost in the GCC 11 timeframe (at least on aarch64 and Power9 -- thanks Pat for testing the latter). There are 6 patches, split into two groups of 3. The first 3 are just preparatory patches, although patch 2 does contain a minor bug fix. The other 3 patches are the ones that together fix the regression. I realise this is a bit invasive for stage 3. However, the series is fixing a large regression in an important benchmark and AFAIK there are no known acceptable mitigations that we could apply instead. I think the series is also working with concepts that already exist in IRA: it's really about tweaking the cost model used to control them. We also still have at least 3 months (more realistically 4 months) of testing before GCC 12 is released. So perhaps one option would be to apply any approved version of the series now, but with the understanding that if there's significant fallout (more than a handful of small tweaks or fixes), we would simply revert the patches rather than trying to rework them in-situ. The series is confined to IRA so reverting it should be simple. Would that be OK? Richard. thank you for working on these issues. I don't think there is a problem with the GCC development stage here. These are patches solving existing PR(s). Of course it is better to do such changes earlier at the stage3, so IMHO the timing is right. I don't expect that the changes will result in serious problems like wrong code generation or RA crashes as they are about improving RA heuristics. They can result in new GCC test failures on some targets (we have many overconstrained tests expecting an exact GCC output). If we are overwhelmed with the new failures we can revert the patches. The first 3 patches are ok to commit. I'll look at the rest 3 ones this weekend and write you my opinion on Monday. I don't think there will be a problem with the last 3 patches. They are clearly improving RA heuristics. I just need some time to think about them. Thank you again for picking this difficult PR and working on it. Each patch bootstrapped & regression-tested individually on aarch64-linux-gnu. Also tested as a series on aarch64_be-elf, arm-linux-gnueabihf, powerpc64le-linux-gnu, and x86_64-linux-gnu.
Re: [power-ieee128] RFH: LTO broken
Hi Jakub, 00251038 06ad0015 R_PPC64_JMP_SLOT __cabsieee128 + 0 All these should for POWER_IEEE128 use atan2q@QUADMATH_1.0 etc. So, seems all these come from f951 compiled sources. For user code, I think the agreement was if you want to use successfully -mabi=ieeelongdouble, you need glibc 2.32 or later, which is why the Fortran FE doesn't conditionalize on whether glibc 2.32 is available or not and just emits __WHATEVERieee128 entrypoints. That was the idea, I think. But for Fortran compiled sources in libgfortran, we need to use __WHATEVERieee128 only if glibc 2.32 or later and WHATEVERq (from libquadmath) otherwise. I guess easiest would be to do this always in the FE, but we need to determine in the FE if the target is glibc 2.32 or later. Instead of determining this in the front end, maybe we can add an option (documented, but marked as useful as only for internal use and with no guarantee that it will remain) and use that option when compiling libgfortran. On the other side, on glibc 2.32+ build, we still use some libquadmath APIs when we shouldn't: readelf -Wr /home/jakub/gcc/obj/powerpc64le-unknown-linux-gnu/libgfortran/.libs/libgfortran.so.5 | grep QUADMATH 002502c8 00260015 R_PPC64_JMP_SLOT fmaq@QUADMATH_1.0 + 0 002505f8 00670015 R_PPC64_JMP_SLOT tanq@QUADMATH_1.0 + 0 00250930 009b0015 R_PPC64_JMP_SLOT fabsq@QUADMATH_1.0 + 0 00250940 009d0015 R_PPC64_JMP_SLOT sinq@QUADMATH_1.0 + 0 00250c98 00cf0015 R_PPC64_JMP_SLOT copysignq@QUADMATH_1.0 + 0 00251038 01070015 R_PPC64_JMP_SLOT cosq@QUADMATH_1.0 + 0 00251068 010a0015 R_PPC64_JMP_SLOT fmodq@QUADMATH_1.0 + 0 These should use __fmaieee128, __tanieee128 etc. instead. This one seems easily fixed by the following patch, ok for power-ieee128? OK! Best regards Thomas
Re: [PATCH] libgomp, OpenMP, nvptx: Low-latency memory allocator
On 06/01/2022 17:53, Tom de Vries wrote: My current understanding is that this is a backend problem, and needs to be fixed by defining atomic_store patterns which take care of this peculiarity. You mentioned on IRC that I ought to initialize the free chain using atomics also, and that you are working on an atomic store implementation. This patch fixes the initialization issue. It works with my device, I think. Please test it with your device when the backend issue is fixed. Thanks very much! Andrewlibgomp, nvptx: low-latency memory allocator This patch adds support for allocating low-latency ".shared" memory on NVPTX GPU device, via the omp_low_lat_mem_space and omp_alloc. The memory can be allocated, reallocated, and freed using a basic but fast algorithm, is thread safe and the size of the low-latency heap can be configured using the GOMP_NVPTX_LOWLAT_POOL environment variable. The use of the PTX dynamic_smem_size feature means that the minimum version requirement is now bumped to 4.1 (still old at this point). libgomp/ChangeLog: * allocator.c (MEMSPACE_ALLOC): New macro. (MEMSPACE_CALLOC): New macro. (MEMSPACE_REALLOC): New macro. (MEMSPACE_FREE): New macro. (dynamic_smem_size): New constants. (omp_alloc): Use MEMSPACE_ALLOC. Implement fall-backs for predefined allocators. (omp_free): Use MEMSPACE_FREE. (omp_calloc): Use MEMSPACE_CALLOC. Implement fall-backs for predefined allocators. (omp_realloc): Use MEMSPACE_REALLOC. Implement fall-backs for predefined allocators. * config/nvptx/team.c (__nvptx_lowlat_heap_root): New variable. (__nvptx_lowlat_pool): New asm varaible. (gomp_nvptx_main): Initialize the low-latency heap. * plugin/plugin-nvptx.c (lowlat_pool_size): New variable. (GOMP_OFFLOAD_init_device): Read the GOMP_NVPTX_LOWLAT_POOL envvar. (GOMP_OFFLOAD_run): Apply lowlat_pool_size. * config/nvptx/allocator.c: New file. * testsuite/libgomp.c/allocators-1.c: New test. * testsuite/libgomp.c/allocators-2.c: New test. * testsuite/libgomp.c/allocators-3.c: New test. * testsuite/libgomp.c/allocators-4.c: New test. * testsuite/libgomp.c/allocators-5.c: New test. * testsuite/libgomp.c/allocators-6.c: New test. diff --git a/libgomp/allocator.c b/libgomp/allocator.c index 07a5645f4cc..b1f5fe0a5e2 100644 --- a/libgomp/allocator.c +++ b/libgomp/allocator.c @@ -34,6 +34,38 @@ #define omp_max_predefined_alloc omp_thread_mem_alloc +/* These macros may be overridden in config//allocator.c. */ +#ifndef MEMSPACE_ALLOC +#define MEMSPACE_ALLOC(MEMSPACE, SIZE) \ + ((void)MEMSPACE, malloc (SIZE)) +#endif +#ifndef MEMSPACE_CALLOC +#define MEMSPACE_CALLOC(MEMSPACE, SIZE) \ + ((void)MEMSPACE, calloc (1, SIZE)) +#endif +#ifndef MEMSPACE_REALLOC +#define MEMSPACE_REALLOC(MEMSPACE, ADDR, OLDSIZE, SIZE) \ + ((void)MEMSPACE, (void)OLDSIZE, realloc (ADDR, SIZE)) +#endif +#ifndef MEMSPACE_FREE +#define MEMSPACE_FREE(MEMSPACE, ADDR, SIZE) \ + ((void)MEMSPACE, (void)SIZE, free (ADDR)) +#endif + +/* Map the predefined allocators to the correct memory space. + The index to this table is the omp_allocator_handle_t enum value. */ +static const omp_memspace_handle_t predefined_alloc_mapping[] = { + omp_default_mem_space, /* omp_null_allocator. */ + omp_default_mem_space, /* omp_default_mem_alloc. */ + omp_large_cap_mem_space, /* omp_large_cap_mem_alloc. */ + omp_default_mem_space, /* omp_const_mem_alloc. */ + omp_high_bw_mem_space, /* omp_high_bw_mem_alloc. */ + omp_low_lat_mem_space, /* omp_low_lat_mem_alloc. */ + omp_low_lat_mem_space, /* omp_cgroup_mem_alloc. */ + omp_low_lat_mem_space, /* omp_pteam_mem_alloc. */ + omp_low_lat_mem_space, /* omp_thread_mem_alloc. */ +}; + struct omp_allocator_data { omp_memspace_handle_t memspace; @@ -281,7 +313,7 @@ retry: allocator_data->used_pool_size = used_pool_size; gomp_mutex_unlock (_data->lock); #endif - ptr = malloc (new_size); + ptr = MEMSPACE_ALLOC (allocator_data->memspace, new_size); if (ptr == NULL) { #ifdef HAVE_SYNC_BUILTINS @@ -297,7 +329,10 @@ retry: } else { - ptr = malloc (new_size); + omp_memspace_handle_t memspace = (allocator_data + ? allocator_data->memspace + : predefined_alloc_mapping[allocator]); + ptr = MEMSPACE_ALLOC (memspace, new_size); if (ptr == NULL) goto fail; } @@ -315,32 +350,35 @@ retry: return ret; fail: - if (allocator_data) + int fallback = (allocator_data + ? allocator_data->fallback + : allocator == omp_default_mem_alloc + ? omp_atv_null_fb + : omp_atv_default_mem_fb); + switch (fallback) { - switch (allocator_data->fallback) +case
[PATCH] libstdc++: Fix and simplify freestanding configuration [PR103866]
Tested powerpc64le-linux and by building a mips-none-elf cross with --disable-hosted-libstdcxx --without-headers (which fails currently). Any objections? This fixes the --disable-hosted-libstdcxx build so that it works with --without-headers. Currently you need to also use --with-newlib, which is confusing for users who aren't actually using newlib. The AM_PROG_LIBTOOL checks are currently skipped for --with-newlib and --with-avrlibc builds, with this change they are also skipped when using --without-headers. It would be nice if using --disable-hosted-libstdcxx automatically skipped those checks, but GLIBCXX_ENABLE_HOSTED comes too late to make the AM_PROG_LIBTOOL checks depend on $is_hosted. The checks for EOF, SEEK_CUR etc. cause the build to fail if there is no available. Unlike most headers, which get a HAVE_FOO_H macro, is in autoconf's default includes, so every check tries to include it unconditionally. This change skips those checks for freestanding builds. Similarly, the checks for types done by GCC_HEADER_STDINT try to include and fail for --without-headers builds. This change skips the use of GCC_HEADER_STDINT for freestanding. We can probably stop using GCC_HEADER_STDINT entirely, since only one file uses the gstdint.h header that is generated, and that could easily be changed to use instead. That can wait for stage 1. We also need to skip the GLIBCXX_CROSSCONFIG stage if --without-headers was used, since we don't have any of the functions it deals with. The end result of the changes above is that it should not be necessary for a --disable-hosted-libstdcxx --without-headers build to also use --with-newlib. Finally, compile libsupc++ with -ffreestanding when --without-headers is used, so that will use instead of expecting it to come from libc. libstdc++-v3/ChangeLog: PR libstdc++/103866 * acinclude.m4 (GLIBCXX_COMPUTE_STDIO_INTEGER_CONSTANTS): Do nothing for freestanding builds. (GLIBCXX_ENABLE_HOSTED): Define FREESTANDING_FLAGS. * configure.ac: Do not use AC_LIBTOOL_DLOPEN when configured with --without-headers. Do not use GCC_HEADER_STDINT for freestanding builds. * libsupc++/Makefile.am (HOSTED_CXXFLAGS): Use -ffreestanding for freestanding builds. * configure: Regenerate. * Makefile.in: Regenerate. * doc/Makefile.in: Regenerate. * include/Makefile.in: Regenerate. * libsupc++/Makefile.in: Regenerate. * po/Makefile.in: Regenerate. * python/Makefile.in: Regenerate. * src/Makefile.in: Regenerate. * src/c++11/Makefile.in: Regenerate. * src/c++17/Makefile.in: Regenerate. * src/c++20/Makefile.in: Regenerate. * src/c++98/Makefile.in: Regenerate. * src/filesystem/Makefile.in: Regenerate. * testsuite/Makefile.in: Regenerate. --- libstdc++-v3/Makefile.in| 1 + libstdc++-v3/acinclude.m4 | 8 ++ libstdc++-v3/configure | 35 ++--- libstdc++-v3/configure.ac | 10 +-- libstdc++-v3/doc/Makefile.in| 1 + libstdc++-v3/include/Makefile.in| 1 + libstdc++-v3/libsupc++/Makefile.am | 2 +- libstdc++-v3/libsupc++/Makefile.in | 3 ++- libstdc++-v3/po/Makefile.in | 1 + libstdc++-v3/python/Makefile.in | 1 + libstdc++-v3/src/Makefile.in| 1 + libstdc++-v3/src/c++11/Makefile.in | 1 + libstdc++-v3/src/c++17/Makefile.in | 1 + libstdc++-v3/src/c++20/Makefile.in | 1 + libstdc++-v3/src/c++98/Makefile.in | 1 + libstdc++-v3/src/filesystem/Makefile.in | 1 + libstdc++-v3/testsuite/Makefile.in | 1 + 17 files changed, 56 insertions(+), 14 deletions(-) diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4 index 635168d7e25..b770d5bcdc4 100644 --- a/libstdc++-v3/acinclude.m4 +++ b/libstdc++-v3/acinclude.m4 @@ -2081,6 +2081,7 @@ dnl Compute the EOF, SEEK_CUR, and SEEK_END integer constants. dnl AC_DEFUN([GLIBCXX_COMPUTE_STDIO_INTEGER_CONSTANTS], [ +if test "$is_hosted" = yes; then AC_CACHE_CHECK([for the value of EOF], glibcxx_cv_stdio_eof, [ AC_COMPUTE_INT([glibcxx_cv_stdio_eof], [[EOF]], [#include ], @@ -2104,6 +2105,7 @@ AC_DEFUN([GLIBCXX_COMPUTE_STDIO_INTEGER_CONSTANTS], [ ]) AC_DEFINE_UNQUOTED(_GLIBCXX_STDIO_SEEK_END, $glibcxx_cv_stdio_seek_end, [Define to the value of the SEEK_END integer constant.]) +fi ]) dnl @@ -2923,12 +2925,16 @@ AC_DEFUN([GLIBCXX_ENABLE_HOSTED], [ enable_hosted_libstdcxx=yes ;; esac]) + freestanding_flags= if test "$enable_hosted_libstdcxx" = no; then AC_MSG_NOTICE([Only freestanding libraries will be built]) is_hosted=no hosted_define=0 enable_abi_check=no enable_libstdcxx_pch=no +if test "x$with_headers" = xno; then + freestanding_flags="-ffreestanding" +fi
[Patch, fortran] PR103366 - [9/10/11/12 Regression] ICE in gfc_conv_gfc_desc_to_cfi_desc, at fortran/trans-expr.c:5647
I doubt that this is a regression on 9-11 branches since the testcase compiles correctly on each of my copies of these branches. IMHO it is rather more likely to have been caused by 64f9623765da3306b0ab6a47997dc5d62c2ea261, which introduced this new form of gfc_conv_gfc_desc_to_cfi_desc. The patch is self-explanatory. OK for mainline? Paul Fortran: Match unlimited polymorphic argument to assumed type [PR103366]. 2022-01-07 Paul Thomas gcc/fortran PR fortran/103366 * trans-expr.c (gfc_conv_gfc_desc_to_cfi_desc): Allow unlimited polymorphic actual argument passed to assumed type formal. gcc/testsuite/ PR fortran/103366 * gfortran.dg/pr103366.f90: New test. diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c index 381915e2a76..2e15a7e874c 100644 --- a/gcc/fortran/trans-expr.c +++ b/gcc/fortran/trans-expr.c @@ -50,10 +50,10 @@ static tree gfc_get_character_len (tree type) { tree len; - + gcc_assert (type && TREE_CODE (type) == ARRAY_TYPE && TYPE_STRING_FLAG (type)); - + len = TYPE_MAX_VALUE (TYPE_DOMAIN (type)); len = (len) ? (len) : (integer_zero_node); return fold_convert (gfc_charlen_type_node, len); @@ -67,10 +67,10 @@ tree gfc_get_character_len_in_bytes (tree type) { tree tmp, len; - + gcc_assert (type && TREE_CODE (type) == ARRAY_TYPE && TYPE_STRING_FLAG (type)); - + tmp = TYPE_SIZE_UNIT (TREE_TYPE (type)); tmp = (tmp && !integer_zerop (tmp)) ? (fold_convert (gfc_charlen_type_node, tmp)) : (NULL_TREE); @@ -5630,6 +5630,16 @@ gfc_conv_gfc_desc_to_cfi_desc (gfc_se *parmse, gfc_expr *e, gfc_symbol *fsym) itype = CFI_type_other; // FIXME: Or CFI_type_cptr ? break; case BT_CLASS: + if (UNLIMITED_POLY (e) && fsym->ts.type == BT_ASSUMED) + { + // F2017: 7.3.2.2: "An entity that is declared using the TYPE(*) + // type specifier is assumed-type and is an unlimited polymorphic + // entity." The actual argument _data component is passed. + itype = CFI_type_other; // FIXME: Or CFI_type_cptr ? + break; + } + else + gcc_unreachable (); case BT_PROCEDURE: case BT_HOLLERITH: case BT_UNION: ! { dg-do compile } ! ! Test the fix for PR103366. ! ! Contributed by Gerhardt Steinmetz ! program p call u([1]) contains subroutine s(x) bind(c) type(*) :: x(..) end subroutine u(x) class(*) :: x(..) call s(x) ! Used to ICE here end end
Re: [power-ieee128] RFH: LTO broken
On Fri, Jan 07, 2022 at 12:29:25PM +0100, Jakub Jelinek wrote: > we don't do it consistently: > readelf -Wr > /home/jakub/gcc/obj38/powerpc64le-unknown-linux-gnu/libgfortran/.libs/libgfortran.so.5.0.0 > | grep ieee128 > 00250310 01280015 R_PPC64_JMP_SLOT > __atan2ieee128 + 0 > 00250340 01420015 R_PPC64_JMP_SLOT > __clogieee128 + 0 > 00250438 01a30015 R_PPC64_JMP_SLOT > __acoshieee128 + 0 > 002504b8 01cc0015 R_PPC64_JMP_SLOT > __csinieee128 + 0 > 00250500 01f30015 R_PPC64_JMP_SLOT > __sinhieee128 + 0 > 00250570 022a0015 R_PPC64_JMP_SLOT > __asinieee128 + 0 > 00250580 022d0015 R_PPC64_JMP_SLOT > __roundieee128 + 0 > 002505a0 023e0015 R_PPC64_JMP_SLOT > __logieee128 + 0 > 002505c8 02490015 R_PPC64_JMP_SLOT > __tanieee128 + 0 > 00250630 02750015 R_PPC64_JMP_SLOT > __ccosieee128 + 0 > 00250670 028a0015 R_PPC64_JMP_SLOT > __log10ieee128 + 0 > 002506c8 02bd0015 R_PPC64_JMP_SLOT > __cexpieee128 + 0 > 002506d8 02c80015 R_PPC64_JMP_SLOT > __coshieee128 + 0 > 002509b0 03ef0015 R_PPC64_JMP_SLOT > __truncieee128 + 0 > 00250af8 04a60015 R_PPC64_JMP_SLOT > __expieee128 + 0 > 00250b50 04c60015 R_PPC64_JMP_SLOT > __fmodieee128 + 0 > 00250bb0 04e70015 R_PPC64_JMP_SLOT > __tanhieee128 + 0 > 00250c38 05130015 R_PPC64_JMP_SLOT > __acosieee128 + 0 > 00250ce0 05540015 R_PPC64_JMP_SLOT > __sinieee128 + 0 > 00250d60 057e0015 R_PPC64_JMP_SLOT > __atanieee128 + 0 > 00250dd8 05b10015 R_PPC64_JMP_SLOT > __sqrtieee128 + 0 > 00250e98 06020015 R_PPC64_JMP_SLOT > __cosieee128 + 0 > 00250eb0 060a0015 R_PPC64_JMP_SLOT > __atanhieee128 + 0 > 00250ef0 06200015 R_PPC64_JMP_SLOT > __asinhieee128 + 0 > 00250fd8 067f0015 R_PPC64_JMP_SLOT > __csqrtieee128 + 0 > 00251038 06ad0015 R_PPC64_JMP_SLOT > __cabsieee128 + 0 > All these should for POWER_IEEE128 use atan2q@QUADMATH_1.0 etc. So, seems all these come from f951 compiled sources. For user code, I think the agreement was if you want to use successfully -mabi=ieeelongdouble, you need glibc 2.32 or later, which is why the Fortran FE doesn't conditionalize on whether glibc 2.32 is available or not and just emits __WHATEVERieee128 entrypoints. But for Fortran compiled sources in libgfortran, we need to use __WHATEVERieee128 only if glibc 2.32 or later and WHATEVERq (from libquadmath) otherwise. I guess easiest would be to do this always in the FE, but we need to determine in the FE if the target is glibc 2.32 or later. > On the other side, on glibc 2.32+ build, we still use some libquadmath APIs > when we shouldn't: > readelf -Wr > /home/jakub/gcc/obj/powerpc64le-unknown-linux-gnu/libgfortran/.libs/libgfortran.so.5 > | grep QUADMATH > 002502c8 00260015 R_PPC64_JMP_SLOT > fmaq@QUADMATH_1.0 + 0 > 002505f8 00670015 R_PPC64_JMP_SLOT > tanq@QUADMATH_1.0 + 0 > 00250930 009b0015 R_PPC64_JMP_SLOT > fabsq@QUADMATH_1.0 + 0 > 00250940 009d0015 R_PPC64_JMP_SLOT > sinq@QUADMATH_1.0 + 0 > 00250c98 00cf0015 R_PPC64_JMP_SLOT > copysignq@QUADMATH_1.0 + 0 > 00251038 01070015 R_PPC64_JMP_SLOT > cosq@QUADMATH_1.0 + 0 > 00251068 010a0015 R_PPC64_JMP_SLOT > fmodq@QUADMATH_1.0 + 0 > These should use __fmaieee128, __tanieee128 etc. instead. This one seems easily fixed by the following patch, ok for power-ieee128? 2022-01-07 Jakub Jelinek * libgfortran.h (__copysignieee128, __fmaieee128, __fmodieee128): Declare. * intrinsics/trigd.c (COPYSIGN, FMOD, FABS, FMA, SIN, COS, TAN): If POWER_IEEE128 is defined, define these for kind 17 include. * intrinsics/trigd_lib.inc (COPYSIGN, FMOD, FABS, FMA, SIN, COS, TAN): Don't define if COPYSIGN is already defined. --- libgfortran/libgfortran.h.jj2022-01-07 09:39:10.222157644 + +++
Re: [PATCH] target: [PR102941] Fix inline-asm flags with non-REG_P output
apinski--- via Gcc-patches writes: > From: Andrew Pinski > > So the problem here is that arm_md_asm_adjust would > just create a set directly to the output memory which is wrong. > It needs to output to a temp register first and then do a > move. > > OK? Bootstrapped and tested on aarch64-linux-gnu with no regressions. > I have no way to test on arm even though this touches common code. > > PR target/102941 > > gcc/ChangeLog: > > * config/arm/aarch-common.c (arm_md_asm_adjust): > Use a temp if !REG_P. > > gcc/testsuite/ChangeLog: > > * gcc.target/aarch64/asm-flag-7.c: New test. > * gcc.target/arm/asm-flag-7.c: New test. OK, thanks, and sorry for the delay. Richard > --- > gcc/config/arm/aarch-common.c | 2 +- > gcc/testsuite/gcc.target/aarch64/asm-flag-7.c | 22 ++ > gcc/testsuite/gcc.target/arm/asm-flag-7.c | 23 +++ > 3 files changed, 46 insertions(+), 1 deletion(-) > create mode 100644 gcc/testsuite/gcc.target/aarch64/asm-flag-7.c > create mode 100644 gcc/testsuite/gcc.target/arm/asm-flag-7.c > > diff --git a/gcc/config/arm/aarch-common.c b/gcc/config/arm/aarch-common.c > index 67343fe4025..60b3516c1df 100644 > --- a/gcc/config/arm/aarch-common.c > +++ b/gcc/config/arm/aarch-common.c > @@ -641,7 +641,7 @@ arm_md_asm_adjust (vec , vec & > /*inputs*/, >rtx x = gen_rtx_REG (mode, CC_REGNUM); >x = gen_rtx_fmt_ee (code, word_mode, x, const0_rtx); > > - if (dest_mode == word_mode) > + if (dest_mode == word_mode && REG_P (dest)) > emit_insn (gen_rtx_SET (dest, x)); >else > { > diff --git a/gcc/testsuite/gcc.target/aarch64/asm-flag-7.c > b/gcc/testsuite/gcc.target/aarch64/asm-flag-7.c > new file mode 100644 > index 000..6c31b854b0b > --- /dev/null > +++ b/gcc/testsuite/gcc.target/aarch64/asm-flag-7.c > @@ -0,0 +1,22 @@ > +/* Test that "=@cc*" works with MEM_P RTX */ > +/* PR target/102941 */ > +/* { dg-do compile } */ > +/* { dg-options "-O" } */ > + > +#ifndef __GCC_ASM_FLAG_OUTPUTS__ > +#error "missing preprocessor define" > +#endif > +int test_cmpu_x; > + > +void f(long *); > +long > +test_cmpu_y() { > + long le; > + f(); > + __asm__("cmp %" > + "[x], %" > + "[y]" > + : "=@ccls"(le) > + : [x] ""(test_cmpu_x), [y] ""(test_cmpu_y)); > +return le; > +} > diff --git a/gcc/testsuite/gcc.target/arm/asm-flag-7.c > b/gcc/testsuite/gcc.target/arm/asm-flag-7.c > new file mode 100644 > index 000..ac11da0a3a8 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/arm/asm-flag-7.c > @@ -0,0 +1,23 @@ > +/* Test that "=@cc*" works with MEM_P RTX */ > +/* PR target/102941 */ > +/* { dg-do compile } */ > +/* { dg-options "-O" } */ > +/* { dg-skip-if "" { arm_thumb1 } } */ > + > +#ifndef __GCC_ASM_FLAG_OUTPUTS__ > +#error "missing preprocessor define" > +#endif > +int test_cmpu_x; > + > +void f(long *); > +long > +test_cmpu_y() { > + long le; > + f(); > + __asm__("cmp %" > + "[x], %" > + "[y]" > + : "=@ccls"(le) > + : [x] ""(test_cmpu_x), [y] ""(test_cmpu_y)); > +return le; > +}
Re: [vect] Re-analyze all modes for epilogues
"Andre Vieira (lists)" writes: > Made the suggested changes. > > Regarding the name change to partial vectors, I agree in the name change > since that is the terminology we are using in the loop_vinfo members > too, but is there an actual difference between predication/masking and > partial vectors that I am missing? “Predication/masking” refers to the ability to enable and disable operations on a lane-by-lane basis. E.g. it means that patterns like 10100010 are possible. “Operating on partial vectors” is the ability to operate on just the first N lanes of a vector, for some given N. It means that patterns like 1100 are possible but patterns like 10100010 might not be. At the moment, “operating on partial vectors” also requires either direct support for loading and storing the first N lanes, or a way of generating a loop predicate/mask from N and using predication/masking. So the two concepts overlap, but support for one doesn't directly imply support for the other. > OK for trunk? > > gcc/ChangeLog: > > * tree-vect-loop.c (vect_better_loop_vinfo_p): Round factors up > for epilogue costing. > (vect_analyze_loop): Re-analyze all modes for epilogues, unless > we are guaranteed that we can't > have partial vectors. > (genopinit.c) (partial_vectors_supported): Generate new function. > > gcc/testsuite/ChangeLog: > > * gcc.target/aarch64/masked_epilogue.c: New test. OK, thanks. Richard > diff --git a/gcc/genopinit.c b/gcc/genopinit.c > index > 195ddf74fa2b7d89760622073dcec9d5d339a097..2bc7cdbf53337beae181afd7bb05b366ab068c6a > 100644 > --- a/gcc/genopinit.c > +++ b/gcc/genopinit.c > @@ -321,6 +321,7 @@ main (int argc, const char **argv) > " bool supports_vec_scatter_store_cached;\n" > "};\n" > "extern void init_all_optabs (struct target_optabs *);\n" > +"extern bool partial_vectors_supported_p (void);\n" > "\n" > "extern struct target_optabs default_target_optabs;\n" > "extern struct target_optabs *this_fn_optabs;\n" > @@ -373,6 +374,33 @@ main (int argc, const char **argv) > fprintf (s_file, " ena[%u] = HAVE_%s;\n", i, p->name); >fprintf (s_file, "}\n\n"); > > + fprintf (s_file, > +"/* Returns TRUE if the target supports any of the partial vector\n" > +" optabs: while_ult_optab, len_load_optab or len_store_optab,\n" > +" for any mode. */\n" > +"bool\npartial_vectors_supported_p (void)\n{\n"); > + bool any_match = false; > + fprintf (s_file, "\treturn"); > + bool first = true; > + for (i = 0; patterns.iterate (i, ); ++i) > +{ > +#define CMP_NAME(N) !strncmp (p->name, (N), strlen ((N))) > + if (CMP_NAME("while_ult") || CMP_NAME ("len_load") > + || CMP_NAME ("len_store")) > + { > + if (first) > + fprintf (s_file, " HAVE_%s", p->name); > + else > + fprintf (s_file, " || HAVE_%s", p->name); > + first = false; > + any_match = true; > + } > +} > + if (!any_match) > +fprintf (s_file, " false"); > + fprintf (s_file, ";\n}\n"); > + > + >/* Perform a binary search on a pre-encoded optab+mode*2. */ >/* ??? Perhaps even better to generate a minimal perfect hash. > Using gperf directly is awkward since it's so geared to working > diff --git a/gcc/testsuite/gcc.target/aarch64/masked_epilogue.c > b/gcc/testsuite/gcc.target/aarch64/masked_epilogue.c > new file mode 100644 > index > ..286a7be236f337fee4c4650f42da72000855c5e6 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/aarch64/masked_epilogue.c > @@ -0,0 +1,10 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-details > -march=armv8-a+sve -msve-vector-bits=scalable" } */ > + > +void f(unsigned char y[restrict], > + unsigned char x[restrict], int n) { > + for (int i = 0; i < n; ++i) > +y[i] = (y[i] + x[i] + 1) >> 1; > +} > + > +/* { dg-final { scan-tree-dump {LOOP EPILOGUE VECTORIZED \(MODE=VNx} "vect" > } } */ > diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c > index > a28bb6321d76b8222bc8cfdade151ca9b4dca406..5af98a36678ae61e99f93beb90920e2d0940c53a > 100644 > --- a/gcc/tree-vect-loop.c > +++ b/gcc/tree-vect-loop.c > @@ -2824,11 +2824,13 @@ vect_better_loop_vinfo_p (loop_vec_info > new_loop_vinfo, > { > unsigned HOST_WIDE_INT main_vf_max > = estimated_poly_value (main_poly_vf, POLY_VALUE_MAX); > + unsigned HOST_WIDE_INT old_vf_max > + = estimated_poly_value (old_vf, POLY_VALUE_MAX); > + unsigned HOST_WIDE_INT new_vf_max > + = estimated_poly_value (new_vf, POLY_VALUE_MAX); > > - old_factor = main_vf_max / estimated_poly_value (old_vf, > -POLY_VALUE_MAX); > - new_factor = main_vf_max / estimated_poly_value (new_vf, > -
[PATCH] c++, match.pd: Evaluate in constant evaluation comparisons like + 12 == + 24 [PR89074]
Hi! The match.pd address_comparison simplification can only handle ADDR_EXPR comparisons possibly converted to some other type (I wonder if we shouldn't restrict it in address_compare to casts to pointer types or pointer-sized integer types, I think we shouldn't optimize (short) () == (short) () because we really don't know whether it will be true or false). On GIMPLE, most of pointer to pointer casts are useless and optimized away and further we have in gimple_fold_stmt_to_constant_1 an optimization that folds p+ const_int into _REF[..., off] On GENERIC, we don't do that and e.g. for constant evaluation it could be pretty harmful if e.g. such pointers are dereferenced, because it can lose what exact field it was starting with etc., all it knows is the base and offset, type and alias set. Instead of teaching the match.pd address_compare about 3 extra variants where one or both compared operands are pointer_plus, this patch attempts to fold operands of comparisons similarly to gimple_fold_stmt_to_constant_1 before calling fold_binary on it. There is another thing though, while we do have (x p+ y) p+ z to x p+ (y + z) simplification which works on GIMPLE well because of the useless pointer conversions, on GENERIC we can have pointer casts in between and at that point we can end up with large expressions like ((type3) (((type2) ((type1) ( + 2) + 2) + 2) + 2)) etc. Pointer-plus doesn't really care what exact pointer type it has as long as it is a pointer, so the following match.pd simplification for GENERIC only (it is useless for GIMPLE) also moves the cast so that nested p+ can be simplified. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? Note, I've noticed we don't really diagnose going out of bounds with pointer_plus (unlike e.g. with ARRAY_REF) during constant evaluation, I think another patch for cxx_eval_binary_expression with POINTER_PLUS will be needed. But it isn't clear to me what exactly it should do in case of subobjects. If we start with address of a whole var, (), I guess we should diagnose if the pointer_plus gets before start of the var (i.e. "negative") or 1 byte past the end of the var, but what if we start with or [3] ? For , shall we diagnose out of bounds of field (except perhaps flexible members?) or the whole var? For ARRAY_REFs, I assume we must at least strip all the outer ARRAY_REFs and so start with too, right? 2022-01-07 Jakub Jelinek PR c++/89074 gcc/ * match.pd ((ptr) (x p+ y) p+ z -> (ptr) (x p+ (y + z))): New GENERIC simplification. gcc/cp/ * constexpr.c (cxx_maybe_fold_addr_pointer_plus): New function. (cxx_eval_binary_expression): Use it. gcc/testsuite/ * g++.dg/cpp1y/constexpr-89074-2.C: New test. * g++.dg/cpp1z/constexpr-89074-1.C: New test. --- gcc/match.pd.jj 2022-01-05 20:30:08.768806236 +0100 +++ gcc/match.pd2022-01-06 19:59:53.596114417 +0100 @@ -2143,6 +2143,11 @@ (define_operator_list SYNC_FETCH_AND_AND (simplify (pointer_plus (pointer_plus:s @0 @1) @3) (pointer_plus @0 (plus @1 @3))) +#if GENERIC +(simplify + (pointer_plus (convert:s (pointer_plus:s @0 @1)) @3) + (convert:type (pointer_plus @0 (plus @1 @3 +#endif /* Pattern match tem1 = (long) ptr1; --- gcc/cp/constexpr.c.jj 2022-01-03 10:40:48.403063535 +0100 +++ gcc/cp/constexpr.c 2022-01-06 20:47:44.596623219 +0100 @@ -3288,6 +3288,38 @@ cxx_fold_pointer_plus_expression (const return NULL_TREE; } +/* Try to fold expressions like + (struct S *) ([0].D.2378 + 12) + into + [(void *) + 12B] + This is something normally done by gimple_fold_stmt_to_constant_1 + on GIMPLE, but is undesirable on GENERIC if we are e.g. going to + dereference the address because some details are lost. + For pointer comparisons we want such folding though so that + match.pd address_compare optimization works. */ + +static tree +cxx_maybe_fold_addr_pointer_plus (tree t) +{ + while (CONVERT_EXPR_P (t) +&& POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0 +t = TREE_OPERAND (t, 0); + if (TREE_CODE (t) != POINTER_PLUS_EXPR) +return NULL_TREE; + tree op0 = TREE_OPERAND (t, 0); + tree op1 = TREE_OPERAND (t, 1); + if (TREE_CODE (op1) != INTEGER_CST) +return NULL_TREE; + while (CONVERT_EXPR_P (op0) +&& POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (op0, 0 +op0 = TREE_OPERAND (op0, 0); + if (TREE_CODE (op0) != ADDR_EXPR) +return NULL_TREE; + op1 = fold_convert (ptr_type_node, op1); + tree r = fold_build2 (MEM_REF, TREE_TYPE (TREE_TYPE (op0)), op0, op1); + return build1_loc (EXPR_LOCATION (t), ADDR_EXPR, TREE_TYPE (op0), r); +} + /* Subroutine of cxx_eval_constant_expression. Like cxx_eval_unary_expression, except for binary expressions. */ @@ -3347,6 +3379,15 @@ cxx_eval_binary_expression (const conste else if (TREE_CODE (rhs) == PTRMEM_CST) rhs = cplus_expand_constant (rhs); } + if (r == NULL_TREE + &&
Re: [PATCH] [RTL/fwprop] Allow propagations from inner loop to outer loop.
liuhongt via Gcc-patches writes: >>Huh, loop_father should never be NULL. Maybe when fwprop is run after RTL >>loop opts you instead want to add a check for current_loops or >>alternelatively initialize loops in fwprop. > > Oh, I didn't know that, i once saw there's ICE and thought it's related to > NULL loop. But I can't reproduce the ICE either in GCC testsuite or buiding > spec2017. Anyway, here's update patch. > > gcc/ChangeLog: > > PR rtl/103750 > * fwprop.c (forward_propagate_into): Allow propagations from > inner loop to outer loop. > > gcc/testsuite/ChangeLog: > > * g++.target/i386/pr103750-fwprop-1.C: New test. > --- > build.log | 0 > gcc/fwprop.c | 7 +++-- > .../g++.target/i386/pr103750-fwprop-1.C | 26 +++ > 3 files changed, 31 insertions(+), 2 deletions(-) > create mode 100644 build.log > create mode 100644 gcc/testsuite/g++.target/i386/pr103750-fwprop-1.C > > diff --git a/build.log b/build.log > new file mode 100644 > index 000..e69de29bb2d > diff --git a/gcc/fwprop.c b/gcc/fwprop.c > index 2eab4fd4614..4f5d6a8d4fc 100644 > --- a/gcc/fwprop.c > +++ b/gcc/fwprop.c > @@ -866,10 +866,13 @@ forward_propagate_into (use_info *use, bool > reg_prop_only = false) >rtx src = SET_SRC (def_set); > >/* Allow propagations into a loop only for reg-to-reg copies, since > - replacing one register by another shouldn't increase the cost. */ > + replacing one register by another shouldn't increase the cost. > + Propagations from inner loop to outer loop should be also ok. */ “should also be ok” OK with that change, thanks. Richard >struct loop *def_loop = def_insn->bb ()->cfg_bb ()->loop_father; >struct loop *use_loop = use->bb ()->cfg_bb ()->loop_father; > - if ((reg_prop_only || def_loop != use_loop) > + if ((reg_prop_only > + || (def_loop != use_loop > +&& !flow_loop_nested_p (use_loop, def_loop))) >&& (!reg_single_def_p (dest) || !reg_single_def_p (src))) > return false; > > diff --git a/gcc/testsuite/g++.target/i386/pr103750-fwprop-1.C > b/gcc/testsuite/g++.target/i386/pr103750-fwprop-1.C > new file mode 100644 > index 000..26987d307aa > --- /dev/null > +++ b/gcc/testsuite/g++.target/i386/pr103750-fwprop-1.C > @@ -0,0 +1,26 @@ > +/* PR target/103750. */ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -std=c++1y -march=cannonlake -fdump-rtl-fwprop1" } */ > +/* { dg-final { scan-rtl-dump-not "subreg:HI\[ > \\\(\]*reg:SI\[^\n]*\n\[^\n]*UNSPEC_TZCNT" "fwprop1" } } */ > + > +#include > +const char16_t *qustrchr(char16_t *n, char16_t *e, char16_t c) noexcept > +{ > + __m256i mch256 = _mm256_set1_epi16(c); > + for ( ; n < e; n += 32) { > +__m256i data1 = _mm256_loadu_si256(reinterpret_cast(n)); > +__m256i data2 = _mm256_loadu_si256(reinterpret_cast(n) > + 1); > +__mmask16 mask1 = _mm256_cmpeq_epu16_mask(data1, mch256); > +__mmask16 mask2 = _mm256_cmpeq_epu16_mask(data2, mch256); > +if (_kortestz_mask16_u8(mask1, mask2)) > + continue; > + > +unsigned idx = _tzcnt_u32(mask1); > +if (mask1 == 0) { > + idx = __tzcnt_u16(mask2); > + n += 16; > +} > +return n + idx; > + } > + return e; > +}
Re: [PATCH v4 04/12] LoongArch Port: Machine Decsription files.
在 2022/1/7 上午1:54, Xi Ruoyao 写道: On Fri, 2021-12-24 at 17:28 +0800, chenglulu wrote: +(define_insn "*zero_extendsidi2_internal" + [(set (match_operand:DI 0 "register_operand" "=r,r,r") + (subreg:DI (match_operand:SI 1 "nonimmediate_operand" "r,ZC,W") 0))] + "TARGET_64BIT" + "@ + bstrpick.d\t%0,%1,31,0 + ldptr.w\t%0,%1\n\tlu32i.d\t%0,0 + ld.wu\t%0,%1" + [(set_attr "move_type" "arith,load,load") + (set_attr "mode" "DI") + (set_attr "insn_count" "1,2,1")]) This pattern is generating wrong code, causing FAIL: gcc.dg/compat/scalar-by-value-3 c_compat_x_tst.o-c_compat_y_tst.o execute This failure is a real bug, the reduced testcase is attached. In the assembly: # ... bstrins.d $r5,$r13,31,0 addi.d $r12,$r22,-228 bstrpick.d $r12,$r12,31,0 bstrins.d $r5,$r12,63,32 addi.w $r4,$r0,14 # 0xe bl testvaci This obviously does not make any sense: it calculates the *address* of g[0]'s imaginary part, truncates it to 32-bit, then pass it as the *value* of the imaginary part to testvaci(). The problem is: before the reload pass, the compiler consider g[0] a (virtual) register. It only becomes MEM after the reload pass. Adding reload_completed as the condition of this insn seems able to fix the issue. However I'm not sure if other insns need the change too. +;; See the comment before the *and3 pattern why this is generated by +;; combine. A minor issue: the comment before 'and3' does not exist. Thanks, we are working on this. In addition, we will check other instruction templates.
Re: [power-ieee128] RFH: LTO broken
On Thu, Jan 06, 2022 at 09:01:54PM +0100, Thomas Koenig wrote: > > On 06.01.22 06:00, Michael Meissner via Fortran wrote: > > I pushed the patch to the branch. > > Test results are looking quite good right now. I've just tried to build libgfortran on an old glibc system (gcc112.fsffrance.org) and unfortunately we still have work to do: [jakub@gcc2-power8 obj38]$ LD_PRELOAD=/home/jakub/gcc/obj38/powerpc64le-unknown-linux-gnu/libgfortran/.libs/libgfortran.so.5.0.0 /bin/true [jakub@gcc2-power8 obj38]$ LD_BIND_NOW=1 LD_PRELOAD=/home/jakub/gcc/obj38/powerpc64le-unknown-linux-gnu/libgfortran/.libs/libgfortran.so.5.0.0 /bin/true /bin/true: symbol lookup error: /home/jakub/gcc/obj38/powerpc64le-unknown-linux-gnu/libgfortran/.libs/libgfortran.so.5.0.0: undefined symbol: __atan2ieee128 While we do use some libquadmath APIs: readelf -Wr /home/jakub/gcc/obj38/powerpc64le-unknown-linux-gnu/libgfortran/.libs/libgfortran.so.5.0.0 | grep QUADMATH 00251268 05e40026 R_PPC64_ADDR64 quadmath_snprintf@QUADMATH_1.0 + 0 00251270 03060026 R_PPC64_ADDR64 strtoflt128@QUADMATH_1.0 + 0 002502e0 01160015 R_PPC64_JMP_SLOT ynq@QUADMATH_1.0 + 0 00250390 01600015 R_PPC64_JMP_SLOT sqrtq@QUADMATH_1.0 + 0 00250508 01fa0015 R_PPC64_JMP_SLOT fmaq@QUADMATH_1.0 + 0 00250530 02120015 R_PPC64_JMP_SLOT fabsq@QUADMATH_1.0 + 0 00250760 03060015 R_PPC64_JMP_SLOT strtoflt128@QUADMATH_1.0 + 0 00250990 03df0015 R_PPC64_JMP_SLOT cosq@QUADMATH_1.0 + 0 002509f0 040a0015 R_PPC64_JMP_SLOT expq@QUADMATH_1.0 + 0 00250a88 04510015 R_PPC64_JMP_SLOT erfcq@QUADMATH_1.0 + 0 00250a98 045e0015 R_PPC64_JMP_SLOT jnq@QUADMATH_1.0 + 0 00250ac8 047e0015 R_PPC64_JMP_SLOT sinq@QUADMATH_1.0 + 0 00250e38 05db0015 R_PPC64_JMP_SLOT fmodq@QUADMATH_1.0 + 0 00250e48 05e00015 R_PPC64_JMP_SLOT tanq@QUADMATH_1.0 + 0 00250e58 05e40015 R_PPC64_JMP_SLOT quadmath_snprintf@QUADMATH_1.0 + 0 00250f20 06290015 R_PPC64_JMP_SLOT copysignq@QUADMATH_1.0 + 0 we don't do it consistently: readelf -Wr /home/jakub/gcc/obj38/powerpc64le-unknown-linux-gnu/libgfortran/.libs/libgfortran.so.5.0.0 | grep ieee128 00250310 01280015 R_PPC64_JMP_SLOT __atan2ieee128 + 0 00250340 01420015 R_PPC64_JMP_SLOT __clogieee128 + 0 00250438 01a30015 R_PPC64_JMP_SLOT __acoshieee128 + 0 002504b8 01cc0015 R_PPC64_JMP_SLOT __csinieee128 + 0 00250500 01f30015 R_PPC64_JMP_SLOT __sinhieee128 + 0 00250570 022a0015 R_PPC64_JMP_SLOT __asinieee128 + 0 00250580 022d0015 R_PPC64_JMP_SLOT __roundieee128 + 0 002505a0 023e0015 R_PPC64_JMP_SLOT __logieee128 + 0 002505c8 02490015 R_PPC64_JMP_SLOT __tanieee128 + 0 00250630 02750015 R_PPC64_JMP_SLOT __ccosieee128 + 0 00250670 028a0015 R_PPC64_JMP_SLOT __log10ieee128 + 0 002506c8 02bd0015 R_PPC64_JMP_SLOT __cexpieee128 + 0 002506d8 02c80015 R_PPC64_JMP_SLOT __coshieee128 + 0 002509b0 03ef0015 R_PPC64_JMP_SLOT __truncieee128 + 0 00250af8 04a60015 R_PPC64_JMP_SLOT __expieee128 + 0 00250b50 04c60015 R_PPC64_JMP_SLOT __fmodieee128 + 0 00250bb0 04e70015 R_PPC64_JMP_SLOT __tanhieee128 + 0 00250c38 05130015 R_PPC64_JMP_SLOT __acosieee128 + 0 00250ce0 05540015 R_PPC64_JMP_SLOT __sinieee128 + 0 00250d60 057e0015 R_PPC64_JMP_SLOT __atanieee128 + 0 00250dd8 05b10015 R_PPC64_JMP_SLOT __sqrtieee128 + 0 00250e98 06020015 R_PPC64_JMP_SLOT __cosieee128 + 0 00250eb0 060a0015 R_PPC64_JMP_SLOT __atanhieee128 + 0 00250ef0 06200015 R_PPC64_JMP_SLOT __asinhieee128 + 0 00250fd8
Re: [PATCH 1/6] ira: Add a ira_loop_border_costs class
Jan Hubicka writes: >> The final index into (ira_)memory_move_cost is 1 for loads and >> 0 for stores. Thus the combination: >> >> entry_freq * memory_cost[1] + exit_freq * memory_cost[0] >> >> is the cost of loading a register on entry to a loop and >> storing it back on exit from the loop. This is the cost to >> use if the register is successfully allocated within the >> loop but is spilled in the parent loop. Similarly: >> >> entry_freq * memory_cost[0] + exit_freq * memory_cost[1] >> >> is the cost of storing a register on entry to the loop and >> restoring it on exit from the loop. This is the cost to >> use if the register is spilled within the loop but is >> successfully allocated in the parent loop. >> >> The patch adds a helper class for calculating these values and >> mechanically replaces the existing instances. There is no attempt to >> editorialise the choice between using “spill inside” and “spill outside” >> costs. (I think one of them is the wrong way round, but a later patch >> deals with that.) >> >> No functional change intended. >> >> gcc/ >> PR rtl-optimization/98782 >> * ira-int.h (ira_loop_border_costs): New class. >> * ira-color.c (ira_loop_border_costs::ira_loop_border_costs): >> New constructor. >> (calculate_allocno_spill_cost): Use ira_loop_border_costs. >> (color_pass): Likewise. >> (move_spill_restore): Likewise. > > Thanks for working on this. For profile bits, the patch looks good to > me. In general I am trying to move away from the integer frequencies. > It would be more precise to calculate the m_entry_freq and m_exit_freq > as profile_count m_entry_count, m_exit_count > and do conversion only later. > > count->to_frequency method basically scales it to the range 0...BB_FREQ_MAX. Yeah. If I get time, I'd like to see how easy it would be to move the RAs away from the BB_FREQ_MAX scaling. I agree it's not really precise enough. The problem is that the costs are multiplied by several other things, and there have recently been overflow problems (g:7d02c8bf75980fa2468f). I guess the way to avoid that would be to use sreals, but the problem then is that the costing code (particularly record_reg_classes) is very compile-time sensitive. So it might need a bit of surgery to move over to sreal costs without negatively affecting compile time (and perhaps memory consumption). Of course, RA changes would become much easier if we got rid of old reload. :-) (OK, bit of a cheap shot in this case, but true in general.) Thanks, Richard
Re: [power-ieee128] OPEN CONV
On 07.01.22 10:22, Jakub Jelinek wrote: On Thu, Jan 06, 2022 at 09:01:54PM +0100, Thomas Koenig wrote: On 06.01.22 06:00, Michael Meissner via Fortran wrote: What is still missing is the conversion for unformatted I/O, both ways. I'll start doing some stuff on it. Just one question: What are functions that I can use to convert from IBM long double to IEEE and long double and vice versa? It was in an e-mail somewhere, but I cannot find it at the moment. So, what's the plan for that? Can't find CONVERT= in Fortran 2018, so I assume it is a non-standard extension, Correct. https://www.intel.com/content/www/us/en/develop/documentation/fortran-compiler-oneapi-dev-guide-and-reference/top/language-reference/file-operation-i-o-statements/open-statement-specifiers/open-convert-specifier.html#open-convert-specifier documents the Intel one We followed Intel on that one. NAG also has it (although the details differ). and we accept CONVERT='native' CONVERT='swap' CONVERT='big_endian' CONVERT='little_endian' Now, I suppose for powerpc64le we want to add some more, but the question is how they play together with the byteswapping and how to name them, so that it is clear they talk about REAL/COMPLEX KIND=16 format and nothing else. Can we (or do we) want to allow multiple comma separated strings from the orthogonal choices, like CONVERT='big_endian,ibm_extended' CONVERT='swap,ieee_extended' or add ibm_extended, ieee_extended and strings that combine those with swap, big_endian and little_endian ibm_extended_swap, ieee_extended_little etc.? In https://gcc.gnu.org/pipermail/fortran/2021-October/056895.html I made a suggestion how how the format could look like. I used a plus sign instead of a comma because I thought the environment variable should follow the same syntax as the CONVERT specifier, and I did not want to think about having commas in there :-) Thinking about this again after some time, I think the syntax of the environment variable would be clearer if the keywords for the two conversions were separate, so somethig like big_endian;r16_ieee;r16_ibm:10-20; for the environment variable and CONVERT="big_endian,r16_ibm" would probably be better. Best regards Thomas
Re: [committed] c++: Add testcase for recently fixed PR [PR69681]
On Thu, Jan 06, 2022 at 10:44:09AM -0500, Patrick Palka via Gcc-patches wrote: > Fixed ever since r12-6188. > > PR c++/69681 > > gcc/testsuite/ChangeLog: > > * g++.dg/cpp0x/constexpr-compare2.C: New test. Note, I've tested my https://gcc.gnu.org/pipermail/gcc-patches/2022-January/587745.html patch before you've committed this test, that patch makes it FAIL again. The thing is that in address_compare now we make it all the way to tree sz0 = DECL_SIZE_UNIT (base0); tree sz1 = DECL_SIZE_UNIT (base1); /* If sizes are unknown, e.g. VLA or not representable, punt. */ if (!tree_fits_poly_int64_p (sz0) || !tree_fits_poly_int64_p (sz1)) return 2; which wants to check if one pointer is to a start of one object and another pointer to the end of another one. But, base0 and base1 are both FUNCTION_DECLs, and those seem to never have DECL_SIZE_UNIT set on them, whether the functions are external or defined locally. We've already proven that base0 and base1 are different. Can we with folding_initializer set (or even unset?) assume that if one or both of the bases are FUNCTION_DECLs they will compare unequal regardless if the other pointer is at the start or end of some variable? For the !folding_initializer case, one thing is that while we've dealt with aliases visible to the compiler already and punted, there could again be aliases not visible to the compiler etc. There is also a theoretical chance that .text section with some functions in it could be immediately followed by .rodata section with variables, but zero sized functions are rare and using address arithmetics to get to the end of a function isn't something we should support. Some functions and variables could be also defined in assembly and could be adjacent... So at least limiting it to folding_initializer would be wise, but the question is what exactly should be valid and what should be invalid in C++. So, thoughts on this? > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-compare2.C > @@ -0,0 +1,10 @@ > +// PR c++/69681 > +// { dg-do compile { target c++11 } } > + > +void f(); > +void g(); > +static_assert(f != g, ""); > + > +#if __cpp_constexpr >= 201603L > +static_assert([]{} != []{}, ""); > +#endif > -- > 2.34.1.493.ge83ba647f7 Jakub
[power-ieee128] OPEN CONV
On Thu, Jan 06, 2022 at 09:01:54PM +0100, Thomas Koenig wrote: > > On 06.01.22 06:00, Michael Meissner via Fortran wrote: > What is still missing is the conversion for unformatted I/O, both > ways. I'll start doing some stuff on it. Just one question: > What are functions that I can use to convert from IBM long double > to IEEE and long double and vice versa? It was in an e-mail somewhere, > but I cannot find it at the moment. So, what's the plan for that? Can't find CONVERT= in Fortran 2018, so I assume it is a non-standard extension, https://www.intel.com/content/www/us/en/develop/documentation/fortran-compiler-oneapi-dev-guide-and-reference/top/language-reference/file-operation-i-o-statements/open-statement-specifiers/open-convert-specifier.html#open-convert-specifier documents the Intel one and we accept CONVERT='native' CONVERT='swap' CONVERT='big_endian' CONVERT='little_endian' Now, I suppose for powerpc64le we want to add some more, but the question is how they play together with the byteswapping and how to name them, so that it is clear they talk about REAL/COMPLEX KIND=16 format and nothing else. Can we (or do we) want to allow multiple comma separated strings from the orthogonal choices, like CONVERT='big_endian,ibm_extended' CONVERT='swap,ieee_extended' or add ibm_extended, ieee_extended and strings that combine those with swap, big_endian and little_endian ibm_extended_swap, ieee_extended_little etc.? Jakub
Re: [PATCH] nvptx: Add support for PTX's cnot instruction.
On 1/6/22 17:42, Roger Sayle wrote: Happy New Year for 2022. This is a simple patch, now that the nvptx backend has transitioned to STORE_FLAG_VALUE=1, that adds support for NVidia's cnot instruction, that implements C/C++ style logical negation. Happy newyear to you too :) LGTM, please apply. Thanks, - Tom Previously, the simple function: int foo(int x) { return !x; } on nvptx-none with -O2 would generate: mov.u32 %r24, %ar0; setp.eq.u32 %r28, %r24, 0; selp.u32%value, 1, 0, %r28; with this patch, GCC now generates: mov.u32 %r24, %ar0; cnot.b32%value, %r24; This patch has been tested on nvptx-none hosted on x86_64-pc-linux-gnu (including newlib) with a make and make -k check with no new failures. Ok for mainline? 2022-01-06 Roger Sayle gcc/ChangeLog * config/nvptx/nvptx.md (*cnot2): New define_insn. gcc/testsuite/ChangeLog * gcc.target/nvptx/cnot-1.c: New test case. Thanks in advance, Roger --