aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/gcc.dg
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/testsuite/gcc.dg')
-rw-r--r--gcc/testsuite/gcc.dg/diagnostic-token-ranges.c120
-rw-r--r--gcc/testsuite/gcc.dg/diagnostic-tree-expr-ranges-2.c23
-rw-r--r--gcc/testsuite/gcc.dg/goacc/nvptx-merged-loop.c30
-rw-r--r--gcc/testsuite/gcc.dg/graphite/fuse-1.c10
-rw-r--r--gcc/testsuite/gcc.dg/graphite/fuse-2.c4
-rw-r--r--gcc/testsuite/gcc.dg/graphite/graphite.exp2
-rw-r--r--gcc/testsuite/gcc.dg/graphite/isl-ast-gen-blocks-1.c3
-rw-r--r--gcc/testsuite/gcc.dg/graphite/isl-ast-gen-blocks-2.c3
-rw-r--r--gcc/testsuite/gcc.dg/graphite/isl-ast-gen-blocks-3.c3
-rw-r--r--gcc/testsuite/gcc.dg/graphite/isl-ast-gen-blocks-4.c3
-rw-r--r--gcc/testsuite/gcc.dg/graphite/isl-ast-gen-if-1.c3
-rw-r--r--gcc/testsuite/gcc.dg/graphite/isl-ast-gen-if-2.c3
-rw-r--r--gcc/testsuite/gcc.dg/graphite/isl-ast-gen-single-loop-1.c3
-rw-r--r--gcc/testsuite/gcc.dg/graphite/isl-ast-gen-single-loop-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/graphite/isl-ast-gen-single-loop-3.c2
-rw-r--r--gcc/testsuite/gcc.dg/graphite/isl-ast-gen-user-1.c12
-rw-r--r--gcc/testsuite/gcc.dg/graphite/isl-codegen-loop-dumping.c17
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic-test-expressions-1.c422
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-trees-1.c65
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_show_trees.c174
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_show_locus.c24
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_tree_expression_range.c98
-rw-r--r--gcc/testsuite/gcc.dg/plugin/levenshtein-test-1.c9
-rw-r--r--gcc/testsuite/gcc.dg/plugin/levenshtein_plugin.c64
-rw-r--r--gcc/testsuite/gcc.dg/plugin/plugin.exp5
-rw-r--r--gcc/testsuite/gcc.dg/pr65521.c1
-rw-r--r--gcc/testsuite/gcc.dg/pr67784-1.c54
-rw-r--r--gcc/testsuite/gcc.dg/pr67784-2.c54
-rw-r--r--gcc/testsuite/gcc.dg/pr68286.c17
-rw-r--r--gcc/testsuite/gcc.dg/pr68306-2.c12
-rw-r--r--gcc/testsuite/gcc.dg/pr68306-3.c21
-rw-r--r--gcc/testsuite/gcc.dg/pr68306.c11
-rw-r--r--gcc/testsuite/gcc.dg/pr68320.c67
-rw-r--r--gcc/testsuite/gcc.dg/spellcheck-fields.c63
-rw-r--r--gcc/testsuite/gcc.dg/spellcheck-options-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/spellcheck-options-2.c5
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr68264.c104
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr68234.c24
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/split-path-1.c67
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-7.c10
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-subgroups-1.c44
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-subgroups-2.c41
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-subgroups-3.c41
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr65947-1.c7
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr65947-10.c1
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr65947-12.c41
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr65947-13.c41
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr65947-2.c1
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr65947-3.c1
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr65947-4.c1
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr65947-5.c1
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr65947-6.c1
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr68305.c13
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;
+}