1 // { dg-options "-Wcatch-value=3" }
2 
~AA3 struct A { virtual ~A() {} };
4 struct B : A {};
5 struct C {};
6 struct D : C {};
7 
foo()8 void foo()
9 {
10   try {}
11   catch (D)    {}  // { dg-warning "10:catching type" }
12   catch (C)    {}  // { dg-warning "10:catching type" }
13   catch (B)    {}  // { dg-warning "10:catching polymorphic type" }
14   catch (A)    {}  // { dg-warning "10:catching polymorphic type" }
15   catch (A*)   {}  // { dg-warning "catching non-reference type" }
16   catch (int)  {}  // { dg-warning "10:catching non-reference type" }
17 
18   try {}
19   catch (D&)   {}
20   catch (C&)   {}
21   catch (B&)   {}
22   catch (A&)   {}
23   catch (A*)   {}  // { dg-warning "catching non-reference type" }
24   catch (int&) {}
25 }
26 
foo1()27 template<typename T> void foo1()
28 {
29   try {}
30   catch (T) {}  // { dg-warning "10:catching" }
31 }
32 
foo2()33 template<typename T> void foo2()
34 {
35   try {}
36   catch (T*) {}  // { dg-warning "catching non-reference type" }
37 
38   try {}
39   catch (T&) {}
40 
41   try {}
42   catch (const T&) {}
43 }
44 
bar()45 void bar()
46 {
47   foo1<int&>();
48   foo1<const A&>();
49   foo1<B&>();
50   foo1<const C&>();
51   foo1<D&>();
52 
53   foo1<int>();  // { dg-message "required" }
54   foo1<A>();    // { dg-message "required" }
55   foo1<B>();    // { dg-message "required" }
56   foo1<C>();    // { dg-message "required" }
57   foo1<D>();    // { dg-message "required" }
58 
59   foo2<int>();  // { dg-message "required" }
60   foo2<A>();    // { dg-message "required" }
61   foo2<B>();    // { dg-message "required" }
62   foo2<C>();    // { dg-message "required" }
63   foo2<D>();    // { dg-message "required" }
64 }
65