thakis updated this revision to Diff 48418.
thakis added a comment.

Thanks! All done.


http://reviews.llvm.org/D16552

Files:
  include/clang/AST/DeclCXX.h
  lib/AST/ASTImporter.cpp
  lib/AST/DeclCXX.cpp
  lib/Sema/SemaInit.cpp
  lib/Serialization/ASTReaderDecl.cpp
  lib/Serialization/ASTWriter.cpp
  test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp
  test/CXX/dcl.decl/dcl.init/p6.cpp
  test/CXX/drs/dr4xx.cpp
  test/SemaCXX/attr-selectany.cpp
  test/SemaCXX/constexpr-value-init.cpp
  test/SemaCXX/cxx0x-cursory-default-delete.cpp
  test/SemaCXX/illegal-member-initialization.cpp
  www/cxx_dr_status.html

Index: www/cxx_dr_status.html
===================================================================
--- www/cxx_dr_status.html
+++ www/cxx_dr_status.html
@@ -1308,11 +1308,11 @@
     <td>Constructors should not be allowed to return normally after an exception</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr class="open" id="212">
+  <tr id="212">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#212";>212</a></td>
-    <td>drafting</td>
+    <td>tentatively ready</td>
     <td>Implicit instantiation is not described clearly enough</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="213">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#213";>213</a></td>
@@ -3023,7 +3023,7 @@
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#497";>497</a></td>
     <td>CD1</td>
     <td>Missing required initialization in example</td>
-    <td class="full" align="center">Yes</td>
+    <td class="none" align="center">Superseded by <a href="#253">253</a></td>
   </tr>
   <tr class="open" id="498">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#498";>498</a></td>
@@ -9137,7 +9137,7 @@
   </tr>
   <tr class="open" id="1554">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1554";>1554</a></td>
-    <td>drafting</td>
+    <td>open</td>
     <td>Access and alias templates</td>
     <td align="center">Not resolved</td>
   </tr>
@@ -11043,11 +11043,11 @@
     <td>Non-identifier characters in <I>ud-suffix</I></td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open" id="1872">
+  <tr id="1872">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1872";>1872</a></td>
-    <td>drafting</td>
+    <td>tentatively ready</td>
     <td>Instantiations of <TT>constexpr</TT> templates that cannot appear in constant expressions</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="1873">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1873";>1873</a></td>
@@ -11763,11 +11763,11 @@
     <td>Inheriting constructors vs default arguments</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open" id="1992">
+  <tr id="1992">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1992";>1992</a></td>
-    <td>drafting</td>
+    <td>tentatively ready</td>
     <td><TT>new (std::nothrow) int[N]</TT> can throw</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
   <tr class="open" id="1993">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1993";>1993</a></td>
@@ -11787,11 +11787,11 @@
     <td><I>exception-specification</I>s and non-type template parameters</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr id="1996">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/";>1996</a></td>
-    <td></td>
+  <tr class="open" id="1996">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1996";>1996</a></td>
+    <td>drafting</td>
     <td>Reference list-initialization ignores conversion functions</td>
-    <td class="none" align="center">Unknown</td>
+    <td align="center">Not resolved</td>
   </tr>
   <tr class="open" id="1997">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1997";>1997</a></td>
@@ -12095,7 +12095,7 @@
   </tr>
   <tr id="2047">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2047";>2047</a></td>
-    <td>ready</td>
+    <td>tentatively ready</td>
     <td>Coordinating &#8220;throws anything&#8221; specifications</td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -12195,11 +12195,11 @@
     <td>Type/nontype hiding in class scope</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open" id="2064">
+  <tr id="2064">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2064";>2064</a></td>
-    <td>drafting</td>
+    <td>tentatively ready</td>
     <td>Conflicting specifications for dependent <I>decltype-specifier</I>s</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
   <tr class="open" id="2065">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2065";>2065</a></td>
@@ -12435,11 +12435,11 @@
     <td>Lvalue-to-rvalue conversion is irrelevant in odr-use of a reference</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open" id="2104">
+  <tr id="2104">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2104";>2104</a></td>
-    <td>drafting</td>
+    <td>tentatively ready</td>
     <td>Internal-linkage <TT>constexpr</TT> references and ODR requirements</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
   <tr class="open" id="2105">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2105";>2105</a></td>
@@ -12543,11 +12543,11 @@
     <td>More flexible lambda syntax</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open" id="2122">
