aboutsummaryrefslogtreecommitdiff
path: root/test/SemaCXX/cxx1y-contextual-conversion-tweaks.cpp
blob: 58bbbb2a04421f0fcba7f09098de5ccac844c2b9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
// RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only %s
// RUN: %clang_cc1 -std=c++1y %s -verify -DCXX1Y

// Explicit member declarations behave as in C++11.

namespace n3323_example {

  template <class T> class zero_init {
  public:
    zero_init() : val(static_cast<T>(0)) {}
    zero_init(T val) : val(val) {}

    operator T &() { return val; }     //@13
    operator T() const { return val; } //@14

  private:
    T val;
  };

  void Delete() {
    zero_init<int *> p;
    p = new int(7);
    delete p; //@23
    delete (p + 0);
    delete + p;
  }

  void Switch() {
    zero_init<int> i;
    i = 7;
    switch (i) {} // @31
    switch (i + 0) {}
    switch (+i) {}
  }
}

#ifdef CXX1Y
#else
//expected-error@23 {{ambiguous conversion of delete expression of type 'zero_init<int *>' to a pointer}}
//expected-note@13 {{conversion to pointer type 'int *'}}
//expected-note@14 {{conversion to pointer type 'int *'}}
//expected-error@31 {{multiple conversions from switch condition type 'zero_init<int>' to an integral or enumeration type}}
//expected-note@13 {{conversion to integral type 'int'}}
//expected-note@14 {{conversion to integral type 'int'}}
#endif

namespace extended_examples {

  struct A0 {
    operator int();      // matching and viable
  };

  struct A1 {
    operator int() &&;   // matching and not viable
  };

  struct A2 {
    operator float();    // not matching
  };

  struct A3 {
    template<typename T> operator T();  // not matching (ambiguous anyway)
  };

  struct A4 {
    template<typename T> operator int();  // not matching (ambiguous anyway)
  };

  struct B1 {
    operator int() &&;  // @70
    operator int();     // @71  -- duplicate declaration with different qualifier is not allowed
  };

  struct B2 {
    operator int() &&;  // matching but not viable
    operator float();   // not matching
  };

  void foo(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, B2 b2) {
    switch (a0) {}
    switch (a1) {}     // @81 -- fails for different reasons
    switch (a2) {}     // @82
    switch (a3) {}     // @83
    switch (a4) {}     // @84
    switch (b2) {}     // @85 -- fails for different reasons
  }
}

//expected-error@71 {{cannot overload a member function without a ref-qualifier with a member function with ref-qualifier '&&'}}
//expected-note@70 {{previous declaration is here}}
//expected-error@82 {{statement requires expression of integer type ('extended_examples::A2' invalid)}}
//expected-error@83 {{statement requires expression of integer type ('extended_examples::A3' invalid)}}
//expected-error@84 {{statement requires expression of integer type ('extended_examples::A4' invalid)}}

#ifdef CXX1Y
//expected-error@81 {{statement requires expression of integer type ('extended_examples::A1' invalid)}}
//expected-error@85 {{statement requires expression of integer type ('extended_examples::B2' invalid)}}
#else
//expected-error@81 {{cannot initialize object parameter of type 'extended_examples::A1' with an expression of type 'extended_examples::A1'}}
//expected-error@85 {{cannot initialize object parameter of type 'extended_examples::B2' with an expression of type 'extended_examples::B2'}}
#endif

namespace extended_examples_cxx1y {

  struct A1 {   // leads to viable match in C++1y, and no viable match in C++11
    operator int() &&;                  // matching but not viable
    template <typename T> operator T(); // In C++1y: matching and viable, since disambiguated by L.100
  };

  struct A2 {   // leads to ambiguity in C++1y, and no viable match in C++11
    operator int() &&;                    // matching but not viable
    template <typename T> operator int(); // In C++1y: matching but ambiguous (disambiguated by L.105).
  };

  struct B1 {    // leads to one viable match in both cases
    operator int();                  // matching and viable
    template <typename T> operator T(); // In C++1y: matching and viable, since disambiguated by L.110
  };

  struct B2 {    // leads to one viable match in both cases
    operator int();                  // matching and viable
    template <typename T> operator int(); // In C++1y: matching but ambiguous, since disambiguated by L.115
  };

  struct C {    // leads to no match in both cases
    operator float();                  // not matching
    template <typename T> operator T(); // In C++1y: not matching, nor viable.
  };

  struct D {   // leads to viable match in C++1y, and no viable match in C++11
    operator int() &&;                  // matching but not viable
    operator float();                   // not matching
    template <typename T> operator T(); // In C++1y: matching and viable, since disambiguated by L.125
  };


  void foo(A1 a1, A2 a2, B1 b1, B2 b2, C c, D d) {
    switch (a1) {} // @138 --  should presumably call templated conversion operator to convert to int.
    switch (a2) {} // @139
    switch (b1) {}
    switch (b2) {}
    switch (c) {}  // @142
    switch (d) {}  // @143
  }
}

//expected-error@142 {{statement requires expression of integer type ('extended_examples_cxx1y::C' invalid)}}

#ifdef CXX1Y
//expected-error@139 {{statement requires expression of integer type ('extended_examples_cxx1y::A2' invalid)}}
#else
//expected-error@138 {{cannot initialize object parameter of type 'extended_examples_cxx1y::A1' with an expression of type 'extended_examples_cxx1y::A1'}}
//expected-error@139 {{cannot initialize object parameter of type 'extended_examples_cxx1y::A2' with an expression of type 'extended_examples_cxx1y::A2'}}
//expected-error@143 {{cannot initialize object parameter of type 'extended_examples_cxx1y::D' with an expression of type 'extended_examples_cxx1y::D'}}
#endif

namespace extended_examples_array_bounds {
  
  typedef decltype(sizeof(int)) size_t;
  
  struct Foo {
    operator size_t();   // @162
    operator unsigned short();  // @163
  };

  void bar() {
    Foo x;
    int *p = new int[x];        // @168
  }
}

#ifdef CXX1Y
#else
//expected-error@168 {{ambiguous conversion of array size expression of type 'extended_examples_array_bounds::Foo' to an integral or enumeration type}}
//expected-note@162 {{conversion to integral type 'size_t'}}
//expected-note@163 {{conversion to integral type 'unsigned short' declared here}}
#endif