diff options
Diffstat (limited to 'gcc/testsuite/gcc.dg')
53 files changed, 1771 insertions, 81 deletions
diff --git a/gcc/testsuite/gcc.dg/diagnostic-token-ranges.c b/gcc/testsuite/gcc.dg/diagnostic-token-ranges.c new file mode 100644 index 00000000000..ac969e30d94 --- /dev/null +++ b/gcc/testsuite/gcc.dg/diagnostic-token-ranges.c @@ -0,0 +1,120 @@ +/* { dg-options "-fdiagnostics-show-caret -Wc++-compat" } */ + +/* Verify that various diagnostics show source code ranges. */ + +/* These ones merely use token ranges; they don't use tree ranges. */ + +void undeclared_identifier (void) +{ + name; /* { dg-error "'name' undeclared" } */ +/* +{ dg-begin-multiline-output "" } + name; + ^~~~ +{ dg-end-multiline-output "" } +*/ +} + +void unknown_type_name (void) +{ + foo bar; /* { dg-error "unknown type name 'foo'" } */ +/* +{ dg-begin-multiline-output "" } + foo bar; + ^~~ +{ dg-end-multiline-output "" } +*/ + + qux *baz; /* { dg-error "unknown type name 'qux'" } */ +/* +{ dg-begin-multiline-output "" } + qux *baz; + ^~~ +{ dg-end-multiline-output "" } +*/ +} + +void test_identifier_conflicts_with_cplusplus (void) +{ + int new; /* { dg-warning "identifier 'new' conflicts with" } */ +/* +{ dg-begin-multiline-output "" } + int new; + ^~~ +{ dg-end-multiline-output "" } +*/ +} + +extern void +bogus_varargs (...); /* { dg-error "ISO C requires a named argument before '...'" } */ +/* +{ dg-begin-multiline-output "" } + bogus_varargs (...); + ^~~ +{ dg-end-multiline-output "" } +*/ + +extern void +foo (unknown_type param); /* { dg-error "unknown type name 'unknown_type'" } */ +/* +{ dg-begin-multiline-output "" } + foo (unknown_type param); + ^~~~~~~~~~~~ +{ dg-end-multiline-output "" } +*/ + +void wide_string_literal_in_asm (void) +{ + asm (L"nop"); /* { dg-error "wide string literal in 'asm'" } */ +/* +{ dg-begin-multiline-output "" } + asm (L"nop"); + ^~~~~~ +{ dg-end-multiline-output "" } +*/ +} + +void break_and_continue_in_wrong_places (void) +{ + if (0) + break; /* { dg-error "break statement not within loop or switch" } */ +/* { dg-begin-multiline-output "" } + break; + ^~~~~ + { dg-end-multiline-output "" } */ + + if (1) + ; + else + continue; /* { dg-error "continue statement not within a loop" } */ +/* { dg-begin-multiline-output "" } + continue; + ^~~~~~~~ + { dg-end-multiline-output "" } */ +} + +/* Various examples of bad type decls. */ + +int float bogus; /* { dg-error "two or more data types in declaration specifiers" } */ +/* { dg-begin-multiline-output "" } + int float bogus; + ^~~~~ + { dg-end-multiline-output "" } */ + +long long long bogus2; /* { dg-error "'long long long' is too long for GCC" } */ +/* { dg-begin-multiline-output "" } + long long long bogus2; + ^~~~ + { dg-end-multiline-output "" } */ + +long short bogus3; /* { dg-error "both 'long' and 'short' in declaration specifiers" } */ +/* { dg-begin-multiline-output "" } + long short bogus3; + ^~~~~ + { dg-end-multiline-output "" } */ + +signed unsigned bogus4; /* { dg-error "both 'signed' and 'unsigned' in declaration specifiers" } */ +/* { dg-begin-multiline-output "" } + signed unsigned bogus4; + ^~~~~~~~ + { dg-end-multiline-output "" } */ diff --git a/gcc/testsuite/gcc.dg/diagnostic-tree-expr-ranges-2.c b/gcc/testsuite/gcc.dg/diagnostic-tree-expr-ranges-2.c new file mode 100644 index 00000000000..302e233a04a --- /dev/null +++ b/gcc/testsuite/gcc.dg/diagnostic-tree-expr-ranges-2.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-Wuninitialized -fdiagnostics-show-caret" } */ + +int test_uninit_1 (void) +{ + int result; + return result; /* { dg-warning "uninitialized" } */ +/* { dg-begin-multiline-output "" } + return result; + ^~~~~~ + { dg-end-multiline-output "" } */ +} + +int test_uninit_2 (void) +{ + int result; + result += 3; /* { dg-warning "uninitialized" } */ +/* { dg-begin-multiline-output "" } + result += 3; + ~~~~~~~^~~~ + { dg-end-multiline-output "" } */ + return result; +} diff --git a/gcc/testsuite/gcc.dg/goacc/nvptx-merged-loop.c b/gcc/testsuite/gcc.dg/goacc/nvptx-merged-loop.c new file mode 100644 index 00000000000..3ff537c1d97 --- /dev/null +++ b/gcc/testsuite/gcc.dg/goacc/nvptx-merged-loop.c @@ -0,0 +1,30 @@ +/* { dg-do link } */ +/* { dg-require-effective-target offload_nvptx } */ +/* { dg-options "-fopenacc -O2 -foffload=-fdump-rtl-mach\\ -dumpbase\\ nvptx-merged-loop.c\\ -Wa,--no-verify" } */ + +#define N (32*32*32+17) +void __attribute__ ((noinline)) Foo (int *ary) +{ + int ix; + +#pragma acc parallel num_workers(32) vector_length(32) copyout(ary[0:N]) + { + /* Loop partitioning should be merged. */ +#pragma acc loop worker vector + for (unsigned ix = 0; ix < N; ix++) + { + ary[ix] = ix; + } + } +} + +int main () +{ + int ary[N]; + + Foo (ary); + + return 0; +} + +/* { dg-final { scan-rtl-dump "Merging loop .* into " "mach" } } */ diff --git a/gcc/testsuite/gcc.dg/graphite/fuse-1.c b/gcc/testsuite/gcc.dg/graphite/fuse-1.c index c9bb67debe1..249276c08ab 100644 --- a/gcc/testsuite/gcc.dg/graphite/fuse-1.c +++ b/gcc/testsuite/gcc.dg/graphite/fuse-1.c @@ -1,7 +1,6 @@ /* Check that the two loops are fused and that we manage to fold the two xor operations. */ -/* { dg-options "-O2 -floop-nest-optimize -fdump-tree-forwprop-all" } */ -/* { dg-do run } */ +/* { dg-options "-O2 -floop-nest-optimize -fdump-tree-forwprop-all -fdump-tree-graphite-all" } */ /* Make sure we fuse the loops like this: ISL AST generated by ISL: @@ -9,15 +8,12 @@ for (int c0 = 0; c0 <= 99; c0 += 1) { S_3(c0); S_6(c0); S_9(c0); -} -*/ -/* { dg-final { scan-tree-dump-times "ISL AST generated by ISL:.*for (int c0 = 0; c0 <= 99; c0 += 1) \{.*S_.*(c0);.*S_.*(c0);.*S_.*(c0);.*\}" 1 "graphite" } } */ +} */ +/* { dg-final { scan-tree-dump-times "ISL AST generated by ISL:.*for \\(int c0 = 0; c0 <= 99; c0 \\+= 1\\) \\{.*S_.*\\(c0\\);.*S_.*\\(c0\\);.*S_.*\\(c0\\);.*\\}" 1 "graphite" } } */ /* Check that after fusing the loops, the scalar computation is also fused. */ /* { dg-final { scan-tree-dump-times "gimple_simplified to\[^\\n\]*\\^ 12" 1 "forwprop4" } } */ - - #define MAX 100 int A[MAX]; diff --git a/gcc/testsuite/gcc.dg/graphite/fuse-2.c b/gcc/testsuite/gcc.dg/graphite/fuse-2.c index aaa5e2f8c36..2f27c66fd32 100644 --- a/gcc/testsuite/gcc.dg/graphite/fuse-2.c +++ b/gcc/testsuite/gcc.dg/graphite/fuse-2.c @@ -1,6 +1,4 @@ /* Check that the three loops are fused. */ -/* { dg-options "-O2 -floop-nest-optimize" } */ -/* { dg-do run } */ /* Make sure we fuse the loops like this: ISL AST generated by ISL: @@ -11,7 +9,7 @@ for (int c0 = 0; c0 <= 99; c0 += 1) { } */ -/* { dg-final { scan-tree-dump-times "ISL AST generated by ISL:.*for (int c0 = 0; c0 <= 99; c0 += 1) \{.*S_.*(c0);.*S_.*(c0);.*S_.*(c0);.*\}" 1 "graphite" } } */ +/* { dg-final { scan-tree-dump-times "ISL AST generated by ISL:.*for \\(int c0 = 0; c0 <= 99; c0 \\+= 1\\) \\{.*S_.*\\(c0\\);.*S_.*\\(c0\\);.*S_.*\\(c0\\);.*\\}" 1 "graphite" } } */ #define MAX 100 int A[MAX], B[MAX], C[MAX]; diff --git a/gcc/testsuite/gcc.dg/graphite/graphite.exp b/gcc/testsuite/gcc.dg/graphite/graphite.exp index f2d1417d87e..8e1a2299a23 100644 --- a/gcc/testsuite/gcc.dg/graphite/graphite.exp +++ b/gcc/testsuite/gcc.dg/graphite/graphite.exp @@ -43,6 +43,8 @@ set id_files [lsort [glob -nocomplain $srcdir/$subdir/id-*.c ] ] set run_id_files [lsort [glob -nocomplain $srcdir/$subdir/run-id-*.c ] ] set opt_files [lsort [glob -nocomplain $srcdir/$subdir/interchange-*.c \ $srcdir/$subdir/uns-interchange-*.c \ + $srcdir/$subdir/isl-ast-gen-*.c \ + $srcdir/$subdir/fuse-*.c \ $srcdir/$subdir/block-*.c \ $srcdir/$subdir/uns-block-*.c ] ] set vect_files [lsort [glob -nocomplain $srcdir/$subdir/vect-*.c ] ] diff --git a/gcc/testsuite/gcc.dg/graphite/isl-ast-gen-blocks-1.c b/gcc/testsuite/gcc.dg/graphite/isl-ast-gen-blocks-1.c index 6146b18fc03..cd67d87534e 100644 --- a/gcc/testsuite/gcc.dg/graphite/isl-ast-gen-blocks-1.c +++ b/gcc/testsuite/gcc.dg/graphite/isl-ast-gen-blocks-1.c @@ -1,6 +1,3 @@ -/* { dg-do run } */ -/* { dg-options "-O2 -fgraphite-identity" } */ - int n = 50; static int __attribute__((noinline)) foo () diff --git a/gcc/testsuite/gcc.dg/graphite/isl-ast-gen-blocks-2.c b/gcc/testsuite/gcc.dg/graphite/isl-ast-gen-blocks-2.c index 42ff30a5c58..d97a8ab20d5 100644 --- a/gcc/testsuite/gcc.dg/graphite/isl-ast-gen-blocks-2.c +++ b/gcc/testsuite/gcc.dg/graphite/isl-ast-gen-blocks-2.c @@ -1,6 +1,3 @@ -/* { dg-do run } */ -/* { dg-options "-O2 -fgraphite-identity" } */ - int k = 50; static int __attribute__((noinline)) foo () diff --git a/gcc/testsuite/gcc.dg/graphite/isl-ast-gen-blocks-3.c b/gcc/testsuite/gcc.dg/graphite/isl-ast-gen-blocks-3.c index 771d337bdde..9c5223c5d73 100644 --- a/gcc/testsuite/gcc.dg/graphite/isl-ast-gen-blocks-3.c +++ b/gcc/testsuite/gcc.dg/graphite/isl-ast-gen-blocks-3.c @@ -1,6 +1,3 @@ -/* { dg-do run } */ -/* { dg-options "-O2 -fgraphite-identity" } */ - /* We use a global variable 'k' to avoid ipa-cp. */ int k = 50; static int __attribute__((noinline)) diff --git a/gcc/testsuite/gcc.dg/graphite/isl-ast-gen-blocks-4.c b/gcc/testsuite/gcc.dg/graphite/isl-ast-gen-blocks-4.c index 803eea732bf..45ecad5d6e9 100644 --- a/gcc/testsuite/gcc.dg/graphite/isl-ast-gen-blocks-4.c +++ b/gcc/testsuite/gcc.dg/graphite/isl-ast-gen-blocks-4.c @@ -1,6 +1,3 @@ -/* { dg-do run } */ -/* { dg-options "-O2 -fgraphite-identity" } */ - static int __attribute__((noinline)) foo (int k, int n1, int n2, int n3) { diff --git a/gcc/testsuite/gcc.dg/graphite/isl-ast-gen-if-1.c b/gcc/testsuite/gcc.dg/graphite/isl-ast-gen-if-1.c index 2b05c7bb57d..a0eb24216db 100644 --- a/gcc/testsuite/gcc.dg/graphite/isl-ast-gen-if-1.c +++ b/gcc/testsuite/gcc.dg/graphite/isl-ast-gen-if-1.c @@ -1,6 +1,3 @@ -/* { dg-do run } */ -/* { dg-options "-O2 -fgraphite-identity" } */ - int st = 1; static void __attribute__((noinline)) foo (int a[], int n) diff --git a/gcc/testsuite/gcc.dg/graphite/isl-ast-gen-if-2.c b/gcc/testsuite/gcc.dg/graphite/isl-ast-gen-if-2.c index 90111e70a1a..27e7fa42c6b 100644 --- a/gcc/testsuite/gcc.dg/graphite/isl-ast-gen-if-2.c +++ b/gcc/testsuite/gcc.dg/graphite/isl-ast-gen-if-2.c @@ -1,6 +1,3 @@ -/* { dg-do run } */ -/* { dg-options "-O2 -fgraphite-identity" } */ - /* This test case tests reduction, where the pbbs are duplicated. */ static int __attribute__((noinline)) diff --git a/gcc/testsuite/gcc.dg/graphite/isl-ast-gen-single-loop-1.c b/gcc/testsuite/gcc.dg/graphite/isl-ast-gen-single-loop-1.c index 754452be00c..6c141a1b232 100644 --- a/gcc/testsuite/gcc.dg/graphite/isl-ast-gen-single-loop-1.c +++ b/gcc/testsuite/gcc.dg/graphite/isl-ast-gen-single-loop-1.c @@ -1,6 +1,3 @@ -/* { dg-do run } */ -/* { dg-options "-O2 -fgraphite-identity" } */ - int foo () { diff --git a/gcc/testsuite/gcc.dg/graphite/isl-ast-gen-single-loop-2.c b/gcc/testsuite/gcc.dg/graphite/isl-ast-gen-single-loop-2.c index 04c7dbaf017..d37a49388b2 100644 --- a/gcc/testsuite/gcc.dg/graphite/isl-ast-gen-single-loop-2.c +++ b/gcc/testsuite/gcc.dg/graphite/isl-ast-gen-single-loop-2.c @@ -1,5 +1,3 @@ -/* { dg-do run } */ -/* { dg-options "-O2 -fgraphite-identity" } */ int n = 50; void diff --git a/gcc/testsuite/gcc.dg/graphite/isl-ast-gen-single-loop-3.c b/gcc/testsuite/gcc.dg/graphite/isl-ast-gen-single-loop-3.c index 204acd3955b..d96f99fe52d 100644 --- a/gcc/testsuite/gcc.dg/graphite/isl-ast-gen-single-loop-3.c +++ b/gcc/testsuite/gcc.dg/graphite/isl-ast-gen-single-loop-3.c @@ -1,5 +1,3 @@ -/* { dg-do run } */ -/* { dg-options "-O2 -fgraphite-identity" } */ int n = 50; void diff --git a/gcc/testsuite/gcc.dg/graphite/isl-ast-gen-user-1.c b/gcc/testsuite/gcc.dg/graphite/isl-ast-gen-user-1.c index 760c1a2f283..8f246d8e6a4 100644 --- a/gcc/testsuite/gcc.dg/graphite/isl-ast-gen-user-1.c +++ b/gcc/testsuite/gcc.dg/graphite/isl-ast-gen-user-1.c @@ -1,14 +1,10 @@ -/* { dg-do compile } */ -/* { dg-options "-O2 -fgraphite-identity" } */ - -#include <stdio.h> -#include <stdlib.h> - static const int N = 12; +int nSlip; -void Crystal_Cholesky (int nSlip, int a[N][N]) +int main () { int i, j, k, fdot = 0; + int a[N][N]; for ( i = 1; i < nSlip; i++) { @@ -19,6 +15,8 @@ void Crystal_Cholesky (int nSlip, int a[N][N]) a[i][j] = a[i][j] - fdot; } } + + return 0; } diff --git a/gcc/testsuite/gcc.dg/graphite/isl-codegen-loop-dumping.c b/gcc/testsuite/gcc.dg/graphite/isl-codegen-loop-dumping.c deleted file mode 100644 index 70ac24c46d7..00000000000 --- a/gcc/testsuite/gcc.dg/graphite/isl-codegen-loop-dumping.c +++ /dev/null @@ -1,17 +0,0 @@ -/* { dg-options "-O2 -fgraphite-identity -fdump-tree-graphite-all" } */ - -int -main (int n, int *a) -{ - int i, j; - - for (i = 0; i < n - 1; i++) - for (j = 0; j < n; j++) - a[j] = i + n; - - return 0; -} - -/* { dg-final { scan-tree-dump-times "ISL AST generated by ISL: \n\\{\n S_2\\();\n if \\(P_19 >= 1\\)\n - for \\(int c1 = 0; c1 < n - 1; c1 \\+= 1\\) \\{ \n for \\(int c3 = 0; c3 < n; c3 \\+= 1\\)\n - S_4\\(c1, c3\\); \n S_6\\(c1\\);\n \\} \n\\}" 1 "graphite"} } */ diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-expressions-1.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-expressions-1.c new file mode 100644 index 00000000000..5485aafec01 --- /dev/null +++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-expressions-1.c @@ -0,0 +1,422 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdiagnostics-show-caret" } */ + +/* This is a collection of unittests to verify that we're correctly + capturing the source code ranges of various kinds of expression. + + It uses the various "diagnostic_test_*_expression_range_plugin" + plugins which handles "__emit_expression_range" by generating a warning + at the given source range of the input argument. Each of the + different plugins do this at a different phase of the internal + representation (tree, gimple, etc), so we can verify that the + source code range information is valid at each phase. + + We want to accept an expression of any type. To do this in C, we + use variadic arguments, but C requires at least one argument before + the ellipsis, so we have a dummy one. */ + +extern void __emit_expression_range (int dummy, ...); + +int global; + +void test_parentheses (int a, int b) +{ + __emit_expression_range (0, (a + b) ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, (a + b) ); + ~~~^~~~ + { dg-end-multiline-output "" } */ + + __emit_expression_range (0, (a + b) * (a - b) ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, (a + b) * (a - b) ); + ~~~~~~~~^~~~~~~~~ + { dg-end-multiline-output "" } */ + + __emit_expression_range (0, !(a && b) ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, !(a && b) ); + ^~~~~~~~~ + { dg-end-multiline-output "" } */ +} + +/* Postfix expressions. ************************************************/ + +void test_array_reference (int *arr) +{ + __emit_expression_range (0, arr[100] ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, arr[100] ); + ~~~^~~~~ + { dg-end-multiline-output "" } */ +} + +int test_function_call (int p, int q, int r) +{ + __emit_expression_range (0, test_function_call (p, q, r) ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, test_function_call (p, q, r) ); + ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ + { dg-end-multiline-output "" } */ + return 0; +} + +struct test_struct +{ + int field; +}; + +int test_structure_references (struct test_struct *ptr) +{ + struct test_struct local; + local.field = 42; + + __emit_expression_range (0, local.field ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, local.field ); + ~~~~~^~~~~~ + { dg-end-multiline-output "" } */ + + __emit_expression_range (0, ptr->field ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, ptr->field ); + ~~~^~~~~~~ + { dg-end-multiline-output "" } */ +} + +int test_postfix_incdec (int i) +{ + __emit_expression_range (0, i++ ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, i++ ); + ~^~ + { dg-end-multiline-output "" } */ + + __emit_expression_range (0, i-- ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, i-- ); + ~^~ + { dg-end-multiline-output "" } */ +} + +/* Unary operators. ****************************************************/ + +int test_prefix_incdec (int i) +{ + __emit_expression_range (0, ++i ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, ++i ); + ^~~ + { dg-end-multiline-output "" } */ + + __emit_expression_range (0, --i ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, --i ); + ^~~ + { dg-end-multiline-output "" } */ +} + +void test_address_operator (void) +{ + __emit_expression_range (0, &global ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, &global ); + ^~~~~~~ + { dg-end-multiline-output "" } */ +} + +void test_indirection (int *ptr) +{ + __emit_expression_range (0, *ptr ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, *ptr ); + ^~~~ + { dg-end-multiline-output "" } */ +} + +void test_unary_minus (int i) +{ + __emit_expression_range (0, -i ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, -i ); + ^~ + { dg-end-multiline-output "" } */ +} + +void test_ones_complement (int i) +{ + __emit_expression_range (0, ~i ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, ~i ); + ^~ + { dg-end-multiline-output "" } */ +} + +void test_logical_negation (int flag) +{ + __emit_expression_range (0, !flag ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, !flag ); + ^~~~~ + { dg-end-multiline-output "" } */ +} + +/* Casts. ****************************************************/ + +void test_cast (void *ptr) +{ + __emit_expression_range (0, (int *)ptr ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, (int *)ptr ); + ^~~~~~~~~~ + { dg-end-multiline-output "" } */ + +} + +/* Binary operators. *******************************************/ + +void test_multiplicative_operators (int lhs, int rhs) +{ + __emit_expression_range (0, lhs * rhs ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, lhs * rhs ); + ~~~~^~~~~ + { dg-end-multiline-output "" } */ + + __emit_expression_range (0, lhs / rhs ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, lhs / rhs ); + ~~~~^~~~~ + { dg-end-multiline-output "" } */ + + __emit_expression_range (0, lhs % rhs ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, lhs % rhs ); + ~~~~^~~~~ + { dg-end-multiline-output "" } */ +} + +void test_additive_operators (int lhs, int rhs) +{ + __emit_expression_range (0, lhs + rhs ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, lhs + rhs ); + ~~~~^~~~~ + { dg-end-multiline-output "" } */ + + __emit_expression_range (0, lhs - rhs ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, lhs - rhs ); + ~~~~^~~~~ + { dg-end-multiline-output "" } */ +} + +void test_shift_operators (int lhs, int rhs) +{ + __emit_expression_range (0, lhs << rhs ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, lhs << rhs ); + ~~~~^~~~~~ + { dg-end-multiline-output "" } */ + + __emit_expression_range (0, lhs >> rhs ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, lhs >> rhs ); + ~~~~^~~~~~ + { dg-end-multiline-output "" } */ +} + +void test_relational_operators (int lhs, int rhs) +{ + __emit_expression_range (0, lhs < rhs ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, lhs < rhs ); + ~~~~^~~~~ + { dg-end-multiline-output "" } */ + + __emit_expression_range (0, lhs > rhs ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, lhs > rhs ); + ~~~~^~~~~ + { dg-end-multiline-output "" } */ + + __emit_expression_range (0, lhs <= rhs ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, lhs <= rhs ); + ~~~~^~~~~~ + { dg-end-multiline-output "" } */ + + __emit_expression_range (0, lhs >= rhs ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, lhs >= rhs ); + ~~~~^~~~~~ + { dg-end-multiline-output "" } */ +} + +void test_equality_operators (int lhs, int rhs) +{ + __emit_expression_range (0, lhs == rhs ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, lhs == rhs ); + ~~~~^~~~~~ + { dg-end-multiline-output "" } */ + + __emit_expression_range (0, lhs != rhs ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, lhs != rhs ); + ~~~~^~~~~~ + { dg-end-multiline-output "" } */ +} + +void test_bitwise_binary_operators (int lhs, int rhs) +{ + __emit_expression_range (0, lhs & rhs ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, lhs & rhs ); + ~~~~^~~~~ + { dg-end-multiline-output "" } */ + + __emit_expression_range (0, lhs ^ rhs ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, lhs ^ rhs ); + ~~~~^~~~~ + { dg-end-multiline-output "" } */ + + __emit_expression_range (0, lhs | rhs ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, lhs | rhs ); + ~~~~^~~~~ + { dg-end-multiline-output "" } */ +} + +void test_logical_operators (int lhs, int rhs) +{ + __emit_expression_range (0, lhs && rhs ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, lhs && rhs ); + ~~~~^~~~~~ + { dg-end-multiline-output "" } */ + + __emit_expression_range (0, lhs || rhs ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, lhs || rhs ); + ~~~~^~~~~~ + { dg-end-multiline-output "" } */ +} + +/* Conditional operator. *******************************************/ + +void test_conditional_operators (int flag, int on_true, int on_false) +{ + __emit_expression_range (0, flag ? on_true : on_false ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, flag ? on_true : on_false ); + ~~~~~~~~~~~~~~~^~~~~~~~~~ + { dg-end-multiline-output "" } */ +} + +/* Assignment expressions. *******************************************/ + +void test_assignment_expressions (int dest, int other) +{ + __emit_expression_range (0, dest = other ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, dest = other ); + ~~~~~^~~~~~~ + { dg-end-multiline-output "" } */ + + __emit_expression_range (0, dest *= other ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, dest *= other ); + ~~~~~^~~~~~~~ + { dg-end-multiline-output "" } */ + + __emit_expression_range (0, dest /= other ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, dest /= other ); + ~~~~~^~~~~~~~ + { dg-end-multiline-output "" } */ + + __emit_expression_range (0, dest %= other ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, dest %= other ); + ~~~~~^~~~~~~~ + { dg-end-multiline-output "" } */ + + __emit_expression_range (0, dest += other ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, dest += other ); + ~~~~~^~~~~~~~ + { dg-end-multiline-output "" } */ + + __emit_expression_range (0, dest -= other ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, dest -= other ); + ~~~~~^~~~~~~~ + { dg-end-multiline-output "" } */ + + __emit_expression_range (0, dest <<= other ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, dest <<= other ); + ~~~~~^~~~~~~~~ + { dg-end-multiline-output "" } */ + + __emit_expression_range (0, dest >>= other ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, dest >>= other ); + ~~~~~^~~~~~~~~ + { dg-end-multiline-output "" } */ + + __emit_expression_range (0, dest &= other ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, dest &= other ); + ~~~~~^~~~~~~~ + { dg-end-multiline-output "" } */ + + __emit_expression_range (0, dest ^= other ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, dest ^= other ); + ~~~~~^~~~~~~~ + { dg-end-multiline-output "" } */ + + __emit_expression_range (0, dest |= other ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, dest |= other ); + ~~~~~^~~~~~~~ + { dg-end-multiline-output "" } */ +} + +/* Comma operator. *******************************************/ + +void test_comma_operator (int a, int b) +{ + __emit_expression_range (0, (a++, a + b) ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, (a++, a + b) ); + ~~~~^~~~~~~~ + { dg-end-multiline-output "" } */ +} + +/* Examples of non-trivial expressions. ****************************/ + +extern double sqrt (double x); + +void test_quadratic (double a, double b, double c) +{ + __emit_expression_range (0, b * b - 4 * a * c ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, b * b - 4 * a * c ); + ~~~~~~^~~~~~~~~~~ + { dg-end-multiline-output "" } */ + + __emit_expression_range (0, + (-b + sqrt (b * b - 4 * a * c)) + / (2 * a)); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + (-b + sqrt (b * b - 4 * a * c)) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + / (2 * a)); + ^~~~~~~~~ + { dg-end-multiline-output "" } */ + +} diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-trees-1.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-trees-1.c new file mode 100644 index 00000000000..7473a07961f --- /dev/null +++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-trees-1.c @@ -0,0 +1,65 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdiagnostics-show-caret" } */ + +/* This is an example file for use with + diagnostic_plugin_show_trees.c. + + The plugin handles "__show_tree" by recursively dumping + the internal structure of the second input argument. + + We want to accept an expression of any type. To do this in C, we + use variadic arguments, but C requires at least one argument before + the ellipsis, so we have a dummy one. */ + +extern void __show_tree (int dummy, ...); + +extern double sqrt (double x); + +void test_quadratic (double a, double b, double c) +{ + __show_tree (0, + (-b + sqrt (b * b - 4 * a * c)) + / (2 * a)); + +/* { dg-begin-multiline-output "" } + (-b + sqrt (b * b - 4 * a * c)) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + / (2 * a)); + ^~~~~~~~~ + { dg-end-multiline-output "" } */ + +/* { dg-begin-multiline-output "" } + (-b + sqrt (b * b - 4 * a * c)) + ~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~ + { dg-end-multiline-output "" } */ + +/* { dg-begin-multiline-output "" } + (-b + sqrt (b * b - 4 * a * c)) + ^~~~~~~~~~~~~~~~~~~~~~~~ + { dg-end-multiline-output "" } */ + +/* { dg-begin-multiline-output "" } + (-b + sqrt (b * b - 4 * a * c)) + ~~~~~~^~~~~~~~~~~ + { dg-end-multiline-output "" } */ + +/* { dg-begin-multiline-output "" } + (-b + sqrt (b * b - 4 * a * c)) + ~~^~~ + { dg-end-multiline-output "" } */ + +/* { dg-begin-multiline-output "" } + (-b + sqrt (b * b - 4 * a * c)) + ~~~~~~^~~ + { dg-end-multiline-output "" } */ + +/* { dg-begin-multiline-output "" } + (-b + sqrt (b * b - 4 * a * c)) + ~~^~~ + { dg-end-multiline-output "" } */ + +/* { dg-begin-multiline-output "" } + / (2 * a)); + ~~~^~~~ + { dg-end-multiline-output "" } */ +} diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_show_trees.c b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_show_trees.c new file mode 100644 index 00000000000..5a911c17a4e --- /dev/null +++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_show_trees.c @@ -0,0 +1,174 @@ +/* This plugin recursively dumps the source-code location ranges of + expressions, at the pre-gimplification tree stage. */ +/* { dg-options "-O" } */ + +#include "gcc-plugin.h" +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "tree.h" +#include "stringpool.h" +#include "toplev.h" +#include "basic-block.h" +#include "hash-table.h" +#include "vec.h" +#include "ggc.h" +#include "basic-block.h" +#include "tree-ssa-alias.h" +#include "internal-fn.h" +#include "gimple-fold.h" +#include "tree-eh.h" +#include "gimple-expr.h" +#include "is-a.h" +#include "gimple.h" +#include "gimple-iterator.h" +#include "tree.h" +#include "tree-pass.h" +#include "intl.h" +#include "plugin-version.h" +#include "diagnostic.h" +#include "context.h" +#include "gcc-rich-location.h" +#include "print-tree.h" + +/* + Hack: fails with linker error: +./diagnostic_plugin_show_trees.so: undefined symbol: _ZN17gcc_rich_location8add_exprEP9tree_node + since nothing in the tree is using gcc_rich_location::add_expr yet. + + I've tried various workarounds (adding DEBUG_FUNCTION to the + method, taking its address), but can't seem to fix it that way. + So as a nasty workaround, the following material is copied&pasted + from gcc-rich-location.c: */ + +static bool +get_range_for_expr (tree expr, location_range *r) +{ + if (EXPR_HAS_RANGE (expr)) + { + source_range sr = EXPR_LOCATION_RANGE (expr); + + /* Do we have meaningful data? */ + if (sr.m_start && sr.m_finish) + { + r->m_start = expand_location (sr.m_start); + r->m_finish = expand_location (sr.m_finish); + return true; + } + } + + return false; +} + +/* Add a range to the rich_location, covering expression EXPR. */ + +void +gcc_rich_location::add_expr (tree expr) +{ + gcc_assert (expr); + + location_range r; + r.m_show_caret_p = false; + if (get_range_for_expr (expr, &r)) + add_range (&r); +} + +/* FIXME: end of material taken from gcc-rich-location.c */ + +int plugin_is_GPL_compatible; + +static void +show_tree (tree node) +{ + if (!CAN_HAVE_RANGE_P (node)) + return; + + gcc_rich_location richloc (EXPR_LOCATION (node)); + richloc.add_expr (node); + + if (richloc.get_num_locations () < 2) + { + error_at_rich_loc (&richloc, "range not found"); + return; + } + + enum tree_code code = TREE_CODE (node); + + location_range *range = richloc.get_range (1); + inform_at_rich_loc (&richloc, + "%s at range %i:%i-%i:%i", + get_tree_code_name (code), + range->m_start.line, + range->m_start.column, + range->m_finish.line, + range->m_finish.column); + + /* Recurse. */ + int min_idx = 0; + int max_idx = TREE_OPERAND_LENGTH (node); + switch (code) + { + case CALL_EXPR: + min_idx = 3; + break; + + default: + break; + } + + for (int i = min_idx; i < max_idx; i++) + show_tree (TREE_OPERAND (node, i)); +} + +tree +cb_walk_tree_fn (tree * tp, int * walk_subtrees, + void * data ATTRIBUTE_UNUSED) +{ + if (TREE_CODE (*tp) != CALL_EXPR) + return NULL_TREE; + + tree call_expr = *tp; + tree fn = CALL_EXPR_FN (call_expr); + if (TREE_CODE (fn) != ADDR_EXPR) + return NULL_TREE; + fn = TREE_OPERAND (fn, 0); + if (TREE_CODE (fn) != FUNCTION_DECL) + return NULL_TREE; + if (strcmp (IDENTIFIER_POINTER (DECL_NAME (fn)), "__show_tree")) + return NULL_TREE; + + /* Get arg 1; print it! */ + tree arg = CALL_EXPR_ARG (call_expr, 1); + + show_tree (arg); + + return NULL_TREE; +} + +static void +callback (void *gcc_data, void *user_data) +{ + tree fndecl = (tree)gcc_data; + walk_tree (&DECL_SAVED_TREE (fndecl), cb_walk_tree_fn, NULL, NULL); +} + +int +plugin_init (struct plugin_name_args *plugin_info, + struct plugin_gcc_version *version) +{ + struct register_pass_info pass_info; + const char *plugin_name = plugin_info->base_name; + int argc = plugin_info->argc; + struct plugin_argument *argv = plugin_info->argv; + + if (!plugin_default_version_check (version, &gcc_version)) + return 1; + + register_callback (plugin_name, + PLUGIN_PRE_GENERICIZE, + callback, + NULL); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_show_locus.c b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_show_locus.c index 8f5724ec27d..158c6124a99 100644 --- a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_show_locus.c +++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_show_locus.c @@ -109,7 +109,8 @@ get_loc (unsigned int line_num, unsigned int col_num) /* Convert from 0-based column numbers to 1-based column numbers. */ source_location loc - = linemap_position_for_line_and_column (line_map, + = linemap_position_for_line_and_column (line_table, + line_map, line_num, col_num + 1); return loc; @@ -163,7 +164,7 @@ test_show_locus (function *fun) if (0 == strcmp (fnname, "test_simple")) { const int line = fnstart_line + 2; - rich_location richloc (get_loc (line, 15)); + rich_location richloc (line_table, get_loc (line, 15)); richloc.add_range (get_loc (line, 10), get_loc (line, 14), false); richloc.add_range (get_loc (line, 16), get_loc (line, 16), false); warning_at_rich_loc (&richloc, 0, "test"); @@ -172,7 +173,7 @@ test_show_locus (function *fun) if (0 == strcmp (fnname, "test_simple_2")) { const int line = fnstart_line + 2; - rich_location richloc (get_loc (line, 24)); + rich_location richloc (line_table, get_loc (line, 24)); richloc.add_range (get_loc (line, 6), get_loc (line, 22), false); richloc.add_range (get_loc (line, 26), @@ -183,7 +184,7 @@ test_show_locus (function *fun) if (0 == strcmp (fnname, "test_multiline")) { const int line = fnstart_line + 2; - rich_location richloc (get_loc (line + 1, 7)); + rich_location richloc (line_table, get_loc (line + 1, 7)); richloc.add_range (get_loc (line, 7), get_loc (line, 23), false); richloc.add_range (get_loc (line + 1, 9), @@ -194,7 +195,7 @@ test_show_locus (function *fun) if (0 == strcmp (fnname, "test_many_lines")) { const int line = fnstart_line + 2; - rich_location richloc (get_loc (line + 5, 7)); + rich_location richloc (line_table, get_loc (line + 5, 7)); richloc.add_range (get_loc (line, 7), get_loc (line + 4, 65), false); richloc.add_range (get_loc (line + 5, 9), @@ -223,7 +224,7 @@ test_show_locus (function *fun) source_range src_range; src_range.m_start = get_loc (line, 12); src_range.m_finish = get_loc (line, 20); - rich_location richloc (caret); + rich_location richloc (line_table, caret); richloc.set_range (0, src_range, true, false); warning_at_rich_loc (&richloc, 0, "test"); } @@ -237,7 +238,7 @@ test_show_locus (function *fun) source_range src_range; src_range.m_start = get_loc (line, 90); src_range.m_finish = get_loc (line, 98); - rich_location richloc (caret); + rich_location richloc (line_table, caret); richloc.set_range (0, src_range, true, false); warning_at_rich_loc (&richloc, 0, "test"); } @@ -248,7 +249,7 @@ test_show_locus (function *fun) const int line = fnstart_line + 2; location_t caret_a = get_loc (line, 7); location_t caret_b = get_loc (line, 11); - rich_location richloc (caret_a); + rich_location richloc (line_table, caret_a); richloc.add_range (caret_b, caret_b, true); global_dc->caret_chars[0] = 'A'; global_dc->caret_chars[1] = 'B'; @@ -269,7 +270,7 @@ test_show_locus (function *fun) const int line = fnstart_line + 3; location_t caret_a = get_loc (line, 5); location_t caret_b = get_loc (line - 1, 19); - rich_location richloc (caret_a); + rich_location richloc (line_table, caret_a); richloc.add_range (caret_b, caret_b, true); global_dc->caret_chars[0] = '1'; global_dc->caret_chars[1] = '2'; @@ -304,11 +305,6 @@ plugin_init (struct plugin_name_args *plugin_info, if (!plugin_default_version_check (version, &gcc_version)) return 1; - /* For now, tell the dc to expect ranges and thus to colorize the source - lines, not just the carets/underlines. This will be redundant - once the C frontend generates ranges. */ - global_dc->colorize_source_p = true; - for (int i = 0; i < argc; i++) { if (0 == strcmp (argv[i].key, "color")) diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_tree_expression_range.c b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_tree_expression_range.c new file mode 100644 index 00000000000..89cc95acd99 --- /dev/null +++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_tree_expression_range.c @@ -0,0 +1,98 @@ +/* This plugin verifies the source-code location ranges of + expressions, at the pre-gimplification tree stage. */ +/* { dg-options "-O" } */ + +#include "gcc-plugin.h" +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "tree.h" +#include "stringpool.h" +#include "toplev.h" +#include "basic-block.h" +#include "hash-table.h" +#include "vec.h" +#include "ggc.h" +#include "basic-block.h" +#include "tree-ssa-alias.h" +#include "internal-fn.h" +#include "gimple-fold.h" +#include "tree-eh.h" +#include "gimple-expr.h" +#include "is-a.h" +#include "gimple.h" +#include "gimple-iterator.h" +#include "tree.h" +#include "tree-pass.h" +#include "intl.h" +#include "plugin-version.h" +#include "diagnostic.h" +#include "context.h" +#include "print-tree.h" + +int plugin_is_GPL_compatible; + +static void +emit_warning (location_t loc) +{ + source_range src_range = get_range_from_loc (line_table, loc); + warning_at (loc, 0, + "tree range %i:%i-%i:%i", + LOCATION_LINE (src_range.m_start), + LOCATION_COLUMN (src_range.m_start), + LOCATION_LINE (src_range.m_finish), + LOCATION_COLUMN (src_range.m_finish)); +} + +tree +cb_walk_tree_fn (tree * tp, int * walk_subtrees, + void * data ATTRIBUTE_UNUSED) +{ + if (TREE_CODE (*tp) != CALL_EXPR) + return NULL_TREE; + + tree call_expr = *tp; + tree fn = CALL_EXPR_FN (call_expr); + if (TREE_CODE (fn) != ADDR_EXPR) + return NULL_TREE; + fn = TREE_OPERAND (fn, 0); + if (TREE_CODE (fn) != FUNCTION_DECL) + return NULL_TREE; + if (strcmp (IDENTIFIER_POINTER (DECL_NAME (fn)), "__emit_expression_range")) + return NULL_TREE; + + /* Get arg 1; print it! */ + tree arg = CALL_EXPR_ARG (call_expr, 1); + + emit_warning (EXPR_LOCATION (arg)); + + return NULL_TREE; +} + +static void +callback (void *gcc_data, void *user_data) +{ + tree fndecl = (tree)gcc_data; + walk_tree (&DECL_SAVED_TREE (fndecl), cb_walk_tree_fn, NULL, NULL); +} + +int +plugin_init (struct plugin_name_args *plugin_info, + struct plugin_gcc_version *version) +{ + struct register_pass_info pass_info; + const char *plugin_name = plugin_info->base_name; + int argc = plugin_info->argc; + struct plugin_argument *argv = plugin_info->argv; + + if (!plugin_default_version_check (version, &gcc_version)) + return 1; + + register_callback (plugin_name, + PLUGIN_PRE_GENERICIZE, + callback, + NULL); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/plugin/levenshtein-test-1.c b/gcc/testsuite/gcc.dg/plugin/levenshtein-test-1.c new file mode 100644 index 00000000000..ac49992780d --- /dev/null +++ b/gcc/testsuite/gcc.dg/plugin/levenshtein-test-1.c @@ -0,0 +1,9 @@ +/* Placeholder C source file for unit-testing gcc/spellcheck.c. */ +/* { dg-do compile } */ +/* { dg-options "-O" } */ + +int +main (int argc, char **argv) +{ + return 0; +} diff --git a/gcc/testsuite/gcc.dg/plugin/levenshtein_plugin.c b/gcc/testsuite/gcc.dg/plugin/levenshtein_plugin.c new file mode 100644 index 00000000000..3e7dc788930 --- /dev/null +++ b/gcc/testsuite/gcc.dg/plugin/levenshtein_plugin.c @@ -0,0 +1,64 @@ +/* Plugin for unittesting gcc/spellcheck.h. */ + +#include "config.h" +#include "gcc-plugin.h" +#include "system.h" +#include "coretypes.h" +#include "spellcheck.h" +#include "diagnostic.h" + +int plugin_is_GPL_compatible; + +static void +levenshtein_distance_unit_test_oneway (const char *a, const char *b, + edit_distance_t expected) +{ + edit_distance_t actual = levenshtein_distance (a, b); + if (actual != expected) + error ("levenshtein_distance (\"%s\", \"%s\") : expected: %i got %i", + a, b, expected, actual); +} + + +static void +levenshtein_distance_unit_test (const char *a, const char *b, + edit_distance_t expected) +{ + /* Run every test both ways to ensure it's symmetric. */ + levenshtein_distance_unit_test_oneway (a, b, expected); + levenshtein_distance_unit_test_oneway (b, a, expected); +} + +/* Callback handler for the PLUGIN_FINISH event; run + levenshtein_distance unit tests here. */ + +static void +on_finish (void */*gcc_data*/, void */*user_data*/) +{ + levenshtein_distance_unit_test ("", "nonempty", strlen ("nonempty")); + levenshtein_distance_unit_test ("saturday", "sunday", 3); + levenshtein_distance_unit_test ("foo", "m_foo", 2); + levenshtein_distance_unit_test ("hello_world", "HelloWorld", 3); + levenshtein_distance_unit_test + ("the quick brown fox jumps over the lazy dog", "dog", 40); + levenshtein_distance_unit_test + ("the quick brown fox jumps over the lazy dog", + "the quick brown dog jumps over the lazy fox", + 4); + levenshtein_distance_unit_test + ("Lorem ipsum dolor sit amet, consectetur adipiscing elit,", + "All your base are belong to us", + 44); +} + +int +plugin_init (struct plugin_name_args *plugin_info, + struct plugin_gcc_version */*version*/) +{ + register_callback (plugin_info->base_name, + PLUGIN_FINISH, + on_finish, + NULL); /* void *user_data */ + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/plugin/plugin.exp b/gcc/testsuite/gcc.dg/plugin/plugin.exp index 941bccc4387..06080cce8d2 100644 --- a/gcc/testsuite/gcc.dg/plugin/plugin.exp +++ b/gcc/testsuite/gcc.dg/plugin/plugin.exp @@ -66,6 +66,11 @@ set plugin_test_list [list \ { diagnostic_plugin_test_show_locus.c \ diagnostic-test-show-locus-bw.c \ diagnostic-test-show-locus-color.c } \ + { diagnostic_plugin_test_tree_expression_range.c \ + diagnostic-test-expressions-1.c } \ + { diagnostic_plugin_show_trees.c \ + diagnostic-test-show-trees-1.c } \ + { levenshtein_plugin.c levenshtein-test-1.c } \ ] foreach plugin_test $plugin_test_list { diff --git a/gcc/testsuite/gcc.dg/pr65521.c b/gcc/testsuite/gcc.dg/pr65521.c index 97879e2e139..be73dfbcfe7 100644 --- a/gcc/testsuite/gcc.dg/pr65521.c +++ b/gcc/testsuite/gcc.dg/pr65521.c @@ -1,6 +1,7 @@ /* PR ipa/65521 */ /* { dg-do compile } */ /* { dg-options "-O2 -fcompare-debug" } */ +/* { dg-xfail-if "" { powerpc-ibm-aix* } { "*" } { "" } } */ struct S { int s; }; int f6 (void *, unsigned long); diff --git a/gcc/testsuite/gcc.dg/pr67784-1.c b/gcc/testsuite/gcc.dg/pr67784-1.c new file mode 100644 index 00000000000..d5e85fc0c8b --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr67784-1.c @@ -0,0 +1,54 @@ +/* PR c/67784 */ +/* { dg-do compile } */ +/* { dg-options "" } */ + +typedef int T; + +void +fn1 (void) +{ + for (int T;;) + if (1) + ; + T *x; +} + +void +fn2 (void) +{ + for (int T;;) + if (1) + T = 1; + T *x; +} + +void +fn3 (void) +{ + for (int T;;) + if (1) + { + } + T *x; +} + +void +fn4 (void) +{ + for (int T;;) + if (1) +L: + ; + T *x; +} + +void +fn5 (void) +{ + for (int T;;) + if (1) + ; + else + ; + T *x; +} diff --git a/gcc/testsuite/gcc.dg/pr67784-2.c b/gcc/testsuite/gcc.dg/pr67784-2.c new file mode 100644 index 00000000000..de3b1c89a89 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr67784-2.c @@ -0,0 +1,54 @@ +/* PR c/67784 */ +/* { dg-do compile } */ +/* { dg-options "" } */ + +int T; + +void +fn1 (void) +{ + for (typedef int T;;) /* { dg-error "declaration of non-variable" } */ + if (1) + ; + T *x; /* { dg-error "undeclared" } */ +} + +void +fn2 (void) +{ + for (typedef int T;;) /* { dg-error "declaration of non-variable" } */ + if (1) + T = 1; /* { dg-error "expected expression" } */ + T *x; /* { dg-error "undeclared" } */ +} + +void +fn3 (void) +{ + for (typedef int T;;) /* { dg-error "declaration of non-variable" } */ + if (1) + { + } + T *x; /* { dg-error "undeclared" } */ +} + +void +fn4 (void) +{ + for (typedef int T;;) /* { dg-error "declaration of non-variable" } */ + if (1) +L: + ; + T *x; /* { dg-error "undeclared" } */ +} + +void +fn5 (void) +{ + for (typedef int T;;) /* { dg-error "declaration of non-variable" } */ + if (1) + ; + else + ; + T *x; /* { dg-error "undeclared" } */ +} diff --git a/gcc/testsuite/gcc.dg/pr68286.c b/gcc/testsuite/gcc.dg/pr68286.c new file mode 100644 index 00000000000..d0392e85a65 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr68286.c @@ -0,0 +1,17 @@ +/* PR target/68286 */ +/* { dg-do compile } */ +/* { dg-options "-O3" } */ + +int a, b, c; +int fn1 () +{ + int d[] = {0}; + for (; c; c++) + { + float e = c; + if (e) + d[0]++; + } + b = d[0]; + return a; +} diff --git a/gcc/testsuite/gcc.dg/pr68306-2.c b/gcc/testsuite/gcc.dg/pr68306-2.c new file mode 100644 index 00000000000..4672ebe7987 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr68306-2.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O3" } */ +/* { dg-additional-options "-mno-sse -mno-mmx" { target i?86-*-* x86_64-*-* } } */ + +struct { + int tz_minuteswest; + int tz_dsttime; +} a, b; +void fn1() { + b.tz_minuteswest = a.tz_minuteswest; + b.tz_dsttime = a.tz_dsttime; +} diff --git a/gcc/testsuite/gcc.dg/pr68306-3.c b/gcc/testsuite/gcc.dg/pr68306-3.c new file mode 100644 index 00000000000..f5a8c102cf8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr68306-3.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-O3" } */ +/* { dg-additional-options "-mno-sse -mno-mmx" { target i?86-*-* x86_64-*-* } } */ +/* { dg-additional-options "-mno-altivec -mno-vsx" { target powerpc*-*-* } } */ + +extern void fn2(); +struct { + unsigned qp_num; + unsigned starting_psn; + void *private_data; +} a; +struct { + unsigned id; + unsigned qpn; + unsigned psn; +} b; +void fn1() { + a.qp_num = b.qpn; + a.starting_psn = b.psn; + fn2(b.id); +} diff --git a/gcc/testsuite/gcc.dg/pr68306.c b/gcc/testsuite/gcc.dg/pr68306.c new file mode 100644 index 00000000000..54e5b40f221 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr68306.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O3" } */ +/* { dg-additional-options "-mno-sse -mno-mmx" { target i?86-*-* x86_64-*-* } } */ + +enum powerpc_pmc_type { PPC_PMC_IBM }; +struct { + unsigned num_pmcs; + enum powerpc_pmc_type pmc_type; +} a; +enum powerpc_pmc_type b; +void fn1() { a.num_pmcs = a.pmc_type = b; } diff --git a/gcc/testsuite/gcc.dg/pr68320.c b/gcc/testsuite/gcc.dg/pr68320.c new file mode 100644 index 00000000000..7060af8993e --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr68320.c @@ -0,0 +1,67 @@ +/* PR c/68320 */ +/* { dg-do compile } */ +/* { dg-options "" } */ + +void +fn1 (void) +{ + for (typedef int T;;) /* { dg-error "declaration of non-variable" } */ + if (1) + ; + T x; /* { dg-error "unknown type name" } */ +} + +void +fn2 (int i) +{ + for (typedef int T;;) /* { dg-error "declaration of non-variable" } */ + if (1) + i = 5; + T x; /* { dg-error "unknown type name" } */ +} + +void +fn3 (void) +{ + for (typedef int T;;) /* { dg-error "declaration of non-variable" } */ + if (1) + { + } + T *x; /* { dg-error "unknown type name" } */ +} + +void +fn4 (void) +{ + for (typedef int T;;) /* { dg-error "declaration of non-variable" } */ + if (1) + ; + T, T; /* { dg-error "undeclared" } */ +} + +void +fn5 (void) +{ + for (typedef int T;;) /* { dg-error "declaration of non-variable" } */ + if (1) + ; + T = 10; /* { dg-error "undeclared" } */ +} + +void +fn6 (void) +{ + for (typedef int T;;) /* { dg-error "declaration of non-variable" } */ + if (1) + ; + T[0]; /* { dg-error "undeclared" } */ +} + +void +fn7 (void) +{ + for (typedef int T;;) /* { dg-error "declaration of non-variable" } */ + if (1) + ; + T (); /* { dg-warning "implicit declaration" } */ +} diff --git a/gcc/testsuite/gcc.dg/spellcheck-fields.c b/gcc/testsuite/gcc.dg/spellcheck-fields.c new file mode 100644 index 00000000000..01be5508dc5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/spellcheck-fields.c @@ -0,0 +1,63 @@ +/* { dg-do compile } */ + +struct foo +{ + int foo; + int bar; + int baz; +}; + +int test (struct foo *ptr) +{ + return ptr->m_bar; /* { dg-error "'struct foo' has no member named 'm_bar'; did you mean 'bar'?" } */ +} + +int test2 (void) +{ + struct foo instance = {0, 0, 0}; + return instance.m_bar; /* { dg-error "'struct foo' has no member named 'm_bar'; did you mean 'bar'?" } */ +} + +struct s { + struct j { int aa; } kk; + int ab; +}; + +void test3 (struct s x) +{ + x.ac; /* { dg-error "'struct s' has no member named 'ac'; did you mean 'ab'?" } */ +} + +int test4 (struct foo *ptr) +{ + return sizeof (ptr->foa); /* { dg-error "'struct foo' has no member named 'foa'; did you mean 'foo'?" } */ +} + +/* Verify that we don't offer nonsensical suggestions. */ + +int test5 (struct foo *ptr) +{ + return ptr->this_is_unlike_any_of_the_fields; /* { dg-bogus "did you mean" } */ + /* { dg-error "has no member named" "" { target *-*-* } 40 } */ +} + +union u +{ + int color; + int shape; +}; + +int test6 (union u *ptr) +{ + return ptr->colour; /* { dg-error "'union u' has no member named 'colour'; did you mean 'color'?" } */ +} + +struct has_anon +{ + struct { int color; } s; +}; + +int test7 (struct has_anon *ptr) +{ + return ptr->s.colour; /* { dg-error "'struct <anonymous>' has no member named 'colour'; did you mean 'color'?" } */ +} diff --git a/gcc/testsuite/gcc.dg/spellcheck-options-1.c b/gcc/testsuite/gcc.dg/spellcheck-options-1.c new file mode 100644 index 00000000000..cd5fdcacfdb --- /dev/null +++ b/gcc/testsuite/gcc.dg/spellcheck-options-1.c @@ -0,0 +1,4 @@ +/* { dg-do compile } */ +/* { dg-options "-Wcoercion" } */ +/* { dg-error "unrecognized command line option '-Wcoercion'; did you mean '-Wconversion'?" "" { target *-*-* } 0 } */ + diff --git a/gcc/testsuite/gcc.dg/spellcheck-options-2.c b/gcc/testsuite/gcc.dg/spellcheck-options-2.c new file mode 100644 index 00000000000..786266df390 --- /dev/null +++ b/gcc/testsuite/gcc.dg/spellcheck-options-2.c @@ -0,0 +1,5 @@ +/* { dg-do compile } */ +/* { dg-options "-Wthis-should-not-get-a-hint" } */ +/* { dg-bogus "did you mean" "" { target *-*-* } 0 } */ +/* { dg-error "unrecognized command line option '-Wthis-should-not-get-a-hint'" "" { target *-*-* } 0 } */ + diff --git a/gcc/testsuite/gcc.dg/torture/pr68264.c b/gcc/testsuite/gcc.dg/torture/pr68264.c new file mode 100644 index 00000000000..96304742525 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr68264.c @@ -0,0 +1,104 @@ +/* { dg-do run } */ +/* { dg-require-effective-target fenv_exceptions } */ + +#include <fenv.h> +#include <math.h> +#include <errno.h> + +extern void abort (void) __attribute__ ((noreturn)); + +#define LARGE_NEG_MAYBE_ERANGE 0x01 +#define LARGE_NEG_ERANGE 0x02 +#define LARGE_POS_ERANGE 0x04 +#define LARGE_NEG_EDOM 0x08 +#define LARGE_POS_EDOM 0x10 + +#define LARGE_ERANGE (LARGE_NEG_ERANGE | LARGE_POS_ERANGE) +#define LARGE_EDOM (LARGE_NEG_EDOM | LARGE_POS_EDOM) +#define POWER_ERANGE (LARGE_NEG_MAYBE_ERANGE | LARGE_POS_ERANGE) + +#define TEST(CALL, FLAGS) (CALL, tester (FLAGS)) + +volatile double d; +volatile int i; + +static void (*tester) (int); + +void +check_quiet_nan (int flags __attribute__ ((unused))) +{ + if (fetestexcept (FE_ALL_EXCEPT)) + abort (); + if (errno) + abort (); +} + +void +check_large_neg (int flags) +{ + if (flags & LARGE_NEG_MAYBE_ERANGE) + return; + int expected_errno = (flags & LARGE_NEG_ERANGE ? ERANGE + : flags & LARGE_NEG_EDOM ? EDOM + : 0); + if (expected_errno != errno) + abort (); + errno = 0; +} + +void +check_large_pos (int flags) +{ + int expected_errno = (flags & LARGE_POS_ERANGE ? ERANGE + : flags & LARGE_POS_EDOM ? EDOM + : 0); + if (expected_errno != errno) + abort (); + errno = 0; +} + +void +test (void) +{ + TEST (acos (d), LARGE_EDOM); + TEST (asin (d), LARGE_EDOM); + TEST (acosh (d), LARGE_NEG_EDOM); + TEST (atanh (d), LARGE_EDOM); + TEST (cosh (d), LARGE_ERANGE); + TEST (sinh (d), LARGE_ERANGE); + TEST (log (d), LARGE_NEG_EDOM); + TEST (log2 (d), LARGE_NEG_EDOM); + TEST (log10 (d), LARGE_NEG_EDOM); + /* Disabled due to glibc PR 6792, fixed in Apr 2015. */ + if (0) + TEST (log1p (d), LARGE_NEG_EDOM); + TEST (exp (d), POWER_ERANGE); + TEST (exp2 (d), POWER_ERANGE); + TEST (expm1 (d), POWER_ERANGE); + TEST (sqrt (d), LARGE_NEG_EDOM); + TEST (pow (100.0, d), POWER_ERANGE); + TEST (pow (i, d), POWER_ERANGE); +} + +int +main (void) +{ + errno = 0; + i = 100; + d = __builtin_nan (""); + tester = check_quiet_nan; + feclearexcept (FE_ALL_EXCEPT); + test (); + + d = -1.0e80; + tester = check_large_neg; + errno = 0; + test (); + + d = 1.0e80; + tester = check_large_pos; + errno = 0; + test (); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr68234.c b/gcc/testsuite/gcc.dg/tree-ssa/pr68234.c new file mode 100644 index 00000000000..e7c2a95aa4c --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr68234.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-vrp2" } */ + +extern int nc; +void ff (unsigned long long); + +void +f (void) +{ + unsigned char resp[1024]; + int c; + int bl = 0; + unsigned long long *dwords = (unsigned long long *) (resp + 5); + for (c = 0; c < nc; c++) + { + /* PR middle-end/68234, this signed division should be optimized into + right shift as vrp pass should deduct range info of 'bl' falls into + positive number. */ + ff (dwords[bl / 64]); + bl++; + } +} + +/* { dg-final { scan-tree-dump ">> 6" "vrp2" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/split-path-1.c b/gcc/testsuite/gcc.dg/tree-ssa/split-path-1.c new file mode 100644 index 00000000000..12398924dba --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/split-path-1.c @@ -0,0 +1,67 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -fdump-tree-split-paths-details " } */ + +#include <stdio.h> +#include <stdlib.h> + +#define RGBMAX 255 + +int +test() +{ + int i, Pels; + unsigned char sum = 0; + unsigned char xr, xg, xb; + unsigned char xc, xm, xy, xk; + unsigned char *ReadPtr, *EritePtr; + + ReadPtr = ( unsigned char *) malloc (sizeof (unsigned char) * 100); + EritePtr = ( unsigned char *) malloc (sizeof (unsigned char) * 100); + + for (i = 0; i < 100;i++) + { + ReadPtr[i] = 100 - i; + } + + for (i = 0; i < 100; i++) + { + xr = *ReadPtr++; + xg = *ReadPtr++; + xb = *ReadPtr++; + + xc = (unsigned char) (RGBMAX - xr); + xm = (unsigned char) (RGBMAX - xg); + xy = (unsigned char) (RGBMAX - xb); + + if (xc < xm) + { + xk = (unsigned char) (xc < xy ? xc : xy); + } + else + { + xk = (unsigned char) (xm < xy ? xm : xy); + } + + xc = (unsigned char) (xc - xk); + xm = (unsigned char) (xm - xk); + xy = (unsigned char) (xy - xk); + + *EritePtr++ = xc; + *EritePtr++ = xm; + *EritePtr++ = xy; + *EritePtr++ = xk; + sum += *EritePtr; + } + return sum; +} + +int +main() +{ + if (test() != 33) + abort(); + + return 0; +} + +/* { dg-final { scan-tree-dump "Duplicating join block" "split-paths" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-7.c b/gcc/testsuite/gcc.dg/vect/bb-slp-7.c index ab54a48332f..b8bef8cffb4 100644 --- a/gcc/testsuite/gcc.dg/vect/bb-slp-7.c +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-7.c @@ -16,12 +16,12 @@ main1 (unsigned int x, unsigned int y) unsigned int *pout = &out[0]; unsigned int a0, a1, a2, a3; - /* Non isomorphic. */ + /* Non isomorphic, even 64-bit subgroups. */ a0 = *pin++ + 23; - a1 = *pin++ + 142; + a1 = *pin++ * 142; a2 = *pin++ + 2; a3 = *pin++ * 31; - + *pout++ = a0 * x; *pout++ = a1 * y; *pout++ = a2 * x; @@ -29,7 +29,7 @@ main1 (unsigned int x, unsigned int y) /* Check results. */ if (out[0] != (in[0] + 23) * x - || out[1] != (in[1] + 142) * y + || out[1] != (in[1] * 142) * y || out[2] != (in[2] + 2) * x || out[3] != (in[3] * 31) * y) abort(); @@ -47,4 +47,4 @@ int main (void) } /* { dg-final { scan-tree-dump-times "basic block vectorized" 0 "slp2" } } */ - + diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-subgroups-1.c b/gcc/testsuite/gcc.dg/vect/bb-slp-subgroups-1.c new file mode 100644 index 00000000000..39c23c397e7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-subgroups-1.c @@ -0,0 +1,44 @@ +/* { dg-require-effective-target vect_int } */ +/* PR tree-optimization/67682. */ + +#include "tree-vect.h" + +int __attribute__((__aligned__(8))) a[8]; +int __attribute__((__aligned__(8))) b[4]; + +__attribute__ ((noinline)) void +test () +{ + a[0] = b[0]; + a[1] = b[1]; + a[2] = b[2]; + a[3] = b[3]; + a[4] = 0; + a[5] = 0; + a[6] = 0; + a[7] = 0; +} + +int +main (int argc, char **argv) +{ + check_vect (); + + for (int i = 0; i < 8; i++) + a[i] = 1; + for (int i = 0; i < 4; i++) + b[i] = i + 4; + __asm__ volatile ("" : : : "memory"); + test (a, b); + __asm__ volatile ("" : : : "memory"); + for (int i = 0; i < 4; i++) + if (a[i] != i+4) + abort (); + for (int i = 4; i < 8; i++) + if (a[i] != 0) + abort (); + return 0; +} + +/* { dg-final { scan-tree-dump-times "Basic block will be vectorized using SLP" 1 "slp2" } } */ +/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp2" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-subgroups-2.c b/gcc/testsuite/gcc.dg/vect/bb-slp-subgroups-2.c new file mode 100644 index 00000000000..13c51f3440b --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-subgroups-2.c @@ -0,0 +1,41 @@ +/* { dg-require-effective-target vect_int } */ +/* PR tree-optimization/67682. */ + +#include "tree-vect.h" + +int __attribute__((__aligned__(8))) a[8]; +int __attribute__((__aligned__(8))) b[4]; + +__attribute__ ((noinline)) void +test () +{ + a[0] = b[2] + 1; + a[1] = b[0] + 2; + a[2] = b[1] + 3; + a[3] = b[1] + 4; + a[4] = b[3] * 3; + a[5] = b[0] * 4; + a[6] = b[2] * 5; + a[7] = b[1] * 7; +} + +int +main (int argc, char **argv) +{ + check_vect (); + + for (int i = 0; i < 8; i++) + a[i] = 1; + for (int i = 0; i < 4; i++) + b[i] = i + 4; + __asm__ volatile ("" : : : "memory"); + test (a, b); + __asm__ volatile ("" : : : "memory"); + if ((a[0] != 7) || a[1] != 6 || (a[2] != 8) || (a[3] != 9) + || (a[4] != 21) || (a[5] != 16) || (a[6] != 30) || (a[7] != 35)) + abort (); + return 0; +} + +/* { dg-final { scan-tree-dump-times "Basic block will be vectorized using SLP" 1 "slp2" } } */ +/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp2" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-subgroups-3.c b/gcc/testsuite/gcc.dg/vect/bb-slp-subgroups-3.c new file mode 100644 index 00000000000..6ae9a897686 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-subgroups-3.c @@ -0,0 +1,41 @@ +/* { dg-require-effective-target vect_int } */ +/* PR tree-optimization/67682. */ + +#include "tree-vect.h" + +int __attribute__((__aligned__(8))) a[8]; +int __attribute__((__aligned__(8))) b[8]; + +__attribute__ ((noinline)) void +test () +{ + a[0] = b[0] + 1; + a[1] = b[1] + 2; + a[2] = b[2] + 3; + a[3] = b[3] + 4; + a[4] = b[0] * 3; + a[5] = b[2] * 4; + a[6] = b[4] * 5; + a[7] = b[6] * 7; +} + +int +main (int argc, char **argv) +{ + check_vect (); + + for (int i = 0; i < 8; i++) + a[i] = 1; + for (int i = 0; i < 8; i++) + b[i] = i + 4; + __asm__ volatile ("" : : : "memory"); + test (a, b); + __asm__ volatile ("" : : : "memory"); + if ((a[0] != 5) || (a[1] != 7) || (a[2] != 9) || (a[3] != 11) + || (a[4] != 12) || (a[5] != 24) || (a[6] != 40) || (a[7] != 70)) + abort (); + return 0; +} + +/* { dg-final { scan-tree-dump-times "Basic block will be vectorized using SLP" 1 "slp2" } } */ +/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp2" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr65947-1.c b/gcc/testsuite/gcc.dg/vect/pr65947-1.c index 7933f5c8612..1e7a05dc8cc 100644 --- a/gcc/testsuite/gcc.dg/vect/pr65947-1.c +++ b/gcc/testsuite/gcc.dg/vect/pr65947-1.c @@ -9,7 +9,7 @@ extern void abort (void) __attribute__ ((noreturn)); int condition_reduction (int *a, int min_v) { - int last = -1; + int last = 66; /* High start value. */ for (int i = 0; i < N; i++) if (a[i] < min_v) @@ -28,12 +28,13 @@ main (void) 31, 32 }; - int ret = condition_reduction (a, 16); + int ret = condition_reduction (a, 1); - if (ret != 19) + if (ret != 17) abort (); return 0; } /* { dg-final { scan-tree-dump-times "LOOP VECTORIZED" 2 "vect" { xfail { ! vect_max_reduc } } } } */ +/* { dg-final { scan-tree-dump-times "condition expression based on integer induction." 4 "vect" { xfail { ! vect_max_reduc } } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr65947-10.c b/gcc/testsuite/gcc.dg/vect/pr65947-10.c index 9a43a6059fa..b4c6659b77c 100644 --- a/gcc/testsuite/gcc.dg/vect/pr65947-10.c +++ b/gcc/testsuite/gcc.dg/vect/pr65947-10.c @@ -37,4 +37,5 @@ main (void) } /* { dg-final { scan-tree-dump-times "LOOP VECTORIZED" 2 "vect" { xfail { ! vect_max_reduc } } } } */ +/* { dg-final { scan-tree-dump-not "condition expression based on integer induction." "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr65947-12.c b/gcc/testsuite/gcc.dg/vect/pr65947-12.c new file mode 100644 index 00000000000..fb5ffd48c7b --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr65947-12.c @@ -0,0 +1,41 @@ +/* { dg-require-effective-target vect_condition } */ + +extern void abort (void) __attribute__ ((noreturn)); + +#define N 32 + +/* Simple condition reduction where the result is a negative of the induction. + Will fail to vectorize to a simple case. */ + +signed int +condition_reduction (signed int *a, signed int min_v) +{ + signed int last = -1; + + for (signed int i = 0; i < N; i++) + if (a[i] < min_v) + last = -i; + + return last; +} + +int +main (void) +{ + signed int a[N] = { + 11, -12, 13, 14, 15, 16, 17, 18, 19, 20, + 1, 2, -3, 4, 5, 6, 7, -8, 9, 10, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32 + }; + + signed int ret = condition_reduction (a, 16); + + if (ret != -19) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "LOOP VECTORIZED" 2 "vect" { xfail { ! vect_max_reduc } } } } */ +/* { dg-final { scan-tree-dump-not "condition expression based on integer induction." "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr65947-13.c b/gcc/testsuite/gcc.dg/vect/pr65947-13.c new file mode 100644 index 00000000000..8c6faddd189 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr65947-13.c @@ -0,0 +1,41 @@ +/* { dg-require-effective-target vect_condition } */ + +extern void abort (void) __attribute__ ((noreturn)); + +#define N 32 + +/* Simple condition reduction with a reversed loop. + Will fail to vectorize to a simple case. */ + +int +condition_reduction (int *a, int min_v) +{ + int last = -1; + + for (int i = N-1; i >=0; i--) + if (a[i] < min_v) + last = i; + + return last; +} + +int +main (void) +{ + int a[N] = { + 17, 28, 13, 14, 15, 16, 17, 18, 19, 20, + 1, 2, -3, 4, 5, 6, 7, -8, 9, 10, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32 + }; + + int ret = condition_reduction (a, 16); + + if (ret != 2) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "LOOP VECTORIZED" 2 "vect" { xfail { ! vect_max_reduc } } } } */ +/* { dg-final { scan-tree-dump-not "condition expression based on integer induction." "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr65947-2.c b/gcc/testsuite/gcc.dg/vect/pr65947-2.c index 9c627d9d7d5..9e9ff538286 100644 --- a/gcc/testsuite/gcc.dg/vect/pr65947-2.c +++ b/gcc/testsuite/gcc.dg/vect/pr65947-2.c @@ -38,3 +38,4 @@ main (void) } /* { dg-final { scan-tree-dump-times "LOOP VECTORIZED" 2 "vect" { xfail { ! vect_max_reduc } } } } */ +/* { dg-final { scan-tree-dump-not "condition expression based on integer induction." "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr65947-3.c b/gcc/testsuite/gcc.dg/vect/pr65947-3.c index e115de2a282..4b6aa9216b0 100644 --- a/gcc/testsuite/gcc.dg/vect/pr65947-3.c +++ b/gcc/testsuite/gcc.dg/vect/pr65947-3.c @@ -48,3 +48,4 @@ main (void) } /* { dg-final { scan-tree-dump-times "LOOP VECTORIZED" 2 "vect" { xfail { ! vect_max_reduc } } } } */ +/* { dg-final { scan-tree-dump-not "condition expression based on integer induction." "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr65947-4.c b/gcc/testsuite/gcc.dg/vect/pr65947-4.c index 76a0567aa54..f4e7fdc97c8 100644 --- a/gcc/testsuite/gcc.dg/vect/pr65947-4.c +++ b/gcc/testsuite/gcc.dg/vect/pr65947-4.c @@ -37,4 +37,5 @@ main (void) } /* { dg-final { scan-tree-dump-times "LOOP VECTORIZED" 2 "vect" { xfail { ! vect_max_reduc } } } } */ +/* { dg-final { scan-tree-dump-times "condition expression based on integer induction." 4 "vect" { xfail { ! vect_max_reduc } } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr65947-5.c b/gcc/testsuite/gcc.dg/vect/pr65947-5.c index 360e3b51ee1..21be8d0b749 100644 --- a/gcc/testsuite/gcc.dg/vect/pr65947-5.c +++ b/gcc/testsuite/gcc.dg/vect/pr65947-5.c @@ -39,3 +39,4 @@ main (void) /* { dg-final { scan-tree-dump-times "LOOP VECTORIZED" 1 "vect" { xfail { ! vect_max_reduc } } } } */ /* { dg-final { scan-tree-dump "loop size is greater than data size" "vect" { xfail { ! vect_max_reduc } } } } */ +/* { dg-final { scan-tree-dump-not "condition expression based on integer induction." "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr65947-6.c b/gcc/testsuite/gcc.dg/vect/pr65947-6.c index 4997ef79cae..e1432403b2d 100644 --- a/gcc/testsuite/gcc.dg/vect/pr65947-6.c +++ b/gcc/testsuite/gcc.dg/vect/pr65947-6.c @@ -37,3 +37,4 @@ main (void) } /* { dg-final { scan-tree-dump-times "LOOP VECTORIZED" 2 "vect" { xfail { ! vect_max_reduc } } } } */ +/* { dg-final { scan-tree-dump-not "condition expression based on integer induction." "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr68305.c b/gcc/testsuite/gcc.dg/vect/pr68305.c new file mode 100644 index 00000000000..fde3db723cc --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr68305.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-O3" } */ +/* { dg-additional-options "-mavx2" { target avx_runtime } } */ + +int a, b; + +void +fn1 () +{ + int c, d; + for (; b; b++) + a = a ^ !c ^ !d; +} |