+  <tr id="2122">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2122";>2122</a></td>
-    <td>drafting</td>
+    <td>tentatively ready</td>
     <td>Glvalues of <TT>void</TT> type</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
   <tr class="open" id="2123">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2123";>2123</a></td>
@@ -12585,11 +12585,11 @@
     <td>Imprecise rule for reference member initializer</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open" id="2129">
+  <tr id="2129">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2129";>2129</a></td>
-    <td>drafting</td>
+    <td>tentatively ready</td>
     <td>Non-object prvalues and constant expressions</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="2130">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2130";>2130</a></td>
@@ -12651,29 +12651,29 @@
     <td>Floating-point requirements for integer representation</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open" id="2140">
+  <tr id="2140">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2140";>2140</a></td>
-    <td>drafting</td>
+    <td>tentatively ready</td>
     <td>Lvalue-to-rvalue conversion of <TT>std::nullptr_t</TT></td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open" id="2141">
+  <tr id="2141">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2141";>2141</a></td>
-    <td>drafting</td>
+    <td>tentatively ready</td>
     <td>Ambiguity in <I>new-expression</I> with <I>elaborated-type-specifier</I></td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="2142">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2142";>2142</a></td>
     <td>NAD</td>
     <td>Missing definition of associated classes and namespaces</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open" id="2143">
+  <tr id="2143">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2143";>2143</a></td>
-    <td>drafting</td>
+    <td>tentatively ready</td>
     <td>Value-dependency via injected-class-name</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
   <tr class="open" id="2144">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2144";>2144</a></td>
@@ -12687,11 +12687,11 @@
     <td>Parenthesized declarator in function definition</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open" id="2146">
+  <tr id="2146">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2146";>2146</a></td>
-    <td>drafting</td>
+    <td>tentatively ready</td>
     <td>Scalar object vs memory location in definition of &#8220;unsequenced&#8221;</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="2147">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2147";>2147</a></td>
@@ -12729,29 +12729,29 @@
     <td>Can an alternative token be used as a <I>ud-suffix</I>?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open" id="2153">
+  <tr id="2153">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2153";>2153</a></td>
-    <td>drafting</td>
+    <td>tentatively ready</td>
     <td><I>pure-specifier</I> in friend declaration</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open" id="2154">
+  <tr id="2154">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2154";>2154</a></td>
-    <td>drafting</td>
+    <td>tentatively ready</td>
     <td>Ambiguity of <I>pure-specifier</I></td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
   <tr class="open" id="2155">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2155";>2155</a></td>
     <td>review</td>
     <td>Defining classes and enumerations via <I>using-declaration</I>s</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open" id="2156">
+  <tr id="2156">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2156";>2156</a></td>
-    <td>drafting</td>
+    <td>tentatively ready</td>
     <td>Definition of enumeration declared by <I>using-declaration</I></td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="2157">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2157";>2157</a></td>
@@ -12783,17 +12783,17 @@
     <td>Explicit instantiation declaration and &#8220;preceding initialization&#8221;</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open" id="2162">
+  <tr id="2162">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2162";>2162</a></td>
-    <td>drafting</td>
+    <td>tentatively ready</td>
     <td>Capturing <TT>this</TT> by reference</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open" id="2163">
+  <tr id="2163">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2163";>2163</a></td>
-    <td>drafting</td>
+    <td>tentatively ready</td>
     <td>Labels in <TT>constexpr</TT> functions</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
   <tr class="open" id="2164">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2164";>2164</a></td>
@@ -12813,11 +12813,11 @@
     <td>Unclear meaning of &#8220;undefined <TT>constexpr</TT> function&#8221;</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open" id="2167">
+  <tr id="2167">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2167";>2167</a></td>
-    <td>drafting</td>
+    <td>tentatively ready</td>
     <td>Non-member references with lifetimes within the current evaluation</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
   <tr class="open" id="2168">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2168";>2168</a></td>
@@ -12827,7 +12827,7 @@
   </tr>
   <tr class="open" id="2169">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2169";>2169</a></td>
-    <td>drafting</td>
+    <td>open</td>
     <td>Narrowing conversions and overload resolution</td>
     <td align="center">Not resolved</td>
   </tr>
@@ -12861,17 +12861,17 @@
     <td>Unclear rules for friend definitions in templates</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open" id="2175">
+  <tr id="2175">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2175";>2175</a></td>
-    <td>drafting</td>
+    <td>tentatively ready</td>
     <td>Ambiguity with attribute in conversion operator declaration</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open" id="2176">
