summaryrefslogtreecommitdiff
path: root/test/SemaCXX/cxx0x-initializer-aggregates.cpp
blob: f53ac6dff930bbf4ded467feff0bb4941f3b4c9c (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
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
// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s

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

namespace aggregate {
  // Direct list initialization does NOT allow braces to be elided!
  struct S {
    int ar[2];
    struct T {
      int i1;
      int i2;
    } t;
    struct U {
      int i1;
    } u[2];
    struct V {
      int var[2];
    } v;
  };

  void bracing() {
    S s1 = { 1, 2, 3 ,4, 5, 6, 7, 8 }; // no-error
    S s2{ {1, 2}, {3, 4}, { {5}, {6} }, { {7, 8} } }; // completely braced
    S s3{ 1, 2, 3, 4, 5, 6 }; // expected-error 5 {{cannot omit braces}}
    S s4{ {1, 2}, {3, 4}, {5, 6}, { {7, 8} } }; // expected-error 2 {{cannot omit braces}}
    S s5{ {1, 2}, {3, 4}, { {5}, {6} }, {7, 8} }; // expected-error {{cannot omit braces}}
  }

  void bracing_new() {
    new S{ {1, 2}, {3, 4}, { {5}, {6} }, { {7, 8} } }; // completely braced
    new S{ 1, 2, 3, 4, 5, 6 }; // expected-error 5 {{cannot omit braces}}
    new S{ {1, 2}, {3, 4}, {5, 6}, { {7, 8} } }; // expected-error 2 {{cannot omit braces}}
    new S{ {1, 2}, {3, 4}, { {5}, {6} }, {7, 8} }; // expected-error {{cannot omit braces}}
  }

  void bracing_construct() {
    (void) S{ {1, 2}, {3, 4}, { {5}, {6} }, { {7, 8} } }; // completely braced
    (void) S{ 1, 2, 3, 4, 5, 6 }; // expected-error 5 {{cannot omit braces}}
    (void) S{ {1, 2}, {3, 4}, {5, 6}, { {7, 8} } }; // expected-error 2 {{cannot omit braces}}
    (void) S{ {1, 2}, {3, 4}, { {5}, {6} }, {7, 8} }; // expected-error {{cannot omit braces}}
  }

  struct String {
    String(const char*);
  };

  struct A {
    int m1;
    int m2;
  };

  void function_call() {
    void takes_A(A);
    takes_A({1, 2});
  }

  struct B {
    int m1;
    String m2;
  };

  void overloaded_call() {
    one overloaded(A);
    two overloaded(B);

    static_assert(sizeof(overloaded({1, 2})) == sizeof(one), "bad overload");
    static_assert(sizeof(overloaded({1, "two"})) == sizeof(two),
      "bad overload");
    // String is not default-constructible
    static_assert(sizeof(overloaded({1})) == sizeof(one), "bad overload");
  }

  struct C { int a[2]; C():a({1, 2}) { } }; // expected-error {{parenthesized initialization of a member array is a GNU extension}}
}

namespace array_explicit_conversion {
  typedef int test1[2];
  typedef int test2[];
  template<int x> struct A { int a[x]; }; // expected-error {{'a' declared as an array with a negative size}}
  typedef A<1> test3[];
  typedef A<-1> test4[];
  void f() {
    (void)test1{1};
    (void)test2{1};
    (void)test3{{{1}}};
    (void)test4{{{1}}}; // expected-note {{in instantiation of template class 'array_explicit_conversion::A<-1>' requested here}}
  }
}

namespace sub_constructor {
  struct DefaultConstructor { // expected-note 2 {{not viable}}
    DefaultConstructor(); // expected-note  {{not viable}}
    int x;
  };
  struct NoDefaultConstructor1 { // expected-note 2 {{not viable}}
    NoDefaultConstructor1(int); // expected-note {{not viable}}
    int x;
  };
  struct NoDefaultConstructor2 {  // expected-note 4 {{not viable}}
    NoDefaultConstructor2(int,int); // expected-note 2 {{not viable}}
    int x;
  };

  struct Aggr {
    DefaultConstructor a;
    NoDefaultConstructor1 b;
    NoDefaultConstructor2 c;
  };

  Aggr ok1 { {}, {0} , {0,0} };
  Aggr ok2 = { {}, {0} , {0,0} };
  Aggr too_many { {0} , {0} , {0,0} }; // expected-error {{no matching constructor for initialization}}
  Aggr too_few { {} , {0} , {0} }; // expected-error {{no matching constructor for initialization}}
  Aggr invalid { {} , {&ok1} , {0,0} }; // expected-error {{no matching constructor for initialization}}
  NoDefaultConstructor2 array_ok[] = { {0,0} , {0,1} };
  NoDefaultConstructor2 array_error[] = { {0,0} , {0} }; // expected-error {{no matching constructor for initialization}}
}

namespace multidimensional_array {
  void g(const int (&)[2][2]) {}
  void g(const int (&)[2][2][2]) = delete;

  void h() {
    g({{1,2},{3,4}});
  }
}

namespace array_addressof {
  using T = int[5];
  T *p = &T{1,2,3,4,5}; // expected-error {{taking the address of a temporary object of type 'T' (aka 'int [5]')}}
}