forked from OSchip/llvm-project
Implement some tests for defaulted constructors. To do this I had to
suppress an error we were previously emitting on valid union code. llvm-svn: 131440
This commit is contained in:
parent
54459240e3
commit
8b4551844c
|
@ -2017,24 +2017,26 @@ BuildImplicitMemberInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (FieldBaseElementType->isReferenceType()) {
|
||||
SemaRef.Diag(Constructor->getLocation(),
|
||||
diag::err_uninitialized_member_in_ctor)
|
||||
<< (int)Constructor->isImplicit()
|
||||
<< SemaRef.Context.getTagDeclType(Constructor->getParent())
|
||||
<< 0 << Field->getDeclName();
|
||||
SemaRef.Diag(Field->getLocation(), diag::note_declared_at);
|
||||
return true;
|
||||
}
|
||||
if (!Field->getParent()->isUnion()) {
|
||||
if (FieldBaseElementType->isReferenceType()) {
|
||||
SemaRef.Diag(Constructor->getLocation(),
|
||||
diag::err_uninitialized_member_in_ctor)
|
||||
<< (int)Constructor->isImplicit()
|
||||
<< SemaRef.Context.getTagDeclType(Constructor->getParent())
|
||||
<< 0 << Field->getDeclName();
|
||||
SemaRef.Diag(Field->getLocation(), diag::note_declared_at);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (FieldBaseElementType.isConstQualified()) {
|
||||
SemaRef.Diag(Constructor->getLocation(),
|
||||
diag::err_uninitialized_member_in_ctor)
|
||||
<< (int)Constructor->isImplicit()
|
||||
<< SemaRef.Context.getTagDeclType(Constructor->getParent())
|
||||
<< 1 << Field->getDeclName();
|
||||
SemaRef.Diag(Field->getLocation(), diag::note_declared_at);
|
||||
return true;
|
||||
if (FieldBaseElementType.isConstQualified()) {
|
||||
SemaRef.Diag(Constructor->getLocation(),
|
||||
diag::err_uninitialized_member_in_ctor)
|
||||
<< (int)Constructor->isImplicit()
|
||||
<< SemaRef.Context.getTagDeclType(Constructor->getParent())
|
||||
<< 1 << Field->getDeclName();
|
||||
SemaRef.Diag(Field->getLocation(), diag::note_declared_at);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Nothing to initialize.
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
|
||||
|
||||
void fn() = default; // expected-error {{only special member}}
|
||||
struct foo {
|
||||
void fn() = default; // expected-error {{only special member}}
|
||||
|
||||
foo() = default;
|
||||
foo(const foo&) = default;
|
||||
foo(foo&) = default;
|
||||
foo& operator = (const foo&) = default;
|
||||
foo& operator = (foo&) = default;
|
||||
~foo() = default;
|
||||
};
|
||||
|
||||
struct bar {
|
||||
bar();
|
||||
bar(const bar&);
|
||||
bar(bar&);
|
||||
bar& operator = (const bar&);
|
||||
bar& operator = (bar&);
|
||||
~bar();
|
||||
};
|
||||
|
||||
bar::bar() = default;
|
||||
bar::bar(const bar&) = default;
|
||||
bar::bar(bar&) = default;
|
||||
bar& bar::operator = (const bar&) = default;
|
||||
bar& bar::operator = (bar&) = default;
|
||||
bar::~bar() = default;
|
||||
|
||||
// FIXME: static_assert(__is_trivial(foo), "foo should be trivial");
|
||||
|
||||
static_assert(!__has_trivial_destructor(bar), "bar's destructor isn't trivial");
|
||||
static_assert(!__has_trivial_constructor(bar),
|
||||
"bar's default constructor isn't trivial");
|
||||
static_assert(!__has_trivial_copy(bar), "bar has no trivial copy");
|
||||
static_assert(!__has_trivial_assign(bar), "bar has no trivial assign");
|
||||
|
||||
void tester() {
|
||||
foo f, g(f);
|
||||
bar b, c(b);
|
||||
f = g;
|
||||
b = c;
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
|
||||
|
||||
struct non_trivial {
|
||||
non_trivial();
|
||||
non_trivial(const non_trivial&);
|
||||
non_trivial& operator = (const non_trivial&);
|
||||
~non_trivial();
|
||||
};
|
||||
|
||||
union bad_union { // expected-note {{marked deleted here}}
|
||||
non_trivial nt;
|
||||
};
|
||||
bad_union u; // expected-error {{call to deleted constructor}}
|
||||
union bad_union2 { // expected-note {{marked deleted here}}
|
||||
const int i;
|
||||
};
|
||||
bad_union2 u2; // expected-error {{call to deleted constructor}}
|
||||
|
||||
struct bad_anon { // expected-note {{marked deleted here}}
|
||||
union {
|
||||
non_trivial nt;
|
||||
};
|
||||
};
|
||||
bad_anon a; // expected-error {{call to deleted constructor}}
|
||||
struct bad_anon2 { // expected-note {{marked deleted here}}
|
||||
union {
|
||||
const int i;
|
||||
};
|
||||
};
|
||||
bad_anon2 a2; // expected-error {{call to deleted constructor}}
|
||||
|
||||
// This would be great except that we implement
|
||||
union good_union {
|
||||
const int i;
|
||||
float f;
|
||||
};
|
||||
good_union gu;
|
||||
struct good_anon {
|
||||
union {
|
||||
const int i;
|
||||
float f;
|
||||
};
|
||||
};
|
||||
good_anon ga;
|
||||
|
||||
struct good : non_trivial {
|
||||
non_trivial nt;
|
||||
};
|
||||
good g;
|
|
@ -59,3 +59,10 @@ namespace PR7948 {
|
|||
struct S { const int x; ~S(); };
|
||||
const S arr[2] = { { 42 } };
|
||||
}
|
||||
|
||||
// This is valid
|
||||
union U {
|
||||
const int i;
|
||||
float f;
|
||||
};
|
||||
U u;
|
||||
|
|
Loading…
Reference in New Issue