From 40372354290407a1126a43e01bbc515b1a904ca6 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Sun, 18 Sep 2011 00:06:34 +0000 Subject: [PATCH] Fix PR10531. Attach an initializer to anonymous unions, since the default constructor might not be trivial (if there is an in-class initializer for some member) and might be deleted. llvm-svn: 139991 --- clang/lib/Sema/SemaDecl.cpp | 6 ++++ clang/test/CodeGenCXX/mangle.cpp | 11 ------ .../CodeGenCXX/member-init-anon-union.cpp | 35 +++++++++++++++++++ .../SemaCXX/cxx0x-deleted-default-ctor.cpp | 12 +++++++ 4 files changed, 53 insertions(+), 11 deletions(-) create mode 100644 clang/test/CodeGenCXX/member-init-anon-union.cpp diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index dfa8f15b213f..497aa6c9ade6 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -2739,6 +2739,12 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, Record->getLocation(), /*IdentifierInfo=*/0, Context.getTypeDeclType(Record), TInfo, SC, SCAsWritten); + + // Default-initialize the implicit variable. This initialization will be + // trivial in almost all cases, except if a union member has an in-class + // initializer: + // union { int n = 0; }; + ActOnUninitializedDecl(Anon, /*TypeMayContainAuto=*/false); } Anon->setImplicit(); diff --git a/clang/test/CodeGenCXX/mangle.cpp b/clang/test/CodeGenCXX/mangle.cpp index 453b7b713ac6..60edc42bc972 100644 --- a/clang/test/CodeGenCXX/mangle.cpp +++ b/clang/test/CodeGenCXX/mangle.cpp @@ -533,17 +533,6 @@ namespace test15 { template void f<7>(S<7 + e>); } -// rdar://problem/8125400. Don't crash. -namespace test16 { - static union {}; - static union { union {}; }; - static union { struct {}; }; - static union { union { union {}; }; }; - static union { union { struct {}; }; }; - static union { struct { union {}; }; }; - static union { struct { struct {}; }; }; -} - // rdar://problem/8302148 namespace test17 { template struct A {}; diff --git a/clang/test/CodeGenCXX/member-init-anon-union.cpp b/clang/test/CodeGenCXX/member-init-anon-union.cpp new file mode 100644 index 000000000000..d45dfa0d764d --- /dev/null +++ b/clang/test/CodeGenCXX/member-init-anon-union.cpp @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 %s -std=c++0x -emit-llvm -o - | FileCheck %s + +// PR10531. + +static union { + int a = 42; + char *b; +}; + +int f() { return a; } + +// CHECK: define internal void @__cxx_global_var_init +// CHECK-NOT: } +// CHECK: call {{.*}}@"[[CONSTRUCT_GLOBAL:.*]]C1Ev" + + +int g() { + union { + int a; + int b = 81; + }; + // CHECK: define {{.*}}_Z1gv + // CHECK-NOT: } + // CHECK: call {{.*}}@"[[CONSTRUCT_LOCAL:.*]]C1Ev" + return b; +} + + +// CHECK: define {{.*}}@"[[CONSTRUCT_LOCAL]]C2Ev" +// CHECK-NOT: } +// CHECK: store i32 81 + +// CHECK: define {{.*}}@"[[CONSTRUCT_GLOBAL]]C2Ev" +// CHECK-NOT: } +// CHECK: store i32 42 diff --git a/clang/test/SemaCXX/cxx0x-deleted-default-ctor.cpp b/clang/test/SemaCXX/cxx0x-deleted-default-ctor.cpp index dcb6ba2790be..d2fd6cb62fa7 100644 --- a/clang/test/SemaCXX/cxx0x-deleted-default-ctor.cpp +++ b/clang/test/SemaCXX/cxx0x-deleted-default-ctor.cpp @@ -118,3 +118,15 @@ struct late_delete { late_delete(); }; late_delete::late_delete() = default; // expected-error {{would delete it}} + +// See also rdar://problem/8125400. +namespace empty { + static union {}; // expected-error {{deleted constructor}} expected-note {{here}} + static union { union {}; }; + static union { struct {}; }; + static union { union { union {}; }; }; + static union { union { struct {}; }; }; + static union { struct { union {}; }; }; // expected-error {{deleted constructor}} expected-note {{here}} + static union { struct { struct {}; }; }; +} +