diff options
| author | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-12-08 02:01:17 +0000 |
|---|---|---|
| committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-12-08 02:01:17 +0000 |
| commit | 593f993a68550aff3b668c97a62447ee146d509b (patch) | |
| tree | cc5435f6ef285e7c6abcf4f9b3515346034980a1 /clang/include | |
| parent | 1536e3b2c39a927337d4647ae2c3cd7103bb2772 (diff) | |
| download | bcm5719-llvm-593f993a68550aff3b668c97a62447ee146d509b.tar.gz bcm5719-llvm-593f993a68550aff3b668c97a62447ee146d509b.zip | |
Implement C++03 [dcl.init]p5's checking for value-initialization of references
properly, rather than faking it up by pretending that a reference member makes
the default constructor non-trivial. That leads to rejects-valids when putting
such types inside unions.
llvm-svn: 169662
Diffstat (limited to 'clang/include')
| -rw-r--r-- | clang/include/clang/AST/DeclCXX.h | 19 | ||||
| -rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 |
2 files changed, 21 insertions, 0 deletions
diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h index c13389c62b0..4728e500a19 100644 --- a/clang/include/clang/AST/DeclCXX.h +++ b/clang/include/clang/AST/DeclCXX.h @@ -353,6 +353,11 @@ class CXXRecordDecl : public RecordDecl { /// \brief True if any field has an in-class initializer. bool HasInClassInitializer : 1; + /// \brief True if any field is of reference type, and does not have an + /// in-class initializer. In this case, value-initialization of this class + /// is illegal in C++98 even if the class has a trivial default constructor. + bool HasUninitializedReferenceMember : 1; + /// \brief The trivial special members which this class has, per /// C++11 [class.ctor]p5, C++11 [class.copy]p12, C++11 [class.copy]p25, /// C++11 [class.dtor]p5. @@ -982,6 +987,20 @@ public: /// for non-static data members. bool hasInClassInitializer() const { return data().HasInClassInitializer; } + /// \brief Whether this class or any of its subobjects has any members of + /// reference type which would make value-initialization ill-formed, per + /// C++03 [dcl.init]p5: + /// -- if T is a non-union class type without a user-declared constructor, + /// then every non-static data member and base-class component of T is + /// value-initialized + /// [...] + /// A program that calls for [...] value-initialization of an entity of + /// reference type is ill-formed. + bool hasUninitializedReferenceMember() const { + return !isUnion() && !hasUserDeclaredConstructor() && + data().HasUninitializedReferenceMember; + } + /// isPOD - Whether this class is a POD-type (C++ [class]p4), which is a class /// that is an aggregate that has no non-static non-POD data members, no /// reference data members, no user-defined copy assignment operator and no diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index d1066d62190..c21cd794ab4 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -1238,6 +1238,8 @@ def err_reference_var_requires_init : Error< "declaration of reference variable %0 requires an initializer">; def err_reference_without_init : Error< "reference to type %0 requires an initializer">; +def note_value_initialization_here : Note< + "in value-initialization of type %0 here">; def err_reference_has_multiple_inits : Error< "reference cannot be initialized with multiple values">; def err_init_non_aggr_init_list : Error< |

