]> granicus.if.org Git - clang/commitdiff
PR10954: variant members should not be implicitly initialized in constructors if no
authorRichard Smith <richard-llvm@metafoo.co.uk>
Sun, 18 Sep 2011 11:14:50 +0000 (11:14 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Sun, 18 Sep 2011 11:14:50 +0000 (11:14 +0000)
mem-initializer is specified for them, unless an in-class initializer is specified.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@139996 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaDeclCXX.cpp
test/CXX/special/class.init/class.base.init/p8-0x.cpp

index 0f7af4e30dd112284b1b20842bc5085166a8ec81..b408f7f0882f0b0fb8ca65b30095ebd21cfa147a 100644 (file)
@@ -2291,6 +2291,11 @@ static bool CollectFieldInitializer(Sema &SemaRef, BaseAndFieldInfo &Info,
     return false;
   }
 
+  // Don't build an implicit initializer for union members if none was
+  // explicitly specified.
+  if (Field->getParent()->isUnion())
+    return false;
+
   // Don't try to build an implicit initializer if there were semantic
   // errors in any of the initializers (and therefore we might be
   // missing some that the user actually wrote).
@@ -2464,17 +2469,6 @@ bool Sema::SetCtorInitializers(CXXConstructorDecl *Constructor,
         continue;
       }
       
-      // If this field is somewhere within an anonymous union, we only 
-      // initialize it if there's an explicit initializer.
-      if (isWithinAnonymousUnion(F)) {
-        if (CXXCtorInitializer *Init
-              = Info.AllBaseFields.lookup(F->getAnonField())) {
-          Info.AllToInit.push_back(Init);
-        }
-        
-        continue;
-      }
-      
       // Initialize each field of an anonymous struct individually.
       if (CollectFieldInitializer(*this, Info, F->getAnonField(), F))
         HadError = true;
index 8512a9f7bb3a6c62ccf74a97d1d0b39d94b66fb1..81ed9c2570541d79942fb694ab298dc45955e035 100644 (file)
@@ -5,11 +5,15 @@ struct S {
   int &a; // expected-note 2{{here}}
   int &b = n;
 
+  union {
+    const int k = 42;
+  };
+
   S() {} // expected-error {{constructor for 'S' must explicitly initialize the reference member 'a'}}
   S(int) : a(n) {} // ok
   S(char) : b(n) {} // expected-error {{constructor for 'S' must explicitly initialize the reference member 'a'}}
   S(double) : a(n), b(n) {} // ok
-};
+} s(0);
 
 union U {
   int a = 0;
@@ -21,3 +25,27 @@ union U {
   U(char) : b('y') {} // desired-error {{at most one member of a union may be initialized}}
   U(double) : a(1), b('y') {} // desired-error {{at most one member of a union may be initialized}}
 };
+
+// PR10954: variant members do not acquire an implicit initializer.
+namespace VariantMembers {
+  struct NoDefaultCtor {
+    NoDefaultCtor(int);
+  };
+  union V {
+    NoDefaultCtor ndc;
+    int n;
+
+    V() {}
+    V(int n) : n(n) {}
+    V(int n, bool) : ndc(n) {}
+  };
+  struct K {
+    union {
+      NoDefaultCtor ndc;
+      int n;
+    };
+    K() {}
+    K(int n) : n(n) {}
+    K(int n, bool) : ndc(n) {}
+  };
+}