+  <tr id="2176">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2176";>2176</a></td>
-    <td>drafting</td>
+    <td>tentatively ready</td>
     <td>Destroying the returned object when a destructor throws</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
   <tr class="open" id="2177">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2177";>2177</a></td>
@@ -12891,11 +12891,11 @@
     <td>Required diagnostic for partial specialization after first use</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open" id="2180">
+  <tr id="2180">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2180";>2180</a></td>
-    <td>drafting</td>
+    <td>tentatively ready</td>
     <td>Virtual bases in destructors and defaulted assignment operators</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
   <tr class="open" id="2181">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2181";>2181</a></td>
Index: test/CXX/drs/dr4xx.cpp
===================================================================
--- test/CXX/drs/dr4xx.cpp
+++ test/CXX/drs/dr4xx.cpp
@@ -1197,12 +1197,12 @@
   int check6[ __is_trivially_assignable(B, const B&) ? 1 : -1];
 }
 
-namespace dr497 { // dr497: yes
+namespace dr497 { // dr497: sup 253
   void before() {
     struct S {
       mutable int i;
     };
-    const S cs; // expected-error {{default initialization}}
+    const S cs;
     int S::*pm = &S::i;
     cs.*pm = 88; // expected-error {{not assignable}}
   }
Index: test/SemaCXX/illegal-member-initialization.cpp
===================================================================
--- test/SemaCXX/illegal-member-initialization.cpp
+++ test/SemaCXX/illegal-member-initialization.cpp
@@ -7,6 +7,7 @@
 };
 
 struct B {
+  int field;
 };
 
 struct X {
Index: test/SemaCXX/cxx0x-cursory-default-delete.cpp
===================================================================
--- test/SemaCXX/cxx0x-cursory-default-delete.cpp
+++ test/SemaCXX/cxx0x-cursory-default-delete.cpp
@@ -11,6 +11,7 @@
   non_const_copy& operator = (non_const_copy&) &;
   non_const_copy& operator = (non_const_copy&) &&;
   non_const_copy() = default; // expected-note {{not viable}}
+  int uninit_field;
 };
 non_const_copy::non_const_copy(non_const_copy&) = default; // expected-note {{not viable}}
 non_const_copy& non_const_copy::operator = (non_const_copy&) & = default; // expected-note {{not viable}}
@@ -30,6 +31,65 @@
   ncc = cncc; // expected-error {{no viable overloaded}}
 };
 
+struct no_fields { };
+struct all_init {
+  int a = 0;
+  int b = 0;
+};
+struct some_init {
+  int a = 0;
+  int b;
+  int c = 0;
+};
+struct some_init_mutable {
+  int a = 0;
+  mutable int b;
+  int c = 0;
+};
+struct some_init_def {
+  some_init_def() = default;
+  int a = 0;
+  int b;
+  int c = 0;
+};
+struct some_init_ctor {
+  some_init_ctor();
+  int a = 0;
+  int b;
+  int c = 0;
+};
+struct sub_some_init : public some_init_def { };
+struct sub_some_init_ctor : public some_init_def {
+  sub_some_init_ctor();
+};
+struct sub_some_init_ctor2 : public some_init_ctor {
+};
+struct some_init_container {
+  some_init_def sid;
+};
+struct some_init_container_ctor {
+  some_init_container_ctor();
+  some_init_def sid;
+};
+struct no_fields_container {
+  no_fields nf;
+};
+
+void constobjs() {
+  const no_fields nf; // ok
+  const all_init ai; // ok
+  const some_init si; // expected-error {{default initialization of an object of const type 'const some_init' without a user-provided default constructor}}
+  const some_init_mutable sim; // ok
+  const some_init_def sid; // expected-error {{default initialization of an object of const type 'const some_init_def' without a user-provided default constructor}}
+  const some_init_ctor sic; // ok
+  const sub_some_init ssi; // expected-error {{default initialization of an object of const type 'const sub_some_init' without a user-provided default constructor}}
+  const sub_some_init_ctor ssic; // ok
+  const sub_some_init_ctor2 ssic2; // ok
+  const some_init_container sicon; // expected-error {{default initialization of an object of const type 'const some_init_container' without a user-provided default constructor}}
+  const some_init_container_ctor siconc; // ok
+  const no_fields_container nfc; // ok
+}
+
 struct non_const_derived : non_const_copy {
   non_const_derived(const non_const_derived&) = default; // expected-error {{requires it to be non-const}}
   non_const_derived& operator =(non_const_derived&) = default;
Index: test/SemaCXX/constexpr-value-init.cpp
===================================================================
--- test/SemaCXX/constexpr-value-init.cpp
+++ test/SemaCXX/constexpr-value-init.cpp
@@ -14,7 +14,7 @@
   constexpr A a; // expected-error {{constant expression}} expected-note {{in call to 'A()'}}
 }
 
