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 “throws anything” 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 “unsequenced”</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 “preceding initialization”</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 “undefined <TT>constexpr</TT> function”</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