File: p5.cpp

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (61 lines) | stat: -rw-r--r-- 2,370 bytes parent folder | download | duplicates (31)
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
// RUN: %clang_cc1 -std=c++1z -verify %s

template<typename T, bool B> using Fn = T () noexcept(B);

// - If the original A is a function pointer type, A can be "pointer to
//   function" even if the deduced A is "pointer to noexcept function".
struct A {
  template<typename T> operator Fn<T, false>*(); // expected-note {{candidate}}
};
struct B {
  template<typename T> operator Fn<T, true>*();
};
void (*p1)() = A();
void (*p2)() = B();
void (*p3)() noexcept = A(); // expected-error {{no viable conversion}}
void (*p4)() noexcept = B();

// - If the original A is a pointer to member function type, A can be "pointer
//   to member of type function" even if the deduced A is "pointer to member of
//   type noexcept function".
struct C {
  template<typename T> operator Fn<T, false> A::*(); // expected-note {{candidate}}
};
struct D {
  template<typename T> operator Fn<T, true> A::*();
};
void (A::*q1)() = C();
void (A::*q2)() = D();
void (A::*q3)() noexcept = C(); // expected-error {{no viable conversion}}
void (A::*q4)() noexcept = D();

// There is no corresponding rule for references.
// FIXME: This seems like a defect.
// FIXME: We don't actually implement the final check for equal types at all!
// Instead, we handle the matching via [over.ics.user]p3:
//   "If the user-defined conversion is specified by a specialization of a
//   conversion function template, the second standard conversion sequence
//   shall have exact match rank."
// Note that this *does* allow discarding noexcept, since that conversion has
// Exact Match rank.
struct E {
  template<typename T> operator Fn<T, false>&(); // expected-note {{candidate}}
};
struct F {
  template<typename T> operator Fn<T, true>&();
};
void (&r1)() = E();
void (&r2)() = F();
void (&r3)() noexcept = E(); // expected-error {{no viable conversion}}
void (&r4)() noexcept = F();

// FIXME: We reject this for entirely the wrong reason. We incorrectly succeed
// in deducing T = void, U = G::B, and only fail due to [over.ics.user]p3.
struct G {
  template<typename, typename> struct A {};
  template<typename U> struct A<U, int> : A<U, void> {};
  struct B { typedef int type; };

  template<typename T, typename U = B> operator A<T, typename U::type> *(); // expected-note {{candidate function [with T = void, U = G::B]}}
};
G::A<void, void> *g = G(); // expected-error {{no viable conversion}}