summaryrefslogtreecommitdiffstats
path: root/clang/include
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2012-12-08 02:01:17 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2012-12-08 02:01:17 +0000
commit593f993a68550aff3b668c97a62447ee146d509b (patch)
treecc5435f6ef285e7c6abcf4f9b3515346034980a1 /clang/include
parent1536e3b2c39a927337d4647ae2c3cd7103bb2772 (diff)
downloadbcm5719-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.h19
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td2
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<
OpenPOWER on IntegriCloud