-constexpr B b1; // expected-error {{without a user-provided default constructor}}
+constexpr B b1; // ok
 constexpr B b2 = B(); // ok
 static_assert(b2.a.a == 1, "");
 static_assert(b2.a.b == 2, "");
Index: test/SemaCXX/attr-selectany.cpp
===================================================================
--- test/SemaCXX/attr-selectany.cpp
+++ test/SemaCXX/attr-selectany.cpp
@@ -39,7 +39,9 @@
 // The D3D11 headers do something like this.  MSVC doesn't error on this at
 // all, even without the __declspec(selectany), in violation of the standard.
 // We fall back to a warning for selectany to accept headers.
-struct SomeStruct {};
+struct SomeStruct {
+  int foo;
+};
 extern const __declspec(selectany) SomeStruct some_struct; // expected-warning {{default initialization of an object of const type 'const SomeStruct' without a user-provided default constructor is a Microsoft extension}}
 
 // It should be possible to redeclare variables that were defined
Index: test/CXX/dcl.decl/dcl.init/p6.cpp
===================================================================
--- test/CXX/dcl.decl/dcl.init/p6.cpp
+++ test/CXX/dcl.decl/dcl.init/p6.cpp
@@ -4,9 +4,9 @@
 
 // If a program calls for the default initialization of an object of a
 // const-qualified type T, T shall be a class type with a
-// user-provided default constructor.
+// user-provided default constructor, except if T has no uninitialized fields.
 struct MakeNonPOD { MakeNonPOD(); };
-struct NoUserDefault : public MakeNonPOD { };
+struct NoUserDefault : public MakeNonPOD { int field; };
 struct HasUserDefault { HasUserDefault(); };
 
 void test_const_default_init() {
@@ -16,7 +16,7 @@
 }
 
 // rdar://8501008
-struct s0 {};
+struct s0 { int field; };
 struct s1 { static const s0 foo; };
 const struct s0 s1::foo; // expected-error{{default initialization of an object of const type 'const struct s0' without a user-provided default constructor}}
 
