brintos

brintos / llvm-project-archived public Read only

0
0
Text · 20.6 KiB · 204dd9b Raw
694 lines · cpp
1// RUN: %clang_cc1 -std=c++1z -verify %s -DERRORS -Wundefined-func-template2// RUN: %clang_cc1 -std=c++1z -verify %s -UERRORS -Wundefined-func-template3 4// This test is split into two because we only produce "undefined internal"5// warnings if we didn't produce any errors.6#if ERRORS7 8namespace std {9  using size_t = decltype(sizeof(0));10  template<typename T> struct initializer_list {11    const T *p;12    size_t n;13    initializer_list();14  };15}16 17template<typename T> constexpr bool has_type(...) { return false; }18template<typename T> constexpr bool has_type(T&) { return true; }19 20std::initializer_list il1 = {1, 2, 3, 4, 5};21auto il2 = std::initializer_list{1, 2, 3, 4};22auto il3 = std::initializer_list(il1);23auto il4 = std::initializer_list{il1, il1, il1};24static_assert(has_type<std::initializer_list<int>>(il1));25static_assert(has_type<std::initializer_list<int>>(il2));26static_assert(has_type<std::initializer_list<int>>(il3));27static_assert(has_type<std::initializer_list<std::initializer_list<int>>>(il4));28 29auto il5 = std::initializer_list{il1};30// expected-error@-1 {{no viable conversion from 'std::initializer_list<int>' to 'const int'}}31 32template<typename T> struct vector {33  template<typename Iter> vector(Iter, Iter);34  vector(std::initializer_list<T>);35};36 37template<typename T> vector(std::initializer_list<T>) -> vector<T>;38template<typename Iter> explicit vector(Iter, Iter) -> vector<typename Iter::value_type>;39template<typename T> explicit vector(std::size_t, T) -> vector<T>;40 41vector v1 = {1, 2, 3, 4};42static_assert(has_type<vector<int>>(v1));43 44struct iter { typedef char value_type; } it, end;45vector v2(it, end);46static_assert(has_type<vector<char>>(v2));47 48vector v3(5, 5);49static_assert(has_type<vector<int>>(v3));50 51vector v4 = {it, end};52static_assert(has_type<vector<iter>>(v4));53 54vector v5{it, end};55static_assert(has_type<vector<iter>>(v5));56 57template<typename ...T> struct tuple { tuple(T...); };58template<typename ...T> explicit tuple(T ...t) -> tuple<T...>; // expected-note {{declared}}59// FIXME: Remove60template<typename ...T> tuple(tuple<T...>) -> tuple<T...>;61 62const int n = 4;63tuple ta = tuple{1, 'a', "foo", n};64static_assert(has_type<tuple<int, char, const char*, int>>(ta));65 66tuple tb{ta};67static_assert(has_type<tuple<int, char, const char*, int>>(tb));68 69// FIXME: This should be tuple<tuple<...>>; when the above guide is removed.70tuple tc = {ta};71static_assert(has_type<tuple<int, char, const char*, int>>(tc));72 73tuple td = {1, 2, 3}; // expected-error {{selected an explicit deduction guide}}74static_assert(has_type<tuple<int, char, const char*, int>>(td));75 76// FIXME: This is a GCC extension for now; if CWG don't allow this, at least77// add a warning for it.78namespace new_expr {79  tuple<int> *p = new tuple{0};80  tuple<float, float> *q = new tuple(1.0f, 2.0f);81}82 83namespace ambiguity {84  template<typename T> struct A {};85  A(unsigned short) -> A<int>; // expected-note {{candidate}}86  A(short) -> A<int>; // expected-note {{candidate}}87  A a = 0; // expected-error {{ambiguous deduction for template arguments of 'A'}}88 89  template<typename T> struct B {};90  template<typename T> B(T(&)(int)) -> B<int>; // expected-note {{candidate function [with T = int]}}91  template<typename T> B(int(&)(T)) -> B<int>; // expected-note {{candidate function [with T = int]}}92  int f(int);93  B b = f; // expected-error {{ambiguous deduction for template arguments of 'B'}}94}95 96// FIXME: Revisit this once CWG decides if attributes, and [[deprecated]] in97// particular, should be permitted here.98namespace deprecated {99  template<typename T> struct A { A(int); };100  [[deprecated]] A(int) -> A<void>; // expected-note {{marked deprecated here}}101  A a = 0; // expected-warning {{'<deduction guide for A>' is deprecated}}102}103 104namespace dependent {105  template<template<typename...> typename A> decltype(auto) a = A{1, 2, 3};106  static_assert(has_type<vector<int>>(a<vector>));107  static_assert(has_type<tuple<int, int, int>>(a<tuple>));108 109  struct B {110    template<typename T> struct X { X(T); };111    X(int) -> X<int>;112    template<typename T> using Y = X<T>;113  };114  template<typename T> void f() {115    typename T::X tx = 0;116    typename T::Y ty = 0; // expected-warning {{class template argument deduction for alias templates is a C++20 extension}}117  }118  template void f<B>(); // expected-note {{in instantiation of function template specialization 'dependent::f<dependent::B>' requested here}}119 120  template<typename T> struct C { C(T); };121  template<typename T> C(T) -> C<T>;122  template<typename T> void g(T a) {123    C b = 0;124    C c = a;125    using U = decltype(b); // expected-note {{previous}}126    using U = decltype(c); // expected-error {{different types ('C<const char *>' vs 'C<int>')}}127  }128  void h() {129    g(0);130    g("foo"); // expected-note {{instantiation of}}131  }132}133 134namespace look_into_current_instantiation {135  template<typename U> struct Q {};136  template<typename T> struct A {137    using U = T;138    template<typename> using V = Q<A<T>::U>;139    template<typename W = int> A(V<W>);140  };141  A a = Q<float>(); // ok, can look through class-scope typedefs and alias142                    // templates, and members of the current instantiation143  A<float> &r = a;144 145  template<typename T> struct B { // expected-note {{could not match 'look_into_current_instantiation::B<T>' against 'int'}} \146                                  // expected-note {{implicit deduction guide declared as 'template <typename T> B(look_into_current_instantiation::B<T>) -> look_into_current_instantiation::B<T>'}}147    struct X {148      typedef T type;149    };150    B(typename X::type); // expected-note {{couldn't infer template argument 'T'}} \151                         // expected-note {{implicit deduction guide declared as 'template <typename T> B(typename X::type) -> look_into_current_instantiation::B<T>'}}152  };153  B b = 0; // expected-error {{no viable}}154 155  // We should have a substitution failure in the immediate context of156  // deduction when using the C(T, U) constructor (probably; core wording157  // unclear).158  template<typename T> struct C {159    using U = typename T::type;160    C(T, U);161  };162 163  struct R { R(int); typedef R type; };164  C(...) -> C<R>;165 166  C c = {1, 2};167}168 169namespace nondeducible {170  template<typename A, typename B> struct X {};171 172  template<typename A> // expected-note {{non-deducible template parameter 'A'}}173  X() -> X<A, int>; // expected-error {{deduction guide template contains a template parameter that cannot be deduced}}174 175  template<typename A> // expected-note {{non-deducible template parameter 'A'}}176  X(typename X<A, int>::type) -> X<A, int>; // expected-error {{deduction guide template contains a template parameter that cannot be deduced}}177 178  template<typename A = int,179           typename B> // expected-note {{non-deducible template parameter 'B'}}180  X(int) -> X<A, B>; // expected-error {{deduction guide template contains a template parameter that cannot be deduced}}181 182  template<typename A = int,183           typename ...B>184  X(float) -> X<A, B...>; // ok185 186  template <typename> struct UnnamedTemplateParam {};187  template <typename>                                  // expected-note {{non-deducible template parameter (anonymous)}}188  UnnamedTemplateParam() -> UnnamedTemplateParam<int>; // expected-error {{deduction guide template contains a template parameter that cannot be deduced}}189}190 191namespace default_args_from_ctor {192  template <class A> struct S { S(A = 0) {} };193  S s(0);194 195  template <class A> struct T { template<typename B> T(A = 0, B = 0) {} };196  T t(0, 0);197}198 199namespace transform_params {200  template<typename T, T N, template<T (*v)[N]> typename U, T (*X)[N]>201  struct A {202    template<typename V, V M, V (*Y)[M], template<V (*v)[M]> typename W>203    A(U<X>, W<Y>);204 205    static constexpr T v = N;206  };207 208  int n[12];209  template<int (*)[12]> struct Q {};210  Q<&n> qn;211  A a(qn, qn);212  static_assert(a.v == 12);213 214  template<typename ...T> struct B {215    template<T ...V> B(const T (&...p)[V]) {216      constexpr int Vs[] = {V...};217      static_assert(Vs[0] == 3 && Vs[1] == 4 && Vs[2] == 4);218    }219    static constexpr int (*p)(T...) = (int(*)(int, char, char))nullptr;220  };221  B b({1, 2, 3}, "foo", {'x', 'y', 'z', 'w'}); // ok222 223  template<typename ...T> struct C {224    template<T ...V, template<T...> typename X>225      C(X<V...>);226  };227  template<int...> struct Y {};228  C c(Y<0, 1, 2>{});229 230  template<typename ...T> struct D {231    template<T ...V> D(Y<V...>);232  };233  D d(Y<0, 1, 2>{});234}235 236namespace variadic {237  int arr3[3], arr4[4];238 239  // PR32673240  template<typename T> struct A {241    template<typename ...U> A(T, U...);242  };243  A a(1, 2, 3);244 245  template<typename T> struct B {246    template<int ...N> B(T, int (&...r)[N]);247  };248  B b(1, arr3, arr4);249 250  template<typename T> struct C {251    template<template<typename> typename ...U> C(T, U<int>...);252  };253  C c(1, a, b);254 255  template<typename ...U> struct X {256    template<typename T> X(T, U...);257  };258  X x(1, 2, 3);259 260  template<int ...N> struct Y {261    template<typename T> Y(T, int (&...r)[N]);262  };263  Y y(1, arr3, arr4);264 265  template<template<typename> typename ...U> struct Z {266    template<typename T> Z(T, U<int>...);267  };268  Z z(1, a, b);269}270 271namespace tuple_tests {272  // The converting n-ary constructor appears viable, deducing T as an empty273  // pack (until we check its SFINAE constraints).274  namespace libcxx_1 {275    template<class ...T> struct tuple {276      template<class ...Args> struct X { static const bool value = false; };277      template<class ...U, bool Y = X<U...>::value> tuple(U &&...u);278    };279    tuple a = {1, 2, 3};280  }281 282  // Don't get caught by surprise when X<...> doesn't even exist in the283  // selected specialization!284  namespace libcxx_2 {285    template<class ...T> struct tuple {286      template<class ...Args> struct X { static const bool value = false; };287      // Substitution into X<U...>::value succeeds but produces the288      // value-dependent expression289      //   tuple<T...>::X<>::value290      // FIXME: Is that the right behavior?291      template<class ...U, bool Y = X<U...>::value> tuple(U &&...u);292    };293    template <> class tuple<> {};294    tuple a = {1, 2, 3}; // expected-error {{excess elements in struct initializer}}295  }296 297  namespace libcxx_3 {298    template<typename ...T> struct scoped_lock {299      scoped_lock(T...);300    };301    template<> struct scoped_lock<> {};302    scoped_lock l = {};303  }304}305 306namespace dependent {307  template<typename T> struct X { // expected-note 3{{here}}308    X(T);309  };310  template<typename T> int Var(T t) {311    X x(t);312    return X(x) + 1; // expected-error {{invalid operands}}313  }314  template<typename T> int Cast(T t) {315    return X(X(t)) + 1; // expected-error {{invalid operands}}316  }317  template<typename T> int Cast2(T t) {318    return (X)(X)t + 1; // expected-error {{deduction not allowed}}319  }320  template<typename T> int Cast3(T t) {321    return X{X{t}} + 1; // expected-error {{invalid operands}}322  }323  template<typename T> int Cast4(T t) {324    return (X){(X){t}} + 1; // expected-error 2{{deduction not allowed}}325  }326  template<typename T> int New(T t) {327    return X(new X(t)) + 1; // expected-error {{invalid operands}}328  };329  template<typename T> int *New2(T t) {330    return new X(X(t)) * 2; // expected-error {{invalid operands}}331  };332  template int Var(float); // expected-note {{instantiation of}}333  template int Cast(float); // expected-note {{instantiation of}}334  template int Cast3(float); // expected-note {{instantiation of}}335  template int New(float); // expected-note {{instantiation of}}336  template int *New2(float); // expected-note {{instantiation of}}337  template<typename T> int operator+(X<T>, int);338  template int Var(int);339  template int Cast(int);340  template int New(int);341 342  template<template<typename> typename Y> void test() {343    Y(0);344    new Y(0);345    Y y(0);346  }347  template void test<X>();348}349 350namespace injected_class_name {351  template<typename T = void> struct A {352    A();353    template<typename U> A(A<U>);354  };355  A<int> a;356  A b = a;357  using T = decltype(a);358  using T = decltype(b);359}360 361namespace member_guides {362  // PR34520363  template<class>364  struct Foo {365    template <class T> struct Bar {366      Bar(...) {}367    };368    Bar(int) -> Bar<int>;369  };370  Foo<int>::Bar b = 0;371 372  struct A {373    template<typename T> struct Public; // expected-note {{declared public}}374    Public(float) -> Public<float>;375  protected: // expected-note {{declared protected by intervening access specifier}}376    template<typename T> struct Protected; // expected-note 2{{declared protected}}377    Protected(float) -> Protected<float>;378    Public(int) -> Public<int>; // expected-error {{different access}}379  private: // expected-note {{declared private by intervening access specifier}}380    template<typename T> struct Private; // expected-note {{declared private}}381    Protected(int) -> Protected<int>; // expected-error {{different access}}382  public: // expected-note 2{{declared public by intervening access specifier}}383    template<typename T> Public(T) -> Public<T>;384    template<typename T> Protected(T) -> Protected<T>; // expected-error {{different access}}385    template<typename T> Private(T) -> Private<T>; // expected-error {{different access}}386  };387}388 389namespace rdar41903969 {390template <class T> struct A {};391template <class T> struct B;392template <class T> struct C {393  C(A<T>&);394  C(B<T>&);395};396 397void foo(A<int> &a, B<int> &b) {398  (void)C{b};399  (void)C{a};400}401 402template<typename T> struct X {403  X(std::initializer_list<T>) = delete;404  X(const X&);405};406 407template <class T> struct D : X<T> {};408 409void bar(D<int>& d) {410  (void)X{d};411}412}413 414namespace rdar41330135 {415template <int> struct A {};416template <class T>417struct S {418  template <class U>419  S(T a, U t, A<sizeof(t)>);420};421template <class T> struct D {422  D(T t, A<sizeof(t)>);423};424int f() {425  S s(0, 0, A<sizeof(int)>());426  D d(0, A<sizeof(int)>());427}428 429namespace test_dupls {430template<unsigned long> struct X {};431template<typename T> struct A {432  A(T t, X<sizeof(t)>);433};434A a(0, {});435template<typename U> struct B {436  B(U u, X<sizeof(u)>);437};438B b(0, {});439}440 441}442 443namespace no_crash_on_default_arg {444class A {445  template <typename T> class B {446    B(int c = 1);447  };448  // This used to crash due to unparsed default arg above. The diagnostic could449  // be improved, but the point of this test is to simply check we do not crash.450  B(); // expected-error {{deduction guide declaration without trailing return type}}451};452} // namespace no_crash_on_default_arg453 454#pragma clang diagnostic push455#pragma clang diagnostic warning "-Wctad-maybe-unsupported"456namespace test_implicit_ctad_warning {457 458template <class T>459struct Tag {};460 461template <class T>462struct NoExplicit { // expected-note {{add a deduction guide to suppress this warning}}463  NoExplicit(T) {}464  NoExplicit(T, int) {}465};466 467// expected-warning@+1 {{'NoExplicit' may not intend to support class template argument deduction}}468NoExplicit ne(42);469 470template <class U>471struct HasExplicit {472  HasExplicit(U) {}473  HasExplicit(U, int) {}474};475template <class U> HasExplicit(U, int) -> HasExplicit<Tag<U>>;476 477HasExplicit he(42);478 479// Motivating examples from (taken from Stephan Lavavej's 2018 Cppcon talk)480template <class T, class U>481struct AmateurPair { // expected-note {{add a deduction guide to suppress this warning}}482  T first;483  U second;484  explicit AmateurPair(const T &t, const U &u) {}485};486// expected-warning@+1 {{'AmateurPair' may not intend to support class template argument deduction}}487AmateurPair p1(42, "hello world"); // deduces to Pair<int, char[12]>488 489template <class T, class U>490struct AmateurPair2 { // expected-note {{add a deduction guide to suppress this warning}}491  T first;492  U second;493  explicit AmateurPair2(T t, U u) {}494};495// expected-warning@+1 {{'AmateurPair2' may not intend to support class template argument deduction}}496AmateurPair2 p2(42, "hello world"); // deduces to Pair2<int, const char*>497 498template <class T, class U>499struct ProPair {500  T first; U second;501    explicit ProPair(T const& t, U  const& u)  {}502};503template<class T1, class T2>504ProPair(T1, T2) -> ProPair<T1, T2>;505ProPair p3(42, "hello world"); // deduces to ProPair<int, const char*>506static_assert(__is_same(decltype(p3), ProPair<int, const char*>));507 508// Test that user-defined explicit guides suppress the warning even if they509// aren't used as candidates.510template <class T>511struct TestExplicitCtor {512  TestExplicitCtor(T) {}513};514template <class T>515explicit TestExplicitCtor(TestExplicitCtor<T> const&) -> TestExplicitCtor<void>;516TestExplicitCtor<int> ce1{42};517TestExplicitCtor ce2 = ce1;518static_assert(__is_same(decltype(ce2), TestExplicitCtor<int>), "");519 520struct allow_ctad_t {521  allow_ctad_t() = delete;522};523 524template <class T>525struct TestSuppression {526  TestSuppression(T) {}527};528TestSuppression(allow_ctad_t)->TestSuppression<void>;529TestSuppression ta("abc");530static_assert(__is_same(decltype(ta), TestSuppression<const char *>), "");531}532#pragma clang diagnostic pop533 534namespace PR41549 {535 536template <class H, class P> struct umm;537 538template <class H = int, class P = int>539struct umm {540  umm(H h = 0, P p = 0);541};542 543template <class H, class P> struct umm;544 545umm m(1);546 547}548 549namespace PR45124 {550  class a { int d; };551  class b : a {};552 553  struct x { ~x(); };554  template<typename> class y { y(x = x()); };555  template<typename z> y(z)->y<z>;556 557  // Not a constant initializer, but trivial default initialization. We won't558  // detect this as trivial default initialization if synthesizing the implicit559  // deduction guide 'template<typename T> y(x = x()) -> Y<T>;' leaves behind a560  // pending cleanup.561  __thread b g;562}563 564namespace PR47175 {565  template<typename T> struct A { A(T); T x; };566  template<typename T> int &&n = A(T()).x;567  int m = n<int>;568}569 570// Ensure we don't crash when CTAD fails.571template <typename T1, typename T2>572struct Foo {   // expected-note {{candidate function template not viable}} \573               // expected-note {{implicit deduction guide declared as 'template <typename T1, typename T2> Foo(Foo<T1, T2>) -> Foo<T1, T2>'}}574  Foo(T1, T2); // expected-note {{candidate function template not viable}} \575               // expected-note {{implicit deduction guide declared as 'template <typename T1, typename T2> Foo(T1, T2) -> Foo<T1, T2>'}}576};577 578template <typename... Args>579void insert(Args &&...args);580 581void foo() {582  insert(Foo(2, 2, 2)); // expected-error{{no viable constructor or deduction guide}}583}584 585namespace PR52139 {586  struct Abstract {587    template <class... Ts>588    struct overloaded : Ts... {589      using Ts::operator()...;590    };591    template <class... Ts>592    overloaded(Ts...) -> overloaded<Ts...>;593 594  private:595    virtual void f() = 0;596  };597}598 599namespace function_prototypes {600  template<class T> using fptr1 = void (*) (T);601  template<class T> using fptr2 = fptr1<fptr1<T>>;602 603  template<class T> void foo0(fptr1<T>) {604    static_assert(__is_same(T, const char*));605  }606  void bar0(const char *const volatile __restrict);607  void t0() { foo0(&bar0); }608 609  template<class T> void foo1(fptr1<const T *>) {610     static_assert(__is_same(T, char));611  }612  void bar1(const char * __restrict);613  void t1() { foo1(&bar1); }614 615  template<class T> void foo2(fptr2<const T *>) {616    static_assert(__is_same(T, char));617  }618  void bar2(fptr1<const char * __restrict>);619  void t2() { foo2(&bar2); }620 621  template<class T> void foo3(fptr1<const T *>) {}622  void bar3(char * __restrict);623  void t3() { foo3(&bar3); }624  // expected-error@-1 {{no matching function for call to 'foo3'}}625  // expected-note@-4  {{candidate template ignored: cannot deduce a type for 'T' that would make 'const T' equal 'char'}}626 627  template<class T> void foo4(fptr2<const T *>) {}628  void bar4(fptr1<char * __restrict>);629  void t4() { foo4(&bar4); }630  // expected-error@-1 {{no matching function for call to 'foo4'}}631  // expected-note@-4  {{candidate template ignored: cannot deduce a type for 'T' that would make 'const T' equal 'char'}}632 633  template<typename T> void foo5(T(T)) {}634  const int bar5(int);635  void t5() { foo5(bar5); }636  // expected-error@-1 {{no matching function for call to 'foo5'}}637  // expected-note@-4  {{candidate template ignored: deduced conflicting types for parameter 'T' ('const int' vs. 'int')}}638 639  struct Foo6 {};640  template<typename T> void foo6(void(*)(struct Foo6, T)) {}641  void bar6(Foo6, int);642  void t6() { foo6(bar6); }643}644#else645 646// expected-no-diagnostics647namespace undefined_warnings {648  // Make sure we don't get an "undefined but used internal symbol" warning for the deduction guide here.649  namespace {650    template <typename T>651    struct TemplDObj {652      explicit TemplDObj(T func) noexcept {}653    };654    auto test1 = TemplDObj(0);655 656    TemplDObj(float) -> TemplDObj<double>;657    auto test2 = TemplDObj(.0f);658  }659}660 661namespace GH51710 {662template<typename T>663struct A {664  A(T f()) {}665  A(int f(), T) {}666 667  A(T array[10]) {}668  A(int array[10], T) {}669};670 671template<typename T>672struct B {673   B(T array[]) {}674   B(int array[], T) {}675};676 677 678int foo();679 680void bar() {681  A test1(foo);682  A test2(foo, 1);683 684  int array[10];685  A test3(array);686  A test4(array, 1);687 688  B test5(array);689  B test6(array, 1);690}691} // namespace GH51710692 693#endif694