aboutsummaryrefslogtreecommitdiff
path: root/clang/test/SemaTemplate/concepts-inherited-ctor.cpp
blob: 6ac5a1618784e89ceda4190280cc3ace9345e51e (plain)
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
// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s

namespace GH62361 {
  template <typename T, typename U = void*> struct B { // expected-note 14{{candidate}}
    B() // expected-note 7{{not viable}}
      requires __is_same(T, int); // expected-note 7{{because '__is_same(char, int)' evaluated to false}}
  };

  template <typename U> struct B<void, U> : B<int, U> {
    using B<int, U>::B;
  };

  template<typename T>
  void g(B<T>); // expected-note {{cannot convert}}

  void f1() {
    B<void> b1;
    B<void> b2{};
    B<void> b3 = {};
    new B<void>{};
    new B<void>();
    g<void>({});
    B<void>{};
    B<void>();
  }

  void f2() {
    B<int> b1;
    B<int> b2{};
    B<int> b3 = {};
    new B<int>{};
    new B<int>();
    g<int>({});
    B<int>{};
    B<int>();
  }

  void f3() {
    B<char> b1; // expected-error {{no matching constructor}}
    B<char> b2{}; // expected-error {{no matching constructor}}
    B<char> b3 = {}; // expected-error {{no matching constructor}}
    new B<char>{}; // expected-error {{no matching constructor}}
    new B<char>(); // expected-error {{no matching constructor}}
    g<char>({}); // expected-error {{no matching function}}
    B<char>{}; // expected-error {{no matching constructor}}
    B<char>(); // expected-error {{no matching constructor}}
  }
}

namespace no_early_substitution {
  template <typename T> concept X = true;

  struct A {};

  template <typename T> struct B {
    B() requires X<T*>;
    B();
  };

  template <typename U = int, typename V = A>
  struct C : public B<V&> {
    using B<V&>::B;
  };

  void foo() {
    // OK, we only substitute T ~> V& into X<T*> in a SFINAE context,
    // during satisfaction checks.
    C();
  }
}

namespace GH62362 {
  template<typename T>
    concept C = true;
  template <typename T> struct Test {
    Test()
      requires(C<T>);
  };
  struct Bar : public Test<int> {
    using Test<int>::Test;
  };
  template <>
    struct Test<void> : public Test<int> {
      using Test<int>::Test;
    };

  void foo() {
    Bar();
    Test<void>();
  }
}