From 8792047470073df0da4a5b91997d6058193d7676 Mon Sep 17 00:00:00 2001 From: Tobias Burnus Date: Tue, 4 Oct 2022 17:03:32 +0200 Subject: OpenMP: Update invoke.texi and fix fortran/parse.cc for -fopenmp-simd Split off from the 'Fortran: Add OpenMP's assume(s) directives' patch. gcc/ * doc/invoke.texi (-fopenmp): Mention C++ attribut syntax. (-fopenmp-simd): Likewise; update permitted directives. gcc/fortran/ * parse.cc (decode_omp_directive): Handle '(end) loop' and 'scan' also with -fopenmp-simd. gcc/testsuite/ * gfortran.dg/gomp/openmp-simd-7.f90: New test. --- gcc/testsuite/gfortran.dg/gomp/openmp-simd-7.f90 | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 gcc/testsuite/gfortran.dg/gomp/openmp-simd-7.f90 (limited to 'gcc/testsuite') diff --git a/gcc/testsuite/gfortran.dg/gomp/openmp-simd-7.f90 b/gcc/testsuite/gfortran.dg/gomp/openmp-simd-7.f90 new file mode 100644 index 0000000..d7010bb --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/openmp-simd-7.f90 @@ -0,0 +1,23 @@ +! { dg-options "-fno-openmp -fopenmp-simd -fdump-tree-original" } + +subroutine foo (a, b) + integer, contiguous :: a(:), b(:) + integer :: i + !$omp simd reduction (inscan, +:r) + do i = 1, 1024 + r = r + a(i) + !$omp scan inclusive(r) + b(i) = r + end do + !$omp end simd + + !$omp loop + do i = 1, 1024 + a(i) = a(i) + i + end do + !$omp end loop +end + +! { dg-final { scan-tree-dump "#pragma omp simd linear\\(i:1\\) reduction\\(inscan,\\+:r\\)" "original" } } +! { dg-final { scan-tree-dump "#pragma omp scan inclusive\\(r\\)" "original" } } +! { dg-final { scan-tree-dump "#pragma omp loop" "original" } } -- cgit v1.1 From c1b0a767f04a8ccbaff2a7b71d5c817cdb469630 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Tue, 4 Oct 2022 16:39:18 +0100 Subject: aarch64: Define __ARM_FEATURE_RCPC https://github.com/ARM-software/acle/pull/199 adds a new feature macro for RCPC, for use in things like inline assembly. This patch adds the associated support to GCC. Also, RCPC is required for Armv8.3-A and later, but the armv8.3-a entry didn't include it. This was probably harmless in practice since GCC simply ignored the extension until now. (The GAS definition is OK.) gcc/ * config/aarch64/aarch64.h (AARCH64_ISA_RCPC): New macro. * config/aarch64/aarch64-arches.def (armv8.3-a): Include RCPC. * config/aarch64/aarch64-cores.def (thunderx3t110, zeus, neoverse-v1) (neoverse-512tvb, saphira): Remove RCPC from these Armv8.3-A+ cores. * config/aarch64/aarch64-c.cc (aarch64_update_cpp_builtins): Define __ARM_FEATURE_RCPC when appropriate. gcc/testsuite/ * gcc.target/aarch64/pragma_cpp_predefs_1.c: Add RCPC tests. --- .../gcc.target/aarch64/pragma_cpp_predefs_1.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'gcc/testsuite') diff --git a/gcc/testsuite/gcc.target/aarch64/pragma_cpp_predefs_1.c b/gcc/testsuite/gcc.target/aarch64/pragma_cpp_predefs_1.c index bfb044f..307fa3d 100644 --- a/gcc/testsuite/gcc.target/aarch64/pragma_cpp_predefs_1.c +++ b/gcc/testsuite/gcc.target/aarch64/pragma_cpp_predefs_1.c @@ -248,6 +248,26 @@ #error "__ARM_FEATURE_CRC32 is not defined but should be!" #endif +#pragma GCC target ("arch=armv8.2-a") +#ifdef __ARM_FEATURE_RCPC +#error "__ARM_FEATURE_RCPC is defined but should not be!" +#endif + +#pragma GCC target ("arch=armv8.2-a+rcpc") +#ifndef __ARM_FEATURE_RCPC +#error "__ARM_FEATURE_RCPC is not defined but should be!" +#endif + +#pragma GCC target ("+norcpc") +#ifdef __ARM_FEATURE_RCPC +#error "__ARM_FEATURE_RCPC is defined but should not be!" +#endif + +#pragma GCC target ("arch=armv8.3-a") +#ifndef __ARM_FEATURE_RCPC +#error "__ARM_FEATURE_RCPC is not defined but should be!" +#endif + int foo (int a) { -- cgit v1.1 From ce3a1b5976079b1467473b4628f05797fd2eae08 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Tue, 4 Oct 2022 17:06:04 -0400 Subject: c++: fix debug info for array temporary [PR107154] In the testcase the elaboration of the array init that happens at genericize time was getting the location info for the end of the function; fixed by doing the expansion at the location of the original expression. PR c++/107154 gcc/cp/ChangeLog: * cp-gimplify.cc (cp_genericize_init_expr): Use iloc_sentinel. (cp_genericize_target_expr): Likewise. gcc/testsuite/ChangeLog: * g++.dg/debug/dwarf2/lineno-array1.C: New test. --- gcc/testsuite/g++.dg/debug/dwarf2/lineno-array1.C | 25 +++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 gcc/testsuite/g++.dg/debug/dwarf2/lineno-array1.C (limited to 'gcc/testsuite') diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/lineno-array1.C b/gcc/testsuite/g++.dg/debug/dwarf2/lineno-array1.C new file mode 100644 index 0000000..befac5f --- /dev/null +++ b/gcc/testsuite/g++.dg/debug/dwarf2/lineno-array1.C @@ -0,0 +1,25 @@ +// PR c++/107154 +// { dg-do compile { target c++11 } } +// { dg-additional-options "-gno-as-loc-support -dA" } +// Test that we emit debug info exactly once for the last line. +// { dg-final { scan-assembler-times {:25:1} 1 } } + +bool dummy; + +struct S { + const char *p; + S(const char *p): p(p) {} + ~S() { dummy = true; } +}; + +using Sar = S[]; + +struct X { + X(Sar&&) { } +}; + +int main() +{ + X x(Sar{"", ""}); + return 0; +} -- cgit v1.1 From 85872a69ee1b123557c7c352d45ef608e70b20fb Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Wed, 5 Oct 2022 00:17:25 +0000 Subject: Daily bump. --- gcc/testsuite/ChangeLog | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'gcc/testsuite') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0c6e5d4..8a30bb4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,39 @@ +2022-10-04 Jason Merrill + + PR c++/107154 + * g++.dg/debug/dwarf2/lineno-array1.C: New test. + +2022-10-04 Richard Sandiford + + * gcc.target/aarch64/pragma_cpp_predefs_1.c: Add RCPC tests. + +2022-10-04 Tobias Burnus + + * gfortran.dg/gomp/openmp-simd-7.f90: New test. + +2022-10-04 Jakub Jelinek + + * c-c++-common/gomp/declare-target-4.c: Move tests that are now + rejected into declare-target-7.c. + * c-c++-common/gomp/declare-target-6.c: Adjust expected diagnostics. + * c-c++-common/gomp/declare-target-7.c: New test. + * c-c++-common/gomp/begin-declare-target-1.c: New test. + * c-c++-common/gomp/begin-declare-target-2.c: New test. + * c-c++-common/gomp/begin-declare-target-3.c: New test. + * c-c++-common/gomp/begin-declare-target-4.c: New test. + * g++.dg/gomp/attrs-9.C: Add begin declare target tests. + * g++.dg/gomp/attrs-18.C: New test. + +2022-10-04 Aldy Hernandez + + PR tree-optimization/107130 + * gcc.dg/tree-ssa/pr107130.c: New test. + +2022-10-04 Lewis Hyatt + + PR c/91669 + * c-c++-common/pr91669.c: New test. + 2022-10-03 Torbjörn SVENSSON Yvan ROUX -- cgit v1.1 From bfca9505f6fce631c2488f89aa156d56c7fae9ed Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Tue, 4 Oct 2022 20:19:07 -0400 Subject: analyzer: revamp side-effects of call summaries [PR107072] With -fanalyzer-call-summaries the analyzer canl attempt to summarize the effects of some function calls at their call site, rather than simulate the call directly, which can avoid big slowdowns during analysis. Previously, this summarization was extremely simplistic: no attempt was made to update sm-state, and region_model::update_for_call_summary would simply set the return value of the function to UNKNOWN, and assume the function had no side effects. This patch implements less simplistic summarizations: it tracks each possible return enode from the called function, and attempts to generate a successor enode from the callsite for each that have compatible conditions, mapping state changes in the summary to state changes at the callsite. It also implements the beginnings of heuristics for generating user-facing descriptions of a summary e.g. "when 'foo' returns NULL" versus: "when 'foo' returns a heap-allocated buffer" This still has some bugs, but much more accurately tracks the effects of a call, and so is an improvement; it should only have an effect when -fanalyzer-call-summaries is enabled. As before, -fanalyzer-call-summaries is disabled by default in analyzer.opt (but enabled by default in the test suite). gcc/ChangeLog: PR analyzer/107072 * Makefile.in (ANALYZER_OBJS): Add analyzer/call-summary.o. gcc/analyzer/ChangeLog: PR analyzer/107072 * analyzer-logging.h: Include "diagnostic-core.h". * analyzer.h: Include "function.h". (class call_summary): New forward decl. (class call_summary_replay): New forward decl. (struct per_function_data): New forward decl. (struct interesting_t): New forward decl. (custom_edge_info::update_state): New vfunc. * call-info.cc (custom_edge_info::update_state): New. * call-summary.cc: New file. * call-summary.h: New file. * constraint-manager.cc: Include "analyzer/call-summary.h". (class replay_fact_visitor): New. (constraint_manager::replay_call_summary): New. * constraint-manager.h (constraint_manager::replay_call_summary): New. * engine.cc: Include "analyzer/call-summary.h". (exploded_node::on_stmt): Handle call summaries. (class call_summary_edge_info): New. (exploded_node::replay_call_summaries): New. (exploded_node::replay_call_summary): New. (per_function_data::~per_function_data): New. (per_function_data::add_call_summary): Move here from header and reimplement. (exploded_graph::process_node): Call update_state rather than update_model when handling bifurcation (viz_callgraph_node::dump_dot): Use a regular label rather than an HTML table; add summaries to dump. * exploded-graph.h: Include "alloc-pool.h", "fibonacci_heap.h", "supergraph.h", "sbitmap.h", "shortest-paths.h", "analyzer/sm.h", "analyzer/program-state.h", and "analyzer/diagnostic-manager.h". (exploded_node::replay_call_summaries): New decl. (exploded_node::replay_call_summary): New decl. (per_function_data::~per_function_data): New decl. (per_function_data::add_call_summary): Move implemention from header. (per_function_data::m_summaries): Update type of element. * known-function-manager.h: Include "analyzer/analyzer-logging.h". * program-point.h: Include "pretty-print.h" and "analyzer/call-string.h". * program-state.cc: Include "analyzer/call-summary.h". (sm_state_map::replay_call_summary): New. (program_state::replay_call_summary): New. * program-state.h (sm_state_map::replay_call_summary): New decl. (program_state::replay_call_summary): New decl. * region-model-manager.cc (region_model_manager::get_or_create_asm_output_svalue): New overload. * region-model-manager.h (region_model_manager::get_or_create_asm_output_svalue): New overload decl. * region-model.cc: Include "analyzer/call-summary.h". (region_model::maybe_update_for_edge): Remove call to region_model::update_for_call_summary on SUPEREDGE_INTRAPROCEDURAL_CALL. (region_model::update_for_call_summary): Delete. (region_model::replay_call_summary): New. * region-model.h (region_model::replay_call_summary): New decl. (region_model::update_for_call_summary): Delete decl. * store.cc: Include "analyzer/call-summary.h". (store::replay_call_summary): New. (store::replay_call_summary_cluster): New. * store.h: Include "tristate.h". (is_a_helper ::test): New. (store::replay_call_summary): New decl. (store::replay_call_summary_cluster): New decl. * supergraph.cc (get_ultimate_function_for_cgraph_edge): Remove "static" from decl. (supergraph_call_edge): Make stmt param const. * supergraph.h: Include "ordered-hash-map.h", "cfg.h", "basic-block.h", "gimple.h", "gimple-iterator.h", and "digraph.h". (supergraph_call_edge): Make stmt param const. (get_ultimate_function_for_cgraph_edge): New decl. * svalue.cc (compound_svalue::compound_svalue): Assert that we're not nesting compound_svalues. * svalue.h: Include "json.h", "analyzer/store.h", and "analyzer/program-point.h". (asm_output_svalue::get_num_outputs): New accessor. gcc/testsuite/ChangeLog: PR analyzer/107072 * gcc.dg/analyzer/call-summaries-2.c: New test. * gcc.dg/analyzer/call-summaries-3.c: New test. * gcc.dg/analyzer/call-summaries-asm-x86.c: New test. * gcc.dg/analyzer/call-summaries-malloc.c: New test. * gcc.dg/analyzer/call-summaries-pr107072.c: New test. Signed-off-by: David Malcolm --- gcc/testsuite/gcc.dg/analyzer/call-summaries-2.c | 646 +++++++++++++++++++++ gcc/testsuite/gcc.dg/analyzer/call-summaries-3.c | 29 + .../gcc.dg/analyzer/call-summaries-asm-x86.c | 20 + .../gcc.dg/analyzer/call-summaries-malloc.c | 80 +++ .../gcc.dg/analyzer/call-summaries-pr107072.c | 90 +++ 5 files changed, 865 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/analyzer/call-summaries-2.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/call-summaries-3.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/call-summaries-asm-x86.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/call-summaries-malloc.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/call-summaries-pr107072.c (limited to 'gcc/testsuite') diff --git a/gcc/testsuite/gcc.dg/analyzer/call-summaries-2.c b/gcc/testsuite/gcc.dg/analyzer/call-summaries-2.c new file mode 100644 index 0000000..0aaf67b --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/call-summaries-2.c @@ -0,0 +1,646 @@ +/* { dg-additional-options "-fanalyzer-call-summaries --param analyzer-min-snodes-for-call-summary=0" } */ + +/* There need to be at least two calls to a function for the + call-summarization code to be used. + TODO: add some kind of test that summarization *was* used. */ + +#include +#include "analyzer-decls.h" + +extern int external_fn (void *); + +int returns_const (void) +{ + return 42; +} + +void test_summarized_returns_const (void) +{ + __analyzer_eval (returns_const () == 42); /* { dg-warning "TRUE" } */ + __analyzer_eval (returns_const () == 42); /* { dg-warning "TRUE" } */ +} + +void test_summarized_returns_const_2 (void) +{ + returns_const (); /* { dg-message "when 'returns_const' returns" } */ + __analyzer_dump_path (); /* { dg-message "path" } */ +} + +int returns_param (int i) +{ + return i; +} + +void test_summarized_returns_param (int j) +{ + __analyzer_eval (returns_param (j) == j); /* { dg-warning "TRUE" } */ + __analyzer_eval (returns_param (j) == j); /* { dg-warning "TRUE" } */ +} + +void writes_const_to_ptr (int *p) +{ + *p = 42; +} + +void test_summarized_writes_const_to_ptr (void) +{ + int i, j; + writes_const_to_ptr (&i); + writes_const_to_ptr (&j); + __analyzer_eval (i == 42); /* { dg-warning "TRUE" } */ + __analyzer_eval (j == 42); /* { dg-warning "TRUE" } */ +} + +// TODO: we should complain about this: + +void test_summarized_write_through_null (void) +{ + writes_const_to_ptr (NULL); +} + +void writes_param_to_ptr (int i, int *p) +{ + *p = i; +} + +void test_summarized_writes_param_to_ptr (int j) +{ + int x, y; + writes_param_to_ptr (j, &x); + writes_param_to_ptr (j, &y); + __analyzer_eval (x == j); /* { dg-warning "TRUE" } */ + __analyzer_eval (y == j); /* { dg-warning "TRUE" } */ +} + +int g; + +void writes_to_global (int i) +{ + g = i; +} + +void test_writes_to_global (int x, int y) +{ + writes_to_global (x); + __analyzer_eval (g == x); /* { dg-warning "TRUE" } */ + + writes_to_global (y); + __analyzer_eval (g == y); /* { dg-warning "TRUE" } */ +} + +int reads_from_global (void) +{ + return g; +} + +void test_reads_from_global (int x, int y) +{ + g = x; + __analyzer_eval (reads_from_global () == x); /* { dg-warning "TRUE" } */ + + g = y; + __analyzer_eval (reads_from_global () == y); /* { dg-warning "TRUE" } */ +} + +/* Example of a unary op. */ + +int returns_negation (int i) +{ + return -i; +} + +void test_returns_negation (int x) +{ + __analyzer_eval (returns_negation (5) == -5); /* { dg-warning "TRUE" } */ + __analyzer_eval (returns_negation (x) == -x); /* { dg-warning "TRUE" } */ + __analyzer_eval (returns_negation (-x) == x); /* { dg-warning "TRUE" } */ +} + +/* Example of a binary op. */ + +int returns_sum (int i, int j) +{ + return i + j; +} + +void test_returns_sum (int x, int y) +{ + __analyzer_eval (returns_sum (5, 3) == 8); /* { dg-warning "TRUE" } */ + __analyzer_eval (returns_sum (7, 2) == 9); /* { dg-warning "TRUE" } */ + __analyzer_eval (returns_sum (x, y) == x + y); /* { dg-warning "TRUE" } */ +} + +struct coord +{ + int x; + int y; +}; + +struct coord make_coord (int x, int y) +{ + struct coord result = {x, y}; + return result; +} + +void test_make_coord (int i, int j) +{ + struct coord c1 = make_coord (3, 4); + __analyzer_eval (c1.x == 3); /* { dg-warning "TRUE" } */ + __analyzer_eval (c1.y == 4); /* { dg-warning "TRUE" } */ + + struct coord c2 = make_coord (i, j); + __analyzer_eval (c2.x == i); /* { dg-warning "TRUE" } */ + __analyzer_eval (c2.y == j); /* { dg-warning "TRUE" } */ +} + +/* Example of nested usage of summaries. */ + +struct rect +{ + struct coord nw; + struct coord se; +}; + +struct rect make_rect (int top, int bottom, int left, int right) +{ + struct rect result = {make_coord (left, top), + make_coord (right, bottom)}; + return result; +} + +void test_make_rect (int top, int bottom, int left, int right) +{ + struct rect r1 = make_rect (3, 4, 5, 6); + __analyzer_eval (r1.nw.y == 3); /* { dg-warning "TRUE" } */ + __analyzer_eval (r1.se.y == 4); /* { dg-warning "TRUE" } */ + __analyzer_eval (r1.nw.x == 5); /* { dg-warning "TRUE" } */ + __analyzer_eval (r1.se.x == 6); /* { dg-warning "TRUE" } */ + + struct rect r2 = make_rect (top, bottom, left, right); + __analyzer_eval (r2.nw.y == top); /* { dg-warning "TRUE" } */ + __analyzer_eval (r2.se.y == bottom); /* { dg-warning "TRUE" } */ + __analyzer_eval (r2.nw.x == left); /* { dg-warning "TRUE" } */ + __analyzer_eval (r2.se.x == right); /* { dg-warning "TRUE" } */ +} + +const char *returns_str (void) +{ + return "abc"; +} + +void test_returns_str (void) +{ + __analyzer_eval (returns_str () != NULL); /* { dg-warning "TRUE" } */ + __analyzer_eval (returns_str ()[0] == 'a'); /* { dg-warning "TRUE" } */ + __analyzer_eval (returns_str ()[1] == 'b'); /* { dg-warning "TRUE" } */ + __analyzer_eval (returns_str ()[2] == 'c'); /* { dg-warning "TRUE" } */ + __analyzer_eval (returns_str ()[3] == '\0'); /* { dg-warning "TRUE" } */ +} + +int returns_field (struct coord *p) +{ + return p->y; +} + +void test_returns_field (struct coord *q) +{ + __analyzer_eval (returns_field (q) == q->y); /* { dg-warning "TRUE" } */ + __analyzer_eval (returns_field (q) == q->y); /* { dg-warning "TRUE" } */ +} + +void writes_to_fields (struct coord *p, int x, int y) +{ + p->x = x; + p->y = y; +} + +void test_writes_to_field (struct coord *q, int qx, int qy) +{ + struct coord a, b; + writes_to_fields (&a, 1, 2); + __analyzer_eval (a.x == 1); /* { dg-warning "TRUE" } */ + __analyzer_eval (a.y == 2); /* { dg-warning "TRUE" } */ + writes_to_fields (&b, 3, 4); + __analyzer_eval (b.x == 3); /* { dg-warning "TRUE" } */ + __analyzer_eval (b.y == 4); /* { dg-warning "TRUE" } */ + writes_to_fields (q, qx, qy); + __analyzer_eval (q->x == qx); /* { dg-warning "TRUE" } */ + __analyzer_eval (q->y == qy); /* { dg-warning "TRUE" } */ +} + +/* Example of nested function summarization. */ + +int get_min_x (struct rect *p) +{ + return p->nw.x; +} + +int get_min_y (struct rect *p) +{ + return p->nw.y; +} + +int get_max_x (struct rect *p) +{ + return p->se.x; +} + +int get_max_y (struct rect *p) +{ + return p->se.y; +} + +int get_area (struct rect *p) +{ + return ((get_max_x (p) - get_min_x (p)) + * (get_max_y (p) - get_min_y (p))); +} + +void test_get_area (int top, int bottom, int left, int right, struct rect *p) +{ + { + /* 1x1 at origin. */ + struct rect a = make_rect (0, 1, 0, 1); + __analyzer_eval (get_min_y (&a) == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (get_max_y (&a) == 1); /* { dg-warning "TRUE" } */ + __analyzer_eval (get_min_x (&a) == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (get_max_x (&a) == 1); /* { dg-warning "TRUE" } */ + __analyzer_eval (get_area (&a) == 1); /* { dg-warning "TRUE" } */ + } + + { + /* 4x5. */ + struct rect b = make_rect (3, 7, 4, 9); + __analyzer_eval (get_min_y (&b) == 3); /* { dg-warning "TRUE" } */ + __analyzer_eval (get_max_y (&b) == 7); /* { dg-warning "TRUE" } */ + __analyzer_eval (get_min_x (&b) == 4); /* { dg-warning "TRUE" } */ + __analyzer_eval (get_max_x (&b) == 9); /* { dg-warning "TRUE" } */ + __analyzer_eval (get_area (&b) == 20); /* { dg-warning "TRUE" } */ + } + + { + /* Symbolic. */ + struct rect c = make_rect (top, bottom, left, right); + __analyzer_eval (get_min_y (&c) == top); /* { dg-warning "TRUE" } */ + __analyzer_eval (get_max_y (&c) == bottom); /* { dg-warning "TRUE" } */ + __analyzer_eval (get_min_x (&c) == left); /* { dg-warning "TRUE" } */ + __analyzer_eval (get_max_x (&c) == right); /* { dg-warning "TRUE" } */ + __analyzer_eval (get_area (&c) == ((right - left) * (bottom - top))); /* { dg-warning "TRUE" } */ + } + + /* Symbolic via ptr. */ + __analyzer_eval (get_min_y (p) == p->nw.y); /* { dg-warning "TRUE" } */ + __analyzer_eval (get_max_y (p) == p->se.y); /* { dg-warning "TRUE" } */ + __analyzer_eval (get_min_x (p) == p->nw.x); /* { dg-warning "TRUE" } */ + __analyzer_eval (get_max_x (p) == p->se.x); /* { dg-warning "TRUE" } */ + __analyzer_eval (get_area (p) == ((p->se.x - p->nw.x) * (p->se.y - p->nw.y))); /* { dg-warning "TRUE" } */ +} + +int returns_element (int i) +{ + static const int arr[3] = {7, 8, 9}; + return arr[i]; +} + +void test_returns_element (int j) +{ + __analyzer_eval (returns_element (0) == 7); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (returns_element (1) == 8); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (returns_element (2) == 9); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (returns_element (3) == 10); /* { dg-warning "UNKNOWN" } */ + // TODO: out of bounds +} + +const int *returns_element_ptr (int i) +{ + static const int arr[3] = {7, 8, 9}; + return &arr[i]; +} + +int test_returns_element_ptr (int j) +{ + __analyzer_eval (*returns_element_ptr (0) == 7); /* { dg-warning "TRUE" } */ + __analyzer_eval (*returns_element_ptr (1) == 8); /* { dg-warning "TRUE" } */ + __analyzer_eval (*returns_element_ptr (2) == 9); /* { dg-warning "TRUE" } */ + return *returns_element_ptr (3); /* { dg-warning "buffer overread" } */ +} + +int returns_offset (int arr[3], int i) +{ + return arr[i]; +} + +void test_returns_offset (int outer_arr[3], int idx) +{ + int a[3] = {4, 5, 6}; + __analyzer_eval (returns_offset (a, 0) == 4); /* { dg-warning "TRUE" } */ + __analyzer_eval (returns_offset (a, 1) == 5); /* { dg-warning "TRUE" } */ + __analyzer_eval (returns_offset (a, 2) == 6); /* { dg-warning "TRUE" } */ + __analyzer_eval (returns_offset (a, idx) == a[idx]); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (returns_offset (outer_arr, 0) == outer_arr[0]); /* { dg-warning "TRUE" } */ + __analyzer_eval (returns_offset (outer_arr, idx) == outer_arr[idx]); /* { dg-warning "TRUE" } */ +} + +int returns_offset_2 (int arr[], int i) +{ + return arr[i]; +} + +void test_returns_offset_2 (int outer_arr[], int idx) +{ + int a[3] = {4, 5, 6}; + __analyzer_eval (returns_offset_2 (a, 0) == 4); /* { dg-warning "TRUE" } */ + __analyzer_eval (returns_offset_2 (a, 1) == 5); /* { dg-warning "TRUE" } */ + __analyzer_eval (returns_offset_2 (a, 2) == 6); /* { dg-warning "TRUE" } */ + __analyzer_eval (returns_offset_2 (a, idx) == a[idx]); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (returns_offset_2 (outer_arr, 0) == outer_arr[0]); /* { dg-warning "TRUE" } */ + __analyzer_eval (returns_offset_2 (outer_arr, idx) == outer_arr[idx]); /* { dg-warning "TRUE" } */ +} + +int returns_offset_3 (int *p, int i) +{ + return p[i]; +} + +void test_returns_offset_3 (int *q, int j) +{ + __analyzer_eval (returns_offset_3 (q, j) == q[j]); /* { dg-warning "TRUE" } */ + __analyzer_eval (returns_offset_3 (q, j) == q[j]); /* { dg-warning "TRUE" } */ +} + +/* With state merging, this is summarized as returning "UNKNOWN". */ + +int two_outcomes (int flag, int x, int y) +{ + if (flag) + return x; + else + return y; +} + +void test_two_outcomes (int outer_flag, int a, int b) +{ + int r; + __analyzer_eval (two_outcomes (1, a, b) == a); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (two_outcomes (0, a, b) == b); /* { dg-warning "UNKNOWN" } */ + r = two_outcomes (outer_flag, a, b); + if (outer_flag) + __analyzer_eval (r == a); /* { dg-warning "UNKNOWN" } */ + else + __analyzer_eval (r == b); /* { dg-warning "UNKNOWN" } */ +} + +/* Verify that summary replays capture postconditions. */ + +void check_int_nonnegative (int i) +{ + if (i < 0) + __builtin_unreachable (); +} + +void test_check_int_nonnegative (int i, int j) +{ + __analyzer_eval (i >= 0); /* { dg-warning "UNKNOWN" } */ + check_int_nonnegative (i); + __analyzer_eval (i >= 0); /* { dg-warning "TRUE" } */ + + __analyzer_eval (j >= 0); /* { dg-warning "UNKNOWN" } */ + check_int_nonnegative (j); + __analyzer_eval (j >= 0); /* { dg-warning "TRUE" } */ +} + +void calls_external_fn (void) +{ + external_fn (NULL); +} + +void test_calls_external_fn (void) +{ + g = 1; + __analyzer_eval (g == 1); /* { dg-warning "TRUE" } */ + calls_external_fn (); + calls_external_fn (); + __analyzer_eval (g == 1); /* { dg-warning "UNKNOWN" "expected" { xfail *-*-* } } */ + /* { dg-bogus "TRUE" "bogus" { xfail *-*-* } .-1 } */ + // TODO(xfails) +} + +int returns_iterator (int n) +{ + int i; + for (i = 0; i < n; i++) + { + } + return i; +} + +void test_returns_iterator (int j, int k) +{ + __analyzer_eval (returns_iterator (j) == j); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (returns_iterator (k) == k); /* { dg-warning "UNKNOWN" } */ + /* TODO: ideally we'd capture these equalities, but this is an issue + with how we handle loops. */ +} + +int returns_external_result (void) +{ + return external_fn (NULL); +} + +int test_returns_external_result (void) +{ + int i, j; + i = returns_external_result (); + j = returns_external_result (); + __analyzer_eval (i == j); /* { dg-warning "UNKNOWN" } */ + return i * j; +} + +int uses_alloca (int i) +{ + int *p = alloca (sizeof (int)); + *p = i; + return *p; +} + +void test_uses_alloca (int x) +{ + __analyzer_eval (uses_alloca (42) == 42); /* { dg-warning "TRUE" } */ + __analyzer_eval (uses_alloca (x) == x); /* { dg-warning "TRUE" } */ +} + +struct bits +{ + unsigned b0 : 1; + unsigned b1 : 1; + unsigned b2 : 1; + unsigned b3 : 1; + unsigned b4 : 1; + unsigned b5 : 1; + unsigned b6 : 1; + unsigned b7 : 1; +}; + +int returns_bitfield (struct bits b) +{ + return b.b3; +} + +void test_returns_bitfield (struct bits s) +{ + __analyzer_eval (returns_bitfield (s) == s.b3); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (returns_bitfield (s) == s.b3); /* { dg-warning "UNKNOWN" } */ + // TODO: ideally it would figure out that these are equal +} + +int consume_two_ints_from_va_list (__builtin_va_list ap) +{ + int i, j; + i = __builtin_va_arg (ap, int); + j = __builtin_va_arg (ap, int); + return i * j; +} + +int test_consume_two_ints_from_va_list (__builtin_va_list ap1) +{ + int p1, p2; + __builtin_va_list ap2; + __builtin_va_copy (ap2, ap1); + p1 = consume_two_ints_from_va_list (ap1); + p2 = consume_two_ints_from_va_list (ap2); + __analyzer_eval (p1 == p2); /* { dg-warning "UNKNOWN" } */ + // TODO: ideally it would figure out these are equal + __builtin_va_end (ap2); +} + +int consume_two_ints_from_varargs (int placeholder, ...) +{ + int i, j; + __builtin_va_list ap; + __builtin_va_start (ap, placeholder); + i = __builtin_va_arg (ap, int); + j = __builtin_va_arg (ap, int); + __builtin_va_end (ap); + return i * j; +} + +void test_consume_two_ints_from_varargs (int x, int y) +{ + __analyzer_eval (consume_two_ints_from_varargs (0, 4, 5) == 20); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (consume_two_ints_from_varargs (0, 3, 6) == 18); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (consume_two_ints_from_varargs (0, x, 6) == x * y); /* { dg-warning "UNKNOWN" } */ + // TODO: ideally it would figure these out +} + +extern int const_fn_1 (int) __attribute__ ((const)); +int calls_const_fn (int i) +{ + return const_fn_1 (i); +} + +void test_calls_const_fn (int x) +{ + int r1, r2; + r1 = calls_const_fn (x); + r2 = calls_const_fn (x); + __analyzer_eval (r1 == r2); /* { dg-warning "TRUE" } */ +} + +typedef struct iv2 { int arr[2]; } iv2_t; +typedef struct iv4 { int arr[4]; } iv4_t; + +iv2_t returns_iv2_t (int x, int y) +{ + iv2_t result = {x, y}; + return result; +} + +void test_returns_iv2_t (int a, int b) +{ + __analyzer_eval (returns_iv2_t (a, b).arr[0] == a); /* { dg-warning "TRUE" } */ + __analyzer_eval (returns_iv2_t (a, b).arr[1] == b); /* { dg-warning "TRUE" } */ +} + +iv4_t returns_iv4_t (int a, iv2_t bc, int d) +{ + iv4_t result = {a, bc.arr[0], bc.arr[1], d}; + return result; +} + +void test_returns_iv4_t (int p, iv2_t qr, int s) +{ + __analyzer_eval (returns_iv4_t (p, qr, s).arr[0] == p); /* { dg-warning "TRUE" } */ + __analyzer_eval (returns_iv4_t (p, qr, s).arr[1] == qr.arr[0]); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (returns_iv4_t (p, qr, s).arr[2] == qr.arr[1]); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (returns_iv4_t (p, qr, s).arr[3] == s); /* { dg-warning "TRUE" } */ + // TODO: ideally the UNKNOWNs would be TRUEs. +} + +void copies_iv2_t (int *p, iv2_t xy) +{ + __builtin_memcpy (p, &xy, sizeof (xy)); +} + +void test_copies_iv2_t (iv2_t ab, iv2_t cd) +{ + iv4_t t; + copies_iv2_t (&t.arr[0], ab); + copies_iv2_t (&t.arr[2], cd); + __analyzer_eval (t.arr[0] = ab.arr[0]); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (t.arr[1] = ab.arr[1]); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (t.arr[2] = cd.arr[0]); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (t.arr[3] = cd.arr[1]); /* { dg-warning "UNKNOWN" } */ + // TODO: ideally the UNKNOWNs would be TRUEs. +} + +void partially_inits (int *p, int v) +{ + p[1] = v; +} + +void test_partially_inits (int x) +{ + int arr[2]; + partially_inits (arr, x); + partially_inits (arr, x); + + __analyzer_eval (arr[0]); /* { dg-warning "UNKNOWN" "eval" } */ + /* { dg-warning "use of uninitialized value 'arr\\\[0\\\]'" "uninit" { target *-*-* } .-1 } */ + + __analyzer_eval (arr[1] == x); /* { dg-warning "UNKNOWN" "eval" } */ + /* { dg-bogus "use of uninitialized value 'arr\\\[1\\\]'" "uninit" { xfail *-*-* } .-1 } */ + // TODO(xfail), and eval should be "TRUE" +} + +int uses_switch (int i) +{ + switch (i) + { + case 0: + return 42; + case 1: + return 17; + default: + return i * 2; + } +} + +void test_uses_switch (int x) +{ + __analyzer_eval (uses_switch (0) == 42); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (uses_switch (1) == 17); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (uses_switch (2) == x * 2); /* { dg-warning "UNKNOWN" } */ + // TODO: ideally the UNKNOWNs would be TRUEs. +} + +int *returns_ptr_to_first_field (struct coord *p) +{ + return &p->x; +} + +void test_returns_ptr_to_first_field (struct coord *q) +{ + __analyzer_eval (returns_ptr_to_first_field (q) == (int *)q); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (returns_ptr_to_first_field (q) == (int *)q); /* { dg-warning "UNKNOWN" } */ + // TODO: ideally the UNKNOWNs would be TRUEs. +} diff --git a/gcc/testsuite/gcc.dg/analyzer/call-summaries-3.c b/gcc/testsuite/gcc.dg/analyzer/call-summaries-3.c new file mode 100644 index 0000000..d63eb0c --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/call-summaries-3.c @@ -0,0 +1,29 @@ +/* { dg-additional-options "-fanalyzer-call-summaries --param analyzer-min-snodes-for-call-summary=0 -fno-analyzer-state-merge" } */ + +/* There need to be at least two calls to a function for the + call-summarization code to be used. + TODO: add some kind of test that summarization *was* used. */ + +#include "analyzer-decls.h" + +/* With state merging disabled, we get two summaries here. */ + +int two_outcomes (int flag, int x, int y) +{ + if (flag) + return x; + else + return y; +} + +void test_two_outcomes (int outer_flag, int a, int b) +{ + int r; + __analyzer_eval (two_outcomes (1, a, b) == a); /* { dg-warning "TRUE" } */ + __analyzer_eval (two_outcomes (0, a, b) == b); /* { dg-warning "TRUE" } */ + r = two_outcomes (outer_flag, a, b); + if (outer_flag) + __analyzer_eval (r == a); /* { dg-warning "TRUE" } */ + else + __analyzer_eval (r == b); /* { dg-warning "TRUE" } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/call-summaries-asm-x86.c b/gcc/testsuite/gcc.dg/analyzer/call-summaries-asm-x86.c new file mode 100644 index 0000000..cc23283 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/call-summaries-asm-x86.c @@ -0,0 +1,20 @@ +/* { dg-do compile { target x86_64-*-* } } */ +/* { dg-additional-options "-fanalyzer-call-summaries --param analyzer-min-snodes-for-call-summary=0" } */ + +#include "analyzer-decls.h" + +int returns_asm_value (void) +{ + int dst; + asm ("mov 42, %0" + : "=r" (dst)); + return dst; +} + +void test_returns_asm_value (void) +{ + int a, b; + a = returns_asm_value (); + b = returns_asm_value (); + __analyzer_eval (a == b); /* { dg-warning "TRUE" } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/call-summaries-malloc.c b/gcc/testsuite/gcc.dg/analyzer/call-summaries-malloc.c new file mode 100644 index 0000000..87173a0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/call-summaries-malloc.c @@ -0,0 +1,80 @@ +/* { dg-additional-options "-fanalyzer-call-summaries --param analyzer-min-snodes-for-call-summary=0" } */ + +/* There need to be at least two calls to a function for the + call-summarization code to be used. + TODO: add some kind of test that summarization *was* used. */ + +#include +#include +#include "analyzer-decls.h" + +int *malloc_int (int i) +{ + int *res = malloc (sizeof (int)); + if (!res) + return NULL; + *res = i; + return res; +} + +void test_malloc_int (int x) +{ + int *p, *q; + + p = malloc_int (42); + if (p) + __analyzer_eval (*p == 42); /* { dg-warning "TRUE" } */ + free (p); + + q = malloc_int (x); + if (q) + __analyzer_eval (*q == x); /* { dg-warning "TRUE" } */ + free (q); +} + +void test_leak (int x) +{ + int *p = malloc_int (x); /* { dg-message "when 'malloc_int' returns pointer to heap-allocated buffer" } */ +} /* { dg-message "leak of 'p'" } */ + +void *wrapped_malloc (size_t sz) +{ + return malloc (sz); +} + +void wrapped_free (void *p) +{ + free (p); +} + +void test_wrapped_malloc_and_free (size_t sz) +{ + void *p = wrapped_malloc (100); + void *q = wrapped_malloc (sz); + __analyzer_dump_capacity (p); /* { dg-warning "capacity: '\\(\[^\n\r\]*\\)100'" } */ + __analyzer_dump_capacity (q); /* { dg-warning "capacity: 'INIT_VAL\\(sz_\[^\n\r\]*\\)'" } */ + wrapped_free (p); + wrapped_free (q); +} + +void test_use_after_free (void) +{ + // TODO +} + +void test_use_without_check (size_t sz) +{ + char *buf = wrapped_malloc (sz); /* { dg-message "this call could return NULL" } */ + memset (buf, 'x', sz); /* { dg-warning "use of possibly-NULL 'buf' where non-null expected" } */ + wrapped_free (buf); +} + +void test_out_of_bounds (size_t sz) +{ + char *buf = wrapped_malloc (sz); + if (!buf) + return; + memset (buf, 'x', sz); + buf[sz] = '\0'; /* { dg-warning "heap-based buffer overflow" } */ + wrapped_free (buf); +} diff --git a/gcc/testsuite/gcc.dg/analyzer/call-summaries-pr107072.c b/gcc/testsuite/gcc.dg/analyzer/call-summaries-pr107072.c new file mode 100644 index 0000000..1e689b3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/call-summaries-pr107072.c @@ -0,0 +1,90 @@ +/* { dg-additional-options "-fanalyzer-call-summaries --param analyzer-min-snodes-for-call-summary=0" } */ + +/* There need to be at least two calls to a function for the + call-summarization code to be used. + TODO: add some kind of test that summarization *was* used. */ + +/* Reduced from an example in Emacs in which string_char_and_length + was being incorrectly summarized, failing to see the write to *length. */ + +typedef long int ptrdiff_t; +typedef struct Lisp_X *Lisp_Word; +typedef Lisp_Word Lisp_Object; +extern _Bool STRING_MULTIBYTE(Lisp_Object str); +extern unsigned char *SDATA(Lisp_Object string); +enum { MAX_2_BYTE_CHAR = 0x7FF }; +enum { MAX_3_BYTE_CHAR = 0xFFFF }; +enum { MAX_4_BYTE_CHAR = 0x1FFFFF }; +enum { MAX_5_BYTE_CHAR = 0x3FFF7F }; +extern int make_char_multibyte(int c); +static inline int string_char_and_length(unsigned char const *p, int *length) { + int c = p[0]; + if (!(c & 0x80)) { + *length = 1; + return c; + } + ((0xC0 <= c) ? (void)0 : __builtin_unreachable()); + int d = (c << 6) + p[1] - ((0xC0 << 6) + 0x80); + if (!(c & 0x20)) { + *length = 2; + return d + (c < 0xC2 ? 0x3FFF80 : 0); + } + d = (d << 6) + p[2] - ((0x20 << 12) + 0x80); + if (!(c & 0x10)) { + *length = 3; + ((MAX_2_BYTE_CHAR < d && d <= MAX_3_BYTE_CHAR) + ? (void)0 + : __builtin_unreachable()); + return d; + } + d = (d << 6) + p[3] - ((0x10 << 18) + 0x80); + if (!(c & 0x08)) { + *length = 4; + ((MAX_3_BYTE_CHAR < d && d <= MAX_4_BYTE_CHAR) + ? (void)0 + : __builtin_unreachable()); + return d; + } + d = (d << 6) + p[4] - ((0x08 << 24) + 0x80); + *length = 5; + ((MAX_4_BYTE_CHAR < d && d <= MAX_5_BYTE_CHAR) + ? (void)0 + : __builtin_unreachable()); + return d; +} +int fetch_string_char_advance(Lisp_Object string, + ptrdiff_t *charidx, + ptrdiff_t *byteidx) { + int output; + ptrdiff_t b = *byteidx; + unsigned char *chp = SDATA(string) + b; + if (STRING_MULTIBYTE(string)) { + int chlen; + output = string_char_and_length(chp, &chlen); + b += chlen; + } else { + output = *chp; + b++; + } + (*charidx)++; + *byteidx = b; + return output; +} +int fetch_string_char_as_multibyte_advance(Lisp_Object string, + ptrdiff_t *charidx, + ptrdiff_t *byteidx) { + int output; + ptrdiff_t b = *byteidx; + unsigned char *chp = SDATA(string) + b; + if (STRING_MULTIBYTE(string)) { + int chlen; + output = string_char_and_length(chp, &chlen); + b += chlen; + } else { + output = make_char_multibyte(*chp); + b++; + } + (*charidx)++; + *byteidx = b; + return output; +} -- cgit v1.1 From b77bcdf445685f28dae9e42b69e006801d653001 Mon Sep 17 00:00:00 2001 From: Vineet Gupta Date: Fri, 2 Sep 2022 14:05:33 -0700 Subject: RISC-V: remove deprecate pic code model macro Came across this deprecated symbol when looking around for -mexplicit-relocs handling in code Signed-off-by: Vineet Gupta gcc/ChangeLog: * config/riscv/riscv-c.cc (riscv_cpu_cpp_builtins): Remove __riscv_cmodel_pic, that deprecated in last version. gcc/testsuite/ChangeLog: * gcc.target/riscv/predef-1.c: Remove __riscv_cmodel_pic check. * gcc.target/riscv/predef-2.c: Ditto. * gcc.target/riscv/predef-3.c: Ditto. * gcc.target/riscv/predef-4.c: Ditto. * gcc.target/riscv/predef-5.c: Ditto. * gcc.target/riscv/predef-6.c: Ditto. * gcc.target/riscv/predef-7.c: Ditto. * gcc.target/riscv/predef-8.c: Ditto. --- gcc/testsuite/gcc.target/riscv/predef-1.c | 3 --- gcc/testsuite/gcc.target/riscv/predef-2.c | 3 --- gcc/testsuite/gcc.target/riscv/predef-3.c | 3 --- gcc/testsuite/gcc.target/riscv/predef-4.c | 3 --- gcc/testsuite/gcc.target/riscv/predef-5.c | 3 --- gcc/testsuite/gcc.target/riscv/predef-6.c | 3 --- gcc/testsuite/gcc.target/riscv/predef-7.c | 3 --- gcc/testsuite/gcc.target/riscv/predef-8.c | 3 --- 8 files changed, 24 deletions(-) (limited to 'gcc/testsuite') diff --git a/gcc/testsuite/gcc.target/riscv/predef-1.c b/gcc/testsuite/gcc.target/riscv/predef-1.c index 2e57ce6..9dddc18 100644 --- a/gcc/testsuite/gcc.target/riscv/predef-1.c +++ b/gcc/testsuite/gcc.target/riscv/predef-1.c @@ -58,9 +58,6 @@ int main () { #if defined(__riscv_cmodel_medany) #error "__riscv_cmodel_medlow" #endif -#if defined(__riscv_cmodel_pic) -#error "__riscv_cmodel_medlow" -#endif return 0; } diff --git a/gcc/testsuite/gcc.target/riscv/predef-2.c b/gcc/testsuite/gcc.target/riscv/predef-2.c index c85b3c9..755fe4e 100644 --- a/gcc/testsuite/gcc.target/riscv/predef-2.c +++ b/gcc/testsuite/gcc.target/riscv/predef-2.c @@ -58,9 +58,6 @@ int main () { #if !defined(__riscv_cmodel_medany) #error "__riscv_cmodel_medlow" #endif -#if defined(__riscv_cmodel_pic) -#error "__riscv_cmodel_medlow" -#endif return 0; } diff --git a/gcc/testsuite/gcc.target/riscv/predef-3.c b/gcc/testsuite/gcc.target/riscv/predef-3.c index 82a89d4..5136453 100644 --- a/gcc/testsuite/gcc.target/riscv/predef-3.c +++ b/gcc/testsuite/gcc.target/riscv/predef-3.c @@ -58,9 +58,6 @@ int main () { #if !defined(__riscv_cmodel_medany) #error "__riscv_cmodel_medany" #endif -#if !defined(__riscv_cmodel_pic) -#error "__riscv_cmodel_pic" -#endif return 0; } diff --git a/gcc/testsuite/gcc.target/riscv/predef-4.c b/gcc/testsuite/gcc.target/riscv/predef-4.c index 5868d39..76b6fee 100644 --- a/gcc/testsuite/gcc.target/riscv/predef-4.c +++ b/gcc/testsuite/gcc.target/riscv/predef-4.c @@ -58,9 +58,6 @@ int main () { #if defined(__riscv_cmodel_medany) #error "__riscv_cmodel_medlow" #endif -#if defined(__riscv_cmodel_pic) -#error "__riscv_cmodel_medlow" -#endif return 0; } diff --git a/gcc/testsuite/gcc.target/riscv/predef-5.c b/gcc/testsuite/gcc.target/riscv/predef-5.c index 4b2bd38..54a5150 100644 --- a/gcc/testsuite/gcc.target/riscv/predef-5.c +++ b/gcc/testsuite/gcc.target/riscv/predef-5.c @@ -58,9 +58,6 @@ int main () { #if !defined(__riscv_cmodel_medany) #error "__riscv_cmodel_medlow" #endif -#if defined(__riscv_cmodel_pic) -#error "__riscv_cmodel_medlow" -#endif return 0; } diff --git a/gcc/testsuite/gcc.target/riscv/predef-6.c b/gcc/testsuite/gcc.target/riscv/predef-6.c index 8e5ea36..f61709f 100644 --- a/gcc/testsuite/gcc.target/riscv/predef-6.c +++ b/gcc/testsuite/gcc.target/riscv/predef-6.c @@ -58,9 +58,6 @@ int main () { #if !defined(__riscv_cmodel_medany) #error "__riscv_cmodel_medany" #endif -#if !defined(__riscv_cmodel_pic) -#error "__riscv_cmodel_medpic" -#endif return 0; } diff --git a/gcc/testsuite/gcc.target/riscv/predef-7.c b/gcc/testsuite/gcc.target/riscv/predef-7.c index 0bde299..4121755 100644 --- a/gcc/testsuite/gcc.target/riscv/predef-7.c +++ b/gcc/testsuite/gcc.target/riscv/predef-7.c @@ -58,9 +58,6 @@ int main () { #if defined(__riscv_cmodel_medany) #error "__riscv_cmodel_medlow" #endif -#if defined(__riscv_cmodel_pic) -#error "__riscv_cmodel_medlow" -#endif return 0; } diff --git a/gcc/testsuite/gcc.target/riscv/predef-8.c b/gcc/testsuite/gcc.target/riscv/predef-8.c index 18aa591..982056a 100644 --- a/gcc/testsuite/gcc.target/riscv/predef-8.c +++ b/gcc/testsuite/gcc.target/riscv/predef-8.c @@ -58,9 +58,6 @@ int main () { #if !defined(__riscv_cmodel_medany) #error "__riscv_cmodel_medlow" #endif -#if defined(__riscv_cmodel_pic) -#error "__riscv_cmodel_medlow" -#endif return 0; } -- cgit v1.1 From 5fe2e4f87e512407c5c560dfec2fe48ba099c807 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torbj=C3=B6rn=20SVENSSON?= Date: Thu, 29 Sep 2022 19:38:10 +0200 Subject: testsuite: /dev/null is not accessible on Windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When running the DejaGNU testsuite on a toolchain built for native Windows, the path /dev/null can't be used to open a stream to void. On native Windows, the resource is instead named "nul". The error would look like this: c:/arm-11.3.rel1/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/bin/ld.exe: cannot find @/dev/null: No such file or directory Patch has been verified on Windows and Linux. gcc/testsuite: * gcc.misc-tests/outputs.exp: Use "@nul" for Windows, "@/dev/null" for other environments. Co-Authored-By: Yvan ROUX Signed-off-by: Torbjörn SVENSSON Signed-off-by: Jonathan Yong <10walls@gmail.com> --- gcc/testsuite/gcc.misc-tests/outputs.exp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'gcc/testsuite') diff --git a/gcc/testsuite/gcc.misc-tests/outputs.exp b/gcc/testsuite/gcc.misc-tests/outputs.exp index ab919db..3fe7270 100644 --- a/gcc/testsuite/gcc.misc-tests/outputs.exp +++ b/gcc/testsuite/gcc.misc-tests/outputs.exp @@ -78,6 +78,13 @@ if {[board_info $dest exists output_format]} { append link_options " additional_flags=-Wl,-oformat,[board_info $dest output_format]" } + +set devnull "/dev/null" +if { [info exists ::env(OS)] && [string match "Windows*" $::env(OS)] } { + # Windows uses special file named "nul" as a substitute for /dev/null + set devnull "nul" +} + # Avoid possible influence from the make jobserver, # otherwise ltrans0.ltrans_args files may be missing. if [info exists env(MAKEFLAGS)] { @@ -353,10 +360,10 @@ outest "$b-21 exe savetmp named2" $mult "-o $b.exe -save-temps" {} {{--1.i --1.s # Additional files are created when an @file is used if !$skip_atsave { -outest "$b-22 exe savetmp namedb-2" $sing "@/dev/null -o $b.exe -save-temps" {} {{--0.i --0.s --0.o .args.0 !!$gld .ld1_args !0 .exe}} -outest "$b-23 exe savetmp named2-2" $mult "@/dev/null -o $b.exe -save-temps" {} {{--1.i --1.s --1.o --2.i --2.s --2.o .args.0 !!$gld .ld1_args !0 .exe}} -outest "$b-24 exe savetmp named2-3" $mult "@/dev/null -I dummy -o $b.exe -save-temps" {} {{--1.i --1.s --1.o --2.i --2.s --2.o -args.0 -args.1 .args.2 !!$gld .ld1_args !0 .exe}} -outest "$b-25 exe savetmp named2-4" $mult "@/dev/null -I dummy -L dummy -o $b.exe -save-temps" {} {{--1.i --1.s --1.o --2.i --2.s --2.o -args.0 -args.1 .args.2 .args.3 !!$gld .ld1_args !0 .exe}} +outest "$b-22 exe savetmp namedb-2" $sing "@$devnull -o $b.exe -save-temps" {} {{--0.i --0.s --0.o .args.0 !!$gld .ld1_args !0 .exe}} +outest "$b-23 exe savetmp named2-2" $mult "@$devnull -o $b.exe -save-temps" {} {{--1.i --1.s --1.o --2.i --2.s --2.o .args.0 !!$gld .ld1_args !0 .exe}} +outest "$b-24 exe savetmp named2-3" $mult "@$devnull -I dummy -o $b.exe -save-temps" {} {{--1.i --1.s --1.o --2.i --2.s --2.o -args.0 -args.1 .args.2 !!$gld .ld1_args !0 .exe}} +outest "$b-25 exe savetmp named2-4" $mult "@$devnull -I dummy -L dummy -o $b.exe -save-temps" {} {{--1.i --1.s --1.o --2.i --2.s --2.o -args.0 -args.1 .args.2 .args.3 !!$gld .ld1_args !0 .exe}} } # Setting the main output to a dir selects it as the default aux&dump @@ -714,7 +721,7 @@ outest "$b-291 lto mult named-2" $mult "-o $b.exe -O2 -flto -fno-use-linker-plug outest "$b-292 lto sing nameddir-2" $sing "-o dir/$b.exe -O2 -flto -fno-use-linker-plugin -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {dir/} {{--0.c.???i.icf --0.c.???r.final .wpa.???i.icf .ltrans0.ltrans.???r.final .ltrans0.ltrans.su .exe} {}} outest "$b-293 lto mult nameddir-2" $mult "-o dir/$b.exe -O2 -flto -fno-use-linker-plugin -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {dir/} {{--1.c.???i.icf --1.c.???r.final --2.c.???i.icf --2.c.???r.final .wpa.???i.icf .ltrans0.ltrans.???r.final .ltrans0.ltrans.su .exe} {}} if !$skip_atsave { -outest "$b-294 lto sing unnamed-3" $sing "@/dev/null -O2 -flto -fno-use-linker-plugin -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage -save-temps $oaout" {} {{a--0.c.???i.icf a--0.c.???r.final a.wpa.???i.icf a.ltrans0.ltrans.???r.final a.ltrans0.ltrans.su a--0.o a--0.s a--0.i a.ltrans0.o a.ltrans.out a.ltrans0.ltrans.o a.ltrans0.ltrans_args a.args.0 a.ltrans0.ltrans.s a.wpa.args.0 a.lto_args a.ld1_args a.ltrans_args a.ltrans0.ltrans.args.0 a.ld_args $aout}} +outest "$b-294 lto sing unnamed-3" $sing "@$devnull -O2 -flto -fno-use-linker-plugin -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage -save-temps $oaout" {} {{a--0.c.???i.icf a--0.c.???r.final a.wpa.???i.icf a.ltrans0.ltrans.???r.final a.ltrans0.ltrans.su a--0.o a--0.s a--0.i a.ltrans0.o a.ltrans.out a.ltrans0.ltrans.o a.ltrans0.ltrans_args a.args.0 a.ltrans0.ltrans.s a.wpa.args.0 a.lto_args a.ld1_args a.ltrans_args a.ltrans0.ltrans.args.0 a.ld_args $aout}} } } -- cgit v1.1 From fa8e3a055a082e38aeab2561a5016b01ebfd6ebd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torbj=C3=B6rn=20SVENSSON?= Date: Thu, 29 Sep 2022 20:07:11 +0200 Subject: testsuite: Windows reports errors with CreateProcess MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the mapper can't be executed, Windows report the error like: .../bad-mapper-1.C: error: failed CreateProcess mapper 'this-will-not-work' On Linux, the same error is reported this way: .../bad-mapper-1.C: error: failed execvp mapper 'this-will-not-work' This patch allows both output forms to be accepted. Patch has been verified on Windows and Linux. gcc/testsuite: * g++.dg/modules/bad-mapper-1.C: Also accept CreateProcess. Co-Authored-By: Yvan ROUX Signed-off-by: Torbjörn SVENSSON Signed-off-by: Jonathan Yong <10walls@gmail.com> --- gcc/testsuite/g++.dg/modules/bad-mapper-1.C | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/testsuite') diff --git a/gcc/testsuite/g++.dg/modules/bad-mapper-1.C b/gcc/testsuite/g++.dg/modules/bad-mapper-1.C index 6d0ed4b..4b23128 100644 --- a/gcc/testsuite/g++.dg/modules/bad-mapper-1.C +++ b/gcc/testsuite/g++.dg/modules/bad-mapper-1.C @@ -1,6 +1,6 @@ // { dg-additional-options "-fmodules-ts -fmodule-mapper=|this-will-not-work" } import unique1.bob; -// { dg-error "-:failed exec.*mapper.* .*this-will-not-work" "" { target { ! { *-*-darwin[89]* *-*-darwin10* } } } 0 } +// { dg-error "-:failed (exec|CreateProcess).*mapper.* .*this-will-not-work" "" { target { ! { *-*-darwin[89]* *-*-darwin10* } } } 0 } // { dg-prune-output "fatal error:" } // { dg-prune-output "failed to read" } // { dg-prune-output "compilation terminated" } -- cgit v1.1 From 1a46a0a8b30405ea353a758971634dabeee89eaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torbj=C3=B6rn=20SVENSSON?= Date: Mon, 19 Sep 2022 18:18:58 +0200 Subject: testsuite: 'b' instruction can't do long enough jumps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After moving the testglue in commit 9d503515cee, the jump to exit and abort is too far for the 'b' instruction on Cortex-M0. As most of the C code would generate a 'bl' instruction instead of a 'b' instruction, lets do the same for the inline assembler. The error seen without this patch: /tmp/cccCRiCl.o: in function `main': stack-protector-1.c:(.text+0x4e): relocation truncated to fit: R_ARM_THM_JUMP11 against symbol `__wrap_exit' defined in .text section in gcc_tg.o stack-protector-1.c:(.text+0x50): relocation truncated to fit: R_ARM_THM_JUMP11 against symbol `__wrap_abort' defined in .text section in gcc_tg.o collect2: error: ld returned 1 exit status gcc/testsuite/ChangeLog: * gcc.target/arm/stack-protector-1.c: Use 'bl' instead of 'b' instruction. * gcc.target/arm/stack-protector-3.c: Likewise. Co-Authored-By: Yvan ROUX Signed-off-by: Torbjörn SVENSSON --- gcc/testsuite/gcc.target/arm/stack-protector-1.c | 4 ++-- gcc/testsuite/gcc.target/arm/stack-protector-3.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'gcc/testsuite') diff --git a/gcc/testsuite/gcc.target/arm/stack-protector-1.c b/gcc/testsuite/gcc.target/arm/stack-protector-1.c index 8d28b0a..3f0ffc9 100644 --- a/gcc/testsuite/gcc.target/arm/stack-protector-1.c +++ b/gcc/testsuite/gcc.target/arm/stack-protector-1.c @@ -56,8 +56,8 @@ asm ( " ldr r1, [sp, #4]\n" CHECK (r1) " mov r0, #0\n" -" b exit\n" +" bl exit\n" "1:\n" -" b abort\n" +" bl abort\n" " .size main, .-main" ); diff --git a/gcc/testsuite/gcc.target/arm/stack-protector-3.c b/gcc/testsuite/gcc.target/arm/stack-protector-3.c index b8f77fa..2f71052 100644 --- a/gcc/testsuite/gcc.target/arm/stack-protector-3.c +++ b/gcc/testsuite/gcc.target/arm/stack-protector-3.c @@ -26,7 +26,7 @@ asm ( " .type __stack_chk_fail, %function\n" "__stack_chk_fail:\n" " movs r0, #0\n" -" b exit\n" +" bl exit\n" " .size __stack_chk_fail, .-__stack_chk_fail" ); -- cgit v1.1 From 233c966dba5012938a1f84e14c26b52d507b2aae Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Wed, 5 Oct 2022 12:14:40 +0200 Subject: testsuite: mark a test with xfail PR tree-optimization/106679 gcc/testsuite/ChangeLog: * gcc.dg/tree-prof/cmpsf-1.c: Mark as a known limitation. --- gcc/testsuite/gcc.dg/tree-prof/cmpsf-1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/testsuite') diff --git a/gcc/testsuite/gcc.dg/tree-prof/cmpsf-1.c b/gcc/testsuite/gcc.dg/tree-prof/cmpsf-1.c index 16adb92..696f459 100644 --- a/gcc/testsuite/gcc.dg/tree-prof/cmpsf-1.c +++ b/gcc/testsuite/gcc.dg/tree-prof/cmpsf-1.c @@ -181,4 +181,4 @@ main (void) exit (0); } -/* { dg-final-use-not-autofdo { scan-tree-dump-not "Invalid sum" "dom2"} } */ +/* { dg-final-use-not-autofdo { scan-tree-dump-not "Invalid sum" "dom2" { xfail *-*-* } } } */ -- cgit v1.1 From 853ce8eea4ff97850a987167e603387b3d0f1401 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Wed, 5 Oct 2022 12:21:03 +0200 Subject: Fix bogus -Wstringop-overflow warning in Ada It comes from a discrepancy between get_offset_range, which uses a signed type, and handle_array_ref, which uses an unsigned one, to do computations. gcc/ PR tree-optimization/106698 * pointer-query.cc (handle_array_ref): Fix handling of low bound. gcc/testsuite/ * gnat.dg/lto26.adb: New test. * gnat.dg/lto26_pkg1.ads, gnat.dg/lto26_pkg1.adb: New helper. * gnat.dg/lto26_pkg2.ads, gnat.dg/lto26_pkg2.adb: Likewise. --- gcc/testsuite/gnat.dg/lto26.adb | 13 +++++++++++++ gcc/testsuite/gnat.dg/lto26_pkg1.adb | 11 +++++++++++ gcc/testsuite/gnat.dg/lto26_pkg1.ads | 11 +++++++++++ gcc/testsuite/gnat.dg/lto26_pkg2.adb | 15 +++++++++++++++ gcc/testsuite/gnat.dg/lto26_pkg2.ads | 9 +++++++++ 5 files changed, 59 insertions(+) create mode 100644 gcc/testsuite/gnat.dg/lto26.adb create mode 100644 gcc/testsuite/gnat.dg/lto26_pkg1.adb create mode 100644 gcc/testsuite/gnat.dg/lto26_pkg1.ads create mode 100644 gcc/testsuite/gnat.dg/lto26_pkg2.adb create mode 100644 gcc/testsuite/gnat.dg/lto26_pkg2.ads (limited to 'gcc/testsuite') diff --git a/gcc/testsuite/gnat.dg/lto26.adb b/gcc/testsuite/gnat.dg/lto26.adb new file mode 100644 index 0000000..a27348b --- /dev/null +++ b/gcc/testsuite/gnat.dg/lto26.adb @@ -0,0 +1,13 @@ +-- { dg-do run } +-- { dg-options "-O2 -flto" { target lto } } + +with Ada.Streams; use Ada.Streams; +with Lto26_Pkg1; use Lto26_Pkg1; + +procedure Lto26 is + R : Rec; +begin + for I in 1 .. 10 loop + Set (R, (7, 0, 84, Stream_Element (I), 0, 0, 0), 1); + end loop; +end; diff --git a/gcc/testsuite/gnat.dg/lto26_pkg1.adb b/gcc/testsuite/gnat.dg/lto26_pkg1.adb new file mode 100644 index 0000000..c68b134 --- /dev/null +++ b/gcc/testsuite/gnat.dg/lto26_pkg1.adb @@ -0,0 +1,11 @@ +with Lto26_Pkg2; use Lto26_Pkg2; + +package body Lto26_Pkg1 is + + procedure Set (R : Rec; A : Stream_Element_Array; C :Unsigned_8) is + procedure My_Build is new Build; + begin + My_Build (A, C); + end; + +end Lto26_Pkg1; diff --git a/gcc/testsuite/gnat.dg/lto26_pkg1.ads b/gcc/testsuite/gnat.dg/lto26_pkg1.ads new file mode 100644 index 0000000..5279747 --- /dev/null +++ b/gcc/testsuite/gnat.dg/lto26_pkg1.ads @@ -0,0 +1,11 @@ +with Ada.Finalization; +with Ada.Streams; use Ada.Streams; +with Interfaces; use Interfaces; + +package Lto26_Pkg1 is + + type Rec is new Ada.Finalization.Limited_Controlled with null record; + + procedure Set (R : Rec; A : Stream_Element_Array; C :Unsigned_8); + +end Lto26_Pkg1; diff --git a/gcc/testsuite/gnat.dg/lto26_pkg2.adb b/gcc/testsuite/gnat.dg/lto26_pkg2.adb new file mode 100644 index 0000000..9f89733 --- /dev/null +++ b/gcc/testsuite/gnat.dg/lto26_pkg2.adb @@ -0,0 +1,15 @@ +package body Lto26_Pkg2 is + + procedure Build (A : Stream_Element_Array; C : Unsigned_8) is + Start : Stream_Element_Offset := A'First; + Next : Stream_Element_Offset; + Length : Unsigned_8; + begin + for I in 1 .. C loop + Length := Unsigned_8 (A (A'First)); + Next := Start + Stream_Element_Offset (Length); + Start := Next; + end loop; + end; + +end Lto26_Pkg2; diff --git a/gcc/testsuite/gnat.dg/lto26_pkg2.ads b/gcc/testsuite/gnat.dg/lto26_pkg2.ads new file mode 100644 index 0000000..68741bb8 --- /dev/null +++ b/gcc/testsuite/gnat.dg/lto26_pkg2.ads @@ -0,0 +1,9 @@ +with Ada.Streams; use Ada.Streams; +with Interfaces; use Interfaces; + +package Lto26_Pkg2 is + + generic + procedure Build (A : Stream_Element_Array; C : Unsigned_8); + +end Lto26_Pkg2; -- cgit v1.1 From 4c451631f722c9939260a5c2fc209802a47e525f Mon Sep 17 00:00:00 2001 From: Aldy Hernandez Date: Tue, 4 Oct 2022 17:05:10 +0200 Subject: [PR tree-optimization/107052] range-ops: Take into account nonzero mask in popcount. PR tree-optimization/107052 gcc/ChangeLog: * gimple-range-op.cc (cfn_popcount::fold_range): Take into account nonzero bit mask. --- gcc/testsuite/gcc.dg/tree-ssa/pr107052.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr107052.c (limited to 'gcc/testsuite') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr107052.c b/gcc/testsuite/gcc.dg/tree-ssa/pr107052.c new file mode 100644 index 0000000..88b5213 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr107052.c @@ -0,0 +1,13 @@ +// { dg-do compile } +// { dg-options "-O2 -fdump-tree-evrp" } + +void link_failure(); +void f(int a) +{ + a &= 0x300; + int b = __builtin_popcount(a); + if (b > 3) + link_failure(); +} + +// { dg-final { scan-tree-dump-not "link_failure" "evrp" } } -- cgit v1.1 From 7d935cdd1a6772699ec0ab4f93711928ca4d30a1 Mon Sep 17 00:00:00 2001 From: Ju-Zhe Zhong Date: Fri, 30 Sep 2022 14:58:16 +0800 Subject: RISC-V: Introduce RVV header to enable builtin types gcc/ChangeLog: * config.gcc: Add riscv_vector.h. * config/riscv/riscv-builtins.cc: Add RVV builtin types support. * config/riscv/riscv-c.cc (riscv_pragma_intrinsic): New function. (riscv_register_pragmas): Ditto. * config/riscv/riscv-protos.h (riscv_register_pragmas): Ditto. (init_builtins): Move declaration from riscv-vector-builtins.h to riscv-protos.h. (mangle_builtin_type): Ditto. (verify_type_context): Ditto. (handle_pragma_vector): New function. * config/riscv/riscv-vector-builtins.cc (GTY): New variable. (register_vector_type): New function. (init_builtins): Add RVV builtin types support. (handle_pragma_vector): New function. * config/riscv/riscv-vector-builtins.h (GCC_RISCV_V_BUILTINS_H): Change name according to file name. (GCC_RISCV_VECTOR_BUILTINS_H): Ditto. (init_builtins): Remove declaration in riscv-vector-builtins.h. (mangle_builtin_type): Ditto. (verify_type_context): Ditto. * config/riscv/riscv.cc: Adjust for RVV builtin types support. * config/riscv/riscv.h (REGISTER_TARGET_PRAGMAS): New macro. * config/riscv/t-riscv: Remove redundant file including. * config/riscv/riscv_vector.h: New file. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/base/pragma-1.c: New test. * gcc.target/riscv/rvv/base/pragma-2.c: New test. * gcc.target/riscv/rvv/base/pragma-3.c: New test. * gcc.target/riscv/rvv/base/user-1.c: New test. * gcc.target/riscv/rvv/base/user-2.c: New test. * gcc.target/riscv/rvv/base/user-3.c: New test. * gcc.target/riscv/rvv/base/user-4.c: New test. * gcc.target/riscv/rvv/base/user-5.c: New test. * gcc.target/riscv/rvv/base/user-6.c: New test. * gcc.target/riscv/rvv/base/vread_csr.c: New test. * gcc.target/riscv/rvv/base/vwrite_csr.c: New test. --- gcc/testsuite/gcc.target/riscv/rvv/base/pragma-1.c | 4 ++ gcc/testsuite/gcc.target/riscv/rvv/base/pragma-2.c | 4 ++ gcc/testsuite/gcc.target/riscv/rvv/base/pragma-3.c | 4 ++ gcc/testsuite/gcc.target/riscv/rvv/base/user-1.c | 65 ++++++++++++++++++++++ gcc/testsuite/gcc.target/riscv/rvv/base/user-2.c | 65 ++++++++++++++++++++++ gcc/testsuite/gcc.target/riscv/rvv/base/user-3.c | 65 ++++++++++++++++++++++ gcc/testsuite/gcc.target/riscv/rvv/base/user-4.c | 65 ++++++++++++++++++++++ gcc/testsuite/gcc.target/riscv/rvv/base/user-5.c | 65 ++++++++++++++++++++++ gcc/testsuite/gcc.target/riscv/rvv/base/user-6.c | 65 ++++++++++++++++++++++ .../gcc.target/riscv/rvv/base/vread_csr.c | 26 +++++++++ .../gcc.target/riscv/rvv/base/vwrite_csr.c | 26 +++++++++ 11 files changed, 454 insertions(+) create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pragma-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pragma-2.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pragma-3.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/user-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/user-2.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/user-3.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/user-4.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/user-5.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/user-6.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/vread_csr.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/vwrite_csr.c (limited to 'gcc/testsuite') diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pragma-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pragma-1.c new file mode 100644 index 0000000..79b1159 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pragma-1.c @@ -0,0 +1,4 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -march=rv32gc -mabi=ilp32d" } */ + +#pragma riscv intrinsic "vector" /* { dg-error {#pragma riscv intrinsic' option 'vector' needs 'V' extension enabled} } */ \ No newline at end of file diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pragma-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pragma-2.c new file mode 100644 index 0000000..fa790b1 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pragma-2.c @@ -0,0 +1,4 @@ +/* { dg-do compile } */ +/* { dg-skip-if "test rvv intrinsic" { *-*-* } { "*" } { "-march=rv*v*" } } */ + +#pragma riscv intrinsic "vector" \ No newline at end of file diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pragma-3.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pragma-3.c new file mode 100644 index 0000000..86da678 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pragma-3.c @@ -0,0 +1,4 @@ +/* { dg-do compile } */ +/* { dg-skip-if "test rvv intrinsic" { *-*-* } { "*" } { "-march=rv*v*" } } */ + +#pragma riscv intrinsic "report-error" /* { dg-error {unknown '#pragma riscv intrinsic' option 'report-error'} } */ \ No newline at end of file diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/user-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/user-1.c new file mode 100644 index 0000000..299e393 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/user-1.c @@ -0,0 +1,65 @@ +/* { dg-do compile } */ +/* { dg-skip-if "test rvv intrinsic" { *-*-* } { "*" } { "-march=rv*v*" } } */ + +#include "riscv_vector.h" + +void foo0 () {vbool64_t t;} +void foo1 () {vbool32_t t;} +void foo2 () {vbool16_t t;} +void foo3 () {vbool8_t t;} +void foo4 () {vbool4_t t;} +void foo5 () {vbool2_t t;} +void foo6 () {vbool1_t t;} +void foo7 () {vint8mf8_t t;} +void foo8 () {vuint8mf8_t t;} +void foo9 () {vint8mf4_t t;} +void foo10 () {vuint8mf4_t t;} +void foo11 () {vint8mf2_t t;} +void foo12 () {vuint8mf2_t t;} +void foo13 () {vint8m1_t t;} +void foo14 () {vuint8m1_t t;} +void foo15 () {vint8m2_t t;} +void foo16 () {vuint8m2_t t;} +void foo17 () {vint8m4_t t;} +void foo18 () {vuint8m4_t t;} +void foo19 () {vint8m8_t t;} +void foo20 () {vuint8m8_t t;} +void foo21 () {vint16mf4_t t;} +void foo22 () {vuint16mf4_t t;} +void foo23 () {vint16mf2_t t;} +void foo24 () {vuint16mf2_t t;} +void foo25 () {vint16m1_t t;} +void foo26 () {vuint16m1_t t;} +void foo27 () {vint16m2_t t;} +void foo28 () {vuint16m2_t t;} +void foo29 () {vint16m4_t t;} +void foo30 () {vuint16m4_t t;} +void foo31 () {vint16m8_t t;} +void foo32 () {vuint16m8_t t;} +void foo33 () {vint32mf2_t t;} +void foo34 () {vuint32mf2_t t;} +void foo35 () {vint32m1_t t;} +void foo36 () {vuint32m1_t t;} +void foo37 () {vint32m2_t t;} +void foo38 () {vuint32m2_t t;} +void foo39 () {vint32m4_t t;} +void foo40 () {vuint32m4_t t;} +void foo41 () {vint32m8_t t;} +void foo42 () {vuint32m8_t t;} +void foo43 () {vint64m1_t t;} +void foo44 () {vuint64m1_t t;} +void foo45 () {vint64m2_t t;} +void foo46 () {vuint64m2_t t;} +void foo47 () {vint64m4_t t;} +void foo48 () {vuint64m4_t t;} +void foo49 () {vint64m8_t t;} +void foo50 () {vuint64m8_t t;} +void foo57 () {vfloat32mf2_t t;} +void foo58 () {vfloat32m1_t t;} +void foo59 () {vfloat32m2_t t;} +void foo60 () {vfloat32m4_t t;} +void foo61 () {vfloat32m8_t t;} +void foo62 () {vfloat64m1_t t;} +void foo63 () {vfloat64m2_t t;} +void foo64 () {vfloat64m4_t t;} +void foo65 () {vfloat64m8_t t;} \ No newline at end of file diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/user-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/user-2.c new file mode 100644 index 0000000..2a88467 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/user-2.c @@ -0,0 +1,65 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -march=rv32gc_zve64x -mabi=ilp32d" } */ + +#include "riscv_vector.h" + +void foo0 () {vbool64_t t;} +void foo1 () {vbool32_t t;} +void foo2 () {vbool16_t t;} +void foo3 () {vbool8_t t;} +void foo4 () {vbool4_t t;} +void foo5 () {vbool2_t t;} +void foo6 () {vbool1_t t;} +void foo7 () {vint8mf8_t t;} +void foo8 () {vuint8mf8_t t;} +void foo9 () {vint8mf4_t t;} +void foo10 () {vuint8mf4_t t;} +void foo11 () {vint8mf2_t t;} +void foo12 () {vuint8mf2_t t;} +void foo13 () {vint8m1_t t;} +void foo14 () {vuint8m1_t t;} +void foo15 () {vint8m2_t t;} +void foo16 () {vuint8m2_t t;} +void foo17 () {vint8m4_t t;} +void foo18 () {vuint8m4_t t;} +void foo19 () {vint8m8_t t;} +void foo20 () {vuint8m8_t t;} +void foo21 () {vint16mf4_t t;} +void foo22 () {vuint16mf4_t t;} +void foo23 () {vint16mf2_t t;} +void foo24 () {vuint16mf2_t t;} +void foo25 () {vint16m1_t t;} +void foo26 () {vuint16m1_t t;} +void foo27 () {vint16m2_t t;} +void foo28 () {vuint16m2_t t;} +void foo29 () {vint16m4_t t;} +void foo30 () {vuint16m4_t t;} +void foo31 () {vint16m8_t t;} +void foo32 () {vuint16m8_t t;} +void foo33 () {vint32mf2_t t;} +void foo34 () {vuint32mf2_t t;} +void foo35 () {vint32m1_t t;} +void foo36 () {vuint32m1_t t;} +void foo37 () {vint32m2_t t;} +void foo38 () {vuint32m2_t t;} +void foo39 () {vint32m4_t t;} +void foo40 () {vuint32m4_t t;} +void foo41 () {vint32m8_t t;} +void foo42 () {vuint32m8_t t;} +void foo43 () {vint64m1_t t;} +void foo44 () {vuint64m1_t t;} +void foo45 () {vint64m2_t t;} +void foo46 () {vuint64m2_t t;} +void foo47 () {vint64m4_t t;} +void foo48 () {vuint64m4_t t;} +void foo49 () {vint64m8_t t;} +void foo50 () {vuint64m8_t t;} +void foo57 () {vfloat32mf2_t t;} /* { dg-error {unknown type name 'vfloat32mf2_t'} } */ +void foo58 () {vfloat32m1_t t;} /* { dg-error {unknown type name 'vfloat32m1_t'} } */ +void foo59 () {vfloat32m2_t t;} /* { dg-error {unknown type name 'vfloat32m2_t'} } */ +void foo60 () {vfloat32m4_t t;} /* { dg-error {unknown type name 'vfloat32m4_t'} } */ +void foo61 () {vfloat32m8_t t;} /* { dg-error {unknown type name 'vfloat32m8_t'} } */ +void foo62 () {vfloat64m1_t t;} /* { dg-error {unknown type name 'vfloat64m1_t'} } */ +void foo63 () {vfloat64m2_t t;} /* { dg-error {unknown type name 'vfloat64m2_t'} } */ +void foo64 () {vfloat64m4_t t;} /* { dg-error {unknown type name 'vfloat64m4_t'} } */ +void foo65 () {vfloat64m8_t t;} /* { dg-error {unknown type name 'vfloat64m8_t'} } */ \ No newline at end of file diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/user-3.c b/gcc/testsuite/gcc.target/riscv/rvv/base/user-3.c new file mode 100644 index 0000000..85a6d04 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/user-3.c @@ -0,0 +1,65 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -march=rv32gc_zve64f -mabi=ilp32d" } */ + +#include "riscv_vector.h" + +void foo0 () {vbool64_t t;} +void foo1 () {vbool32_t t;} +void foo2 () {vbool16_t t;} +void foo3 () {vbool8_t t;} +void foo4 () {vbool4_t t;} +void foo5 () {vbool2_t t;} +void foo6 () {vbool1_t t;} +void foo7 () {vint8mf8_t t;} +void foo8 () {vuint8mf8_t t;} +void foo9 () {vint8mf4_t t;} +void foo10 () {vuint8mf4_t t;} +void foo11 () {vint8mf2_t t;} +void foo12 () {vuint8mf2_t t;} +void foo13 () {vint8m1_t t;} +void foo14 () {vuint8m1_t t;} +void foo15 () {vint8m2_t t;} +void foo16 () {vuint8m2_t t;} +void foo17 () {vint8m4_t t;} +void foo18 () {vuint8m4_t t;} +void foo19 () {vint8m8_t t;} +void foo20 () {vuint8m8_t t;} +void foo21 () {vint16mf4_t t;} +void foo22 () {vuint16mf4_t t;} +void foo23 () {vint16mf2_t t;} +void foo24 () {vuint16mf2_t t;} +void foo25 () {vint16m1_t t;} +void foo26 () {vuint16m1_t t;} +void foo27 () {vint16m2_t t;} +void foo28 () {vuint16m2_t t;} +void foo29 () {vint16m4_t t;} +void foo30 () {vuint16m4_t t;} +void foo31 () {vint16m8_t t;} +void foo32 () {vuint16m8_t t;} +void foo33 () {vint32mf2_t t;} +void foo34 () {vuint32mf2_t t;} +void foo35 () {vint32m1_t t;} +void foo36 () {vuint32m1_t t;} +void foo37 () {vint32m2_t t;} +void foo38 () {vuint32m2_t t;} +void foo39 () {vint32m4_t t;} +void foo40 () {vuint32m4_t t;} +void foo41 () {vint32m8_t t;} +void foo42 () {vuint32m8_t t;} +void foo43 () {vint64m1_t t;} +void foo44 () {vuint64m1_t t;} +void foo45 () {vint64m2_t t;} +void foo46 () {vuint64m2_t t;} +void foo47 () {vint64m4_t t;} +void foo48 () {vuint64m4_t t;} +void foo49 () {vint64m8_t t;} +void foo50 () {vuint64m8_t t;} +void foo57 () {vfloat32mf2_t t;} +void foo58 () {vfloat32m1_t t;} +void foo59 () {vfloat32m2_t t;} +void foo60 () {vfloat32m4_t t;} +void foo61 () {vfloat32m8_t t;} +void foo62 () {vfloat64m1_t t;} /* { dg-error {unknown type name 'vfloat64m1_t'} } */ +void foo63 () {vfloat64m2_t t;} /* { dg-error {unknown type name 'vfloat64m2_t'} } */ +void foo64 () {vfloat64m4_t t;} /* { dg-error {unknown type name 'vfloat64m4_t'} } */ +void foo65 () {vfloat64m8_t t;} /* { dg-error {unknown type name 'vfloat64m8_t'} } */ \ No newline at end of file diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/user-4.c b/gcc/testsuite/gcc.target/riscv/rvv/base/user-4.c new file mode 100644 index 0000000..c51c03e --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/user-4.c @@ -0,0 +1,65 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -march=rv32gc_zve64d -mabi=ilp32d" } */ + +#include "riscv_vector.h" + +void foo0 () {vbool64_t t;} +void foo1 () {vbool32_t t;} +void foo2 () {vbool16_t t;} +void foo3 () {vbool8_t t;} +void foo4 () {vbool4_t t;} +void foo5 () {vbool2_t t;} +void foo6 () {vbool1_t t;} +void foo7 () {vint8mf8_t t;} +void foo8 () {vuint8mf8_t t;} +void foo9 () {vint8mf4_t t;} +void foo10 () {vuint8mf4_t t;} +void foo11 () {vint8mf2_t t;} +void foo12 () {vuint8mf2_t t;} +void foo13 () {vint8m1_t t;} +void foo14 () {vuint8m1_t t;} +void foo15 () {vint8m2_t t;} +void foo16 () {vuint8m2_t t;} +void foo17 () {vint8m4_t t;} +void foo18 () {vuint8m4_t t;} +void foo19 () {vint8m8_t t;} +void foo20 () {vuint8m8_t t;} +void foo21 () {vint16mf4_t t;} +void foo22 () {vuint16mf4_t t;} +void foo23 () {vint16mf2_t t;} +void foo24 () {vuint16mf2_t t;} +void foo25 () {vint16m1_t t;} +void foo26 () {vuint16m1_t t;} +void foo27 () {vint16m2_t t;} +void foo28 () {vuint16m2_t t;} +void foo29 () {vint16m4_t t;} +void foo30 () {vuint16m4_t t;} +void foo31 () {vint16m8_t t;} +void foo32 () {vuint16m8_t t;} +void foo33 () {vint32mf2_t t;} +void foo34 () {vuint32mf2_t t;} +void foo35 () {vint32m1_t t;} +void foo36 () {vuint32m1_t t;} +void foo37 () {vint32m2_t t;} +void foo38 () {vuint32m2_t t;} +void foo39 () {vint32m4_t t;} +void foo40 () {vuint32m4_t t;} +void foo41 () {vint32m8_t t;} +void foo42 () {vuint32m8_t t;} +void foo43 () {vint64m1_t t;} +void foo44 () {vuint64m1_t t;} +void foo45 () {vint64m2_t t;} +void foo46 () {vuint64m2_t t;} +void foo47 () {vint64m4_t t;} +void foo48 () {vuint64m4_t t;} +void foo49 () {vint64m8_t t;} +void foo50 () {vuint64m8_t t;} +void foo57 () {vfloat32mf2_t t;} +void foo58 () {vfloat32m1_t t;} +void foo59 () {vfloat32m2_t t;} +void foo60 () {vfloat32m4_t t;} +void foo61 () {vfloat32m8_t t;} +void foo62 () {vfloat64m1_t t;} +void foo63 () {vfloat64m2_t t;} +void foo64 () {vfloat64m4_t t;} +void foo65 () {vfloat64m8_t t;} \ No newline at end of file diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/user-5.c b/gcc/testsuite/gcc.target/riscv/rvv/base/user-5.c new file mode 100644 index 0000000..fb1c684 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/user-5.c @@ -0,0 +1,65 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -march=rv32gc_zve32x -mabi=ilp32d" } */ + +#include "riscv_vector.h" + +void foo0 () {vbool64_t t;} /* { dg-error {unknown type name 'vbool64_t'} } */ +void foo1 () {vbool32_t t;} +void foo2 () {vbool16_t t;} +void foo3 () {vbool8_t t;} +void foo4 () {vbool4_t t;} +void foo5 () {vbool2_t t;} +void foo6 () {vbool1_t t;} +void foo7 () {vint8mf8_t t;} /* { dg-error {unknown type name 'vint8mf8_t'} } */ +void foo8 () {vuint8mf8_t t;} /* { dg-error {unknown type name 'vuint8mf8_t'} } */ +void foo9 () {vint8mf4_t t;} +void foo10 () {vuint8mf4_t t;} +void foo11 () {vint8mf2_t t;} +void foo12 () {vuint8mf2_t t;} +void foo13 () {vint8m1_t t;} +void foo14 () {vuint8m1_t t;} +void foo15 () {vint8m2_t t;} +void foo16 () {vuint8m2_t t;} +void foo17 () {vint8m4_t t;} +void foo18 () {vuint8m4_t t;} +void foo19 () {vint8m8_t t;} +void foo20 () {vuint8m8_t t;} +void foo21 () {vint16mf4_t t;} /* { dg-error {unknown type name 'vint16mf4_t'} } */ +void foo22 () {vuint16mf4_t t;} /* { dg-error {unknown type name 'vuint16mf4_t'} } */ +void foo23 () {vint16mf2_t t;} +void foo24 () {vuint16mf2_t t;} +void foo25 () {vint16m1_t t;} +void foo26 () {vuint16m1_t t;} +void foo27 () {vint16m2_t t;} +void foo28 () {vuint16m2_t t;} +void foo29 () {vint16m4_t t;} +void foo30 () {vuint16m4_t t;} +void foo31 () {vint16m8_t t;} +void foo32 () {vuint16m8_t t;} +void foo33 () {vint32mf2_t t;} /* { dg-error {unknown type name 'vint32mf2_t'} } */ +void foo34 () {vuint32mf2_t t;} /* { dg-error {unknown type name 'vuint32mf2_t'} } */ +void foo35 () {vint32m1_t t;} +void foo36 () {vuint32m1_t t;} +void foo37 () {vint32m2_t t;} +void foo38 () {vuint32m2_t t;} +void foo39 () {vint32m4_t t;} +void foo40 () {vuint32m4_t t;} +void foo41 () {vint32m8_t t;} +void foo42 () {vuint32m8_t t;} +void foo43 () {vint64m1_t t;} /* { dg-error {unknown type name 'vint64m1_t'} } */ +void foo44 () {vuint64m1_t t;} /* { dg-error {unknown type name 'vuint64m1_t'} } */ +void foo45 () {vint64m2_t t;} /* { dg-error {unknown type name 'vint64m2_t'} } */ +void foo46 () {vuint64m2_t t;} /* { dg-error {unknown type name 'vuint64m2_t'} } */ +void foo47 () {vint64m4_t t;} /* { dg-error {unknown type name 'vint64m4_t'} } */ +void foo48 () {vuint64m4_t t;} /* { dg-error {unknown type name 'vuint64m4_t'} } */ +void foo49 () {vint64m8_t t;} /* { dg-error {unknown type name 'vint64m8_t'} } */ +void foo50 () {vuint64m8_t t;} /* { dg-error {unknown type name 'vuint64m8_t'} } */ +void foo57 () {vfloat32mf2_t t;} /* { dg-error {unknown type name 'vfloat32mf2_t'} } */ +void foo58 () {vfloat32m1_t t;} /* { dg-error {unknown type name 'vfloat32m1_t'} } */ +void foo59 () {vfloat32m2_t t;} /* { dg-error {unknown type name 'vfloat32m2_t'} } */ +void foo60 () {vfloat32m4_t t;} /* { dg-error {unknown type name 'vfloat32m4_t'} } */ +void foo61 () {vfloat32m8_t t;} /* { dg-error {unknown type name 'vfloat32m8_t'} } */ +void foo62 () {vfloat64m1_t t;} /* { dg-error {unknown type name 'vfloat64m1_t'} } */ +void foo63 () {vfloat64m2_t t;} /* { dg-error {unknown type name 'vfloat64m2_t'} } */ +void foo64 () {vfloat64m4_t t;} /* { dg-error {unknown type name 'vfloat64m4_t'} } */ +void foo65 () {vfloat64m8_t t;} /* { dg-error {unknown type name 'vfloat64m8_t'} } */ \ No newline at end of file diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/user-6.c b/gcc/testsuite/gcc.target/riscv/rvv/base/user-6.c new file mode 100644 index 0000000..5361fbd --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/user-6.c @@ -0,0 +1,65 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -march=rv32gc_zve32f -mabi=ilp32d" } */ + +#include "riscv_vector.h" + +void foo0 () {vbool64_t t;} /* { dg-error {unknown type name 'vbool64_t'} } */ +void foo1 () {vbool32_t t;} +void foo2 () {vbool16_t t;} +void foo3 () {vbool8_t t;} +void foo4 () {vbool4_t t;} +void foo5 () {vbool2_t t;} +void foo6 () {vbool1_t t;} +void foo7 () {vint8mf8_t t;} /* { dg-error {unknown type name 'vint8mf8_t'} } */ +void foo8 () {vuint8mf8_t t;} /* { dg-error {unknown type name 'vuint8mf8_t'} } */ +void foo9 () {vint8mf4_t t;} +void foo10 () {vuint8mf4_t t;} +void foo11 () {vint8mf2_t t;} +void foo12 () {vuint8mf2_t t;} +void foo13 () {vint8m1_t t;} +void foo14 () {vuint8m1_t t;} +void foo15 () {vint8m2_t t;} +void foo16 () {vuint8m2_t t;} +void foo17 () {vint8m4_t t;} +void foo18 () {vuint8m4_t t;} +void foo19 () {vint8m8_t t;} +void foo20 () {vuint8m8_t t;} +void foo21 () {vint16mf4_t t;} /* { dg-error {unknown type name 'vint16mf4_t'} } */ +void foo22 () {vuint16mf4_t t;} /* { dg-error {unknown type name 'vuint16mf4_t'} } */ +void foo23 () {vint16mf2_t t;} +void foo24 () {vuint16mf2_t t;} +void foo25 () {vint16m1_t t;} +void foo26 () {vuint16m1_t t;} +void foo27 () {vint16m2_t t;} +void foo28 () {vuint16m2_t t;} +void foo29 () {vint16m4_t t;} +void foo30 () {vuint16m4_t t;} +void foo31 () {vint16m8_t t;} +void foo32 () {vuint16m8_t t;} +void foo33 () {vint32mf2_t t;} /* { dg-error {unknown type name 'vint32mf2_t'} } */ +void foo34 () {vuint32mf2_t t;} /* { dg-error {unknown type name 'vuint32mf2_t'} } */ +void foo35 () {vint32m1_t t;} +void foo36 () {vuint32m1_t t;} +void foo37 () {vint32m2_t t;} +void foo38 () {vuint32m2_t t;} +void foo39 () {vint32m4_t t;} +void foo40 () {vuint32m4_t t;} +void foo41 () {vint32m8_t t;} +void foo42 () {vuint32m8_t t;} +void foo43 () {vint64m1_t t;} /* { dg-error {unknown type name 'vint64m1_t'} } */ +void foo44 () {vuint64m1_t t;} /* { dg-error {unknown type name 'vuint64m1_t'} } */ +void foo45 () {vint64m2_t t;} /* { dg-error {unknown type name 'vint64m2_t'} } */ +void foo46 () {vuint64m2_t t;} /* { dg-error {unknown type name 'vuint64m2_t'} } */ +void foo47 () {vint64m4_t t;} /* { dg-error {unknown type name 'vint64m4_t'} } */ +void foo48 () {vuint64m4_t t;} /* { dg-error {unknown type name 'vuint64m4_t'} } */ +void foo49 () {vint64m8_t t;} /* { dg-error {unknown type name 'vint64m8_t'} } */ +void foo50 () {vuint64m8_t t;} /* { dg-error {unknown type name 'vuint64m8_t'} } */ +void foo57 () {vfloat32mf2_t t;} /* { dg-error {unknown type name 'vfloat32mf2_t'} } */ +void foo58 () {vfloat32m1_t t;} +void foo59 () {vfloat32m2_t t;} +void foo60 () {vfloat32m4_t t;} +void foo61 () {vfloat32m8_t t;} +void foo62 () {vfloat64m1_t t;} /* { dg-error {unknown type name 'vfloat64m1_t'} } */ +void foo63 () {vfloat64m2_t t;} /* { dg-error {unknown type name 'vfloat64m2_t'} } */ +void foo64 () {vfloat64m4_t t;} /* { dg-error {unknown type name 'vfloat64m4_t'} } */ +void foo65 () {vfloat64m8_t t;} /* { dg-error {unknown type name 'vfloat64m8_t'} } */ \ No newline at end of file diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/vread_csr.c b/gcc/testsuite/gcc.target/riscv/rvv/base/vread_csr.c new file mode 100644 index 0000000..9151349f --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/vread_csr.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-O3" } */ +/* { dg-skip-if "test intrinsic using rvv" { *-*-* } { "*" } { "-march=rv*v*zfh*" } } */ + +#include + +unsigned long vread_csr_vstart(void) { + return vread_csr(RVV_VSTART); +} + +unsigned long vread_csr_vxsat(void) { + return vread_csr(RVV_VXSAT); +} + +unsigned long vread_csr_vxrm(void) { + return vread_csr(RVV_VXRM); +} + +unsigned long vread_csr_vcsr(void) { + return vread_csr(RVV_VCSR); +} + +/* { dg-final { scan-assembler-times {csrr\s+(?:ra|[sgtf]p|t[0-6]|s[0-9]|s10|s11|a[0-7]),\s*vstart} 1 } } */ +/* { dg-final { scan-assembler-times {csrr\s+(?:ra|[sgtf]p|t[0-6]|s[0-9]|s10|s11|a[0-7]),\s*vxsat} 1 } } */ +/* { dg-final { scan-assembler-times {csrr\s+(?:ra|[sgtf]p|t[0-6]|s[0-9]|s10|s11|a[0-7]),\s*vxrm} 1 } } */ +/* { dg-final { scan-assembler-times {csrr\s+(?:ra|[sgtf]p|t[0-6]|s[0-9]|s10|s11|a[0-7]),\s*vcsr} 1 } } */ \ No newline at end of file diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/vwrite_csr.c b/gcc/testsuite/gcc.target/riscv/rvv/base/vwrite_csr.c new file mode 100644 index 0000000..a50eba7 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/vwrite_csr.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-O3" } */ +/* { dg-skip-if "test intrinsic using rvv" { *-*-* } { "*" } { "-march=rv*v*zfh*" } } */ + +#include + +void vwrite_csr_vstart(unsigned long value) { + vwrite_csr(RVV_VSTART, value); +} + +void vwrite_csr_vxsat(unsigned long value) { + vwrite_csr(RVV_VXSAT, value); +} + +void vwrite_csr_vxrm(unsigned long value) { + vwrite_csr(RVV_VXRM, value); +} + +void vwrite_csr_vcsr(unsigned long value) { + vwrite_csr(RVV_VCSR, value); +} + +/* { dg-final { scan-assembler-times {csrw\s+vstart,\s*(?:ra|[sgtf]p|t[0-6]|s[0-9]|s10|s11|a[0-7])} 1 } } */ +/* { dg-final { scan-assembler-times {csrw\s+vxsat,\s*(?:ra|[sgtf]p|t[0-6]|s[0-9]|s10|s11|a[0-7])} 1 } } */ +/* { dg-final { scan-assembler-times {csrw\s+vxrm,\s*(?:ra|[sgtf]p|t[0-6]|s[0-9]|s10|s11|a[0-7])} 1 } } */ +/* { dg-final { scan-assembler-times {csrw\s+vcsr,\s*(?:ra|[sgtf]p|t[0-6]|s[0-9]|s10|s11|a[0-7])} 1 } } */ \ No newline at end of file -- cgit v1.1 From e2a228438919d846995bf2c839c9b657442224b2 Mon Sep 17 00:00:00 2001 From: Tobias Burnus Date: Wed, 5 Oct 2022 19:25:27 +0200 Subject: Fortran: Add OpenMP's assume(s) directives libgomp/ChangeLog: * libgomp.texi (OpenMP 5.1 Impl. Status): Mark 'assume' as 'Y'. gcc/fortran/ChangeLog: * dump-parse-tree.cc (show_omp_assumes): New. (show_omp_clauses, show_namespace): Call it. (show_omp_node, show_code_node): Handle OpenMP ASSUME. * gfortran.h (enum gfc_statement): Add ST_OMP_ASSUME, ST_OMP_END_ASSUME, ST_OMP_ASSUMES and ST_NOTHING. (gfc_exec_op): Add EXEC_OMP_ASSUME. (gfc_omp_assumptions): New struct. (gfc_get_omp_assumptions): New XCNEW #define. (gfc_omp_clauses, gfc_namespace): Add assume member. (gfc_resolve_omp_assumptions): New prototype. * match.h (gfc_match_omp_assume, gfc_match_omp_assumes): New. * openmp.cc (omp_code_to_statement): Forward declare. (enum gfc_omp_directive_kind, struct gfc_omp_directive): New. (gfc_free_omp_clauses): Free assume member and its struct data. (enum omp_mask2): Add OMP_CLAUSE_ASSUMPTIONS. (gfc_omp_absent_contains_clause): New. (gfc_match_omp_clauses): Call it; optionally use passed omp_clauses argument. (omp_verify_merge_absent_contains, gfc_match_omp_assume, gfc_match_omp_assumes, gfc_resolve_omp_assumptions): New. (resolve_omp_clauses): Call the latter. (gfc_resolve_omp_directive, omp_code_to_statement): Handle EXEC_OMP_ASSUME. * parse.cc (decode_omp_directive): Parse OpenMP ASSUME(S). (next_statement, parse_executable, parse_omp_structured_block): Handle ST_OMP_ASSUME. (case_omp_decl): Add ST_OMP_ASSUMES. (gfc_ascii_statement): Handle Assumes, optional return string without '!$OMP '/'!$ACC ' prefix. * parse.h (gfc_ascii_statement): Add optional bool arg to prototype. * resolve.cc (gfc_resolve_blocks, gfc_resolve_code): Add EXEC_OMP_ASSUME. (gfc_resolve): Resolve ASSUMES directive. * symbol.cc (gfc_free_namespace): Free omp_assumes member. * st.cc (gfc_free_statement): Handle EXEC_OMP_ASSUME. * trans-openmp.cc (gfc_trans_omp_directive): Likewise. * trans.cc (trans_code): Likewise. gcc/testsuite/ChangeLog: * gfortran.dg/gomp/assume-1.f90: New test. * gfortran.dg/gomp/assume-2.f90: New test. * gfortran.dg/gomp/assumes-1.f90: New test. * gfortran.dg/gomp/assumes-2.f90: New test. --- gcc/testsuite/gfortran.dg/gomp/assume-1.f90 | 24 ++++++++ gcc/testsuite/gfortran.dg/gomp/assume-2.f90 | 27 +++++++++ gcc/testsuite/gfortran.dg/gomp/assumes-1.f90 | 82 ++++++++++++++++++++++++++++ gcc/testsuite/gfortran.dg/gomp/assumes-2.f90 | 19 +++++++ 4 files changed, 152 insertions(+) create mode 100644 gcc/testsuite/gfortran.dg/gomp/assume-1.f90 create mode 100644 gcc/testsuite/gfortran.dg/gomp/assume-2.f90 create mode 100644 gcc/testsuite/gfortran.dg/gomp/assumes-1.f90 create mode 100644 gcc/testsuite/gfortran.dg/gomp/assumes-2.f90 (limited to 'gcc/testsuite') diff --git a/gcc/testsuite/gfortran.dg/gomp/assume-1.f90 b/gcc/testsuite/gfortran.dg/gomp/assume-1.f90 new file mode 100644 index 0000000..8bd5c72 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/assume-1.f90 @@ -0,0 +1,24 @@ +subroutine foo (i, a) + implicit none + integer, value :: i + integer :: a(:) + integer :: j + + j = 7 + !$omp assume no_openmp, absent (target, teams) holds (i < 32) holds (i < 32_2) + !$omp end assume + + !$omp assume no_openmp_routines, contains (simd) + block + !$omp simd + do j = 1, i + a(i) = j + end do + end block + + !$omp assume no_parallelism, contains (error) + if (i >= 32) then + !$omp error at (execution) message ("Should not happen") + end if + !$omp end assume +end diff --git a/gcc/testsuite/gfortran.dg/gomp/assume-2.f90 b/gcc/testsuite/gfortran.dg/gomp/assume-2.f90 new file mode 100644 index 0000000..ca3e04d --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/assume-2.f90 @@ -0,0 +1,27 @@ +subroutine foo (i, a) + implicit none + integer, value :: i + integer :: a(:) + integer :: j + + j = 7 + !$omp assume no_openmp, absent (target, teams,target) holds (i < 32) holds (i < 32_2) ! { dg-error "'TARGET' directive mentioned multiple times in ABSENT clause in !.OMP ASSUME directive" } +! !$omp end assume - silence: 'Unexpected !$OMP END ASSUME statement' + + !$omp assume no_openmp_routines, contains (simd) contains ( simd ) ! { dg-error "'SIMD' directive mentioned multiple times in CONTAINS clause in !.OMP ASSUME directive" } + block + !$omp simd + do j = 1, i + a(i) = j + end do + end block + + !$omp assume no_parallelism, contains (error) absent (error) ! { dg-error "'ERROR' directive mentioned both times in ABSENT and CONTAINS clauses in !.OMP ASSUME directive" } + if (i >= 32) then + !$omp error at (execution) message ("Should not happen") + end if +! !$omp end assume - silence: 'Unexpected !$OMP END ASSUME statement' + + !$omp assume holds (1.0) ! { dg-error "HOLDS expression at .1. must be a logical expression" } + !$omp end assume +end diff --git a/gcc/testsuite/gfortran.dg/gomp/assumes-1.f90 b/gcc/testsuite/gfortran.dg/gomp/assumes-1.f90 new file mode 100644 index 0000000..3d468dc --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/assumes-1.f90 @@ -0,0 +1,82 @@ +! All of the following (up to PROGRAM) are okay: +! +subroutine sub + interface + subroutine sub_iterface() + !$omp assumes no_openmp_routines absent(simd) ! OK inferface of an external subroutine/subprogram + end + end interface + !$omp assumes no_openmp_routines absent(simd) ! OK external subroutine/subprogram +contains + subroutine inner_sub + !$omp assumes no_parallelism absent(teams) ! OK internal subroutine/subprogram + end +end + +integer function func () + !$omp assumes no_openmp_routines absent(simd) ! OK external function/subprogram + interface + integer function func_iterface() + !$omp assumes no_openmp_routines absent(simd) ! OK inferface of an external function/subprogram + end + end interface + func = 0 +contains + integer function inner_func() + !$omp assumes no_parallelism absent(teams) ! OK internal function/subprogram + inner_sub2 = 0 + end +end + +module m + integer ::x + !$omp assumes contains(target) holds(x > 0.0) + + interface + subroutine mod_mod_sub_iterface() + !$omp assumes no_openmp_routines absent(simd) ! OK inferface of an external subroutine/subprogram + end + integer function mod_mod_func_iterface() + !$omp assumes no_openmp_routines absent(error) ! OK inferface of an external subroutine/subprogram + end + end interface + +contains + subroutine mod_sub + interface + subroutine mod_sub_iterface() + !$omp assumes no_openmp_routines absent(simd) ! OK inferface of an external subroutine/subprogram + end + end interface + !$omp assumes no_openmp_routines absent(simd) ! OK module subroutine/subprogram + contains + subroutine mod_inner_sub + !$omp assumes no_parallelism absent(teams) ! OK internal subroutine/subprogram + end + end + + integer function mod_func () + !$omp assumes no_openmp_routines absent(simd) ! OK module function/subprogram + interface + integer function mod_func_iterface() + !$omp assumes no_openmp_routines absent(simd) ! OK inferface of an external function/subprogram + end + end interface + mod_func = 0 + contains + integer function mod_inner_func() + !$omp assumes no_parallelism absent(teams) ! OK internal function/subprogram + mod_inner_sub2 = 0 + end + end +end module m + + +! PROGRAM - invalid as: +! main program is a program unit that is not a subprogram +!$omp assumes no_openmp absent(simd) ! { dg-error "must be in the specification part of a subprogram or module" } + block + ! invalid: block + !$omp assumes no_openmp absent(target) ! { dg-error "must be in the specification part of a subprogram or module" } + end block +end diff --git a/gcc/testsuite/gfortran.dg/gomp/assumes-2.f90 b/gcc/testsuite/gfortran.dg/gomp/assumes-2.f90 new file mode 100644 index 0000000..729c973 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/assumes-2.f90 @@ -0,0 +1,19 @@ +module m + integer ::x +! Nonsense but OpenMP-semantically valid: + !$omp assumes contains(target) holds(x > 0.0) + !$omp assumes absent(target) + !$omp assumes holds(0.0) +! { dg-error "HOLDS expression at .1. must be a logical expression" "" { target *-*-* } .-1 } +end module + +module m2 +interface + subroutine foo + !$omp assumes contains(target) contains(teams,target) ! { dg-error "'TARGET' directive mentioned multiple times in CONTAINS clause in !.OMP ASSUMES directive" } + !$omp assumes absent(declare target) ! { dg-error "Invalid 'DECLARE TARGET' directive at .1. in ABSENT clause: declarative, informational and meta directives not permitted" } + !$omp assumes absent(parallel) absent(do,simd,parallel,distribute) ! { dg-error "'PARALLEL' directive mentioned multiple times in ABSENT clause in !.OMP ASSUMES directive" } + !$omp assumes contains(barrier,atomic) absent(cancel,simd,atomic,distribute) ! { dg-error "'SIMD' directive mentioned both times in ABSENT and CONTAINS clauses in !.OMP ASSUMES directive" } + end subroutine foo +end interface +end module m2 -- cgit v1.1 From 6832c95c0e1a58ba4d342ec002000f9d9d7db5ca Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Wed, 5 Oct 2022 13:52:59 -0400 Subject: analyzer: fix ICEs seen with call summaries on PR 107060 This doesn't fix the various false positives seen with -fanalyzer-call-summaries on PR 107060, but stops it crashing at -O2. gcc/analyzer/ChangeLog: PR analyzer/107060 * call-summary.cc (call_summary_replay::convert_svalue_from_summary_1): Handle NULL results from convert_svalue_from_summary in SK_UNARY_OP and SK_BIN_OP. * engine.cc (impl_region_model_context::on_unknown_change): Bail out on svalues that can't have associated state. * region-model-impl-calls.cc (region_model::impl_call_analyzer_get_unknown_ptr): New. * region-model.cc (region_model::on_stmt_pre): Handle "__analyzer_get_unknown_ptr". * region-model.h (region_model::impl_call_analyzer_get_unknown_ptr): New decl. * store.cc (store::replay_call_summary_cluster): Avoid trying to create binding clusters for base regions that shouldn't have them. gcc/ChangeLog: PR analyzer/107060 * doc/analyzer.texi (__analyzer_get_unknown_ptr): Document. gcc/testsuite/ChangeLog: PR analyzer/107060 * gcc.dg/analyzer/analyzer-decls.h (__analyzer_get_unknown_ptr): New decl. * gcc.dg/analyzer/call-summaries-2.c (test_summarized_writes_param_to_ptr_unknown): New test. Signed-off-by: David Malcolm --- gcc/testsuite/gcc.dg/analyzer/analyzer-decls.h | 3 +++ gcc/testsuite/gcc.dg/analyzer/call-summaries-2.c | 7 +++++++ 2 files changed, 10 insertions(+) (limited to 'gcc/testsuite') diff --git a/gcc/testsuite/gcc.dg/analyzer/analyzer-decls.h b/gcc/testsuite/gcc.dg/analyzer/analyzer-decls.h index d052579..4478d74 100644 --- a/gcc/testsuite/gcc.dg/analyzer/analyzer-decls.h +++ b/gcc/testsuite/gcc.dg/analyzer/analyzer-decls.h @@ -47,4 +47,7 @@ extern void __analyzer_dump_state (const char *name, ...); truthfulness of the argument. */ extern void __analyzer_eval (int); +/* Obtain an "unknown" void *. */ +extern void *__analyzer_get_unknown_ptr (void); + #endif /* #ifndef ANALYZER_DECLS_H. */ diff --git a/gcc/testsuite/gcc.dg/analyzer/call-summaries-2.c b/gcc/testsuite/gcc.dg/analyzer/call-summaries-2.c index 0aaf67b..85cece7 100644 --- a/gcc/testsuite/gcc.dg/analyzer/call-summaries-2.c +++ b/gcc/testsuite/gcc.dg/analyzer/call-summaries-2.c @@ -72,6 +72,13 @@ void test_summarized_writes_param_to_ptr (int j) __analyzer_eval (y == j); /* { dg-warning "TRUE" } */ } +void test_summarized_writes_param_to_ptr_unknown (int j) +{ + int *p = (int *)__analyzer_get_unknown_ptr (); + writes_param_to_ptr (j, p); + __analyzer_eval (*p == j); /* { dg-warning "UNKNOWN" } */ +} + int g; void writes_to_global (int i) -- cgit v1.1 From ef878564140cbcf23f479da88e07e5a996cec6bb Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Wed, 5 Oct 2022 14:07:47 -0400 Subject: analyzer: add regression test for PR 107158 PR analyzer/107158 reports an ICE when using -fanalyzer -fanalyzer-call-summaries on a particular source file. It turns out I just fixed this ICE in r13-3094-g6832c95c0e1a58. This followup patch adds a somewhat reduced reproducer as a regression test. Unfortunately, although the ICE is fixed, there are two false positives from -Wanalyzer-malloc-leak on the test case, so I'm going to use PR analyzer/107158 for tracking those false positives. gcc/testsuite/ChangeLog: PR analyzer/107158 * gcc.dg/analyzer/call-summaries-pr107158.c: New test. Signed-off-by: David Malcolm --- .../gcc.dg/analyzer/call-summaries-pr107158.c | 83 ++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/analyzer/call-summaries-pr107158.c (limited to 'gcc/testsuite') diff --git a/gcc/testsuite/gcc.dg/analyzer/call-summaries-pr107158.c b/gcc/testsuite/gcc.dg/analyzer/call-summaries-pr107158.c new file mode 100644 index 0000000..54f442f --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/call-summaries-pr107158.c @@ -0,0 +1,83 @@ +/* { dg-additional-options "-fanalyzer-call-summaries" } */ + +typedef __SIZE_TYPE__ size_t; +enum { _ISspace = ((5) < 8 ? ((1 << (5)) << 8) : ((1 << (5)) >> 8)) }; +extern const unsigned short int **__ctype_b_loc(void) + __attribute__((__nothrow__, __leaf__, __const__)); +extern void *malloc(size_t __size) + __attribute__((__nothrow__, __leaf__, __malloc__, __alloc_size__(1))); +extern char *strcpy(char *__restrict __dest, const char *__restrict __src) + __attribute__((__nothrow__, __leaf__, __nonnull__(1, 2))); +extern size_t strlen(const char *__s) + __attribute__((__nothrow__, __leaf__, __pure__, __nonnull__(1))); + +struct mydata { + struct mydata *link; + char *name; + char *type; +}; + +static struct mydata *all_data; +static int line_no; + +__attribute__((__noreturn__)) void failed(const char *message); + +static char *string_dup(const char *string) { + char *buf; + + if ((buf = malloc(strlen(string) + 1)) == ((void *)0)) + failed("malloc() failed"); + + return strcpy(buf, string); +} + +static void store_data(const char *name, const char *type) { + struct mydata *p, *q; + + if ((p = (struct mydata *)malloc(sizeof(struct mydata))) == ((void *)0)) + failed("malloc() failed"); + + p->link = ((void *)0); + p->name = string_dup(name); + p->type = string_dup(type); + + if ((q = all_data) == ((void *)0)) + all_data = p; + else { + while (q->link != ((void *)0)) + q = q->link; + q->link = p; + } +} + +static void parse_tbl(char *buffer) { + char *s = buffer; + char *t = s + strlen(s); + + do { + t--; + if (((*__ctype_b_loc())[(int)(((int)*t))] & (unsigned short int)_ISspace)) + *t = '\0'; + else + break; + } while (t > s); + while (((*__ctype_b_loc())[(int)(((int)*s))] & (unsigned short int)_ISspace)) + s++; + buffer = s; + + line_no++; + if (*buffer != ';' && *buffer != '\0') { + if (*buffer == '#') { + store_data(buffer, ""); /* { dg-bogus "leak" "PR analyzer/107158" { xfail *-*-* } } */ + } else { + + while (*s && !((*__ctype_b_loc())[(int)(((int)*s))] & + (unsigned short int)_ISspace)) + s++; + while ( + ((*__ctype_b_loc())[(int)(((int)*s))] & (unsigned short int)_ISspace)) + *s++ = '\0'; + store_data(buffer, s); /* { dg-bogus "leak" "PR analyzer/107158" { xfail *-*-* } } */ + } + } +} -- cgit v1.1 From 966010b2eb4a4c52f139b63548533e7bbd74ec9c Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Thu, 6 Oct 2022 00:17:24 +0000 Subject: Daily bump. --- gcc/testsuite/ChangeLog | 88 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) (limited to 'gcc/testsuite') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8a30bb4..584fba4c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,91 @@ +2022-10-05 David Malcolm + + PR analyzer/107158 + * gcc.dg/analyzer/call-summaries-pr107158.c: New test. + +2022-10-05 David Malcolm + + PR analyzer/107060 + * gcc.dg/analyzer/analyzer-decls.h (__analyzer_get_unknown_ptr): + New decl. + * gcc.dg/analyzer/call-summaries-2.c + (test_summarized_writes_param_to_ptr_unknown): New test. + +2022-10-05 Tobias Burnus + + * gfortran.dg/gomp/assume-1.f90: New test. + * gfortran.dg/gomp/assume-2.f90: New test. + * gfortran.dg/gomp/assumes-1.f90: New test. + * gfortran.dg/gomp/assumes-2.f90: New test. + +2022-10-05 Ju-Zhe Zhong + + * gcc.target/riscv/rvv/base/pragma-1.c: New test. + * gcc.target/riscv/rvv/base/pragma-2.c: New test. + * gcc.target/riscv/rvv/base/pragma-3.c: New test. + * gcc.target/riscv/rvv/base/user-1.c: New test. + * gcc.target/riscv/rvv/base/user-2.c: New test. + * gcc.target/riscv/rvv/base/user-3.c: New test. + * gcc.target/riscv/rvv/base/user-4.c: New test. + * gcc.target/riscv/rvv/base/user-5.c: New test. + * gcc.target/riscv/rvv/base/user-6.c: New test. + * gcc.target/riscv/rvv/base/vread_csr.c: New test. + * gcc.target/riscv/rvv/base/vwrite_csr.c: New test. + +2022-10-05 Aldy Hernandez + + PR tree-optimization/107052 + * gcc.dg/tree-ssa/pr107052.c: New file. + +2022-10-05 Eric Botcazou + + * gnat.dg/lto26.adb: New test. + * gnat.dg/lto26_pkg1.ads, gnat.dg/lto26_pkg1.adb: New helper. + * gnat.dg/lto26_pkg2.ads, gnat.dg/lto26_pkg2.adb: Likewise. + +2022-10-05 Martin Liska + + PR tree-optimization/106679 + * gcc.dg/tree-prof/cmpsf-1.c: Mark as a known limitation. + +2022-10-05 Torbjörn SVENSSON + Yvan ROUX + + * gcc.target/arm/stack-protector-1.c: Use 'bl' instead of 'b' + instruction. + * gcc.target/arm/stack-protector-3.c: Likewise. + +2022-10-05 Torbjörn SVENSSON + Yvan ROUX + + * g++.dg/modules/bad-mapper-1.C: Also accept CreateProcess. + +2022-10-05 Torbjörn SVENSSON + Yvan ROUX + + * gcc.misc-tests/outputs.exp: Use "@nul" for Windows, + "@/dev/null" for other environments. + +2022-10-05 Vineet Gupta + + * gcc.target/riscv/predef-1.c: Remove __riscv_cmodel_pic check. + * gcc.target/riscv/predef-2.c: Ditto. + * gcc.target/riscv/predef-3.c: Ditto. + * gcc.target/riscv/predef-4.c: Ditto. + * gcc.target/riscv/predef-5.c: Ditto. + * gcc.target/riscv/predef-6.c: Ditto. + * gcc.target/riscv/predef-7.c: Ditto. + * gcc.target/riscv/predef-8.c: Ditto. + +2022-10-05 David Malcolm + + PR analyzer/107072 + * gcc.dg/analyzer/call-summaries-2.c: New test. + * gcc.dg/analyzer/call-summaries-3.c: New test. + * gcc.dg/analyzer/call-summaries-asm-x86.c: New test. + * gcc.dg/analyzer/call-summaries-malloc.c: New test. + * gcc.dg/analyzer/call-summaries-pr107072.c: New test. + 2022-10-04 Jason Merrill PR c++/107154 -- cgit v1.1 From 08b51baddc53d64aa4c5e7a81ef3c4bf320293be Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 6 Oct 2022 08:56:48 +0200 Subject: c++, c: Implement C++23 P1774R8 - Portable assumptions [PR106654] The following patch implements C++23 P1774R8 - Portable assumptions paper, by introducing support for [[assume (cond)]]; attribute for C++. In addition to that the patch adds [[gnu::assume (cond)]]; and __attribute__((assume (cond))); support to both C and C++. As described in C++23, the attribute argument is conditional-expression rather than the usual assignment-expression for attribute arguments, the condition is contextually converted to bool (for C truthvalue conversion is done on it) and is never evaluated at runtime. For C++ constant expression evaluation, I only check the simplest conditions for undefined behavior, because otherwise I'd need to undo changes to *ctx->global which happened during the evaluation (but I believe the spec allows that and we can further improve later). The patch uses a new internal function, .ASSUME, to hold the condition in the FEs. At gimplification time, if the condition is simple/without side-effects, it is gimplified as if (cond) ; else __builtin_unreachable (); and otherwise for now dropped on the floor. The intent is to incrementally outline the conditions into separate artificial functions and use .ASSUME further to tell the ranger and perhaps other optimization passes about the assumptions, as detailed in the PR. When implementing it, I found that assume entry hasn't been added to https://eel.is/c++draft/cpp.cond#6 Jonathan said he'll file a NB comment about it, this patch assumes it has been added into the table as 202207L when the paper has been voted in. With the attributes for both C/C++, I'd say we don't need to add __builtin_assume with similar purpose, especially when __builtin_assume in LLVM is just weird. It is strange for side-effects in function call's argument not to be evaluated, and LLVM in that case (annoyingly) warns and ignores the side-effects (but doesn't do then anything with it), if there are no side-effects, it will work like our if (!cond) __builtin_unreachable (); 2022-10-06 Jakub Jelinek PR c++/106654 gcc/ * internal-fn.def (ASSUME): New internal function. * internal-fn.h (expand_ASSUME): Declare. * internal-fn.cc (expand_ASSUME): Define. * gimplify.cc (gimplify_call_expr): Gimplify IFN_ASSUME. * fold-const.h (simple_condition_p): Declare. * fold-const.cc (simple_operand_p_2): Rename to ... (simple_condition_p): ... this. Remove forward declaration. No longer static. Adjust function comment and fix a typo in it. Adjust recursive call. (simple_operand_p): Adjust function comment. (fold_truth_andor): Adjust simple_operand_p_2 callers to call simple_condition_p. * doc/extend.texi: Document assume attribute. Move fallthrough attribute example to its section. gcc/c-family/ * c-attribs.cc (handle_assume_attribute): New function. (c_common_attribute_table): Add entry for assume attribute. * c-lex.cc (c_common_has_attribute): Handle __have_cpp_attribute (assume). gcc/c/ * c-parser.cc (handle_assume_attribute): New function. (c_parser_declaration_or_fndef): Handle assume attribute. (c_parser_attribute_arguments): Add assume_attr argument, if true, parse first argument as conditional expression. (c_parser_gnu_attribute, c_parser_std_attribute): Adjust c_parser_attribute_arguments callers. (c_parser_statement_after_labels) : Handle assume attribute. gcc/cp/ * cp-tree.h (process_stmt_assume_attribute): Implement C++23 P1774R8 - Portable assumptions. Declare. (diagnose_failing_condition): Declare. (find_failing_clause): Likewise. * parser.cc (assume_attr): New enumerator. (cp_parser_parenthesized_expression_list): Handle assume_attr. Remove identifier variable, for id_attr push the identifier into expression_list right away instead of inserting it before all the others at the end. (cp_parser_conditional_expression): New function. (cp_parser_constant_expression): Use it. (cp_parser_statement): Handle assume attribute. (cp_parser_expression_statement): Likewise. (cp_parser_gnu_attribute_list): Use assume_attr for assume attribute. (cp_parser_std_attribute): Likewise. Handle standard assume attribute like gnu::assume. * cp-gimplify.cc (process_stmt_assume_attribute): New function. * constexpr.cc: Include fold-const.h. (find_failing_clause_r, find_failing_clause): New functions, moved from semantics.cc with ctx argument added and if non-NULL, call cxx_eval_constant_expression rather than fold_non_dependent_expr. (cxx_eval_internal_function): Handle IFN_ASSUME. (potential_constant_expression_1): Likewise. * pt.cc (tsubst_copy_and_build): Likewise. * semantics.cc (diagnose_failing_condition): New function. (find_failing_clause_r, find_failing_clause): Moved to constexpr.cc. (finish_static_assert): Use it. Add auto_diagnostic_group. gcc/testsuite/ * gcc.dg/attr-assume-1.c: New test. * gcc.dg/attr-assume-2.c: New test. * gcc.dg/attr-assume-3.c: New test. * g++.dg/cpp2a/feat-cxx2a.C: Add colon to C++20 features comment, add C++20 attributes comment and move C++20 new features after the attributes before them. * g++.dg/cpp23/feat-cxx2b.C: Likewise. Test __has_cpp_attribute(assume). * g++.dg/cpp23/attr-assume1.C: New test. * g++.dg/cpp23/attr-assume2.C: New test. * g++.dg/cpp23/attr-assume3.C: New test. * g++.dg/cpp23/attr-assume4.C: New test. --- gcc/testsuite/g++.dg/cpp23/attr-assume1.C | 191 ++++++++++++++++++++++++++++ gcc/testsuite/g++.dg/cpp23/attr-assume2.C | 83 +++++++++++++ gcc/testsuite/g++.dg/cpp23/attr-assume3.C | 198 ++++++++++++++++++++++++++++++ gcc/testsuite/g++.dg/cpp23/attr-assume4.C | 136 ++++++++++++++++++++ gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C | 88 +++++++------ gcc/testsuite/g++.dg/cpp2a/feat-cxx2a.C | 76 ++++++------ gcc/testsuite/gcc.dg/attr-assume-1.c | 69 +++++++++++ gcc/testsuite/gcc.dg/attr-assume-2.c | 66 ++++++++++ gcc/testsuite/gcc.dg/attr-assume-3.c | 35 ++++++ 9 files changed, 868 insertions(+), 74 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp23/attr-assume1.C create mode 100644 gcc/testsuite/g++.dg/cpp23/attr-assume2.C create mode 100644 gcc/testsuite/g++.dg/cpp23/attr-assume3.C create mode 100644 gcc/testsuite/g++.dg/cpp23/attr-assume4.C create mode 100644 gcc/testsuite/gcc.dg/attr-assume-1.c create mode 100644 gcc/testsuite/gcc.dg/attr-assume-2.c create mode 100644 gcc/testsuite/gcc.dg/attr-assume-3.c (limited to 'gcc/testsuite') diff --git a/gcc/testsuite/g++.dg/cpp23/attr-assume1.C b/gcc/testsuite/g++.dg/cpp23/attr-assume1.C new file mode 100644 index 0000000..76b61e9 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/attr-assume1.C @@ -0,0 +1,191 @@ +// P1774R8 - Portable assumptions +// { dg-do run { target c++11 } } + +namespace std +{ + constexpr bool + isfinite (float x) + { return __builtin_isfinite (x); } + + constexpr bool + isfinite (double x) + { return __builtin_isfinite (x); } + + constexpr bool + isfinite (long double x) + { return __builtin_isfinite (x); } + + constexpr float + sqrt (float x) + { return __builtin_sqrtf (x); } + + constexpr double + sqrt (double x) + { return __builtin_sqrt (x); } + + constexpr long double + sqrt (long double x) + { return __builtin_sqrtl (x); } + + extern "C" void + abort (); +} + +constexpr int +f1 (int i) +{ +#if __cpp_constexpr >= 201603L + auto f = [=] { [[assume (i == 0)]]; }; + return sizeof (f); +#else + return sizeof (int); +#endif +} + +void +f2 () +{ + static_assert (f1 (0) >= sizeof (int), ""); +} + +int +f3 (int i) +{ + [[assume (i == 42)]]; + return i; +} + +int +f4 (int i) +{ + [[assume (++i == 44)]]; + return i; +} + +int a; +int *volatile c; + +bool +f5 () +{ + ++a; + return true; +} + +constexpr int +f6 () +{ +#if __cpp_constexpr >= 201304L + [[assume (f5 ())]]; +#endif + return 1; +} + +template +bool +f7 () +{ +#if __cpp_fold_expressions >= 201411L + [[assume (((args >= 0) && ...))]]; + return ((args >= 0) && ...); +#else + return true; +#endif +} + +bool +f8 (double x) +{ + [[assume (std::isfinite (x) && x >= 0.0)]]; + return std::isfinite (std::sqrt (x)); +} + +double +f9 (double x) +{ + [[assume (std::isfinite (std::sqrt (x)))]]; + return std::sqrt (x); +} + +template +T +f10 (T x) +{ + [[assume (x == N)]]; + return x; +} + +int +f11 (int x) +{ + [[assume (x == 93 ? true : throw 1)]]; + return x; +} + +constexpr int +f12 (int x) +{ +#if __cpp_constexpr >= 201304L + [[assume (++x == 43)]]; +#endif + return x; +} + +static_assert (f12 (42) == 42, ""); + +struct S +{ + operator bool () { return true; } +}; + +int +f13 () +{ + S s; + [[assume (s)]]; + return 0; +} + +template +int +f14 () +{ + T t; + [[assume (t)]]; + return 0; +} + +int +main () +{ + int b = 42; + double d = 42.0, e = 43.0; + c = &b; + [[assume (f5 ())]]; + if (a) + std::abort (); + [[assume (++b == 43)]]; + if (b != 42 || *c != 42) + std::abort (); + static_assert (f6 () == 1, ""); + if (f6 () != 1) + std::abort (); + if (a) + std::abort (); + if (!f7 <0> () || !f7 <1, 2, 3, 4> ()) + std::abort (); + [[assume (d < e)]]; + if (f10 (45) != 45 + || f10 (128LL) != 128LL +#if __cpp_nontype_template_args >= 201911L + || f10 (-42.0L) != -42.0L +#endif + || false) + std::abort (); + int i = 90, j = 91, k = 92; + [[assume (i == 90), assume (j <= 91)]] [[assume (k >= 92)]]; + if (f11 (93) != 93) + std::abort (); + if (f14 () != 0) + std::abort (); +} diff --git a/gcc/testsuite/g++.dg/cpp23/attr-assume2.C b/gcc/testsuite/g++.dg/cpp23/attr-assume2.C new file mode 100644 index 0000000..9e54c14 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/attr-assume2.C @@ -0,0 +1,83 @@ +// P1774R8 - Portable assumptions +// { dg-do compile { target c++11 } } + +[[assume (true)]] void f1 (); // { dg-error "'assume' attribute ignored" } +typedef int intx [[assume (true)]]; // { dg-error "'assume' attribute ignored" } +[[assume (true)]]; // { dg-warning "attribute ignored" } + +void +foo () +{ + int i; + [[assume]]; // { dg-error "wrong number of arguments specified for 'assume' attribute" } + // { dg-message "expected 1, found 0" "" { target *-*-* } .-1 } + [[assume ()]]; // { dg-error "parentheses must be omitted if 'assume' attribute argument list is empty" } + // { dg-error "wrong number of arguments specified for 'assume' attribute" "" { target *-*-* } .-1 } + // { dg-message "expected 1, found 0" "" { target *-*-* } .-2 } + [[assume (true, true)]]; // { dg-error "wrong number of arguments specified for 'assume' attribute" } + // { dg-message "expected 1, found 2" "" { target *-*-* } .-1 } + [[assume (true)]] i = 1; // { dg-warning "'assume' attribute not followed by ';'" } + [[assume (throw 1)]]; // { dg-error "expected primary-expression before 'throw'" } + [[assume (i = 1)]]; // { dg-error "expected '\\\)' before '=' token" } +} + +constexpr int +f2 (int x) +{ +#if __cpp_constexpr >= 201304L + [[assume (x == 42)]]; // { dg-error "failed 'assume' attribute assumption" "" { target c++14 } } +#endif // { dg-message "the comparison reduces to '\\\(x == 42\\\)'" "" { target c++14 } .-1 } + return x; +} + +constexpr int a = f2 (44); + +int +f3 (int x) +{ + __asm ("" : "+r" (x)); + return x; +} + +constexpr int +f4 (int x) +{ +#if __cpp_constexpr >= 201304L + [[assume (f3 (42) == 42)]]; +#endif + return x; +} + +static_assert (f4 (42) == 42, ""); + +struct S {}; + +int +f5 () +{ + S s; + [[assume (s)]]; // { dg-error "could not convert 's' from 'S' to 'bool'" } + return 0; +} + +template +int +f6 () +{ + T t; + [[assume (t)]]; // { dg-error "could not convert 't' from 'S' to 'bool'" } + return 0; +} + +int z = f6 (); + +constexpr int +f7 (int x, int y, int z, int w) +{ +#if __cpp_constexpr >= 201304L + [[assume (x == 42 && y == 43 && z == 44 && w == 45)]]; // { dg-error "failed 'assume' attribute assumption" "" { target c++14 } } +#endif // { dg-message "the comparison reduces to '\\\(z == 44\\\)'" "" { target c++14 } .-1 } + return x; +} + +constexpr int w = f7 (42, 43, 45, 44); diff --git a/gcc/testsuite/g++.dg/cpp23/attr-assume3.C b/gcc/testsuite/g++.dg/cpp23/attr-assume3.C new file mode 100644 index 0000000..0be28c7 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/attr-assume3.C @@ -0,0 +1,198 @@ +// P1774R8 - Portable assumptions +// { dg-do run { target c++11 } } + +namespace std +{ + constexpr bool + isfinite (float x) + { return __builtin_isfinite (x); } + + constexpr bool + isfinite (double x) + { return __builtin_isfinite (x); } + + constexpr bool + isfinite (long double x) + { return __builtin_isfinite (x); } + + constexpr float + sqrt (float x) + { return __builtin_sqrtf (x); } + + constexpr double + sqrt (double x) + { return __builtin_sqrt (x); } + + constexpr long double + sqrt (long double x) + { return __builtin_sqrtl (x); } + + extern "C" void + abort (); +} + +constexpr int +f1 (int i) +{ +#if __cpp_constexpr >= 201603L + auto f = [=] { [[__assume__ (i == 0)]]; }; + return sizeof (f); +#else + return sizeof (int); +#endif +} + +void +f2 () +{ + static_assert (f1 (0) >= sizeof (int), ""); +} + +int +f3 (int i) +{ + [[gnu::assume (i == 42)]]; + return i; +} + +int +f4 (int i) +{ + __attribute__ ((assume (++i == 44))); + return i; +} + +int a; +int *volatile c; + +bool +f5 () +{ + ++a; + return true; +} + +constexpr int +f6 () +{ +#if __cpp_constexpr >= 201304L + [[__assume__ (f5 ())]]; +#endif + return 1; +} + +template +bool +f7 () +{ +#if __cpp_fold_expressions >= 201411L + [[__gnu__::__assume__ (((args >= 0) && ...))]]; + return ((args >= 0) && ...); +#else + return true; +#endif +} + +bool +f8 (double x) +{ + [[gnu::assume (std::isfinite (x) && x >= 0.0)]]; + return std::isfinite (std::sqrt (x)); +} + +double +f9 (double x) +{ + __attribute__((assume (std::isfinite (std::sqrt (x))))); + return std::sqrt (x); +} + +template +T +f10 (T x) +{ + [[__assume__ (x == N)]]; + return x; +} + +int +f11 (int x) +{ + [[gnu::assume (x == 93 ? true : throw 1)]]; + return x; +} + +constexpr int +f12 (int x) +{ +#if __cpp_constexpr >= 201304L + __attribute__((assume (++x == 43))); +#endif + return x; +} + +static_assert (f12 (42) == 42, ""); + +struct S +{ + operator bool () { return true; } +}; + +int +f13 () +{ + S s; + [[__gnu__::__assume__ (s)]]; + return 0; +} + +template +int +f14 () +{ + T t; + __attribute__((assume (t))); + return 0; +} + +int +main () +{ + int b = 42; + double d = 42.0, e = 43.0; + c = &b; + [[__assume__ (f5 ())]]; + if (a) + std::abort (); + [[gnu::assume (++b == 43)]]; + if (b != 42 || *c != 42) + std::abort (); + static_assert (f6 () == 1, ""); + if (f6 () != 1) + std::abort (); + if (a) + std::abort (); + if (!f7 <0> () || !f7 <1, 2, 3, 4> ()) + std::abort (); + __attribute__((assume (d < e))); + if (f10 (45) != 45 + || f10 (128LL) != 128LL +#if __cpp_nontype_template_args >= 201911L + || f10 (-42.0L) != -42.0L +#endif + || false) + std::abort (); + int i = 90, j = 91, k = 92; + [[__assume__ (i == 90), gnu::assume (j <= 91)]] +#if __cplusplus >= 201703L + [[using gnu:assume (k >= 92)]] +#else + [[gnu::assume (k >= 92)]] +#endif + ; + __attribute__((__assume__ (i == 90), assume (j <= 91))) __attribute__((assume (k >= 92))); + if (f11 (93) != 93) + std::abort (); + if (f14 () != 0) + std::abort (); +} diff --git a/gcc/testsuite/g++.dg/cpp23/attr-assume4.C b/gcc/testsuite/g++.dg/cpp23/attr-assume4.C new file mode 100644 index 0000000..059d47b --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/attr-assume4.C @@ -0,0 +1,136 @@ +// P1774R8 - Portable assumptions +// { dg-do compile { target c++11 } } + +[[__assume__ (true)]] void f1 (); // { dg-error "'assume' attribute ignored" } +typedef int intx [[__assume__ (true)]]; // { dg-error "'assume' attribute ignored" } +[[__assume__ (true)]]; // { dg-warning "attribute ignored" } +[[gnu::assume (true)]] void f1a (); // { dg-error "'assume' attribute ignored" } +typedef int inty [[gnu::__assume__ (true)]]; // { dg-error "'assume' attribute ignored" } +[[__gnu__::assume (true)]]; // { dg-warning "attribute ignored" } +__attribute__((assume (true))) void f1b (); // { dg-error "'assume' attribute ignored" } +typedef int intz __attribute__((assume (true)));// { dg-error "'assume' attribute ignored" } + +void +foo () +{ + int i; + [[__assume__]]; // { dg-error "wrong number of arguments specified for 'assume' attribute" } + // { dg-message "expected 1, found 0" "" { target *-*-* } .-1 } + [[__assume__ ()]]; // { dg-error "parentheses must be omitted if 'assume' attribute argument list is empty" } + // { dg-error "wrong number of arguments specified for 'assume' attribute" "" { target *-*-* } .-1 } + // { dg-message "expected 1, found 0" "" { target *-*-* } .-2 } + [[__assume__ (true, true)]]; // { dg-error "wrong number of arguments specified for 'assume' attribute" } + // { dg-message "expected 1, found 2" "" { target *-*-* } .-1 } + [[__assume__ (true)]] i = 1; // { dg-warning "'assume' attribute not followed by ';'" } + [[__assume__ (throw 1)]]; // { dg-error "expected primary-expression before 'throw'" } + [[__assume__ (i = 1)]]; // { dg-error "expected '\\\)' before '=' token" } + [[gnu::assume]]; // { dg-error "wrong number of arguments specified for 'assume' attribute" } + // { dg-message "expected 1, found 0" "" { target *-*-* } .-1 } + [[gnu::assume ()]]; // { dg-error "parentheses must be omitted if 'assume' attribute argument list is empty" } + // { dg-error "wrong number of arguments specified for 'assume' attribute" "" { target *-*-* } .-1 } + // { dg-message "expected 1, found 0" "" { target *-*-* } .-2 } + [[gnu::assume (true, true)]]; // { dg-error "wrong number of arguments specified for 'assume' attribute" } + // { dg-message "expected 1, found 2" "" { target *-*-* } .-1 } + [[gnu::assume (true)]] i = 1; // { dg-warning "'assume' attribute not followed by ';'" } + [[gnu::assume (throw 1)]]; // { dg-error "expected primary-expression before 'throw'" } + [[gnu::assume (i = 1)]]; // { dg-error "expected '\\\)' before '=' token" } + __attribute__((assume)); // { dg-error "wrong number of arguments specified for 'assume' attribute" } + // { dg-message "expected 1, found 0" "" { target *-*-* } .-1 } + __attribute__((assume ())); // { dg-error "wrong number of arguments specified for 'assume' attribute" } + // { dg-message "expected 1, found 0" "" { target *-*-* } .-1 } + __attribute__((assume (true, true))); // { dg-error "wrong number of arguments specified for 'assume' attribute" } + // { dg-message "expected 1, found 2" "" { target *-*-* } .-1 } + __attribute__((assume (true))) i = 1; // { dg-warning "'assume' attribute not followed by ';'" } + __attribute__((assume (throw 1))); // { dg-error "expected primary-expression before 'throw'" } + __attribute__((assume (i = 1))); // { dg-error "expected '\\\)' before '=' token" } +} + +constexpr int +f2 (int x) +{ +#if __cpp_constexpr >= 201304L + [[__assume__ (x == 42)]]; // { dg-error "failed 'assume' attribute assumption" "" { target c++14 } } +#endif + return x; +} + +constexpr int +f2a (int x) +{ +#if __cpp_constexpr >= 201304L + [[gnu::__assume__ (x == 42)]]; // { dg-error "failed 'assume' attribute assumption" "" { target c++14 } } +#endif + return x; +} + +constexpr int +f2b (int x) +{ +#if __cpp_constexpr >= 201304L + __attribute__((__assume__ (x == 42)));// { dg-error "failed 'assume' attribute assumption" "" { target c++14 } } +#endif + return x; +} + +constexpr int a = f2 (44); +constexpr int aa = f2a (44); +constexpr int ab = f2b (44); + +int +f3 (int x) +{ + __asm ("" : "+r" (x)); + return x; +} + +constexpr int +f4 (int x) +{ +#if __cpp_constexpr >= 201304L + [[__assume__ (f3 (42) == 42)]]; +#endif + return x; +} + +constexpr int +f4a (int x) +{ +#if __cpp_constexpr >= 201304L + [[gnu::assume (f3 (42) == 42)]]; +#endif + return x; +} + +constexpr int +f4b (int x) +{ +#if __cpp_constexpr >= 201304L + __attribute__((assume (f3 (42) == 42))); +#endif + return x; +} + +static_assert (f4 (42) == 42, ""); +static_assert (f4a (42) == 42, ""); +static_assert (f4b (42) == 42, ""); + +struct S {}; + +int +f5 () +{ + S s; + [[gnu::assume (s)]]; // { dg-error "could not convert 's' from 'S' to 'bool'" } + return 0; +} + +template +int +f6 () +{ + T t; + __attribute__((assume (t))); // { dg-error "could not convert 't' from 'S' to 'bool'" } + return 0; +} + +int z = f6 (); diff --git a/gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C b/gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C index b52cf37..efe9770 100644 --- a/gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C +++ b/gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C @@ -422,7 +422,7 @@ # error "__cpp_nontype_template_parameter_auto != 201606" #endif -// C++20 features +// C++20 features: #ifndef __cpp_conditional_explicit # error "__cpp_conditional_explicit" @@ -460,6 +460,44 @@ # error "__cpp_aggregate_paren_init != 201902" #endif +#ifndef __cpp_char8_t +# error "__cpp_char8_t" +#elif __cpp_char8_t != 202207 +# error "__cpp_char8_t != 202207" +#endif + +#ifndef __cpp_designated_initializers +# error "__cpp_designated_initializers" +#elif __cpp_designated_initializers != 201707 +# error "__cpp_designated_initializers != 201707" +#endif + +#ifndef __cpp_constexpr_in_decltype +# error "__cpp_constexpr_in_decltype" +#elif __cpp_constexpr_in_decltype != 201711 +# error "__cpp_constexpr_in_decltype != 201711" +#endif + +#ifndef __cpp_consteval +# error "__cpp_consteval" +#elif __cpp_consteval != 201811 +# error "__cpp_consteval != 201811" +#endif + +#ifndef __cpp_concepts +# error "__cpp_concepts" +#elif __cpp_concepts != 202002 +# error "__cpp_concepts != 202002" +#endif + +#ifndef __cpp_using_enum +# error "__cpp_using_enum" +#elif __cpp_using_enum != 201907 +# error "__cpp_using_enum != 201907" +#endif + +// C++20 attributes: + #ifdef __has_cpp_attribute # if ! __has_cpp_attribute(maybe_unused) @@ -502,42 +540,6 @@ # error "__has_cpp_attribute" #endif -#ifndef __cpp_char8_t -# error "__cpp_char8_t" -#elif __cpp_char8_t != 202207 -# error "__cpp_char8_t != 202207" -#endif - -#ifndef __cpp_designated_initializers -# error "__cpp_designated_initializers" -#elif __cpp_designated_initializers != 201707 -# error "__cpp_designated_initializers != 201707" -#endif - -#ifndef __cpp_constexpr_in_decltype -# error "__cpp_constexpr_in_decltype" -#elif __cpp_constexpr_in_decltype != 201711 -# error "__cpp_constexpr_in_decltype != 201711" -#endif - -#ifndef __cpp_consteval -# error "__cpp_consteval" -#elif __cpp_consteval != 201811 -# error "__cpp_consteval != 201811" -#endif - -#ifndef __cpp_concepts -# error "__cpp_concepts" -#elif __cpp_concepts != 202002 -# error "__cpp_concepts != 202002" -#endif - -#ifndef __cpp_using_enum -# error "__cpp_using_enum" -#elif __cpp_using_enum != 201907 -# error "__cpp_using_enum != 201907" -#endif - // C++23 features: #ifndef __cpp_size_t_suffix @@ -575,3 +577,15 @@ #elif __cpp_implicit_move != 202207 # error "__cpp_implicit_move != 202207" #endif + +// C++23 attributes: + +#ifdef __has_cpp_attribute +# if ! __has_cpp_attribute(assume) +# error "__has_cpp_attribute(assume)" +# elif __has_cpp_attribute(assume) != 202207 +# error "__has_cpp_attribute(assume) != 202207" +# endif +#else +# error "__has_cpp_attribute" +#endif diff --git a/gcc/testsuite/g++.dg/cpp2a/feat-cxx2a.C b/gcc/testsuite/g++.dg/cpp2a/feat-cxx2a.C index 02f3a37..16bc0b8 100644 --- a/gcc/testsuite/g++.dg/cpp2a/feat-cxx2a.C +++ b/gcc/testsuite/g++.dg/cpp2a/feat-cxx2a.C @@ -422,7 +422,7 @@ # error "__cpp_nontype_template_parameter_auto != 201606" #endif -// C++20 features +// C++20 features: #ifndef __cpp_conditional_explicit # error "__cpp_conditional_explicit" @@ -460,6 +460,44 @@ # error "__cpp_aggregate_paren_init != 201902" #endif +#ifndef __cpp_char8_t +# error "__cpp_char8_t" +#elif __cpp_char8_t != 202207 +# error "__cpp_char8_t != 202207" +#endif + +#ifndef __cpp_designated_initializers +# error "__cpp_designated_initializers" +#elif __cpp_designated_initializers != 201707 +# error "__cpp_designated_initializers != 201707" +#endif + +#ifndef __cpp_constexpr_in_decltype +# error "__cpp_constexpr_in_decltype" +#elif __cpp_constexpr_in_decltype != 201711 +# error "__cpp_constexpr_in_decltype != 201711" +#endif + +#ifndef __cpp_consteval +# error "__cpp_consteval" +#elif __cpp_consteval != 201811 +# error "__cpp_consteval != 201811" +#endif + +#ifndef __cpp_concepts +# error "__cpp_concepts" +#elif __cpp_concepts != 202002 +# error "__cpp_concepts != 202002" +#endif + +#ifndef __cpp_using_enum +# error "__cpp_using_enum" +#elif __cpp_using_enum != 201907 +# error "__cpp_using_enum != 201907" +#endif + +// C++20 attributes: + #ifdef __has_cpp_attribute # if ! __has_cpp_attribute(maybe_unused) @@ -501,39 +539,3 @@ #else # error "__has_cpp_attribute" #endif - -#ifndef __cpp_char8_t -# error "__cpp_char8_t" -#elif __cpp_char8_t != 202207 -# error "__cpp_char8_t != 202207" -#endif - -#ifndef __cpp_designated_initializers -# error "__cpp_designated_initializers" -#elif __cpp_designated_initializers != 201707 -# error "__cpp_designated_initializers != 201707" -#endif - -#ifndef __cpp_constexpr_in_decltype -# error "__cpp_constexpr_in_decltype" -#elif __cpp_constexpr_in_decltype != 201711 -# error "__cpp_constexpr_in_decltype != 201711" -#endif - -#ifndef __cpp_consteval -# error "__cpp_consteval" -#elif __cpp_consteval != 201811 -# error "__cpp_consteval != 201811" -#endif - -#ifndef __cpp_concepts -# error "__cpp_concepts" -#elif __cpp_concepts != 202002 -# error "__cpp_concepts != 202002" -#endif - -#ifndef __cpp_using_enum -# error "__cpp_using_enum" -#elif __cpp_using_enum != 201907 -# error "__cpp_using_enum != 201907" -#endif diff --git a/gcc/testsuite/gcc.dg/attr-assume-1.c b/gcc/testsuite/gcc.dg/attr-assume-1.c new file mode 100644 index 0000000..16e919e --- /dev/null +++ b/gcc/testsuite/gcc.dg/attr-assume-1.c @@ -0,0 +1,69 @@ +/* Portable assumptions */ +/* { dg-do run } */ +/* { dg-options "-std=c2x" } */ + +int +f1 (int i) +{ + [[gnu::assume (i == 42)]]; + return i; +} + +int +f2 (int i) +{ + __attribute__ ((assume (++i == 44))); + return i; +} + +int a; +int *volatile c; + +int +f3 () +{ + ++a; + return 1; +} + +int +f4 (double x) +{ + [[gnu::assume (__builtin_isfinite (x) && x >= 0.0)]]; + return __builtin_isfinite (__builtin_sqrt (x)); +} + +double +f5 (double x) +{ + __attribute__((assume (__builtin_isfinite (__builtin_sqrt (x))))); + return __builtin_sqrt (x); +} + +int +f6 (int x) +{ + [[gnu::assume (x == 93 ? 1 : 0)]]; + return x; +} + +int +main () +{ + int b = 42; + double d = 42.0, e = 43.0; + c = &b; + [[__gnu__::__assume__ (f3 ())]]; + if (a) + __builtin_abort (); + [[gnu::assume (++b == 43)]]; + if (b != 42 || *c != 42) + __builtin_abort (); + __attribute__((assume (d < e))); + int i = 90, j = 91, k = 92; + [[gnu::__assume__ (i == 90), gnu::assume (j <= 91)]] [[gnu::assume (k >= 92)]] + ; + __attribute__((__assume__ (i == 90), assume (j <= 91))) __attribute__((assume (k >= 92))); + if (f6 (93) != 93) + __builtin_abort (); +} diff --git a/gcc/testsuite/gcc.dg/attr-assume-2.c b/gcc/testsuite/gcc.dg/attr-assume-2.c new file mode 100644 index 0000000..aa782e7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/attr-assume-2.c @@ -0,0 +1,66 @@ +/* Portable assumptions */ +/* { dg-do compile } */ +/* { dg-options "-std=c2x" } */ + +[[gnu::__assume__ (1)]] void f1 (void); /* { dg-warning "'assume' attribute not followed by ';'" } */ + /* { dg-warning "'assume' attribute ignored" "" { target *-*-* } .-1 } */ +typedef int intx [[gnu::assume (1)]]; /* { dg-warning "'assume' attribute ignored" } */ +[[__gnu__::assume (1)]]; /* { dg-warning "'assume' attribute at top level" } */ +__attribute__((assume (1))) void f1b ();/* { dg-warning "'assume' attribute not followed by ';'" } */ + /* { dg-warning "'assume' attribute ignored" "" { target *-*-* } .-1 } */ +typedef int inty __attribute__((assume (1))); /* { dg-warning "'assume' attribute ignored" } */ + +void +foo () +{ + int i; + [[gnu::assume]]; /* { dg-error "wrong number of arguments specified for 'assume' attribute" } */ + /* { dg-message "expected 1, found 0" "" { target *-*-* } .-1 } */ + [[gnu::__assume__ ()]]; /* { dg-error "parentheses must be omitted if attribute argument list is empty" } */ + /* { dg-error "wrong number of arguments specified for 'assume' attribute" "" { target *-*-* } .-1 } */ + /* { dg-message "expected 1, found 0" "" { target *-*-* } .-2 } */ + [[gnu::assume (1, 1)]]; /* { dg-error "wrong number of arguments specified for 'assume' attribute" } */ + /* { dg-message "expected 1, found 2" "" { target *-*-* } .-1 } */ + [[gnu::assume (1)]] i = 1; /* { dg-warning "'assume' attribute ignored" } */ + [[gnu::assume (i = 1)]]; /* { dg-error "expected" } */ + /* { dg-warning "'assume' attribute ignored" "" { target *-*-* } .-1 } */ + __attribute__((assume)); /* { dg-error "wrong number of arguments specified for 'assume' attribute" } */ + /* { dg-message "expected 1, found 0" "" { target *-*-* } .-1 } */ + __attribute__((assume ())); /* { dg-error "wrong number of arguments specified for 'assume' attribute" } */ + /* { dg-message "expected 1, found 0" "" { target *-*-* } .-1 } */ + __attribute__((assume (1, 1))); /* { dg-error "wrong number of arguments specified for 'assume' attribute" } */ + /* { dg-message "expected 1, found 2" "" { target *-*-* } .-1 } */ + __attribute__((assume (i = 1))); /* { dg-error "expected" } */ +} + +int +f2 (int x) +{ + __asm ("" : "+r" (x)); + return x; +} + +int +f3 (int x) +{ + [[gnu::assume (f2 (42) == 42)]]; + return x; +} + +int +f3a (int x) +{ + __attribute__((assume (f2 (42) == 42))); + return x; +} + +struct S {}; + +int +f4 () +{ + struct S s; + [[gnu::assume (s)]]; /* { dg-error "used struct type value where scalar is required" } */ + __attribute__((assume (s))); /* { dg-error "used struct type value where scalar is required" } */ + return 0; +} diff --git a/gcc/testsuite/gcc.dg/attr-assume-3.c b/gcc/testsuite/gcc.dg/attr-assume-3.c new file mode 100644 index 0000000..c611a8f --- /dev/null +++ b/gcc/testsuite/gcc.dg/attr-assume-3.c @@ -0,0 +1,35 @@ +/* Portable assumptions */ +/* { dg-do compile } */ +/* { dg-options "-std=c2x" } */ + +void +foo (int x) +{ + if (x == 1) + goto l1; /* { dg-error "jump into statement expression" } */ + else if (x == 2) + goto l2; /* { dg-error "jump into statement expression" } */ + else if (x == 3) + goto l3; /* { dg-error "jump into statement expression" } */ + [[gnu::assume (({ l0:; if (x == 0) goto l0; 1; }))]]; + [[gnu::assume (({ if (x == 0) __builtin_abort (); 1; }))]]; + [[gnu::assume (({ l1:; 1; }))]]; /* { dg-message "label 'l1' defined here" } */ + [[gnu::assume (({ l2:; 1; }))]]; /* { dg-message "label 'l2' defined here" } */ + __attribute__((assume (({ l3:; 1; })))); /* { dg-message "label 'l3' defined here" } */ + [[gnu::assume (({ l4:; 1; }))]]; /* { dg-message "label 'l4' defined here" } */ + [[gnu::assume (({ l5:; 1; }))]]; /* { dg-message "label 'l5' defined here" } */ + __attribute__((assume (({ l6:; 1; })))); /* { dg-message "label 'l6' defined here" } */ + switch (x) /* { dg-message "switch starts here" } */ + { + case 7: + [[gnu::assume (({ case 8:; 1; }))]]; /* { dg-error "switch jumps into statement expression" } */ + __attribute__((assume (({ default:; 1; })))); /* { dg-error "switch jumps into statement expression" } */ + break; + } + if (x == 4) + goto l4; /* { dg-error "jump into statement expression" } */ + else if (x == 5) + goto l5; /* { dg-error "jump into statement expression" } */ + else if (x == 6) + goto l6; /* { dg-error "jump into statement expression" } */ +} -- cgit v1.1 From 847f5addc4d07a2f3b95f5daa50ab4a64dfd957d Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 6 Oct 2022 10:39:41 +0200 Subject: openmp: Map holds clause to IFN_ASSUME for C/C++ Now that [[assume (cond)]] support is in, this simple patch makes #pragma omp assume holds(cond) use it. 2022-10-06 Jakub Jelinek * c-parser.cc (c_parser_omp_assumption_clauses): Emit IFN_ASSUME call for holds clause on assume construct. * parser.cc (cp_parser_omp_assumption_clauses): Emit IFN_ASSUME call for holds clause on assume construct. * c-c++-common/gomp/assume-4.c: New test. --- gcc/testsuite/c-c++-common/gomp/assume-4.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 gcc/testsuite/c-c++-common/gomp/assume-4.c (limited to 'gcc/testsuite') diff --git a/gcc/testsuite/c-c++-common/gomp/assume-4.c b/gcc/testsuite/c-c++-common/gomp/assume-4.c new file mode 100644 index 0000000..9da2296 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/assume-4.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-fopenmp -O2 -fdump-tree-optimized" } */ +/* { dg-final { scan-tree-dump-times "return 42;" 2 "optimized" } } */ +/* { dg-final { scan-tree-dump-not "return -1;" "optimized" } } */ + +int +foo (int x) +{ + int y; + #pragma omp assume holds (x == 42) + y = x; + return y; +} + +int +bar (int x) +{ + #pragma omp assume holds (x < 42) + ; + if (x == 42) + return -1; + return 42; +} -- cgit v1.1 From 85333b9265720fc4e49397301cb16324d2b89aa7 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Thu, 6 Oct 2022 11:20:16 +0200 Subject: tree-optimization/107107 - tail-merging VN wrong-code The following fixes an unintended(?) side-effect of the special MODIFY_EXPR expression entries we add for tail-merging during VN. We shouldn't value-number the virtual operand differently here. PR tree-optimization/107107 * tree-ssa-sccvn.cc (visit_reference_op_store): Do not affect value-numbering when doing the tail merging MODIFY_EXPR lookup. * gcc.dg/pr107107.c: New testcase. --- gcc/testsuite/gcc.dg/pr107107.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr107107.c (limited to 'gcc/testsuite') diff --git a/gcc/testsuite/gcc.dg/pr107107.c b/gcc/testsuite/gcc.dg/pr107107.c new file mode 100644 index 0000000..5ad6a63 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr107107.c @@ -0,0 +1,25 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -ftree-tail-merge" } */ + +static inline void set_longish(int is_long_long, void *p, long x) +{ + if (is_long_long) + *(long long*)p = x; + else + *(long*)p = x; +} +static long test(long long *p, int index, int mode) +{ + *p = 1; + set_longish(mode, p+index, 2); + return *p; +} +long (*volatile vtest)(long long*, int, int) = test; +int main(void) +{ + long long x; + long result = vtest(&x, 0, 1); + if (result != 2 || x != 2) + __builtin_abort (); + return 0; +} -- cgit v1.1 From b1cfbccc41de6aec950c0f662e7e85ab34bfff8a Mon Sep 17 00:00:00 2001 From: Philipp Tomsich Date: Mon, 3 Oct 2022 21:59:50 +0200 Subject: aarch64: fix off-by-one in reading cpuinfo Fixes: 341573406b39 Don't subtract one from the result of strnlen() when trying to point to the first character after the current string. This issue would cause individual characters (where the 128 byte buffers are stitched together) to be lost. gcc/ChangeLog: * config/aarch64/driver-aarch64.cc (readline): Fix off-by-one. gcc/testsuite/ChangeLog: * gcc.target/aarch64/cpunative/info_18: New test. * gcc.target/aarch64/cpunative/native_cpu_18.c: New test. Signed-off-by: Philipp Tomsich --- gcc/testsuite/gcc.target/aarch64/cpunative/info_18 | 8 ++++++++ .../gcc.target/aarch64/cpunative/native_cpu_18.c | 15 +++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 gcc/testsuite/gcc.target/aarch64/cpunative/info_18 create mode 100644 gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_18.c (limited to 'gcc/testsuite') diff --git a/gcc/testsuite/gcc.target/aarch64/cpunative/info_18 b/gcc/testsuite/gcc.target/aarch64/cpunative/info_18 new file mode 100644 index 0000000..25061a4 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/cpunative/info_18 @@ -0,0 +1,8 @@ +processor : 0 +BogoMIPS : 2000.00 +Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma lrcpc dcpop sha3 asimddp sha512 asimdfhm dit uscat ilrcpc flagm ssbs sb dcpodp flagm2 frint i8mm bf16 rng ecv +CPU implementer : 0xc0 +CPU architecture: 8 +CPU variant : 0x0 +CPU part : 0xac3 +CPU revision : 0 diff --git a/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_18.c b/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_18.c new file mode 100644 index 0000000..b5f0a30 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_18.c @@ -0,0 +1,15 @@ +/* { dg-do compile { target { { aarch64*-*-linux*} && native } } } */ +/* { dg-set-compiler-env-var GCC_CPUINFO "$srcdir/gcc.target/aarch64/cpunative/info_18" } */ +/* { dg-additional-options "-mcpu=native" } */ + +int main() +{ + return 0; +} + +/* { dg-final { scan-assembler {\.arch armv8.6-a\+crc\+fp16\+aes\+sha3\+rng} } } */ + +/* Test one where the boundary of buffer size would overwrite the last + character read when stitching the fgets-calls together. With the + test data provided, this would truncate the 'sha512' into 'ha512' + (dropping the 'sha3' feature). */ -- cgit v1.1 From badd1ac23d24664b2258b1db4d49f37a3f60ccca Mon Sep 17 00:00:00 2001 From: Kyrylo Tkachov Date: Thu, 6 Oct 2022 12:08:40 +0100 Subject: aarch64: Add test for LDAR generation from __atomic_load_n I'd like a test to check the generation of LDAR for atomic_load_n. No new functionality added. gcc/testsuite/ChangeLog: * gcc.target/aarch64/ldar_1.c: New test. --- gcc/testsuite/gcc.target/aarch64/ldar_1.c | 66 +++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 gcc/testsuite/gcc.target/aarch64/ldar_1.c (limited to 'gcc/testsuite') diff --git a/gcc/testsuite/gcc.target/aarch64/ldar_1.c b/gcc/testsuite/gcc.target/aarch64/ldar_1.c new file mode 100644 index 0000000..d968a72 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/ldar_1.c @@ -0,0 +1,66 @@ +/* Test the LDAR instruction generation from atomic acquire loads. */ +/* { dg-do assemble } */ +/* { dg-additional-options "--save-temps -O1" } */ +/* { dg-final { check-function-bodies "**" "" "" } } */ + +#include + +#pragma GCC target "+norcpc" + +uint8_t v_uint8_t; +uint16_t v_uint16_t; +uint32_t v_uint32_t; +uint64_t v_uint64_t; + +/* +** load_uint8_t: +** ... +** ldarb w0, \[x[0-9]+\] +** ret +*/ + +uint8_t +load_uint8_t (void) +{ + return __atomic_load_n (&v_uint8_t, __ATOMIC_ACQUIRE); +} + +/* +** load_uint16_t: +** ... +** ldarh w0, \[x[0-9]+\] +** ret +*/ + +uint16_t +load_uint16_t (void) +{ + return __atomic_load_n (&v_uint16_t, __ATOMIC_ACQUIRE); +} + +/* +** load_uint32_t: +** ... +** ldar w0, \[x[0-9]+\] +** ret +*/ + +uint32_t +load_uint32_t (void) +{ + return __atomic_load_n (&v_uint32_t, __ATOMIC_ACQUIRE); +} + +/* +** load_uint64_t: +** ... +** ldar x0, \[x[0-9]+\] +** ret +*/ + +uint64_t +load_uint64_t (void) +{ + return __atomic_load_n (&v_uint64_t, __ATOMIC_ACQUIRE); +} + -- cgit v1.1 From 33b93ac3f2fb68a2da0d42fd692fe59533f7a84f Mon Sep 17 00:00:00 2001 From: Kyrylo Tkachov Date: Thu, 6 Oct 2022 12:09:28 +0100 Subject: aarch64: Remove redundant zero-extends with LDAR Like other loads in AArch64, the LDARB,LDARH,LDAR instructions clear out the top part of their destination register and we can thus avoid having to explicitly zero-extend it. We were missing a combine pattern that this patch adds. For one of the examples in the testcase we generated: load_uint8_t_ext_uint16_t: adrp x0, .LANCHOR0 add x0, x0, :lo12:.LANCHOR0 ldarb w0, [x0] and w0, w0, 255 ret but now generate: load_uint8_t_ext_uint16_t: adrp x0, .LANCHOR0 add x0, x0, :lo12:.LANCHOR0 ldarb w0, [x0] ret Bootstrapped and tested on aarch64-none-linux-gnu. gcc/ChangeLog: * config/aarch64/atomics.md (*atomic_load_zext): New pattern. gcc/testsuite/ChangeLog: * gcc.target/aarch64/ldar_2.c: New test. --- gcc/testsuite/gcc.target/aarch64/ldar_2.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 gcc/testsuite/gcc.target/aarch64/ldar_2.c (limited to 'gcc/testsuite') diff --git a/gcc/testsuite/gcc.target/aarch64/ldar_2.c b/gcc/testsuite/gcc.target/aarch64/ldar_2.c new file mode 100644 index 0000000..60b0717 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/ldar_2.c @@ -0,0 +1,27 @@ +/* Test that the zero-extending patterns for LDAR are used. */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +#include + +uint8_t v_uint8_t; +uint16_t v_uint16_t; +uint32_t v_uint32_t; +uint64_t v_uint64_t; + +#define FUNC(FROM, TO) \ +TO \ +load_##FROM##_ext_##TO (void) \ +{ \ + return __atomic_load_n (&v_##FROM, __ATOMIC_ACQUIRE); \ +} + +FUNC (uint8_t, uint16_t) +FUNC (uint8_t, uint32_t) +FUNC (uint8_t, uint64_t) +FUNC (uint16_t, uint32_t) +FUNC (uint16_t, uint64_t) +FUNC (uint32_t, uint64_t) + +/* { dg-final { scan-assembler-not {and\tw[0-9+], w[0-9]+, 255} } } */ +/* { dg-final { scan-assembler-not {uxtw\tx[0-9+], w[0-9]+} } } */ -- cgit v1.1 From 0af8d957d5911fc7659b4174cfc2213289bbed23 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Thu, 6 Oct 2022 11:48:03 +0200 Subject: middle-end/107115 - avoid bogus redundant store removal during RTL expansion The following preserves the (premature) redundant store removal done in store_expr by appropriately guarding it with mems_same_for_tbaa_p. The testcase added needs scheduling disabled for now since there's a similar bug there still present. PR middle-end/107115 * expr.cc (store_expr): Check mems_same_for_tbaa_p before eliding a seemingly redundant store. * gcc.dg/torture/pr107115.c: New testcase. --- gcc/testsuite/gcc.dg/torture/pr107115.c | 37 +++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/torture/pr107115.c (limited to 'gcc/testsuite') diff --git a/gcc/testsuite/gcc.dg/torture/pr107115.c b/gcc/testsuite/gcc.dg/torture/pr107115.c new file mode 100644 index 0000000..5f7b6ff --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr107115.c @@ -0,0 +1,37 @@ +/* { dg-do run } */ +/* PR/107115 */ +/* { dg-additional-options "-fno-schedule-insns -fno-schedule-insns2" } */ + +#include + +void test1(long *p1) +{ + p1[0] = 1; +} +long test2(long long *p2, int index1, int index2) +{ + p2[index1] = 2; + return p2[index2]; +} +long test3(long *p3, int index2, long value) +{ + p3[index2] = 3; + p3[index2] = value; + return p3[0]; +} +long test4(void *p4, int index1, int index2) +{ + test1(p4); + long temp = test2(p4, index1, index2); + return test3(p4, index2, temp); +} +long (*volatile vtest)(void *, int, int) = test4; +int main(void) +{ + void *pp = malloc(sizeof (long) + sizeof(long long)); + if (!pp) abort(); + long result = vtest(pp, 0, 0); + if (*(long *)pp != 2 || result != 2) + __builtin_abort (); + return 0; +} -- cgit v1.1 From 3ec926d36fbf7cb3ff45759471139f3a71d1c4de Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Thu, 6 Oct 2022 15:13:50 +0200 Subject: Fix wrong code generated by unroll-and-jam pass There is a loophole in the unroll-and-jam pass that can quickly result in wrong code generation. The code reads: if (!compute_data_dependences_for_loop (outer, true, &loop_nest, &datarefs, &dependences)) { if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "Cannot analyze data dependencies\n"); free_data_refs (datarefs); free_dependence_relations (dependences); continue; } but compute_data_dependences_for_loop may return true even if the analysis is reported as failing by compute_affine_dependence for a dependence pair: (compute_affine_dependence ref_a: data[_14], stmt_a: data[_14] = i_59; ref_b: data[_14], stmt_b: data[_14] = i_59; Data ref a: Data ref b: affine dependence test not usable: access function not affine or constant. ) -> dependence analysis failed Note that this is a self-dependence pair and the code for them reads: /* Nothing interesting for the self dependencies. */ if (dra == drb) continue; This means that the pass may reorder "complex" accesses to the same memory location in successive iterations, which is OK for reads but not for writes. gcc/ * gimple-loop-jam.cc (tree_loop_unroll_and_jam): Bail out for a self dependency that is a write-after-write if the access function is not affine or constant. gcc/testsuite/ * gcc.c-torture/execute/20221006-1.c: New test. --- gcc/testsuite/gcc.c-torture/execute/20221006-1.c | 29 ++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 gcc/testsuite/gcc.c-torture/execute/20221006-1.c (limited to 'gcc/testsuite') diff --git a/gcc/testsuite/gcc.c-torture/execute/20221006-1.c b/gcc/testsuite/gcc.c-torture/execute/20221006-1.c new file mode 100644 index 0000000..80deb3a --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/20221006-1.c @@ -0,0 +1,29 @@ +#include + +int +main (int argc, char** argv) +{ + const int len = argc == 2 ? atoi(argv[1]) : 4; + + int count; + int data[64]; + int M1[len][len]; + int M2[len][len]; + + for (int i = 0; i < len; i++) + for (int j = 0 ; j < len ; j++) + M1[i][j] = M2[i][j] = i*len + j; + + M2[1][0] = M2[0][1]; + + /* This writes successively 0 and 1 into data[M2[0][1]]. */ + for (int i = 0; i < len - 1; i++) + for (int j = 0 ; j < len ; j++) + if (M1[i+1][j] > M1[i][j]) + data[M2[i][j]] = i; + + if (data [M2[0][1]] != 1) + abort (); + + return 0; +} -- cgit v1.1 From 09df0d8b14dda66c5159a1b2cf85b73f26282152 Mon Sep 17 00:00:00 2001 From: Patrick Palka Date: Thu, 6 Oct 2022 10:04:52 -0400 Subject: c++: remove optimize_specialization_lookup_p Roughly speaking, optimize_specialization_lookup_p returns true for a non-template member function of a class template, e.g. template struct A { int f(); }; The idea behind the optimization guarded by this predicate is that if we want to look up the specialization A::f [with T=int], then we can just do a name lookup for f in A and avoid having to add a spec_entry for f in the decl_specializations table. But the benefit of this optimization seems questionable because in order to do the name lookup we first need to look up A [with T=int] in the type_specializations table, which is as expensive as the decl_specializations lookup we're avoiding. And according to some experiments (using stdc++.h, range-v3 and libstdc++ tests) the compiler is slightly (<1%) _faster_ if we disable this optimization. Additionally, this optimization means we won't record an explicit specialization in decl_specializations for such a template either, which is an unfortunate inconsistency that apparently breaks the below modules testcase. So since this optimization doesn't improve performance, and complicates the explicit specialization story which causes issues with modules, this patch proposes to remove it. gcc/cp/ChangeLog: * pt.cc (optimize_specialization_lookup_p): Remove. (retrieve_specialization): Assume the above returns false and simplify accordingly. (register_specialization): Likewise. gcc/testsuite/ChangeLog: * g++.dg/modules/indirect-3_b.C: Expect that the entity foo::TPL<0>::frob is tagged as a specialization instead of as a declaration. * g++.dg/modules/tpl-spec-8_a.H: New test. * g++.dg/modules/tpl-spec-8_b.C: New test. --- gcc/testsuite/g++.dg/modules/indirect-3_b.C | 2 +- gcc/testsuite/g++.dg/modules/tpl-spec-8_a.H | 10 ++++++++++ gcc/testsuite/g++.dg/modules/tpl-spec-8_b.C | 8 ++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/modules/tpl-spec-8_a.H create mode 100644 gcc/testsuite/g++.dg/modules/tpl-spec-8_b.C (limited to 'gcc/testsuite') diff --git a/gcc/testsuite/g++.dg/modules/indirect-3_b.C b/gcc/testsuite/g++.dg/modules/indirect-3_b.C index 5bdfc1d..038b01e 100644 --- a/gcc/testsuite/g++.dg/modules/indirect-3_b.C +++ b/gcc/testsuite/g++.dg/modules/indirect-3_b.C @@ -23,7 +23,7 @@ namespace bar // { dg-final { scan-lang-dump {Lazily binding '::foo@foo:.::TPL'@'foo' section} module } } // { dg-final { scan-lang-dump {Wrote import:-[0-9]* template_decl:'::foo@foo:.::template TPL@foo:.'@foo} module } } -// { dg-final { scan-lang-dump {Cluster members:\n \[0\]=specialization definition '::foo@foo:.::TPL<0x0>'\n \[1\]=specialization declaration '::foo@foo:.::TPL<0x0>::TPL<0x0>'\n( \[.\]=[^\n]* '\n)* \[.\]=decl definition '::foo@foo:.::TPL<0x0>::frob<0x0>'\n} module } } +// { dg-final { scan-lang-dump {Cluster members:\n \[0\]=specialization definition '::foo@foo:.::TPL<0x0>'\n \[1\]=specialization definition '::foo@foo:.::TPL<0x0>::frob<0x0>'\n \[2\]=specialization declaration '::foo@foo:.::TPL<0x0>::TPL<0x0>'} module } } // { dg-final { scan-lang-dump {Cluster members:\n \[0\]=specialization definition '::foo@foo:.::X@foo:.::frob<0x0>'} module } } // { dg-final { scan-lang-dump {Writing:-[0-9]*'s type spec merge key \(specialization\) type_decl:'::foo@foo:.::TPL<0x0>'} module } } diff --git a/gcc/testsuite/g++.dg/modules/tpl-spec-8_a.H b/gcc/testsuite/g++.dg/modules/tpl-spec-8_a.H new file mode 100644 index 0000000..5309130 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/tpl-spec-8_a.H @@ -0,0 +1,10 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +template +struct A { + static void f() { T::nonexistent; } +}; + +template<> +inline void A::f() { } diff --git a/gcc/testsuite/g++.dg/modules/tpl-spec-8_b.C b/gcc/testsuite/g++.dg/modules/tpl-spec-8_b.C new file mode 100644 index 0000000..f23eb37 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/tpl-spec-8_b.C @@ -0,0 +1,8 @@ +// { dg-additional-options -fmodules-ts } +// { dg-do link } + +import "tpl-spec-8_a.H"; + +int main() { + A::f(); +} -- cgit v1.1 From fa258f6894801aef6785f0327594dc803da63fbd Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Thu, 6 Oct 2022 14:26:21 +0000 Subject: c: C2x typeof C2x adds typeof as a standard feature. In general this follows existing GNU C semantics very closely, but there are various ways in which the implementation involves more than simply enabling the keyword for C2x: * As well as typeof, there is a typeof_unqual variant, which removes all qualifiers and _Atomic from the resulting type (whereas typeof preserves qualifiers and _Atomic on qualified or atomic (lvalue or type name) operands). * The typeof keyword is disabled by -fno-asm, so enabling it for C2x needs to be implemented in a way that preserves the disabling by -fno-asm for older standard versions (which having -fno-asm having no effect on it in C2x mode). This is done via adding a new D_EXT11 mask (which is also where the C++ front-end change comes from, to handle D_EXT11 appropriately there for -fno-asm and -fno-gnu-keywords). * GNU typeof treats the noreturn property of a function (as specified in standard C with _Noreturn or [[noreturn]]) as being part of the type of a pointer to function, but it is not part of the type in standard terms. Thus a special case is needed in the typeof implementation, just like in the _Generic implementation, to avoid treating it as a type for standard typeof. It seems plausible this is being used when copying the type of one object to another using typeof, so the existing semantics are preserved for __typeof__, and for typeof in pre-C2x modes, while typeof for C2x or later has the standard semantics. * It turns out that, even after Martin Uecker's changes in this area, there were still cases where rvalues could wrongly have a qualified or atomic type in GCC. This applied to ++ and -- increment and decrement expressions, and also to calls to functions returning an atomic type. (For the latter, the working draft doesn't actually explicitly exclude the function call expression having an atomic type, but given all the changes that have gone into C17 and C2x to avoid rvalues ever having qualified types, and given that lvalue-to-rvalue conversion removes both qualifiers and _Atomic, it seems unlikely that this (or casts, where GCC already removes _Atomic) is actually intended as a route to allow an _Atomic-qualified rvalue; I've noted this to raise as an NB comment on the CD ballot.) Bootstrapped with no regressions for x86_64-pc-linux-gnu. OK to commit (C+ gcc/ * doc/invoke.texi (-fno-asm): Update description of effects on typeof keyword. gcc/c-family/ * c-common.cc (c_common_reswords): Mark typeof as D_EXT11. Add typeof_unqual. * c-common.h (enum rid): Add RID_TYPEOF_UNQUAL. (D_EXT11): New macro. Values of subsequent macros updated. gcc/c/ * c-parser.cc (c_parse_init): Add D_EXT11 to mask if flag_no_asm and not C2x. (c_keyword_starts_typename, c_token_starts_declspecs) (c_parser_declspecs, c_parser_objc_selector): Handle RID_TYPEOF_UNQUAL. (c_parser_typeof_specifier): Handle RID_TYPEOF_UNQUAL. Distinguish typeof for C2x from __typeof__ for all standard versions and typeof before C2x. * c-typeck.cc (build_function_call_vec): Use unqualified version of non-void return type. (build_unary_op): Use unqualified type for increment and decrement. gcc/cp/ * lex.cc (init_reswords): Handle D_EXT11. gcc/testsuite/ * gcc.dg/c11-typeof-1.c, gcc.dg/c2x-typeof-1.c, gcc.dg/c2x-typeof-2.c, gcc.dg/c2x-typeof-3.c, gcc.dg/gnu11-typeof-1.c, gcc.dg/gnu11-typeof-2.c, gcc.dg/gnu2x-typeof-1.c: New tests. --- gcc/testsuite/gcc.dg/c11-typeof-1.c | 6 + gcc/testsuite/gcc.dg/c2x-typeof-1.c | 208 ++++++++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/c2x-typeof-2.c | 27 +++++ gcc/testsuite/gcc.dg/c2x-typeof-3.c | 7 ++ gcc/testsuite/gcc.dg/gnu11-typeof-1.c | 6 + gcc/testsuite/gcc.dg/gnu11-typeof-2.c | 39 +++++++ gcc/testsuite/gcc.dg/gnu2x-typeof-1.c | 39 +++++++ 7 files changed, 332 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/c11-typeof-1.c create mode 100644 gcc/testsuite/gcc.dg/c2x-typeof-1.c create mode 100644 gcc/testsuite/gcc.dg/c2x-typeof-2.c create mode 100644 gcc/testsuite/gcc.dg/c2x-typeof-3.c create mode 100644 gcc/testsuite/gcc.dg/gnu11-typeof-1.c create mode 100644 gcc/testsuite/gcc.dg/gnu11-typeof-2.c create mode 100644 gcc/testsuite/gcc.dg/gnu2x-typeof-1.c (limited to 'gcc/testsuite') diff --git a/gcc/testsuite/gcc.dg/c11-typeof-1.c b/gcc/testsuite/gcc.dg/c11-typeof-1.c new file mode 100644 index 0000000..a2abe8e --- /dev/null +++ b/gcc/testsuite/gcc.dg/c11-typeof-1.c @@ -0,0 +1,6 @@ +/* Test typeof and typeof_unqual not keywords in C11. */ +/* { dg-do compile } */ +/* { dg-options "-std=c11 -pedantic-errors" } */ + +int typeof = 1; +long typeof_unqual = 2; diff --git a/gcc/testsuite/gcc.dg/c2x-typeof-1.c b/gcc/testsuite/gcc.dg/c2x-typeof-1.c new file mode 100644 index 0000000..0b721fe --- /dev/null +++ b/gcc/testsuite/gcc.dg/c2x-typeof-1.c @@ -0,0 +1,208 @@ +/* Test C2x typeof and typeof_unqual. Valid code. */ +/* { dg-do run } */ +/* { dg-options "-std=c2x -pedantic-errors" } */ + +int i; +extern typeof (i) i; +extern typeof (int) i; +extern typeof_unqual (i) i; +extern typeof_unqual (int) i; + +volatile int vi; +extern typeof (volatile int) vi; +extern typeof (vi) vi; + +extern typeof_unqual (volatile int) i; +extern typeof_unqual (vi) i; +extern typeof ((const int) vi) i; +extern typeof ((volatile int) vi) i; + +const int ci; +extern typeof (const int) ci; +extern typeof (ci) ci; + +extern typeof_unqual (const int) i; +extern typeof_unqual (ci) i; +extern typeof ((const int) ci) i; +extern typeof (+ci) i; +extern typeof (0, ci) i; +extern typeof (1 ? ci : ci) i; +extern typeof (0) i; + +const int fci (void); +extern typeof (fci ()) i; + +_Atomic int ai; +extern typeof (_Atomic int) ai; +extern typeof (_Atomic (int)) ai; +extern typeof (ai) ai; + +extern typeof_unqual (_Atomic int) i; +extern typeof_unqual (_Atomic (int)) i; +extern typeof_unqual (ai) i; +extern typeof (+ai) i; +extern typeof ((_Atomic int) ai) i; +extern typeof (0, ai) i; +extern typeof (1 ? ai : ai) i; + +_Atomic int fai (void); +extern typeof (fai ()) i; + +_Atomic const volatile int acvi; +extern typeof (int volatile const _Atomic) acvi; +extern typeof (acvi) acvi; +extern const _Atomic volatile typeof (acvi) acvi; +extern _Atomic volatile typeof (ci) acvi; +extern _Atomic const typeof (vi) acvi; +extern const typeof (ai) volatile acvi; + +extern typeof_unqual (acvi) i; +extern typeof_unqual (typeof (acvi)) i; +extern typeof_unqual (_Atomic typeof_unqual (acvi)) i; + +extern _Atomic typeof_unqual (acvi) ai; + +char c; +volatile char vc; +volatile char *pvc; +volatile char *const cpvc; +const char *pcc; +const char *volatile vpcc; +typeof (*vpcc) cc; + +extern typeof (*cpvc) vc; +extern typeof_unqual (*cpvc) c; +extern typeof_unqual (cpvc) pvc; +extern typeof_unqual (vpcc) pcc; +extern const char cc; + +extern typeof (++vi) i; +extern typeof (++ai) i; +extern typeof (--vi) i; +extern typeof (--ai) i; +extern typeof (vi++) i; +extern typeof (ai++) i; +extern typeof (vi--) i; +extern typeof (ai--) i; + +bool b; +volatile bool vb; +_Atomic bool ab; +extern typeof (++vb) b; +extern typeof (++ab) b; +extern typeof (--vb) b; +extern typeof (--ab) b; +extern typeof (vb++) b; +extern typeof (ab++) b; +extern typeof (vb--) b; +extern typeof (ab--) b; + +extern typeof (vc = 1) c; +extern typeof (vpcc = 0) pcc; +extern typeof (ai *= 2) i; + +int s = sizeof (typeof (int (*)[++i])); + +void *vp; + +/* The non-returning property of a function is not part of the type given by + ISO C typeof. */ +_Noreturn void nf1 (void); +[[noreturn]] void nf2 (void); +void fg (void) {} +typeof (&nf1) pnf1 = fg; +typeof (&nf2) pnf2 = fg; +extern void (*pnf1) (void); +extern void (*pnf2) (void); +extern typeof (nf1) *pnf1; +extern typeof (nf1) *pnf2; +extern typeof (nf2) *pnf1; +extern typeof (nf2) *pnf2; +typeof (*&nf1) fg2, fg2a, fg2b; +typeof (*&nf2) fg3, fg3a, fg3b; +typeof (nf1) fg4, fg4a, fg4b; +typeof (nf2) fg5, fg5a, fg5b; + +extern void abort (void); +extern void exit (int); + +void fg2 (void) {} +_Noreturn void fg2a (void) { abort (); } +[[noreturn]] void fg2b (void) { abort (); } +void fg3 (void) {} +_Noreturn void fg3a (void) { abort (); } +[[noreturn]] void fg3b (void) { abort (); } +void fg4 (void) {} +_Noreturn void fg4a (void) { abort (); } +[[noreturn]] void fg4b (void) { abort (); } +void fg5 (void) {} +_Noreturn void fg5a (void) { abort (); } +[[noreturn]] void fg5b (void) { abort (); } + +extern int only_used_in_typeof; + +static int not_defined (void); + +typeof (i) +main (typeof (*vp)) +{ + volatile typeof (only_used_in_typeof) ii = 2; + if (ii != 2) + abort (); + const typeof (not_defined ()) jj = 3; + if (jj != 3) + abort (); + unsigned int u = 1; + typeof (u) u2 = 0; + typeof (int (*)[++u2]) p = 0; + if (u2 != 1) + abort (); + if (sizeof (*p) != sizeof (int)) + abort (); + typeof_unqual (int (*)[++u2]) q = 0; + if (u2 != 2) + abort (); + if (sizeof (*q) != 2 * sizeof (int)) + abort (); + if (sizeof (*p) != sizeof (int)) + abort (); + typeof (++u2) u3 = 1; + if (u2 != u + u3) + abort (); + typeof_unqual (++u2) u4 = 2; + if (u2 != u4) + abort (); + u = sizeof (typeof (int (*)[++u2])); + if (u2 != 2) + abort (); + u = sizeof (typeof_unqual (int (*)[++u2])); + if (u2 != 2) + abort (); + typeof ((int (*)[++u2]) 0) q2; + if (u2 != 3) + abort (); + typeof ((void) 0, (int (*)[++u2]) 0) q3; + if (u2 != 4) + abort (); + typeof ((int (*)[++u2]) 0, 0) q4; + if (u2 != 4) + abort (); + typeof_unqual ((int (*)[++u2]) 0) q5; + if (u2 != 5) + abort (); + typeof_unqual ((void) 0, (int (*)[++u2]) 0) q6; + if (u2 != 6) + abort (); + typeof_unqual ((int (*)[++u2]) 0, 0) q7; + if (u2 != 6) + abort (); + int a1[6], a2[6]; + int (*pa)[u2] = &a1; + typeof (pa = &a2) pp; + if (pa != &a2) + abort (); + typeof_unqual (pa = &a1) pp2; + if (pa != &a1) + abort (); + exit (0); +} diff --git a/gcc/testsuite/gcc.dg/c2x-typeof-2.c b/gcc/testsuite/gcc.dg/c2x-typeof-2.c new file mode 100644 index 0000000..f1c30a0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c2x-typeof-2.c @@ -0,0 +1,27 @@ +/* Test C2x typeof and typeof_unqual. Invalid code. */ +/* { dg-do compile } */ +/* { dg-options "-std=c2x -pedantic-errors" } */ + +struct s { int i : 2; } x; +union u { unsigned int j : 1; } y; + +typeof (x.i) j; /* { dg-error "applied to a bit-field" } */ +typeof_unqual (x.i) j2; /* { dg-error "applied to a bit-field" } */ +typeof (y.j) j3; /* { dg-error "applied to a bit-field" } */ +typeof_unqual (y.j) j4; /* { dg-error "applied to a bit-field" } */ + +static int ok (void); +static int also_ok (void); +static int not_defined (void); /* { dg-error "used but never defined" } */ +static int also_not_defined (void); /* { dg-error "used but never defined" } */ + +void +f (void) +{ + typeof (ok ()) x = 2; + typeof_unqual (also_ok ()) y = 2; + int a[2]; + int (*p)[x] = &a; + typeof (p + not_defined ()) q; + typeof_unqual (p + also_not_defined ()) q2; +} diff --git a/gcc/testsuite/gcc.dg/c2x-typeof-3.c b/gcc/testsuite/gcc.dg/c2x-typeof-3.c new file mode 100644 index 0000000..c7a0577 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c2x-typeof-3.c @@ -0,0 +1,7 @@ +/* Test C2x typeof and typeof_unqual. -fno-asm has no effect on keywords in + C2x mode. */ +/* { dg-do compile } */ +/* { dg-options "-std=c2x -pedantic-errors -fno-asm" } */ + +int i; +extern typeof (i) i; diff --git a/gcc/testsuite/gcc.dg/gnu11-typeof-1.c b/gcc/testsuite/gcc.dg/gnu11-typeof-1.c new file mode 100644 index 0000000..6477c78 --- /dev/null +++ b/gcc/testsuite/gcc.dg/gnu11-typeof-1.c @@ -0,0 +1,6 @@ +/* Test typeof and typeof_unqual not keywords with -std=gnu11 -fno-asm. */ +/* { dg-do compile } */ +/* { dg-options "-std=gnu11 -fno-asm" } */ + +int typeof = 1; +long typeof_unqual = 2; diff --git a/gcc/testsuite/gcc.dg/gnu11-typeof-2.c b/gcc/testsuite/gcc.dg/gnu11-typeof-2.c new file mode 100644 index 0000000..e60ad46 --- /dev/null +++ b/gcc/testsuite/gcc.dg/gnu11-typeof-2.c @@ -0,0 +1,39 @@ +/* Test typeof propagation of noreturn function attributes with -std=gnu11: + these are part of the type of a function pointer with GNU typeof, but not + with C2x typeof. */ +/* { dg-do link } */ +/* { dg-options "-std=gnu11 -O2" } */ + +_Noreturn void f (void); + +typeof (&f) volatile p; +typeof (&p) volatile pp; + +void link_failure (void); + +void +g (void) +{ + (*p) (); + link_failure (); +} + +void +h (void) +{ + (**pp) (); + link_failure (); +} + +volatile int flag; +volatile int x; + +int +main (void) +{ + if (flag) + g (); + if (flag) + h (); + return x; +} diff --git a/gcc/testsuite/gcc.dg/gnu2x-typeof-1.c b/gcc/testsuite/gcc.dg/gnu2x-typeof-1.c new file mode 100644 index 0000000..f14b54f --- /dev/null +++ b/gcc/testsuite/gcc.dg/gnu2x-typeof-1.c @@ -0,0 +1,39 @@ +/* Test __typeof__ propagation of noreturn function attributes with -std=gnu2x: + these are part of the type of a function pointer with GNU __typeof__, but + not with C2x typeof. */ +/* { dg-do link } */ +/* { dg-options "-std=gnu2x -O2" } */ + +_Noreturn void f (void); + +__typeof__ (&f) volatile p; +__typeof__ (&p) volatile pp; + +void link_failure (void); + +void +g (void) +{ + (*p) (); + link_failure (); +} + +void +h (void) +{ + (**pp) (); + link_failure (); +} + +volatile int flag; +volatile int x; + +int +main (void) +{ + if (flag) + g (); + if (flag) + h (); + return x; +} -- cgit v1.1 From 50c35c691517291dbb77b1661761bc59950ba101 Mon Sep 17 00:00:00 2001 From: Tobias Burnus Date: Thu, 6 Oct 2022 18:42:32 +0200 Subject: openmp: Map holds clause to IFN_ASSUME for Fortran Same as r13-3107-g847f5addc4d07a2f3b95f5daa50ab4a64dfd957d did for C/C++. Convert '!$omp assume holds(cond)' to IFN_ASSUME (cond). gcc/fortran/ * trans-openmp.cc (gfc_trans_omp_assume): New. (gfc_trans_omp_directive): Call it. gcc/testsuite/ * gfortran.dg/gomp/assume-3.f90: New test. * gfortran.dg/gomp/assume-4.f90: New test. --- gcc/testsuite/gfortran.dg/gomp/assume-3.f90 | 46 ++++++++++++++++++++++++++ gcc/testsuite/gfortran.dg/gomp/assume-4.f90 | 50 +++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 gcc/testsuite/gfortran.dg/gomp/assume-3.f90 create mode 100644 gcc/testsuite/gfortran.dg/gomp/assume-4.f90 (limited to 'gcc/testsuite') diff --git a/gcc/testsuite/gfortran.dg/gomp/assume-3.f90 b/gcc/testsuite/gfortran.dg/gomp/assume-3.f90 new file mode 100644 index 0000000..e5deace --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/assume-3.f90 @@ -0,0 +1,46 @@ +! { dg-do compile } +! { dg-options "-fopenmp -O2 -fdump-tree-optimized -fdump-tree-original" } + +! { dg-final { scan-tree-dump-times ".ASSUME \\(x == 42\\);" 1 "original" } } +! { dg-final { scan-tree-dump-times ".ASSUME \\(x <= 41\\);" 1 "original" } } +! { dg-final { scan-tree-dump-times ".ASSUME \\(y <= 6\\);" 1 "original" } } +! { dg-final { scan-tree-dump-times ".ASSUME \\(y > 5\\);" 1 "original" } } + +! { dg-final { scan-tree-dump-times "return 42;" 3 "optimized" } } +! { dg-final { scan-tree-dump-not "return -1;" "optimized" } } + +integer function foo (x) + implicit none + integer, value :: x + integer :: y + !$omp assume holds (x == 42) + y = x; + !$omp end assume + foo = y +end + +integer function bar (x) + implicit none + integer, value :: x + !$omp assume holds (x < 42) + block + end block + if (x == 42) then + bar = -1 + return + end if + bar = 42 +end + +integer function foobar (y) + implicit none + integer, value :: y + !$omp assume holds(y > 5) holds (y < 7) + block + if (y == 6) then + foobar = 42 + return + end if + end block + foobar = -1 +end diff --git a/gcc/testsuite/gfortran.dg/gomp/assume-4.f90 b/gcc/testsuite/gfortran.dg/gomp/assume-4.f90 new file mode 100644 index 0000000..45857c4 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/assume-4.f90 @@ -0,0 +1,50 @@ +! { dg-do compile } +! { dg-options "-fopenmp -O2 -fdump-tree-original -fdump-tree-optimized" } +! { dg-final { scan-tree-dump-times ".ASSUME \\(i_lower_bound \\(\\) < i\\);" 1 "original" } } +! { dg-final { scan-tree-dump-times ".ASSUME \\(TARGET_EXPR i_lower_bound ()) + block + if (i > 4) then + f = 42 + else + f = -1 + end if + end block +contains + function i_lower_bound () + integer :: i_lower_bound + i_lower_bound = 5 + end function +end + +integer function g(j) + implicit none + integer, value :: j + + !$omp assume holds(j < j_upper_bound ()) + block + if (j < 10) then + g = 42 + else + g = -1 + end if + end block +contains + function j_upper_bound () + integer, allocatable :: j_upper_bound + j_upper_bound = 10 + end function +end -- cgit v1.1 From 629b4813e91aba0a8fc9b18434ec1808776a4b3d Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Thu, 6 Oct 2022 15:46:49 -0400 Subject: analyzer: fix another ICE in PR 107158 I overreduced PR analyzer/107158 in r13-3096-gef878564140cbc, and there was another ICE in the original reproducer, which this patch fixes. gcc/analyzer/ChangeLog: PR analyzer/107158 * store.cc (store::replay_call_summary_cluster): Eliminate special-casing of RK_HEAP_ALLOCATED in favor of sharing code with RK_DECL, avoiding an ICE due to attempting to bind a compound_svalue into a binding_cluster when an svalue in the summary cluster converts to a compound_svalue in the caller. gcc/testsuite/ChangeLog: PR analyzer/107158 * gcc.dg/analyzer/call-summaries-pr107158-2.c: New test. Signed-off-by: David Malcolm --- .../gcc.dg/analyzer/call-summaries-pr107158-2.c | 108 +++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/analyzer/call-summaries-pr107158-2.c (limited to 'gcc/testsuite') diff --git a/gcc/testsuite/gcc.dg/analyzer/call-summaries-pr107158-2.c b/gcc/testsuite/gcc.dg/analyzer/call-summaries-pr107158-2.c new file mode 100644 index 0000000..c2e9e2ba --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/call-summaries-pr107158-2.c @@ -0,0 +1,108 @@ +/* { dg-additional-options "-fanalyzer-call-summaries -Wno-analyzer-too-complex" } */ + +typedef __SIZE_TYPE__ size_t; +typedef struct _IO_FILE FILE; +extern char *fgets(char *__restrict __s, int __n, FILE *__restrict __stream) + __attribute__((__access__(__write_only__, 1, 2))); +extern void perror(const char *__s); +enum { + _ISspace = ((5) < 8 ? ((1 << (5)) << 8) : ((1 << (5)) >> 8)), +}; +extern const unsigned short int **__ctype_b_loc(void) + __attribute__((__nothrow__, __leaf__)) __attribute__((__const__)); +extern void *malloc(size_t __size) __attribute__((__nothrow__, __leaf__)) +__attribute__((__malloc__)) __attribute__((__alloc_size__(1))); +extern void exit(int __status) __attribute__((__nothrow__, __leaf__)) +__attribute__((__noreturn__)); +extern char *strcpy(char *__restrict __dest, const char *__restrict __src) + __attribute__((__nothrow__, __leaf__)) __attribute__((__nonnull__(1, 2))); +extern size_t strlen(const char *__s) __attribute__((__nothrow__, __leaf__)) +__attribute__((__pure__)) __attribute__((__nonnull__(1))); + +struct mydata { + struct mydata *link; + char *name; + char *type; +}; + +static struct mydata *all_data; +static int line_no; + +_Noreturn static void failed(const char *message) { + perror(message); + exit(1); +} + +static char *string_dup(const char *string) { + char *buf; + + if ((buf = malloc(strlen(string) + 1)) == ((void *)0)) + failed("malloc() failed"); + + return strcpy(buf, string); +} + +static void store_data(const char *name, const char *type) { + struct mydata *p, *q; + + if ((p = (struct mydata *)malloc(sizeof(struct mydata))) == ((void *)0)) + failed("malloc() failed"); + + p->link = ((void *)0); + p->name = string_dup(name); + p->type = string_dup(type); + + if ((q = all_data) == ((void *)0)) + all_data = p; + else { + while (q->link != ((void *)0)) + q = q->link; + q->link = p; + } +} + +static void parse_tbl(char *buffer) { + char *s = buffer; + char *t = s + strlen(s); + + do { + t--; + if (((*__ctype_b_loc())[(int)(((int)*t))] & (unsigned short int)_ISspace)) + *t = '\0'; + else + break; + } while (t > s); + while (((*__ctype_b_loc())[(int)(((int)*s))] & (unsigned short int)_ISspace)) + s++; + buffer = s; + + line_no++; + if (*buffer != ';' && *buffer != '\0') { + if (*buffer == '#') { + store_data(buffer, ""); /* { dg-bogus "leak" "PR analyzer/107158" { xfail *-*-* } } */ + } else { + + while (*s && !((*__ctype_b_loc())[(int)(((int)*s))] & + (unsigned short int)_ISspace)) + s++; + while ( + ((*__ctype_b_loc())[(int)(((int)*s))] & (unsigned short int)_ISspace)) + *s++ = '\0'; + store_data(buffer, s); /* { dg-bogus "leak" "PR analyzer/107158" { xfail *-*-* } } */ + } + } +} + +/* [...snip...] */ + +static void makecfg(FILE *ifp, FILE *ofp, FILE *ofp2) { + char buffer[8192]; + + /* [...snip...] */ + + line_no = 0; + while (fgets(buffer, sizeof(buffer) - 1, ifp)) + parse_tbl(buffer); + + /* [...snip...] */ +} -- cgit v1.1 From 49b9a8c8cc498b1ed2f566bee858e651e14ba37b Mon Sep 17 00:00:00 2001 From: Aldy Hernandez Date: Thu, 6 Oct 2022 19:11:08 +0200 Subject: [PR107170] Avoid copying incompatible types in legacy VRP. Legacy VRP is calling ranger deep inside the bowels, and then trying to copy an incompatible type. My previous patch in this area assumed that the only possibility out of vr_values::get_value_range for an unsupported type was VARYING, but UNDEFINED can also be returned. PR tree-optimization/107170 gcc/ChangeLog: * vr-values.cc (vr_values::range_of_expr): Do not die on unsupported types. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/pr107170.c: New test. --- gcc/testsuite/gcc.dg/tree-ssa/pr107170.c | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr107170.c (limited to 'gcc/testsuite') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr107170.c b/gcc/testsuite/gcc.dg/tree-ssa/pr107170.c new file mode 100644 index 0000000..7a5a4a3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr107170.c @@ -0,0 +1,8 @@ +// { dg-do compile } +// { dg-options "-O2" } + +int main() { + double a; + if (__builtin_signbit(a)) + __builtin_abort(); +} -- cgit v1.1 From 629d04d35d819bdc26c30d215bc4ea66a74af15b Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Fri, 7 Oct 2022 00:17:52 +0000 Subject: Daily bump. --- gcc/testsuite/ChangeLog | 77 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) (limited to 'gcc/testsuite') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 584fba4c..9577fc1 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,80 @@ +2022-10-06 Aldy Hernandez + + PR tree-optimization/107170 + * gcc.dg/tree-ssa/pr107170.c: New test. + +2022-10-06 David Malcolm + + PR analyzer/107158 + * gcc.dg/analyzer/call-summaries-pr107158-2.c: New test. + +2022-10-06 Tobias Burnus + + * gfortran.dg/gomp/assume-3.f90: New test. + * gfortran.dg/gomp/assume-4.f90: New test. + +2022-10-06 Joseph Myers + + * gcc.dg/c11-typeof-1.c, gcc.dg/c2x-typeof-1.c, + gcc.dg/c2x-typeof-2.c, gcc.dg/c2x-typeof-3.c, + gcc.dg/gnu11-typeof-1.c, gcc.dg/gnu11-typeof-2.c, + gcc.dg/gnu2x-typeof-1.c: New tests. + +2022-10-06 Patrick Palka + + * g++.dg/modules/indirect-3_b.C: Expect that the entity + foo::TPL<0>::frob is tagged as a specialization instead + of as a declaration. + * g++.dg/modules/tpl-spec-8_a.H: New test. + * g++.dg/modules/tpl-spec-8_b.C: New test. + +2022-10-06 Eric Botcazou + + * gcc.c-torture/execute/20221006-1.c: New test. + +2022-10-06 Richard Biener + + PR middle-end/107115 + * gcc.dg/torture/pr107115.c: New testcase. + +2022-10-06 Kyrylo Tkachov + + * gcc.target/aarch64/ldar_2.c: New test. + +2022-10-06 Kyrylo Tkachov + + * gcc.target/aarch64/ldar_1.c: New test. + +2022-10-06 Philipp Tomsich + + * gcc.target/aarch64/cpunative/info_18: New test. + * gcc.target/aarch64/cpunative/native_cpu_18.c: New test. + +2022-10-06 Richard Biener + + PR tree-optimization/107107 + * gcc.dg/pr107107.c: New testcase. + +2022-10-06 Jakub Jelinek + + * c-c++-common/gomp/assume-4.c: New test. + +2022-10-06 Jakub Jelinek + + PR c++/106654 + * gcc.dg/attr-assume-1.c: New test. + * gcc.dg/attr-assume-2.c: New test. + * gcc.dg/attr-assume-3.c: New test. + * g++.dg/cpp2a/feat-cxx2a.C: Add colon to C++20 features + comment, add C++20 attributes comment and move C++20 + new features after the attributes before them. + * g++.dg/cpp23/feat-cxx2b.C: Likewise. Test + __has_cpp_attribute(assume). + * g++.dg/cpp23/attr-assume1.C: New test. + * g++.dg/cpp23/attr-assume2.C: New test. + * g++.dg/cpp23/attr-assume3.C: New test. + * g++.dg/cpp23/attr-assume4.C: New test. + 2022-10-05 David Malcolm PR analyzer/107158 -- cgit v1.1 From 88f04e90f63f08620cc9cd2f059a1315b70bed3b Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Fri, 7 Oct 2022 09:01:04 +0200 Subject: c++: Improve handling of foreigner namespace attributes In some cases we want to look up or remove both standard attributes and attributes from gnu namespace but not others. This patch arranges for ATTR_NS of "" to stand for ATTR_NS NULL or "gnu", so that we don't need 2 separate calls, and introduces is_attribute_namespace_p function which allows testing the namespace of an attribute similar way. The patch also uses the new lookup_attribute overload and extra tests to avoid emitting weird warnings on foreign namespace attributes which we should just ignore (perhaps with a warning), but shouldn't imply any meaning to them just because they have a name matching some standard or gnu attribute name. 2022-10-07 Jakub Jelinek gcc/ * attribs.h (is_attribute_namespace_p): New inline function. (lookup_attribute): Document meaning of ATTR_NS equal to "". * attribs.cc (remove_attribute): Use is_attribute_namespace_p. (private_lookup_attribute): For ATTR_NS "" match either standard attribute or "gnu" namespace one. gcc/c-family/ * c-common.cc (attribute_fallthrough_p): Lookup fallthrough attribute only in gnu namespace or as standard attribute, treat fallthrough attributes in other namespaces like any other unknown attribute. gcc/cp/ * parser.cc (cp_parser_check_std_attribute): Only do checks if attribute is a standard attribute or in gnu namespace and only lookup other attributes in those namespaces. * cp-gimplify.cc (lookup_hotness_attribute): Adjust function comment. Only return true for standard attribute or gnu namespace attribute. (remove_hotness_attribute): Only remove hotness attributes when they are standard or in gnu namespace, implement it in a single loop rather than former 4 now 8 remove_attribute calls. gcc/testsuite/ * g++.dg/cpp1z/fallthrough2.C: New test. * g++.dg/cpp2a/attr-likely7.C: New test. --- gcc/testsuite/g++.dg/cpp1z/fallthrough2.C | 24 +++++++++++++++++++ gcc/testsuite/g++.dg/cpp2a/attr-likely7.C | 38 +++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 gcc/testsuite/g++.dg/cpp1z/fallthrough2.C create mode 100644 gcc/testsuite/g++.dg/cpp2a/attr-likely7.C (limited to 'gcc/testsuite') diff --git a/gcc/testsuite/g++.dg/cpp1z/fallthrough2.C b/gcc/testsuite/g++.dg/cpp1z/fallthrough2.C new file mode 100644 index 0000000..b74323f --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/fallthrough2.C @@ -0,0 +1,24 @@ +// { dg-do compile { target c++17 } } +// { dg-options "-Wextra -Wall -Wpedantic" } + +int +foo (int i) +{ + switch (i) + { + case 2: + ++i; + [[fallthrough, whatever::fallthrough]]; // { dg-bogus "attribute 'fallthrough' specified multiple times" } + case 3: // { dg-warning "'fallthrough' attribute ignored" "" { target *-*-* } .-1 } + ++i; + [[fallthrough, whatever2::fallthrough(1, 2, 3)]]; // { dg-bogus "attribute 'fallthrough' specified multiple times" } + case 4: // { dg-warning "'fallthrough' attribute ignored" "" { target *-*-* } .-1 } + [[whatever3::fallthrough("abcd")]]; // { dg-warning "attributes at the beginning of statement are ignored" } + case 5: + [[whatever4::fallthrough]]; // { dg-bogus "attribute 'fallthrough' not preceding a case label or default label" } + ++i; // { dg-warning "attributes at the beginning of statement are ignored" "" { target *-*-* } .-1 } + default: + break; + } + return i; +} diff --git a/gcc/testsuite/g++.dg/cpp2a/attr-likely7.C b/gcc/testsuite/g++.dg/cpp2a/attr-likely7.C new file mode 100644 index 0000000..638a6d9 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/attr-likely7.C @@ -0,0 +1,38 @@ +// { dg-do compile { target c++20 } } +// { dg-additional-options -fdump-tree-gimple } +// { dg-final { scan-tree-dump-times "hot label" 5 "gimple" } } +// { dg-final { scan-tree-dump-times "cold label" 3 "gimple" } } + +bool b; + +template int f() +{ + if (b) + [[likely, whatever::unlikely ("abcd")]] return 0; // { dg-bogus "ignoring attribute 'unlikely' after earlier 'likely'" } + else // { dg-warning "attributes at the beginning of statement are ignored" "" { target *-*-* } .-1 } + [[unlikely, whatever2::hot]] flabel: return 1; // { dg-warning "'whatever2::hot' scoped attribute directive ignored" } + switch (b) + { + [[likely, whatever3::cold (1, 2, 3)]] case true: break; // { dg-warning "'whatever3::cold' scoped attribute directive ignored" } + }; + return 1; +} + +int main() +{ + if (b) + [[whatever4::unlikely (1), likely]] return 0; // { dg-bogus "ignoring attribute 'likely' after earlier 'unlikely'" } + else if (b) // { dg-warning "attributes at the beginning of statement are ignored" "" { target *-*-* } .-1 } + [[whatever5::hot, unlikely]] elabel: // { dg-warning "'whatever5::hot' scoped attribute directive ignored" } + return 1; + else + [[whatever6::cold, likely]] b = false; // { dg-bogus "ignoring attribute 'likely' after earlier 'cold'" } + // { dg-warning "attributes at the beginning of statement are ignored" "" { target *-*-* } .-1 } + f(); + + switch (b) + { + [[whatever7::unlikely (1), likely]] case true: break; // { dg-warning "'whatever7::unlikely' scoped attribute directive ignored" } + [[whatever8::unlikely, unlikely]] case false: break; // { dg-bogus "attribute 'unlikely' specified multiple times" } + }; // { dg-warning "'whatever8::unlikely' scoped attribute directive ignored" "" { target *-*-* } .-1 } +} -- cgit v1.1 From 89228e3985c5cdf6be58a3b5b1afcad91e9e3422 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Fri, 7 Oct 2022 10:28:56 +0200 Subject: tree-optimization/107153 - autopar SSA update issue autopar performs insertion of stores, eventually requiring a virtual loop PHI and assorted LC PHI adjustments which we intend to do once after the pass finishes. But we also perform intermediate update_ssa after loop duplication which can lose this fact. The following forces renaming of the virtual operand before the final SSA update to fix that. It also removes the explicit update_ssa call from the gimple_duplicate_sese_tail utility as has been done for all other such utilities and instead performs the SSA update from autopar. PR tree-optimization/107153 * tree-cfg.cc (gimple_duplicate_sese_tail): Do not update SSA form here. * tree-parloops.cc (gen_parallel_loop): Update SSA form after to-exit-first transform, no PHI insertion is necessary. (pass_parallelize_loops::execute): Force re-write of the virtual operand SSA web. * gcc.dg/autopar/pr107153.c: New testcase. --- gcc/testsuite/gcc.dg/autopar/pr107153.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/autopar/pr107153.c (limited to 'gcc/testsuite') diff --git a/gcc/testsuite/gcc.dg/autopar/pr107153.c b/gcc/testsuite/gcc.dg/autopar/pr107153.c new file mode 100644 index 0000000..2391a67 --- /dev/null +++ b/gcc/testsuite/gcc.dg/autopar/pr107153.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -floop-parallelize-all -ftree-parallelize-loops=2 -fno-tree-dominator-opts" } */ + +void +foo (int x, int y) +{ + int i; + + for (i = 0; i < 2; i++) + { + } + + while (x) + if (!y) + while (y) + ++y; +} -- cgit v1.1 From d3e5465757c599ea64f611290b7793d3141a6b7c Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Wed, 5 Oct 2022 11:50:59 -0400 Subject: gimplify: prevent some C++ temporary elision In this testcase, we were optimizing away the temporary for f(), but C++17 and above are clear that there is a temporary, and because its destructor has visible side-effects we can't optimize it away under the as-if rule. So disable this optimization for TREE_ADDRESSABLE type. I moved the declaration of volatile_p after the call to gimple_fold_indirect_ref_rhs to minimize indentation changes; I don't see any way the value of that flag could be affected by the call. gcc/ChangeLog: * gimplify.cc (gimplify_modify_expr_rhs): Don't optimize x = *(A*)& to x = for a TREE_ADDRESSABLE type. gcc/testsuite/ChangeLog: * g++.dg/init/elide9.C: New test. --- gcc/testsuite/g++.dg/init/elide9.C | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 gcc/testsuite/g++.dg/init/elide9.C (limited to 'gcc/testsuite') diff --git a/gcc/testsuite/g++.dg/init/elide9.C b/gcc/testsuite/g++.dg/init/elide9.C new file mode 100644 index 0000000..810d60a --- /dev/null +++ b/gcc/testsuite/g++.dg/init/elide9.C @@ -0,0 +1,25 @@ +// The static_cast should prevent temporary elision. +// { dg-do run { target c++11 } } + +int d; +struct A +{ + int i; + A() { } + ~A() { ++d; } +}; + +A f() { return A(); } + +struct B +{ + A a; + B(): a(static_cast(f())) {} +}; + +int main() +{ + { B b; } + if (d != 2) + return -1; +} -- cgit v1.1 From edbb2551d156d69a2e337dcd8daa69f2680d57ea Mon Sep 17 00:00:00 2001 From: Patrick Palka Date: Fri, 7 Oct 2022 09:32:45 -0400 Subject: c++ modules: static var in inline function [PR104433] The below testcase fails to link with the error undefined reference to `f()::y' ultimately because during stream out for the static VAR_DECL y we override DECL_EXTERNAL to true, which later during IPA confuses symbol_table::remove_unreachable_nodes into thinking it's safe to not emit the symbol. The streaming code here already avoids overriding DECL_EXTERNAL for inline vars and functions, so it seems natural to extend this to static vars from an inline function. PR c++/104433 gcc/cp/ChangeLog: * module.cc (trees_out::core_bools): Don't override DECL_EXTERNAL to true for static variables from an inline function. gcc/testsuite/ChangeLog: * g++.dg/modules/static-2_a.H: New test. * g++.dg/modules/static-2_b.C: New test. --- gcc/testsuite/g++.dg/modules/static-2_a.H | 8 ++++++++ gcc/testsuite/g++.dg/modules/static-2_b.C | 9 +++++++++ 2 files changed, 17 insertions(+) create mode 100644 gcc/testsuite/g++.dg/modules/static-2_a.H create mode 100644 gcc/testsuite/g++.dg/modules/static-2_b.C (limited to 'gcc/testsuite') diff --git a/gcc/testsuite/g++.dg/modules/static-2_a.H b/gcc/testsuite/g++.dg/modules/static-2_a.H new file mode 100644 index 0000000..65c7619 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/static-2_a.H @@ -0,0 +1,8 @@ +// PR c++/104433 +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +inline int* f() { + static int y; + return &y; +} diff --git a/gcc/testsuite/g++.dg/modules/static-2_b.C b/gcc/testsuite/g++.dg/modules/static-2_b.C new file mode 100644 index 0000000..bfd35b0 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/static-2_b.C @@ -0,0 +1,9 @@ +// PR c++/104433 +// { dg-additional-options -fmodules-ts } +// { dg-do link } + +import "static-2_a.H"; + +int main() { + f(); +} -- cgit v1.1 From 1a308905c1baf64d0ea4d09d7d92b55e79a2a339 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Wed, 5 Oct 2022 11:15:36 +0200 Subject: IPA: support -flto + -flive-patching=inline-clone There's no fundamental reason why -flive-patching=inline-clone can't coexist with -flto. Yes, one can theoretically have many more clone function that includes a live patch. It is pretty much the same as in-module inlining. gcc/ChangeLog: * opts.cc (finish_options): Print sorry message only for -flive-patching=inline-only-static. gcc/testsuite/ChangeLog: * gcc.dg/live-patching-2.c: Update scanned pattern. * gcc.dg/live-patching-5.c: New test. --- gcc/testsuite/gcc.dg/live-patching-2.c | 4 ++-- gcc/testsuite/gcc.dg/live-patching-5.c | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/live-patching-5.c (limited to 'gcc/testsuite') diff --git a/gcc/testsuite/gcc.dg/live-patching-2.c b/gcc/testsuite/gcc.dg/live-patching-2.c index 0dde4e9..1c4f922 100644 --- a/gcc/testsuite/gcc.dg/live-patching-2.c +++ b/gcc/testsuite/gcc.dg/live-patching-2.c @@ -1,10 +1,10 @@ /* { dg-do compile } */ /* { dg-require-effective-target lto } */ -/* { dg-options "-O2 -flive-patching -flto" } */ +/* { dg-options "-O2 -flive-patching=inline-only-static -flto" } */ int main() { return 0; } -/* { dg-message "sorry, unimplemented: live patching is not supported with LTO" "-flive-patching and -flto together" { target *-*-* } 0 } */ +/* { dg-message "sorry, unimplemented: live patching \\(with 'inline-only-static'\\) is not supported with LTO" "-flive-patching and -flto together" { target *-*-* } 0 } */ diff --git a/gcc/testsuite/gcc.dg/live-patching-5.c b/gcc/testsuite/gcc.dg/live-patching-5.c new file mode 100644 index 0000000..098047a --- /dev/null +++ b/gcc/testsuite/gcc.dg/live-patching-5.c @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target lto } */ +/* { dg-options "-O2 -flive-patching -flto" } */ + +int main() +{ + return 0; +} -- cgit v1.1 From f7f4628054358a92a55d52645cf107aa26ff6765 Mon Sep 17 00:00:00 2001 From: Patrick Palka Date: Fri, 7 Oct 2022 12:01:58 -0400 Subject: c++ modules: ICE with bitfield in class template According to grokbitfield, DECL_BIT_FIELD_REPRESENTATIVE contains the width of the bitfield until we layout the class type (after which it'll contain a decl). Thus for a bitfield in a class template it'll always be the width, and this patch makes us avoid ICEing from mark_class_def in this case. gcc/cp/ChangeLog: * module.cc (trees_out::mark_class_def): Guard against DECL_BIT_FIELD_REPRESENTATIVE not being a decl. gcc/testsuite/ChangeLog: * g++.dg/modules/bfield-3.H: New test. --- gcc/testsuite/g++.dg/modules/bfield-3.H | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 gcc/testsuite/g++.dg/modules/bfield-3.H (limited to 'gcc/testsuite') diff --git a/gcc/testsuite/g++.dg/modules/bfield-3.H b/gcc/testsuite/g++.dg/modules/bfield-3.H new file mode 100644 index 0000000..4fd4db7 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/bfield-3.H @@ -0,0 +1,8 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +template +struct A { + int x : 1; + int y : N; +}; -- cgit v1.1 From f09b99550a3c6cd16f5e9150ebd4b1d87033dcbd Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Fri, 7 Oct 2022 12:41:59 -0400 Subject: analyzer: extract bits from integer constants [PR105783] Fix a false positive from -Wanalyzer-null-dereference due to -fanalyzer failing to grok the value of a particular boolean field initialized to a constant. gcc/analyzer/ChangeLog: PR analyzer/105783 * region-model.cc (selftest::get_bit): New function. (selftest::test_bits_within_svalue_folding): New. (selfftest::analyzer_region_model_cc_tests): Call it. * svalue.cc (constant_svalue::maybe_fold_bits_within): Handle the case of extracting a single bit. gcc/testsuite/ChangeLog: PR analyzer/105783 * gcc.dg/analyzer/pr105783.c: New test. Signed-off-by: David Malcolm --- gcc/testsuite/gcc.dg/analyzer/pr105783.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr105783.c (limited to 'gcc/testsuite') diff --git a/gcc/testsuite/gcc.dg/analyzer/pr105783.c b/gcc/testsuite/gcc.dg/analyzer/pr105783.c new file mode 100644 index 0000000..00f44d0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr105783.c @@ -0,0 +1,26 @@ +/* { dg-additional-options "-O" } */ + +struct ss_s { + union out_or_counting_u { + char *newstr; + unsigned long long cnt; + } uu; + _Bool counting; +}; + +struct ss_s ss_init(void) { + struct ss_s rr = { .counting = 1 }; + return rr; +} + +void ss_out(struct ss_s *t, char cc) { + if (!t->counting) { + *t->uu.newstr++ = cc; + } +} + +int main() { + struct ss_s ss = ss_init(); + ss_out(&ss, 'a'); +} + -- cgit v1.1 From 1879e48f3d8595bc9e7f583bbd12df3c6f5c42dc Mon Sep 17 00:00:00 2001 From: Qing Zhao Date: Fri, 7 Oct 2022 14:58:20 +0000 Subject: Add a new option -fstrict-flex-arrays[=n] and new attribute strict_flex_array Add the following new option -fstrict-flex-arrays[=n] and a corresponding attribute strict_flex_array to GCC: '-fstrict-flex-arrays' Control when to treat the trailing array of a structure as a flexible array member for the purpose of accessing the elements of such an array. The positive form is equivalent to '-fstrict-flex-arrays=3', which is the strictest. A trailing array is treated as a flexible array member only when it declared as a flexible array member per C99 standard onwards. The negative form is equivalent to '-fstrict-flex-arrays=0', which is the least strict. All trailing arrays of structures are treated as flexible array members. '-fstrict-flex-arrays=LEVEL' Control when to treat the trailing array of a structure as a flexible array member for the purpose of accessing the elements of such an array. The value of LEVEL controls the level of strictness The possible values of LEVEL are the same as for the 'strict_flex_array' attribute (*note Variable Attributes::). You can control this behavior for a specific trailing array field of a structure by using the variable attribute 'strict_flex_array' attribute (*note Variable Attributes::). 'strict_flex_array (LEVEL)' The 'strict_flex_array' attribute should be attached to the trailing array field of a structure. It controls when to treat the trailing array field of a structure as a flexible array member for the purposes of accessing the elements of such an array. LEVEL must be an integer betwen 0 to 3. LEVEL=0 is the least strict level, all trailing arrays of structures are treated as flexible array members. LEVEL=3 is the strictest level, only when the trailing array is declared as a flexible array member per C99 standard onwards ('[]'), it is treated as a flexible array member. There are two more levels in between 0 and 3, which are provided to support older codes that use GCC zero-length array extension ('[0]') or one-element array as flexible array members('[1]'): When LEVEL is 1, the trailing array is treated as a flexible array member when it is declared as either '[]', '[0]', or '[1]'; When LEVEL is 2, the trailing array is treated as a flexible array member when it is declared as either '[]', or '[0]'. This attribute can be used with or without the '-fstrict-flex-arrays'. When both the attribute and the option present at the same time, the level of the strictness for the specific trailing array field is determined by the attribute. gcc/c-family/ChangeLog: * c-attribs.cc (handle_strict_flex_array_attribute): New function. (c_common_attribute_table): New item for strict_flex_array. * c.opt: (fstrict-flex-arrays): New option. (fstrict-flex-arrays=): New option. gcc/c/ChangeLog: * c-decl.cc (flexible_array_member_type_p): New function. (one_element_array_type_p): Likewise. (zero_length_array_type_p): Likewise. (add_flexible_array_elts_to_size): Call new utility routine flexible_array_member_type_p. (is_flexible_array_member_p): New function. (finish_struct): Set the new DECL_NOT_FLEXARRAY flag. gcc/cp/ChangeLog: * module.cc (trees_out::core_bools): Stream out new bit decl_not_flexarray. (trees_in::core_bools): Stream in new bit decl_not_flexarray. gcc/ChangeLog: * doc/extend.texi: Document strict_flex_array attribute. * doc/invoke.texi: Document -fstrict-flex-arrays[=n] option. * print-tree.cc (print_node): Print new bit decl_not_flexarray. * tree-core.h (struct tree_decl_common): New bit field decl_not_flexarray. * tree-streamer-in.cc (unpack_ts_decl_common_value_fields): Stream in new bit decl_not_flexarray. * tree-streamer-out.cc (pack_ts_decl_common_value_fields): Stream out new bit decl_not_flexarray. * tree.cc (array_at_struct_end_p): Update it with the new bit field decl_not_flexarray. * tree.h (DECL_NOT_FLEXARRAY): New flag. gcc/testsuite/ChangeLog: * g++.dg/strict-flex-array-1.C: New test. * gcc.dg/strict-flex-array-1.c: New test. --- gcc/testsuite/g++.dg/strict-flex-array-1.C | 31 ++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/strict-flex-array-1.c | 33 ++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 gcc/testsuite/g++.dg/strict-flex-array-1.C create mode 100644 gcc/testsuite/gcc.dg/strict-flex-array-1.c (limited to 'gcc/testsuite') diff --git a/gcc/testsuite/g++.dg/strict-flex-array-1.C b/gcc/testsuite/g++.dg/strict-flex-array-1.C new file mode 100644 index 0000000..92fcffe --- /dev/null +++ b/gcc/testsuite/g++.dg/strict-flex-array-1.C @@ -0,0 +1,31 @@ +/* testing the correct usage of attribute strict_flex_array. */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + + +int x __attribute__ ((strict_flex_array (1))); /* { dg-error "'strict_flex_array' attribute may not be specified for 'x'" } */ + +struct trailing { + int a; + int c __attribute ((strict_flex_array)); /* { dg-error "wrong number of arguments specified for 'strict_flex_array' attribute" } */ +}; + +struct trailing_1 { + int a; + int b; + int c __attribute ((strict_flex_array (2))); /* { dg-error "'strict_flex_array' attribute may not be specified for a non-array field" } */ +}; + +extern int d; + +struct trailing_array_2 { + int a; + int b; + int c[1] __attribute ((strict_flex_array (d))); /* { dg-error "'strict_flex_array' attribute argument not an integer" } */ +}; + +struct trailing_array_3 { + int a; + int b; + int c[0] __attribute ((strict_flex_array (5))); /* { dg-error "'strict_flex_array' attribute argument '5' is not an integer constant between 0 and 3" } */ +}; diff --git a/gcc/testsuite/gcc.dg/strict-flex-array-1.c b/gcc/testsuite/gcc.dg/strict-flex-array-1.c new file mode 100644 index 0000000..5b8a793 --- /dev/null +++ b/gcc/testsuite/gcc.dg/strict-flex-array-1.c @@ -0,0 +1,33 @@ +/* testing the correct usage of attribute strict_flex_array. */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + + +int x __attribute__ ((strict_flex_array (1))); /* { dg-error "'strict_flex_array' attribute may not be specified for 'x'" } */ + +int [[gnu::strict_flex_array(1)]] x; /* { dg-warning "'strict_flex_array' attribute does not apply to types" } */ + +struct trailing { + int a; + int c __attribute ((strict_flex_array)); /* { dg-error "wrong number of arguments specified for 'strict_flex_array' attribute" } */ +}; + +struct trailing_1 { + int a; + int b; + int c __attribute ((strict_flex_array (2))); /* { dg-error "'strict_flex_array' attribute may not be specified for a non-array field" } */ +}; + +extern int d; + +struct trailing_array_2 { + int a; + int b; + int c[1] __attribute ((strict_flex_array (d))); /* { dg-error "'strict_flex_array' attribute argument not an integer" } */ +}; + +struct trailing_array_3 { + int a; + int b; + int c[0] __attribute ((strict_flex_array (5))); /* { dg-error "'strict_flex_array' attribute argument '5' is not an integer constant between 0 and 3" } */ +}; -- cgit v1.1 From b9ad850e86b863c24f6f4f5acf08d49944cc7bbe Mon Sep 17 00:00:00 2001 From: Qing Zhao Date: Fri, 7 Oct 2022 14:59:01 +0000 Subject: Use array_at_struct_end_p in __builtin_object_size [PR101836] Use array_at_struct_end_p to determine whether the trailing array of a structure is flexible array member in __builtin_object_size. gcc/ChangeLog: PR tree-optimization/101836 * tree-object-size.cc (addr_object_size): Use array_at_struct_end_p to determine a flexible array member reference. gcc/testsuite/ChangeLog: PR tree-optimization/101836 * gcc.dg/pr101836.c: New test. * gcc.dg/pr101836_1.c: New test. * gcc.dg/pr101836_2.c: New test. * gcc.dg/pr101836_3.c: New test. * gcc.dg/pr101836_4.c: New test. * gcc.dg/pr101836_5.c: New test. * gcc.dg/strict-flex-array-2.c: New test. * gcc.dg/strict-flex-array-3.c: New test. --- gcc/testsuite/gcc.dg/pr101836.c | 60 ++++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/pr101836_1.c | 60 ++++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/pr101836_2.c | 60 ++++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/pr101836_3.c | 60 ++++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/pr101836_4.c | 60 ++++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/pr101836_5.c | 60 ++++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/strict-flex-array-2.c | 60 ++++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/strict-flex-array-3.c | 60 ++++++++++++++++++++++++++++++ 8 files changed, 480 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr101836.c create mode 100644 gcc/testsuite/gcc.dg/pr101836_1.c create mode 100644 gcc/testsuite/gcc.dg/pr101836_2.c create mode 100644 gcc/testsuite/gcc.dg/pr101836_3.c create mode 100644 gcc/testsuite/gcc.dg/pr101836_4.c create mode 100644 gcc/testsuite/gcc.dg/pr101836_5.c create mode 100644 gcc/testsuite/gcc.dg/strict-flex-array-2.c create mode 100644 gcc/testsuite/gcc.dg/strict-flex-array-3.c (limited to 'gcc/testsuite') diff --git a/gcc/testsuite/gcc.dg/pr101836.c b/gcc/testsuite/gcc.dg/pr101836.c new file mode 100644 index 0000000..efad02c --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr101836.c @@ -0,0 +1,60 @@ +/* -fstrict-flex-arrays is aliased with -ftrict-flex-arrays=3, which is the + strictest, only [] is treated as flexible array. */ +/* PR tree-optimization/101836 */ +/* { dg-do run } */ +/* { dg-options "-O2 -fstrict-flex-arrays" } */ + +#include + +#define expect(p, _v) do { \ + size_t v = _v; \ + if (p == v) \ + printf("ok: %s == %zd\n", #p, p); \ + else \ + { \ + printf("WAT: %s == %zd (expected %zd)\n", #p, p, v); \ + __builtin_abort (); \ + } \ +} while (0); + +struct trailing_array_1 { + int a; + int b; + int c[4]; +}; + +struct trailing_array_2 { + int a; + int b; + int c[1]; +}; + +struct trailing_array_3 { + int a; + int b; + int c[0]; +}; +struct trailing_array_4 { + int a; + int b; + int c[]; +}; + +void __attribute__((__noinline__)) stuff( + struct trailing_array_1 *normal, + struct trailing_array_2 *trailing_1, + struct trailing_array_3 *trailing_0, + struct trailing_array_4 *trailing_flex) +{ + expect(__builtin_object_size(normal->c, 1), 16); + expect(__builtin_object_size(trailing_1->c, 1), 4); + expect(__builtin_object_size(trailing_0->c, 1), 0); + expect(__builtin_object_size(trailing_flex->c, 1), -1); +} + +int main(int argc, char *argv[]) +{ + stuff((void *)argv[0], (void *)argv[0], (void *)argv[0], (void *)argv[0]); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/pr101836_1.c b/gcc/testsuite/gcc.dg/pr101836_1.c new file mode 100644 index 0000000..e2931ce --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr101836_1.c @@ -0,0 +1,60 @@ +/* -fstrict-flex-arrays=3 is the strictest, only [] is treated as + flexible array. */ +/* PR tree-optimization/101836 */ +/* { dg-do run } */ +/* { dg-options "-O2 -fstrict-flex-arrays=3" } */ + +#include + +#define expect(p, _v) do { \ + size_t v = _v; \ + if (p == v) \ + printf("ok: %s == %zd\n", #p, p); \ + else \ + { \ + printf("WAT: %s == %zd (expected %zd)\n", #p, p, v); \ + __builtin_abort (); \ + } \ +} while (0); + +struct trailing_array_1 { + int a; + int b; + int c[4]; +}; + +struct trailing_array_2 { + int a; + int b; + int c[1]; +}; + +struct trailing_array_3 { + int a; + int b; + int c[0]; +}; +struct trailing_array_4 { + int a; + int b; + int c[]; +}; + +void __attribute__((__noinline__)) stuff( + struct trailing_array_1 *normal, + struct trailing_array_2 *trailing_1, + struct trailing_array_3 *trailing_0, + struct trailing_array_4 *trailing_flex) +{ + expect(__builtin_object_size(normal->c, 1), 16); + expect(__builtin_object_size(trailing_1->c, 1), 4); + expect(__builtin_object_size(trailing_0->c, 1), 0); + expect(__builtin_object_size(trailing_flex->c, 1), -1); +} + +int main(int argc, char *argv[]) +{ + stuff((void *)argv[0], (void *)argv[0], (void *)argv[0], (void *)argv[0]); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/pr101836_2.c b/gcc/testsuite/gcc.dg/pr101836_2.c new file mode 100644 index 0000000..7897418 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr101836_2.c @@ -0,0 +1,60 @@ +/* When -fstrict-flex-arrays=2, only [] and [0] are treated as flexiable + arrays. */ +/* PR tree-optimization/101836 */ +/* { dg-do run } */ +/* { dg-options "-O2 -fstrict-flex-arrays=2" } */ + +#include + +#define expect(p, _v) do { \ + size_t v = _v; \ + if (p == v) \ + printf("ok: %s == %zd\n", #p, p); \ + else \ + { \ + printf("WAT: %s == %zd (expected %zd)\n", #p, p, v); \ + __builtin_abort (); \ + } \ +} while (0); + +struct trailing_array_1 { + int a; + int b; + int c[4]; +}; + +struct trailing_array_2 { + int a; + int b; + int c[1]; +}; + +struct trailing_array_3 { + int a; + int b; + int c[0]; +}; +struct trailing_array_4 { + int a; + int b; + int c[]; +}; + +void __attribute__((__noinline__)) stuff( + struct trailing_array_1 *normal, + struct trailing_array_2 *trailing_1, + struct trailing_array_3 *trailing_0, + struct trailing_array_4 *trailing_flex) +{ + expect(__builtin_object_size(normal->c, 1), 16); + expect(__builtin_object_size(trailing_1->c, 1), 4); + expect(__builtin_object_size(trailing_0->c, 1), -1); + expect(__builtin_object_size(trailing_flex->c, 1), -1); +} + +int main(int argc, char *argv[]) +{ + stuff((void *)argv[0], (void *)argv[0], (void *)argv[0], (void *)argv[0]); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/pr101836_3.c b/gcc/testsuite/gcc.dg/pr101836_3.c new file mode 100644 index 0000000..0e69388 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr101836_3.c @@ -0,0 +1,60 @@ +/* When -fstrict-flex-arrays=1, [], [0], and [1] are treated as flexible + arrays. */ +/* PR tree-optimization/101836 */ +/* { dg-do run } */ +/* { dg-options "-O2 -fstrict-flex-arrays=1" } */ + +#include + +#define expect(p, _v) do { \ + size_t v = _v; \ + if (p == v) \ + printf("ok: %s == %zd\n", #p, p); \ + else \ + { \ + printf("WAT: %s == %zd (expected %zd)\n", #p, p, v); \ + __builtin_abort (); \ + } \ +} while (0); + +struct trailing_array_1 { + int a; + int b; + int c[4]; +}; + +struct trailing_array_2 { + int a; + int b; + int c[1]; +}; + +struct trailing_array_3 { + int a; + int b; + int c[0]; +}; +struct trailing_array_4 { + int a; + int b; + int c[]; +}; + +void __attribute__((__noinline__)) stuff( + struct trailing_array_1 *normal, + struct trailing_array_2 *trailing_1, + struct trailing_array_3 *trailing_0, + struct trailing_array_4 *trailing_flex) +{ + expect(__builtin_object_size(normal->c, 1), 16); + expect(__builtin_object_size(trailing_1->c, 1), -1); + expect(__builtin_object_size(trailing_0->c, 1), -1); + expect(__builtin_object_size(trailing_flex->c, 1), -1); +} + +int main(int argc, char *argv[]) +{ + stuff((void *)argv[0], (void *)argv[0], (void *)argv[0], (void *)argv[0]); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/pr101836_4.c b/gcc/testsuite/gcc.dg/pr101836_4.c new file mode 100644 index 0000000..e0025aa --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr101836_4.c @@ -0,0 +1,60 @@ +/* when -fstrict-flex-arrays=0, all trailing arrays are treated as + flexible arrays. */ +/* PR tree-optimization/101836 */ +/* { dg-do run } */ +/* { dg-options "-O2 -fstrict-flex-arrays=0" } */ + +#include + +#define expect(p, _v) do { \ + size_t v = _v; \ + if (p == v) \ + printf("ok: %s == %zd\n", #p, p); \ + else \ + { \ + printf("WAT: %s == %zd (expected %zd)\n", #p, p, v); \ + __builtin_abort (); \ + } \ +} while (0); + +struct trailing_array_1 { + int a; + int b; + int c[4]; +}; + +struct trailing_array_2 { + int a; + int b; + int c[1]; +}; + +struct trailing_array_3 { + int a; + int b; + int c[0]; +}; +struct trailing_array_4 { + int a; + int b; + int c[]; +}; + +void __attribute__((__noinline__)) stuff( + struct trailing_array_1 *normal, + struct trailing_array_2 *trailing_1, + struct trailing_array_3 *trailing_0, + struct trailing_array_4 *trailing_flex) +{ + expect(__builtin_object_size(normal->c, 1), -1); + expect(__builtin_object_size(trailing_1->c, 1), -1); + expect(__builtin_object_size(trailing_0->c, 1), -1); + expect(__builtin_object_size(trailing_flex->c, 1), -1); +} + +int main(int argc, char *argv[]) +{ + stuff((void *)argv[0], (void *)argv[0], (void *)argv[0], (void *)argv[0]); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/pr101836_5.c b/gcc/testsuite/gcc.dg/pr101836_5.c new file mode 100644 index 0000000..0ad8bbf --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr101836_5.c @@ -0,0 +1,60 @@ +/* -fno-strict-flex-arrays is aliased to -fstrict-flex-arrays=0, + all trailing arrays are treated as flexible array. */ +/* PR tree-optimization/101836 */ +/* { dg-do run } */ +/* { dg-options "-O2 -fno-strict-flex-arrays" } */ + +#include + +#define expect(p, _v) do { \ + size_t v = _v; \ + if (p == v) \ + printf("ok: %s == %zd\n", #p, p); \ + else \ + { \ + printf("WAT: %s == %zd (expected %zd)\n", #p, p, v); \ + __builtin_abort (); \ + } \ +} while (0); + +struct trailing_array_1 { + int a; + int b; + int c[4]; +}; + +struct trailing_array_2 { + int a; + int b; + int c[1]; +}; + +struct trailing_array_3 { + int a; + int b; + int c[0]; +}; +struct trailing_array_4 { + int a; + int b; + int c[]; +}; + +void __attribute__((__noinline__)) stuff( + struct trailing_array_1 *normal, + struct trailing_array_2 *trailing_1, + struct trailing_array_3 *trailing_0, + struct trailing_array_4 *trailing_flex) +{ + expect(__builtin_object_size(normal->c, 1), -1); + expect(__builtin_object_size(trailing_1->c, 1), -1); + expect(__builtin_object_size(trailing_0->c, 1), -1); + expect(__builtin_object_size(trailing_flex->c, 1), -1); +} + +int main(int argc, char *argv[]) +{ + stuff((void *)argv[0], (void *)argv[0], (void *)argv[0], (void *)argv[0]); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/strict-flex-array-2.c b/gcc/testsuite/gcc.dg/strict-flex-array-2.c new file mode 100644 index 0000000..2b80c23 --- /dev/null +++ b/gcc/testsuite/gcc.dg/strict-flex-array-2.c @@ -0,0 +1,60 @@ +/* test the combination of attribute strict_flex_array and option + -fstrict-flex-arrays: when both attribute and option specified, + attribute will have higher priority. */ +/* { dg-do run } */ +/* { dg-options "-O2 -fstrict-flex-arrays=3" } */ + +#include + +#define expect(p, _v) do { \ + size_t v = _v; \ + if (p == v) \ + printf("ok: %s == %zd\n", #p, p); \ + else \ + { \ + printf("WAT: %s == %zd (expected %zd)\n", #p, p, v); \ + __builtin_abort (); \ + } \ +} while (0); + +struct trailing_array_1 { + int a; + int b; + int c[4] __attribute__ ((strict_flex_array (0))); +}; + +struct trailing_array_2 { + int a; + int b; + int c[1] __attribute__ ((strict_flex_array (1))); +}; + +struct trailing_array_3 { + int a; + int b; + int c[0] __attribute__ ((strict_flex_array (2))); +}; +struct trailing_array_4 { + int a; + int b; + int c[]; +}; + +void __attribute__((__noinline__)) stuff( + struct trailing_array_1 *normal, + struct trailing_array_2 *trailing_1, + struct trailing_array_3 *trailing_0, + struct trailing_array_4 *trailing_flex) +{ + expect(__builtin_object_size(normal->c, 1), -1); + expect(__builtin_object_size(trailing_1->c, 1), -1); + expect(__builtin_object_size(trailing_0->c, 1), -1); + expect(__builtin_object_size(trailing_flex->c, 1), -1); +} + +int main(int argc, char *argv[]) +{ + stuff((void *)argv[0], (void *)argv[0], (void *)argv[0], (void *)argv[0]); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/strict-flex-array-3.c b/gcc/testsuite/gcc.dg/strict-flex-array-3.c new file mode 100644 index 0000000..602f99d --- /dev/null +++ b/gcc/testsuite/gcc.dg/strict-flex-array-3.c @@ -0,0 +1,60 @@ +/* test the combination of attribute strict_flex_array and option + -fstrict-flex-arrays: when both attribute and option specified, + attribute will have higher priority. */ +/* { dg-do run } */ +/* { dg-options "-O2 -fstrict-flex-arrays=0" } */ + +#include + +#define expect(p, _v) do { \ + size_t v = _v; \ + if (p == v) \ + printf("ok: %s == %zd\n", #p, p); \ + else \ + { \ + printf("WAT: %s == %zd (expected %zd)\n", #p, p, v); \ + __builtin_abort (); \ + } \ +} while (0); + +struct trailing_array_1 { + int a; + int b; + int c[4] __attribute__ ((strict_flex_array (1))); +}; + +struct trailing_array_2 { + int a; + int b; + int c[1] __attribute__ ((strict_flex_array (2))); +}; + +struct trailing_array_3 { + int a; + int b; + int c[0] __attribute__ ((strict_flex_array (3))); +}; +struct trailing_array_4 { + int a; + int b; + int c[]; +}; + +void __attribute__((__noinline__)) stuff( + struct trailing_array_1 *normal, + struct trailing_array_2 *trailing_1, + struct trailing_array_3 *trailing_0, + struct trailing_array_4 *trailing_flex) +{ + expect(__builtin_object_size(normal->c, 1), 16); + expect(__builtin_object_size(trailing_1->c, 1), 4); + expect(__builtin_object_size(trailing_0->c, 1), 0); + expect(__builtin_object_size(trailing_flex->c, 1), -1); +} + +int main(int argc, char *argv[]) +{ + stuff((void *)argv[0], (void *)argv[0], (void *)argv[0], (void *)argv[0]); + + return 0; +} -- cgit v1.1 From 895dd027d5dda51a95d242aec8a49a6dfa5db58d Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Wed, 5 Oct 2022 15:51:30 -0400 Subject: c++: fixes for derived-to-base reference binding [PR107085] This PR reports that struct Base {}; struct Derived : Base {}; static_assert(__reference_constructs_from_temporary(Base const&, Derived)); doesn't pass, which it should: it's just like const Base& b(Derived{}); where we bind 'b' to the Base subobject of a temporary object of type Derived. The ck_base conversion didn't have ->need_temporary_p set because we didn't need to create a temporary object just for the base, but the whole object is a temporary so we're still binding to a temporary. Since the Base subobject is an xvalue, a new function is introduced. PR c++/107085 gcc/cp/ChangeLog: * call.cc (conv_binds_ref_to_temporary): New. (ref_conv_binds_directly): Rename to... (ref_conv_binds_to_temporary): ...this. Use conv_binds_ref_to_temporary. * cp-tree.h (ref_conv_binds_directly): Rename to... (ref_conv_binds_to_temporary): ...this. * method.cc (ref_xes_from_temporary): Use ref_conv_binds_to_temporary. * parser.cc (warn_for_range_copy): Likewise. gcc/testsuite/ChangeLog: * g++.dg/ext/reference_constructs_from_temporary1.C: Adjust expected result. * g++.dg/ext/reference_converts_from_temporary1.C: Likewise. * g++.dg/cpp0x/elision4.C: New test. --- gcc/testsuite/g++.dg/cpp0x/elision4.C | 15 +++++++++++++++ .../g++.dg/ext/reference_constructs_from_temporary1.C | 2 +- .../g++.dg/ext/reference_converts_from_temporary1.C | 2 +- 3 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/elision4.C (limited to 'gcc/testsuite') diff --git a/gcc/testsuite/g++.dg/cpp0x/elision4.C b/gcc/testsuite/g++.dg/cpp0x/elision4.C new file mode 100644 index 0000000..3cc2e3a --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/elision4.C @@ -0,0 +1,15 @@ +// PR c++/107085 +// { dg-do compile { target c++11 } } + +struct X { + X(); + X(X&&); +}; +struct Z : X {}; +X x1 = Z(); +X x2 = X(Z()); + +struct B { }; +struct D : B { }; +B b1 = D(); +B b2 = B(D()); diff --git a/gcc/testsuite/g++.dg/ext/reference_constructs_from_temporary1.C b/gcc/testsuite/g++.dg/ext/reference_constructs_from_temporary1.C index 76de905..5354b1d 100644 --- a/gcc/testsuite/g++.dg/ext/reference_constructs_from_temporary1.C +++ b/gcc/testsuite/g++.dg/ext/reference_constructs_from_temporary1.C @@ -201,7 +201,7 @@ SA(!__reference_constructs_from_temporary(const int&, H)); SA(!__reference_constructs_from_temporary(int&&, G2)); SA(!__reference_constructs_from_temporary(const int&, H2)); -SA(!__reference_constructs_from_temporary(const Base&, Der)); +SA(__reference_constructs_from_temporary(const Base&, Der)); // This fails because std::is_constructible_v> is false. SA(!__reference_constructs_from_temporary(int&&, id)); diff --git a/gcc/testsuite/g++.dg/ext/reference_converts_from_temporary1.C b/gcc/testsuite/g++.dg/ext/reference_converts_from_temporary1.C index 90196c3..e6c159e 100644 --- a/gcc/testsuite/g++.dg/ext/reference_converts_from_temporary1.C +++ b/gcc/testsuite/g++.dg/ext/reference_converts_from_temporary1.C @@ -201,7 +201,7 @@ SA( __reference_converts_from_temporary(const int&, H)); SA(!__reference_converts_from_temporary(int&&, G2)); SA(!__reference_converts_from_temporary(const int&, H2)); -SA(!__reference_converts_from_temporary(const Base&, Der)); +SA(__reference_converts_from_temporary(const Base&, Der)); // This fails because std::is_constructible_v> is false. SA(!__reference_converts_from_temporary(int&&, id)); -- cgit v1.1 From 9ff6c33e2ec0d75958d3f19089519034e8f96a30 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Sat, 8 Oct 2022 00:17:29 +0000 Subject: Daily bump. --- gcc/testsuite/ChangeLog | 59 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) (limited to 'gcc/testsuite') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9577fc1..af8fc3f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,62 @@ +2022-10-07 Marek Polacek + + PR c++/107085 + * g++.dg/ext/reference_constructs_from_temporary1.C: Adjust expected + result. + * g++.dg/ext/reference_converts_from_temporary1.C: Likewise. + * g++.dg/cpp0x/elision4.C: New test. + +2022-10-07 Qing Zhao + + PR tree-optimization/101836 + * gcc.dg/pr101836.c: New test. + * gcc.dg/pr101836_1.c: New test. + * gcc.dg/pr101836_2.c: New test. + * gcc.dg/pr101836_3.c: New test. + * gcc.dg/pr101836_4.c: New test. + * gcc.dg/pr101836_5.c: New test. + * gcc.dg/strict-flex-array-2.c: New test. + * gcc.dg/strict-flex-array-3.c: New test. + +2022-10-07 Qing Zhao + + * g++.dg/strict-flex-array-1.C: New test. + * gcc.dg/strict-flex-array-1.c: New test. + +2022-10-07 David Malcolm + + PR analyzer/105783 + * gcc.dg/analyzer/pr105783.c: New test. + +2022-10-07 Patrick Palka + + * g++.dg/modules/bfield-3.H: New test. + +2022-10-07 Martin Liska + + * gcc.dg/live-patching-2.c: Update scanned pattern. + * gcc.dg/live-patching-5.c: New test. + +2022-10-07 Patrick Palka + + PR c++/104433 + * g++.dg/modules/static-2_a.H: New test. + * g++.dg/modules/static-2_b.C: New test. + +2022-10-07 Jason Merrill + + * g++.dg/init/elide9.C: New test. + +2022-10-07 Richard Biener + + PR tree-optimization/107153 + * gcc.dg/autopar/pr107153.c: New testcase. + +2022-10-07 Jakub Jelinek + + * g++.dg/cpp1z/fallthrough2.C: New test. + * g++.dg/cpp2a/attr-likely7.C: New test. + 2022-10-06 Aldy Hernandez PR tree-optimization/107170 -- cgit v1.1