p5.cpp revision eedf3e99c711b120b82b12a5a087e4a1e5c52222
1// RUN: %clang_cc1 -fsyntax-only -verify %s
2
3// C++0x [temp.arg.nontype] p5:
4//   The following conversions are performed on each expression used as
5//   a non-type template-argument. If a non-type template-argument cannot be
6//   converted to the type of the corresponding template-parameter then the
7//   program is ill-formed.
8//     -- for a non-type template-parameter of integral or enumeration type,
9//        integral promotions (4.5) and integral conversions (4.7) are applied.
10//     -- for a non-type template-parameter of type pointer to object,
11//        qualification conversions (4.4) and the array-to-pointer conversion
12//        (4.2) are applied; if the template-argument is of type
13//        std::nullptr_t, the null pointer conversion (4.10) is applied.
14//     -- For a non-type template-parameter of type reference to object, no
15//        conversions apply. The type referred to by the reference may be more
16//        cv-qualified than the (otherwise identical) type of the
17//        template-argument. The template-parameter is bound directly to the
18//        template-argument, which shall be an lvalue.
19namespace reference_parameters {
20  template <int& N> struct S0 { }; // expected-note 3 {{template parameter is declared here}}
21  template <const int& N> struct S1 { }; // expected-note 2 {{template parameter is declared here}}
22  template <volatile int& N> struct S2 { }; // expected-note 2 {{template parameter is declared here}}
23  template <const volatile int& N> struct S3 { };
24  int i;
25  extern const int ci;
26  volatile int vi;
27  extern const volatile int cvi;
28  void test() {
29    S0<i> s0;
30    S0<ci> s0c; // expected-error{{reference binding of non-type template parameter of type 'int &' to template argument of type 'int const' ignores qualifiers}}
31    S0<vi> s0v; // expected-error{{reference binding of non-type template parameter of type 'int &' to template argument of type 'int volatile' ignores qualifiers}}
32    S0<cvi> s0cv; // expected-error{{reference binding of non-type template parameter of type 'int &' to template argument of type 'int const volatile' ignores qualifiers}}
33
34    S1<i> s1;
35    S1<ci> s1c;
36    S1<vi> s1v; // expected-error{{reference binding of non-type template parameter of type 'int const &' to template argument of type 'int volatile' ignores qualifiers}}
37    S1<cvi> s1cv; // expected-error{{reference binding of non-type template parameter of type 'int const &' to template argument of type 'int const volatile' ignores qualifiers}}
38
39    S2<i> s2;
40    S2<ci> s2c; // expected-error{{reference binding of non-type template parameter of type 'int volatile &' to template argument of type 'int const' ignores qualifiers}}
41    S2<vi> s2v;
42    S2<cvi> s2cv; // expected-error{{reference binding of non-type template parameter of type 'int volatile &' to template argument of type 'int const volatile' ignores qualifiers}}
43
44    S3<i> s3;
45    S3<ci> s3c;
46    S3<vi> s3v;
47    S3<cvi> s3cv;
48  }
49}
50
51//     -- For a non-type template-parameter of type pointer to function, the
52//        function-to-pointer conversion (4.3) is applied; if the
53//        template-argument is of type std::nullptr_t, the null pointer
54//        conversion (4.10) is applied. If the template-argument represents
55//        a set of overloaded functions (or a pointer to such), the matching
56//        function is selected from the set (13.4).
57//     -- For a non-type template-parameter of type reference to function, no
58//        conversions apply. If the template-argument represents a set of
59//        overloaded functions, the matching function is selected from the set
60//        (13.4).
61//     -- For a non-type template-parameter of type pointer to member function,
62//        if the template-argument is of type std::nullptr_t, the null member
63//        pointer conversion (4.11) is applied; otherwise, no conversions
64//        apply. If the template-argument represents a set of overloaded member
65//        functions, the matching member function is selected from the set
66//        (13.4).
67//     -- For a non-type template-parameter of type pointer to data member,
68//        qualification conversions (4.4) are applied; if the template-argument
69//        is of type std::nullptr_t, the null member pointer conversion (4.11)
70//        is applied.
71