Diag(VDecl->getLocation(), diag::err_block_extern_cant_init);
VDecl->setInvalidDecl();
} else if (!VDecl->isInvalidDecl()) {
- if (VDecl->getType()->isReferenceType()
- || isa<InitListExpr>(Init)) {
- InitializationSequence InitSeq(*this, Entity, Kind, &Init, 1);
- if (InitSeq) {
- OwningExprResult Result = InitSeq.Perform(*this, Entity, Kind,
- MultiExprArg(*this, (void**)&Init, 1),
- &DclT);
- if (Result.isInvalid()) {
- VDecl->setInvalidDecl();
- return;
- }
-
- Init = Result.takeAs<Expr>();
- } else {
- InitSeq.Diagnose(*this, Entity, Kind, &Init, 1);
+ InitializationSequence InitSeq(*this, Entity, Kind, &Init, 1);
+ if (InitSeq) {
+ OwningExprResult Result = InitSeq.Perform(*this, Entity, Kind,
+ MultiExprArg(*this, (void**)&Init, 1),
+ &DclT);
+ if (Result.isInvalid()) {
VDecl->setInvalidDecl();
return;
- }
- } else if (CheckInitializerTypes(Init, DclT, Entity, Kind))
+ }
+
+ Init = Result.takeAs<Expr>();
+ } else {
+ InitSeq.Diagnose(*this, Entity, Kind, &Init, 1);
VDecl->setInvalidDecl();
+ return;
+ }
// C++ 3.6.2p2, allow dynamic initialization of static initializers.
// Don't check invalid declarations to avoid emitting useless diagnostics.
case SK_ConstructorInitialization:
case SK_ZeroInitialization:
case SK_CAssignment:
+ case SK_StringInit:
break;
case SK_ConversionSequence:
Steps.push_back(S);
}
+void InitializationSequence::AddStringInitStep(QualType T) {
+ Step S;
+ S.Kind = SK_StringInit;
+ S.Type = T;
+ Steps.push_back(S);
+}
+
void InitializationSequence::SetOverloadFailure(FailureKind Failure,
OverloadingResult Result) {
SequenceKind = FailedSequence;
const InitializationKind &Kind,
Expr *Initializer,
InitializationSequence &Sequence) {
- // FIXME: Implement!
+ Sequence.setSequenceKind(InitializationSequence::StringInit);
+ Sequence.AddStringInitStep(Entity.getType().getType());
}
/// \brief Attempt initialization by constructor (C++ [dcl.init]), which
}
}
}
-
+
+ SourceLocation DeclLoc = Initializer->getLocStart();
+
if (const RecordType *SourceRecordType = SourceType->getAs<RecordType>()) {
// The type we're converting from is a class type, enumerate its conversion
// functions.
+
+ // Try to force the type to be complete before enumerating the conversion
+ // functions; it's okay if this fails, though.
+ S.RequireCompleteType(DeclLoc, SourceType, 0);
+
CXXRecordDecl *SourceRecordDecl
= cast<CXXRecordDecl>(SourceRecordType->getDecl());
}
}
- SourceLocation DeclLoc = Initializer->getLocStart();
-
// Perform overload resolution. If it fails, return the failed result.
OverloadCandidateSet::iterator Best;
if (OverloadingResult Result
return;
}
- // Handle initialization in C
- if (!S.getLangOptions().CPlusPlus) {
- setSequenceKind(CAssignment);
- AddCAssignmentStep(DestType);
- return;
- }
-
// - Otherwise, if the destination type is an array, the program is
// ill-formed.
if (const ArrayType *AT = Context.getAsArrayType(DestType)) {
return;
}
+
+ // Handle initialization in C
+ if (!S.getLangOptions().CPlusPlus) {
+ setSequenceKind(CAssignment);
+ AddCAssignmentStep(DestType);
+ return;
+ }
// - If the destination type is a (possibly cv-qualified) class type:
if (DestType->isRecordType()) {
case SK_ConversionSequence:
case SK_ListInitialization:
case SK_CAssignment:
+ case SK_StringInit:
assert(Args.size() == 1);
CurInit = Sema::OwningExprResult(S, ((Expr **)(Args.get()))[0]->Retain());
if (CurInit.isInvalid())
CurInit = S.Owned(CurInitExpr);
break;
}
+
+ case SK_StringInit: {
+ QualType Ty = Step->Type;
+ CheckStringInit(CurInitExpr, ResultType ? *ResultType : Ty, S);
+ break;
+ }
}
}
StandardConversion,
/// \brief C conversion sequence.
- CAssignment
+ CAssignment,
+
+ /// \brief String initialization
+ StringInit
};
/// \brief Describes the kind of a particular step in an initialization
/// \brief Zero-initialize the object
SK_ZeroInitialization,
/// \brief C assignment
- SK_CAssignment
+ SK_CAssignment,
+ /// \brief Initialization by string
+ SK_StringInit
};
/// \brief A single step in the initialization sequence.
// path. However, that isn't the case yet.
void AddCAssignmentStep(QualType T);
+ /// \brief Add a string init step.
+ void AddStringInitStep(QualType T);
+
/// \brief Note that this initialization sequence failed.
void SetFailed(FailureKind Failure) {
SequenceKind = FailedSequence;
B b;
- A *a = &b; // expected-error{{conversion from 'struct B' to inaccessible base class 'struct A'}} \
- expected-error{{incompatible type initializing 'struct B *', expected 'struct A *'}}
+ A *a = &b; // expected-error{{conversion from 'struct B' to inaccessible base class 'struct A'}}
}
int b;
A a(b);
- int A::*ip = &A::s; // expected-error {{incompatible type initializing 'int *', expected 'int class A::*'}}
+ int A::*ip = &A::s; // expected-error {{cannot initialize a variable of type 'int class A::*' with an rvalue of type 'int *'}}
a.*&A::s = 10; // expected-error{{right hand operand to .* has non pointer-to-member type 'int *'}}
a.*&A::i = 10; // expected-error{{cannot form a pointer-to-member to member 'i' of reference type 'int &'}}
void test_f0() {
int (*f0a)(int, int) = f0;
int (*f0b)(int, int) = &f0;
- int (*f0c)(int, float) = f0; // expected-error{{incompatible type}}
+ int (*f0c)(int, float) = f0; // expected-error{{cannot initialize}}
// FIXME: poor error message above!
}
void test_f0_2() {
using namespace N;
int (*fp0)(int) = f0; // expected-error{{ambiguous}} \
- // expected-error{{initializing}}
+ // expected-error{{cannot initialize}}
float (*fp1)(float) = f0;
}
void variableArrayInit() {
int a = 4;
- char strlit[a] = "foo"; //expected-error{{variable-sized object may not be initialized}}
+ char strlit[a] = "foo"; //expected-error{{array initializer must be an initializer list or string literal}}
int b[a] = { 1, 2, 4 }; //expected-error{{variable-sized object may not be initialized}}
}
int test() {
int a[10];
-int b[10] = a; // expected-error {{initialization with '{...}' expected}}
+int b[10] = a; // expected-error {{array initializer must be an initializer list}}
int +; // expected-error {{expected identifier or '('}}
}
void foo() {
WCHAR_T_TYPE t1[] = L"x";
wchar_t tab[] = L"x";
- WCHAR_T_TYPE t2[] = "x"; // expected-error {{initialization}}
- char t3[] = L"x"; // expected-error {{initialization}}
+ WCHAR_T_TYPE t2[] = "x"; // expected-error {{initializer}}
+ char t3[] = L"x"; // expected-error {{initializer}}
}
class B : private A { }; // expected-note {{'private' inheritance specifier here}}
void f(B* b) {
- A *a = b; // expected-error{{conversion from 'class T1::B' to inaccessible base class 'class T1::A'}} \
- expected-error{{incompatible type initializing 'class T1::B *', expected 'class T1::A *'}}
+ A *a = b; // expected-error{{conversion from 'class T1::B' to inaccessible base class 'class T1::A'}}
}
}
class B : A { }; // expected-note {{inheritance is implicitly 'private'}}
void f(B* b) {
- A *a = b; // expected-error {{conversion from 'class T2::B' to inaccessible base class 'class T2::A'}} \
- expected-error {{incompatible type initializing 'class T2::B *', expected 'class T2::A *'}}
+ A *a = b; // expected-error {{conversion from 'class T2::B' to inaccessible base class 'class T2::A'}}
}
}
class C : public B {
void f(C *c) {
- A* a = c; // expected-error {{conversion from 'class T6::C' to inaccessible base class 'class T6::A'}} \
- expected-error {{incompatible type initializing 'class T6::C *', expected 'class T6::A *'}}
+ A* a = c; // expected-error {{conversion from 'class T6::C' to inaccessible base class 'class T6::A'}}
}
};
--b; // expected-error {{cannot decrement expression of type bool}}
b--; // expected-error {{cannot decrement expression of type bool}}
- bool *b1 = (int *)0; // expected-error{{expected 'bool *'}}
+ bool *b1 = (int *)0; // expected-error{{cannot initialize}}
}
// static_assert_arg_is_bool(x) compiles only if x is a bool.
if (int x=0) ++x;
typedef int arr[10];
- while (arr x=0) ; // expected-error {{an array type is not allowed here}} expected-error {{initialization with '{...}' expected for array}}
+ while (arr x=0) ; // expected-error {{an array type is not allowed here}} expected-error {{array initializer must be an initializer list}}
while (int f()=0) ; // expected-error {{a function type is not allowed here}}
struct S {} s;
while (struct S {} x=0) ; // expected-error {{types may not be defined in conditions}} expected-error {{no viable conversion}} expected-error {{value of type 'struct S' is not contextually convertible to 'bool'}} expected-note{{candidate function}}
while (struct {} x=0) ; // expected-error {{types may not be defined in conditions}} expected-error {{no viable conversion}} expected-error {{value of type 'struct <anonymous>' is not contextually convertible to 'bool'}} expected-note{{candidate function}}
- switch (enum {E} x=0) ; // expected-error {{types may not be defined in conditions}} expected-error {{incompatible type}}
+ switch (enum {E} x=0) ; // expected-error {{types may not be defined in conditions}} expected-error {{cannot initialize}}
if (int x=0) { // expected-note 2 {{previous definition is here}}
int x; // expected-error {{redefinition of 'x'}}
void test_explicit_bool(ExplicitConvToBool ecb) {
bool b1(ecb); // okay
- bool b2 = ecb; // expected-error{{incompatible type initializing 'struct ExplicitConvToBool', expected 'bool'}}
+ bool b2 = ecb; // expected-error{{no viable conversion from 'struct ExplicitConvToBool' to 'bool'}}
accepts_bool(ecb); // expected-error{{no matching function for call to}}
}
struct WithDel {
WithDel() = delete; // expected-note {{candidate function has been explicitly deleted}}
void fn() = delete; // expected-note {{function has been explicitly marked deleted here}}
- operator int() = delete;
+ operator int() = delete; // expected-note {{function has been explicitly marked deleted here}}
void operator +(int) = delete;
int i = delete; // expected-error {{only functions can have deleted definitions}}
WithDel dd; // expected-error {{call to deleted constructor of 'dd'}}
WithDel *d = 0;
d->fn(); // expected-error {{attempt to use a deleted function}}
- int i = *d; // expected-error {{incompatible type initializing}}
+ int i = *d; // expected-error {{invokes a deleted function}}
}
};
struct Derived : Base {
- operator int*();
+ operator int*(); // expected-note {{candidate function}}
};
void foo(const Derived cd, Derived d) {
- int *pi = cd; // expected-error {{incompatible type initializing 'struct Derived const', expected 'int *'}}
+ int *pi = cd; // expected-error {{no viable conversion from 'struct Derived const' to 'int *'}}
int *ppi = d;
}
// return types and arguments must match exactly, no inheritance allowed
void (*(*t7)())() throw(B1) = &s8; // valid
- void (*(*t8)())() throw(A) = &s8; // expected-error {{return types differ}} expected-error {{incompatible type}}
- void (*(*t9)())() throw(D) = &s8; // expected-error {{return types differ}} expected-error {{incompatible type}}
+ void (*(*t8)())() throw(A) = &s8; // expected-error {{return types differ}}
+ void (*(*t9)())() throw(D) = &s8; // expected-error {{return types differ}}
void (*t10)(void (*)() throw(B1)) = &s9; // valid expected-warning{{disambiguated}}
- void (*t11)(void (*)() throw(A)) = &s9; // expected-error {{argument types differ}} expected-error {{incompatible type}} expected-warning{{disambiguated}}
- void (*t12)(void (*)() throw(D)) = &s9; // expected-error {{argument types differ}} expected-error {{incompatible type}} expected-warning{{disambiguated}}
+ void (*t11)(void (*)() throw(A)) = &s9; // expected-error {{argument types differ}} expected-warning{{disambiguated}}
+ void (*t12)(void (*)() throw(D)) = &s9; // expected-error {{argument types differ}} expected-warning{{disambiguated}}
}
// Member function stuff
{
void (Str1::*pfn1)() throw(int) = &Str1::f; // valid
void (Str1::*pfn2)() = &Str1::f; // valid
- void (Str1::*pfn3)() throw() = &Str1::f; // expected-error {{not superset}} expected-error {{incompatible type}}
+ void (Str1::*pfn3)() throw() = &Str1::f; // expected-error {{not superset}}
}
// Don't suppress errors in template instantiation.
pdid = pdi2;
// Fail conversion due to ambiguity and virtuality.
- int F::*pdif = pdi1; // expected-error {{ambiguous conversion from pointer to member of base class 'struct A' to pointer to member of derived class 'struct F'}} expected-error {{incompatible type}}
- int G::*pdig = pdi1; // expected-error {{conversion from pointer to member of class 'struct A' to pointer to member of class 'struct G' via virtual base 'struct D' is not allowed}} expected-error {{incompatible type}}
+ int F::*pdif = pdi1; // expected-error {{ambiguous conversion from pointer to member of base class 'struct A' to pointer to member of derived class 'struct F'}}
+ int G::*pdig = pdi1; // expected-error {{conversion from pointer to member of class 'struct A' to pointer to member of class 'struct G' via virtual base 'struct D' is not allowed}}
// Conversion to member of base.
pdi1 = pdid; // expected-error {{incompatible type assigning 'int struct D::*', expected 'int struct A::*'}}
bool b = nullptr;
// Can't convert nullptr to integral implicitly.
- uintptr_t i = nullptr; // expected-error {{incompatible type initializing}}
+ uintptr_t i = nullptr; // expected-error {{cannot initialize}}
// Operators
(void)(null == nullptr);
}
void f2(id<P1> x) {
- id<P0> l = x; // expected-error {{incompatible type initializing 'id<P1>', expected 'id<P0>'}}
+ id<P0> l = x; // expected-error {{cannot initialize a variable of type 'id<P0>' with an lvalue of type 'id<P1>'}}
}
void f3(A *a) {
- id<P1> l = a; // expected-error {{incompatible type initializing 'A *', expected 'id<P1>'}}
+ id<P1> l = a; // expected-error {{cannot initialize a variable of type 'id<P1>' with an lvalue of type 'A *'}}
}
void f4(int cond, id x, A *a) {
// Fake typeid, lacking a typeinfo header.
namespace std { class type_info {}; }
-struct dummy {}; // expected-note{{candidate function}}
+struct dummy {}; // expected-note 3 {{candidate function}}
template<typename T>
int f0(T x) {
new (t1, u1) int;
delete t1;
- dummy d1 = sizeof(t1); // FIXME: delayed checking okay?
+ dummy d1 = sizeof(t1); // expected-error {{no viable conversion}}
dummy d2 = offsetof(T, foo); // expected-error {{no viable conversion}}
- dummy d3 = __alignof(u1); // FIXME: delayed checking okay?
+ dummy d3 = __alignof(u1); // expected-error {{no viable conversion}}
i1 = typeid(t1); // expected-error {{incompatible type assigning}}
return u1;
int *a(A0<int> &x0, A1<int> &x1) {
int *y0 = x0;
- int *y1 = x1; // expected-error{{initializing}}
+ int *y1 = x1; // expected-error{{no viable conversion}}
}
struct X0Base {