Index: test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp
===================================================================
--- test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp
+++ test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp
@@ -116,6 +116,7 @@
 namespace PR13492 {
   struct B {
     B() = default;
+    int field;
   };
 
   void f() {
Index: lib/Serialization/ASTWriter.cpp
===================================================================
--- lib/Serialization/ASTWriter.cpp
+++ lib/Serialization/ASTWriter.cpp
@@ -5547,6 +5547,7 @@
   Record.push_back(Data.HasOnlyCMembers);
   Record.push_back(Data.HasInClassInitializer);
   Record.push_back(Data.HasUninitializedReferenceMember);
+  Record.push_back(Data.HasUninitializedFields);
   Record.push_back(Data.NeedOverloadResolutionForMoveConstructor);
   Record.push_back(Data.NeedOverloadResolutionForMoveAssignment);
   Record.push_back(Data.NeedOverloadResolutionForDestructor);
Index: lib/Serialization/ASTReaderDecl.cpp
===================================================================
--- lib/Serialization/ASTReaderDecl.cpp
+++ lib/Serialization/ASTReaderDecl.cpp
@@ -1412,6 +1412,7 @@
   Data.HasOnlyCMembers = Record[Idx++];
   Data.HasInClassInitializer = Record[Idx++];
   Data.HasUninitializedReferenceMember = Record[Idx++];
+  Data.HasUninitializedFields = Record[Idx++];
   Data.NeedOverloadResolutionForMoveConstructor = Record[Idx++];
   Data.NeedOverloadResolutionForMoveAssignment = Record[Idx++];
   Data.NeedOverloadResolutionForDestructor = Record[Idx++];
@@ -1536,6 +1537,7 @@
   MATCH_FIELD(HasOnlyCMembers)
   MATCH_FIELD(HasInClassInitializer)
   MATCH_FIELD(HasUninitializedReferenceMember)
+  MATCH_FIELD(HasUninitializedFields)
   MATCH_FIELD(NeedOverloadResolutionForMoveConstructor)
   MATCH_FIELD(NeedOverloadResolutionForMoveAssignment)
   MATCH_FIELD(NeedOverloadResolutionForDestructor)
Index: lib/Sema/SemaInit.cpp
===================================================================
--- lib/Sema/SemaInit.cpp
+++ lib/Sema/SemaInit.cpp
@@ -3515,18 +3515,23 @@
   //   If a program calls for the default initialization of an object
   //   of a const-qualified type T, T shall be a class type with a
   //   user-provided default constructor.
+  // C++ core issue 253 proposal:
+  //   If the implicit default constructor initializes all subobjects, no
+  //   initializer should be required.
+  // The 253 proposal is for example needed to process libstdc++ headers in 5.x.
+  CXXConstructorDecl *CtorDecl = cast<CXXConstructorDecl>(Best->Function);
   if (Kind.getKind() == InitializationKind::IK_Default &&
-      Entity.getType().isConstQualified() &&
-      !cast<CXXConstructorDecl>(Best->Function)->isUserProvided()) {
-    if (!maybeRecoverWithZeroInitialization(S, Sequence, Entity))
-      Sequence.SetFailed(InitializationSequence::FK_DefaultInitOfConst);
-    return;
+      Entity.getType().isConstQualified()) {
+    if (!CtorDecl->getParent()->allowConstDefaultInit()) {
+      if (!maybeRecoverWithZeroInitialization(S, Sequence, Entity))
+        Sequence.SetFailed(InitializationSequence::FK_DefaultInitOfConst);
+      return;
+    }
   }
 
   // C++11 [over.match.list]p1:
   //   In copy-list-initialization, if an explicit constructor is chosen, the
   //   initializer is ill-formed.
-  CXXConstructorDecl *CtorDecl = cast<CXXConstructorDecl>(Best->Function);
   if (IsListInit && !Kind.AllowExplicit() && CtorDecl->isExplicit()) {
     Sequence.SetFailed(InitializationSequence::FK_ExplicitConstructor);
     return;
Index: lib/AST/DeclCXX.cpp
===================================================================
--- lib/AST/DeclCXX.cpp
+++ lib/AST/DeclCXX.cpp
@@ -46,34 +46,31 @@
 }
 
 CXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl *D)
-  : UserDeclaredConstructor(false), UserDeclaredSpecialMembers(0),
-    Aggregate(true), PlainOldData(true), Empty(true), Polymorphic(false),
-    Abstract(false), IsStandardLayout(true), HasNoNonEmptyBases(true),
-    HasPrivateFields(false), HasProtectedFields(false), HasPublicFields(false),
-    HasMutableFields(false), HasVariantMembers(false), HasOnlyCMembers(true),
-    HasInClassInitializer(false), HasUninitializedReferenceMember(false),
-    NeedOverloadResolutionForMoveConstructor(false),
-    NeedOverloadResolutionForMoveAssignment(false),
-    NeedOverloadResolutionForDestructor(false),
-    DefaultedMoveConstructorIsDeleted(false),
-    DefaultedMoveAssignmentIsDeleted(false),
-    DefaultedDestructorIsDeleted(false),
-    HasTrivialSpecialMembers(SMF_All),
-    DeclaredNonTrivialSpecialMembers(0),
-    HasIrrelevantDestructor(true),
-    HasConstexprNonCopyMoveConstructor(false),
-    DefaultedDefaultConstructorIsConstexpr(true),
-    HasConstexprDefaultConstructor(false),
-    HasNonLiteralTypeFieldsOrBases(false), ComputedVisibleConversions(false),
-    UserProvidedDefaultConstructor(false), DeclaredSpecialMembers(0),
-    ImplicitCopyConstructorHasConstParam(true),
-    ImplicitCopyAssignmentHasConstParam(true),
-    HasDeclaredCopyConstructorWithConstParam(false),
-    HasDeclaredCopyAssignmentWithConstParam(false),
-    IsLambda(false), IsParsingBaseSpecifiers(false), NumBases(0), NumVBases(0),
-    Bases(), VBases(),
-    Definition(D), FirstFriend() {
-}
+    : UserDeclaredConstructor(false), UserDeclaredSpecialMembers(0),
+      Aggregate(true), PlainOldData(true), Empty(true), Polymorphic(false),
+      Abstract(false), IsStandardLayout(true), HasNoNonEmptyBases(true),
+      HasPrivateFields(false), HasProtectedFields(false),
+      HasPublicFields(false), HasMutableFields(false), HasVariantMembers(false),
+      HasOnlyCMembers(true), HasInClassInitializer(false),
+      HasUninitializedReferenceMember(false), HasUninitializedFields(false),
+      NeedOverloadResolutionForMoveConstructor(false),
+      NeedOverloadResolutionForMoveAssignment(false),
+      NeedOverloadResolutionForDestructor(false),
+      DefaultedMoveConstructorIsDeleted(false),
+      DefaultedMoveAssignmentIsDeleted(false),
+      DefaultedDestructorIsDeleted(false), HasTrivialSpecialMembers(SMF_All),
+      DeclaredNonTrivialSpecialMembers(0), HasIrrelevantDestructor(true),
+      HasConstexprNonCopyMoveConstructor(false),
+      DefaultedDefaultConstructorIsConstexpr(true),
+      HasConstexprDefaultConstructor(false),
+      HasNonLiteralTypeFieldsOrBases(false), ComputedVisibleConversions(false),
+      UserProvidedDefaultConstructor(false), DeclaredSpecialMembers(0),
+      ImplicitCopyConstructorHasConstParam(true),
+      ImplicitCopyAssignmentHasConstParam(true),
+      HasDeclaredCopyConstructorWithConstParam(false),
+      HasDeclaredCopyAssignmentWithConstParam(false), IsLambda(false),
+      IsParsingBaseSpecifiers(false), NumBases(0), NumVBases(0), Bases(),
+      VBases(), Definition(D), FirstFriend() {}
 
 CXXBaseSpecifier *CXXRecordDecl::DefinitionData::getBasesSlowCase() const {
   return Bases.get(Definition->getASTContext().getExternalSource());
@@ -332,6 +329,9 @@
     if (BaseClassDecl->hasUninitializedReferenceMember())
       data().HasUninitializedReferenceMember = true;
 
+    if (!BaseClassDecl->allowConstDefaultInit())
+      data().HasUninitializedFields = true;
+
     addedClassSubobject(BaseClassDecl);
   }
   
@@ -392,6 +392,7 @@
   return !forallBases([](const CXXRecordDecl *) { return true; });
 }
 
