reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    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
// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s

struct one { char c; };
struct two { char c[2]; };

namespace reference {
  struct A {
    int i1, i2;
  };

  void single_init() {
    const int &cri1a = {1};
    const int &cri1b{1};

    int i = 1;
    int &ri1a = {i};
    int &ri1b{i};

    int &ri2 = {1}; // expected-error {{cannot bind to an initializer list temporary}}

    A a{1, 2};
    A &ra1a = {a};
    A &ra1b{a};
  }

  void reference_to_aggregate() {
    const A &ra1{1, 2};
    A &ra2{1, 2}; // expected-error {{cannot bind to an initializer list temporary}}

    const int (&arrayRef)[] = {1, 2, 3};
    static_assert(sizeof(arrayRef) == 3 * sizeof(int), "bad array size");
  }

  struct B {
    int i1;
  };

  void call() {
    one f(const int&);
    f({1});

    one g(int&); // expected-note {{passing argument}}
    g({1}); // expected-error {{cannot bind to an initializer list temporary}}
    int i = 0;
    g({i});

    void h(const B&);
    h({1});

    void a(B&); // expected-note {{passing argument}}
    a({1}); // expected-error {{cannot bind to an initializer list temporary}}
    B b{1};
    a({b});
  }

  void overloading() {
    one f(const int&);
    two f(const B&);

    // First is identity conversion, second is user-defined conversion.
    static_assert(sizeof(f({1})) == sizeof(one), "bad overload resolution");

    one g(int&);
    two g(const B&);

    static_assert(sizeof(g({1})) == sizeof(two), "bad overload resolution");

    one h(const int&);
    two h(const A&);

    static_assert(sizeof(h({1, 2})) == sizeof(two), "bad overload resolution");
  }

  struct X {};

  void edge_cases() {
    int const &b({0}); // expected-error {{cannot initialize reference type 'const int &' with a parenthesized initializer list}}
    const int (&arr)[3] ({1, 2, 3}); // expected-error {{cannot initialize reference type 'const int (&)[3]' with a parenthesized initializer list}}
    const X &x({}); // expected-error {{cannot initialize reference type 'const reference::X &' with a parenthesized initializer list}}
  }

  template<typename T> void dependent_edge_cases() {
    T b({}); // expected-error-re 3{{cannot initialize reference type {{.*}} with a parenthesized init}}
    T({}); // expected-error-re 3{{cannot initialize reference type {{.*}} with a parenthesized init}}
  }
  template void dependent_edge_cases<X>(); // ok
  template void dependent_edge_cases<const int&>(); // expected-note {{instantiation of}}
  template void dependent_edge_cases<const int(&)[1]>(); // expected-note {{instantiation of}}
  template void dependent_edge_cases<const X&>(); // expected-note {{instantiation of}}
}

namespace PR12182 {
  void f(int const(&)[3]);

  void g() {
      f({1, 2});
  }
}

namespace PR12660 {
  const int &i { 1 };
  struct S { S(int); } const &s { 2 };
}

namespace b7891773 {
  typedef void (*ptr)();
  template <class T> void f();
  int g(const ptr &);
  int k = g({ f<int> });
}

namespace inner_init {
  struct A { int n; };
  struct B { A &&r; };
  B b1 { 0 }; // expected-error {{reference to type 'inner_init::A' could not bind to an rvalue of type 'int'}}
  B b2 { { 0 } };
  B b3 { { { 0 } } }; // expected-warning {{braces around scalar init}}

  struct C { C(int); };   // expected-note 2{{candidate constructor (the implicit}} \
                          // expected-note {{candidate constructor not viable: cannot convert initializer list argument to 'int'}}
  struct D { C &&r; };
  D d1 { 0 }; // ok, 0 implicitly converts to C
  D d2 { { 0 } }; // ok, { 0 } calls C(0)
  D d3 { { { 0 } } }; // ok, { { 0 } } calls C({ 0 }), expected-warning {{braces around scalar init}}
  D d4 { { { { 0 } } } }; // expected-error {{no matching constructor for initialization of 'inner_init::C &&'}}

  struct E { explicit E(int); }; // expected-note 2{{here}}
  struct F { E &&r; };
  F f1 { 0 }; // expected-error {{could not bind to an rvalue of type 'int'}}
  F f2 { { 0 } }; // expected-error {{chosen constructor is explicit}}
  F f3 { { { 0 } } }; // expected-error {{chosen constructor is explicit}}
}

namespace PR20844 {
  struct A {};
  struct B { operator A&(); } b;
  A &a{b}; // expected-error {{excess elements}} expected-note {{in initialization of temporary of type 'PR20844::A'}}
}

namespace PR21834 {
const int &a = (const int &){0}; // expected-error {{cannot bind to an initializer list}}
}