summaryrefslogtreecommitdiff
path: root/gcc/testsuite/g++.dg/parse/error11.C
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/testsuite/g++.dg/parse/error11.C')
-rw-r--r--gcc/testsuite/g++.dg/parse/error11.C71
1 files changed, 71 insertions, 0 deletions
diff --git a/gcc/testsuite/g++.dg/parse/error11.C b/gcc/testsuite/g++.dg/parse/error11.C
new file mode 100644
index 000000000..39039a880
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/error11.C
@@ -0,0 +1,71 @@
+// { dg-do compile }
+// { dg-options "-fshow-column" }"
+// Origin: Giovanni Bajo <giovannibajo at gcc dot gnu dot org>
+// Try to find out when the digraph '<:' is used as a mistake, and parse it
+// correctly to avoid cascaded errors.
+
+struct B;
+
+template <class A>
+struct Foo
+{
+ template <class T>
+ struct Nested
+ {
+ static void method(void) {}
+ };
+
+ void method(void) {
+ typename Foo<::B>::template Nested<::B> n; // { dg-error "17:'<::' cannot begin" "17-begin" }
+// { dg-message "17:'<:' is an alternate spelling" "17-alt" { target *-*-* } 19 }
+// { dg-error "39:'<::' cannot begin" "39-begin" { target *-*-* } 19 }
+// { dg-message "39:'<:' is an alternate spelling" "39-alt" { target *-*-* } 19 }
+ n.template Nested<B>::method();
+ n.template Nested<::B>::method(); // { dg-error "22:'<::' cannot begin" "error" }
+// { dg-message "22:'<:' is an alternate" "note" { target *-*-* } 24 }
+ Nested<B>::method();
+ Nested<::B>::method(); // { dg-error "11:'<::' cannot begin" "error" }
+// { dg-message "11:'<:' is an alternate" "note" { target *-*-* } 27 }
+ }
+};
+
+template <int N> struct Foo2 {};
+template struct Foo2<::B>; // { dg-error "21:'<::' cannot begin" "begin" }
+// { dg-message "21:'<:' is an alternate" "alt" { target *-*-* } 33 }
+// { dg-message "25:type/value mismatch" "mismatch" { target *-*-* } 33 }
+// { dg-error "25:expected a constant" "const" { target *-*-* } 33 }
+
+int value = 0;
+
+void func(void)
+{
+ Foo<::B> f; // { dg-error "cannot begin" "begin" }
+// { dg-message "alternate spelling" "alt" { target *-*-* } 42 }
+ f.Foo<B>::method();
+ f.Foo<::B>::method(); // { dg-error "8:cannot begin" "begin" }
+// { dg-message "8:alternate spelling" "alt" { target *-*-* } 45 }
+
+ // Check cases where we the token sequence is the correct one, but there
+ // was no digraph or whitespaces in the middle, so we should not emit
+ // the special error message.
+ Foo<: :B> k2; // { dg-bogus "cannot begin|alternate spelling" "smart error should not be triggered here" }
+ Foo[:B> k1; // { dg-bogus "cannot begin|alternate spelling" "smart error should not be triggered here" }
+// { dg-error "6:missing template arguments before" "template" { target *-*-* } { 51 } }
+// { dg-error "9:expected primary-expression before ':' token" "primary" { target *-*-* } 51 }
+// { dg-error "9:expected '\]' before ':' token" "backslash" { target *-*-* } 51 }
+// { dg-error "9:expected ';' before ':' token" "semicolon" { target *-*-* } 51 }
+// { dg-error "6:missing template arguments before" "template" { target *-*-* } 52 }
+// { dg-error "7:expected primary-expression before ':' token" "primary" { target *-*-* } 52 }
+// { dg-error "7:expected '\]' before ':' token" "backslash" { target *-*-* } 52 }
+// { dg-error "7:expected ';' before ':' token" "semicolon" { target *-*-* } 52 }
+//
+ int Foo[2];
+ Foo[::value] = 0;
+}
+
+template struct Foo<::B>; // { dg-error "20:'<::' cannot begin" "begin" }
+// { dg-message "20:is an alternate" "alt" { target *-*-* } 66 }
+
+// On the first error message, an additional note about the use of
+// -fpermissive should be present
+// { dg-message "17:\\(if you use '-fpermissive' G\\+\\+ will accept your code\\)" "-fpermissive" { target *-*-* } 19 }