+
 bool CXXRecordDecl::isTriviallyCopyable() const {
   // C++0x [class]p5:
   //   A trivially copyable class is a class that:
@@ -702,6 +703,15 @@
       data().IsStandardLayout = false;
     }
 
+    if (!Field->hasInClassInitializer() && !Field->isMutable()) {
+      if (CXXRecordDecl *FieldType = Field->getType()->getAsCXXRecordDecl()) {
+        if (!FieldType->allowConstDefaultInit())
+          data().HasUninitializedFields = true;
+      } else {
+        data().HasUninitializedFields = true;
+      }
+    }
+
     // Record if this field is the first non-literal or volatile field or base.
     if (!T->isLiteralType(Context) || T.isVolatileQualified())
       data().HasNonLiteralTypeFieldsOrBases = true;
Index: lib/AST/ASTImporter.cpp
===================================================================
--- lib/AST/ASTImporter.cpp
+++ lib/AST/ASTImporter.cpp
@@ -2023,6 +2023,7 @@
     ToData.HasInClassInitializer = FromData.HasInClassInitializer;
     ToData.HasUninitializedReferenceMember
       = FromData.HasUninitializedReferenceMember;
+    ToData.HasUninitializedFields = FromData.HasUninitializedFields;
     ToData.NeedOverloadResolutionForMoveConstructor
       = FromData.NeedOverloadResolutionForMoveConstructor;
     ToData.NeedOverloadResolutionForMoveAssignment
Index: include/clang/AST/DeclCXX.h
===================================================================
--- include/clang/AST/DeclCXX.h
+++ include/clang/AST/DeclCXX.h
@@ -378,6 +378,10 @@
     /// even if the class has a trivial default constructor.
     bool HasUninitializedReferenceMember : 1;
 
+    /// \brief True if any non-mutable field whose type doesn't have a user-
+    /// provided default ctor also doesn't have an in-class initializer.
+    bool HasUninitializedFields : 1;
+
     /// \brief These flags are \c true if a defaulted corresponding special
     /// member can't be fully analyzed without performing overload resolution.
     /// @{
@@ -1270,6 +1274,13 @@
     return !(data().HasTrivialSpecialMembers & SMF_Destructor);
   }
 
+  /// \brief Determine whether declaring a const variable with this type is ok
+  /// per core issue 253.
+  bool allowConstDefaultInit() const {
+    return !data().HasUninitializedFields ||
+           hasUserProvidedDefaultConstructor();
+  }
+
   /// \brief Determine whether this class has a destructor which has no
   /// semantic effect.
   ///
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to