1 // { dg-do compile } 2 // { dg-options "-std=gnu++98" } 3 // Origin: <tilps at hotmail dot com> 4 // c++/9154: poor error message for ">>" vs "> >" in template argument list 5 6 7 /* 8 * Test that the error message is issued properly 9 */ 10 template <class T> 11 class A {}; 12 13 A<A<int>> blah; // { dg-error "should be '> >' within" } 14 A<int>> blah2; // { dg-error "spurious '>>'" } 15 16 17 /* 18 * Test that a few valid constructs containing a ">>" token in a 19 * template argument list are handled correctly. 20 */ 21 template <int N> B(void)22void B(void) {} 23 Btest()24int Btest() 25 { 26 B<256 >> 4>(); 27 return 0; 28 } 29 30 template <int N = 123>>4> 31 struct C {}; 32 33 template <int> struct D {}; 34 template <typename> struct E {}; 35 36 E<D< 1>>2 > > E1; 37 38 const int x = 0; 39 E<D< 1>>x > > E2; 40 41 template <int> struct F { 42 typedef int I; 43 }; 44 45 template <typename T = F< 1>>2 >::I> 46 struct G {}; 47 48 /* 49 * In this special case, a valid type-id (H() is a function type) is followed 50 * by '>>', but the argument should still be parsed as an expression, which 51 * will then be rejected as non-constant expression. 52 */ 53 struct H 54 { 55 int operator >>(int); 56 }; 57 58 template <int V> struct L {}; 59 L<H() >> 5> l; // { dg-error "" "non-constant" } 60 61 62 /* 63 * This case used to not emit the nice error message because of a typo 64 * in the code. 65 */ 66 template <void (*)(void)> 67 struct K {}; 68 69 void KFunc(void); 70 71 A<K<&KFunc>> k1; // { dg-error "" } 72 K<&KFunc>> k2; // { dg-error "" } 73