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
|
// RUN: %clang_cc1 -std=c++03 -verify -ast-dump %s > %t-03
// RUN: FileCheck --input-file=%t-03 %s
// RUN: %clang_cc1 -std=c++11 -verify -ast-dump %s > %t-11
// RUN: FileCheck --input-file=%t-11 %s
// RUN: FileCheck --input-file=%t-11 %s --check-prefix=CHECK-CXX11
// RUN: %clang_cc1 -verify -std=c++17 %s
// http://llvm.org/PR7905
namespace PR7905 {
struct S; // expected-note {{forward declaration}}
void foo1() {
(void)(S[]) {{3}}; // expected-error {{array has incomplete element type}}
}
template <typename T> struct M { T m; };
void foo2() {
(void)(M<short> []) {{3}};
}
}
// Check compound literals mixed with C++11 list-initialization.
namespace brace_initializers {
struct POD {
int x, y;
};
struct HasCtor {
HasCtor(int x, int y);
};
struct HasDtor {
int x, y;
~HasDtor();
};
struct HasCtorDtor {
HasCtorDtor(int x, int y);
~HasCtorDtor();
};
POD p = (POD){1, 2};
// CHECK-NOT: CXXBindTemporaryExpr {{.*}} 'brace_initializers::POD'
// CHECK: CompoundLiteralExpr {{.*}} 'POD':'brace_initializers::POD'
// CHECK-NEXT: InitListExpr {{.*}} 'POD':'brace_initializers::POD'
// CHECK-NEXT: ConstantExpr {{.*}}
// CHECK-NEXT: IntegerLiteral {{.*}} 1{{$}}
// CHECK-NEXT: ConstantExpr {{.*}}
// CHECK-NEXT: IntegerLiteral {{.*}} 2{{$}}
void test() {
(void)(POD){1, 2};
// CHECK-NOT: CXXBindTemporaryExpr {{.*}} 'POD':'brace_initializers::POD'
// CHECK-NOT: ConstantExpr {{.*}} 'POD':'brace_initializers::POD'
// CHECK: CompoundLiteralExpr {{.*}} 'POD':'brace_initializers::POD'
// CHECK-NEXT: InitListExpr {{.*}} 'POD':'brace_initializers::POD'
// CHECK-NEXT: IntegerLiteral {{.*}} 1{{$}}
// CHECK-NEXT: IntegerLiteral {{.*}} 2{{$}}
(void)(HasDtor){1, 2};
// CHECK: CXXBindTemporaryExpr {{.*}} 'HasDtor':'brace_initializers::HasDtor'
// CHECK-NEXT: CompoundLiteralExpr {{.*}} 'HasDtor':'brace_initializers::HasDtor'
// CHECK-NEXT: InitListExpr {{.*}} 'HasDtor':'brace_initializers::HasDtor'
// CHECK-NEXT: IntegerLiteral {{.*}} 1{{$}}
// CHECK-NEXT: IntegerLiteral {{.*}} 2{{$}}
#if __cplusplus >= 201103L
(void)(HasCtor){1, 2};
// CHECK-CXX11-NOT: CXXBindTemporaryExpr {{.*}} 'HasCtor':'brace_initializers::HasCtor'
// CHECK-CXX11-NOT: ConstantExpr {{.*}} 'HasCtor':'brace_initializers::HasCtor'
// CHECK-CXX11: CompoundLiteralExpr {{.*}} 'HasCtor':'brace_initializers::HasCtor'
// CHECK-CXX11-NEXT: CXXTemporaryObjectExpr {{.*}} 'HasCtor':'brace_initializers::HasCtor'
// CHECK-CXX11-NEXT: IntegerLiteral {{.*}} 1{{$}}
// CHECK-CXX11-NEXT: IntegerLiteral {{.*}} 2{{$}}
(void)(HasCtorDtor){1, 2};
// CHECK-CXX11: CXXBindTemporaryExpr {{.*}} 'HasCtorDtor':'brace_initializers::HasCtorDtor'
// CHECK-CXX11-NOT: ConstantExpr {{.*}} 'HasCtorDtor':'brace_initializers::HasCtorDtor'
// CHECK-CXX11: CompoundLiteralExpr {{.*}} 'HasCtorDtor':'brace_initializers::HasCtorDtor'
// CHECK-CXX11-NEXT: CXXTemporaryObjectExpr {{.*}} 'HasCtorDtor':'brace_initializers::HasCtorDtor'
// CHECK-CXX11-NEXT: IntegerLiteral {{.*}} 1{{$}}
// CHECK-CXX11-NEXT: IntegerLiteral {{.*}} 2{{$}}
#endif
}
struct PrivateDtor {
int x, y;
private:
~PrivateDtor(); // expected-note {{declared private here}}
};
void testPrivateDtor() {
(void)(PrivateDtor){1, 2}; // expected-error {{temporary of type 'PrivateDtor' has private destructor}}
}
}
// This doesn't necessarily need to be an error, but CodeGen can't handle it
// at the moment.
int PR17415 = (int){PR17415}; // expected-error {{initializer element is not a compile-time constant}}
// Make sure we accept this. (Not sure if we actually should... but we do
// at the moment.)
template<unsigned> struct Value { };
template<typename T>
int &check_narrowed(Value<sizeof((T){1.1})>);
#if __cplusplus >= 201103L
// Compound literals in global lambdas have automatic storage duration
// and are not subject to the constant-initialization rules.
int computed_with_lambda = [] {
int x = 5;
int result = ((int[]) { x, x + 2, x + 4, x + 6 })[0];
return result;
}();
#endif
namespace DynamicFileScopeLiteral {
// This covers the case where we have a file-scope compound literal with a
// non-constant initializer in C++. Previously, we had a bug where Clang forgot
// to consider initializer list elements for bases.
struct Empty {};
struct Foo : Empty { // expected-note 0+ {{candidate constructor}}
int x;
int y;
};
int f();
#if __cplusplus < 201103L
// expected-error@+6 {{non-aggregate type 'Foo' cannot be initialized with an initializer list}}
#elif __cplusplus < 201703L
// expected-error@+4 {{no matching constructor}}
#else
// expected-error@+2 {{initializer element is not a compile-time constant}}
#endif
Foo o = (Foo){ {}, 1, f() };
}
|