summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorAlexis Hunt <alercah@gmail.com>2011-05-17 00:19:05 +0000
committerAlexis Hunt <alercah@gmail.com>2011-05-17 00:19:05 +0000
commit8b4551844c1b5114c855b672dd69f61da15f4028 (patch)
treeb03d35141bf3824250b90b576b98bff93776b030 /clang
parent54459240e3967bf05aeee38e6559c3a7fd724d48 (diff)
downloadbcm5719-llvm-8b4551844c1b5114c855b672dd69f61da15f4028.tar.gz
bcm5719-llvm-8b4551844c1b5114c855b672dd69f61da15f4028.zip
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
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp36
-rw-r--r--clang/test/SemaCXX/cxx0x-defaulted-functions.cpp45
-rw-r--r--clang/test/SemaCXX/cxx0x-deleted-default-ctor.cpp49
-rw-r--r--clang/test/SemaCXX/default-constructor-initializers.cpp7
4 files changed, 120 insertions, 17 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index c9dddfe5c6e..e280972f023 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -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.
diff --git a/clang/test/SemaCXX/cxx0x-defaulted-functions.cpp b/clang/test/SemaCXX/cxx0x-defaulted-functions.cpp
new file mode 100644
index 00000000000..86c5fd10e23
--- /dev/null
+++ b/clang/test/SemaCXX/cxx0x-defaulted-functions.cpp
@@ -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;
+}
+
diff --git a/clang/test/SemaCXX/cxx0x-deleted-default-ctor.cpp b/clang/test/SemaCXX/cxx0x-deleted-default-ctor.cpp
new file mode 100644
index 00000000000..0bf89145302
--- /dev/null
+++ b/clang/test/SemaCXX/cxx0x-deleted-default-ctor.cpp
@@ -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;
diff --git a/clang/test/SemaCXX/default-constructor-initializers.cpp b/clang/test/SemaCXX/default-constructor-initializers.cpp
index 9da85567bed..e783f498260 100644
--- a/clang/test/SemaCXX/default-constructor-initializers.cpp
+++ b/clang/test/SemaCXX/default-constructor-initializers.cpp
@@ -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;
OpenPOWER on IntegriCloud