From 225e9826336f85166cbc4636ae61028f6f7868be Mon Sep 17 00:00:00 2001 From: Richard Trieu Date: Mon, 16 Sep 2013 21:54:53 +0000 Subject: [PATCH] Move the uninitialized field check to after all the field initializers are added to the CXXConstructorDecl so that information from the constructor can be used. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@190810 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaDeclCXX.cpp | 56 ++++++++++++++++++++++++++++------------ 1 file changed, 39 insertions(+), 17 deletions(-) diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index d9279533b4..dc33f2faf6 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -2624,23 +2624,6 @@ Sema::BuildMemberInitializer(ValueDecl *Member, Expr *Init, Init = MemberInit.get(); } - // Diagnose value-uses of fields to initialize themselves, e.g. - // foo(foo) - // where foo is not also a parameter to the constructor. - // TODO: implement -Wuninitialized and fold this into that framework. - // FIXME: Warn about the case when other fields are used before being - // initialized. For example, let this field be the i'th field. When - // initializing the i'th field, throw a warning if any of the >= i'th - // fields are used, as they are not yet initialized. - // Right now we are only handling the case where the i'th field uses - // itself in its initializer. - // Also need to take into account that some fields may be initialized by - // in-class initializers, see C++11 [class.base.init]p9. - if (getDiagnostics().getDiagnosticLevel(diag::warn_field_is_uninit, IdLoc) - != DiagnosticsEngine::Ignored) { - CheckInitExprContainsUninitializedFields(*this, Init, Member); - } - if (DirectMember) { return new (Context) CXXCtorInitializer(Context, DirectMember, IdLoc, InitRange.getBegin(), Init, @@ -3707,6 +3690,43 @@ bool CheckRedundantUnionInit(Sema &S, } } +// Diagnose value-uses of fields to initialize themselves, e.g. +// foo(foo) +// where foo is not also a parameter to the constructor. +// TODO: implement -Wuninitialized and fold this into that framework. +// FIXME: Warn about the case when other fields are used before being +// initialized. For example, let this field be the i'th field. When +// initializing the i'th field, throw a warning if any of the >= i'th +// fields are used, as they are not yet initialized. +// Right now we are only handling the case where the i'th field uses +// itself in its initializer. +// Also need to take into account that some fields may be initialized by +// in-class initializers, see C++11 [class.base.init]p9. +static void DiagnoseUnitializedFields( + Sema &SemaRef, const CXXConstructorDecl *Constructor) { + + if (SemaRef.getDiagnostics().getDiagnosticLevel(diag::warn_field_is_uninit, + Constructor->getLocation()) + == DiagnosticsEngine::Ignored) { + return; + } + + for (CXXConstructorDecl::init_const_iterator + FieldInit = Constructor->init_begin(), + FieldInitEnd = Constructor->init_end(); + FieldInit != FieldInitEnd; ++FieldInit) { + + FieldDecl *FD = (*FieldInit)->getAnyMember(); + if (!FD) + continue; + Expr *InitExpr = (*FieldInit)->getInit(); + + if (!isa(InitExpr)) { + CheckInitExprContainsUninitializedFields(SemaRef, InitExpr, FD); + } + } +} + /// ActOnMemInitializers - Handle the member initializers for a constructor. void Sema::ActOnMemInitializers(Decl *ConstructorDecl, SourceLocation ColonLoc, @@ -3771,6 +3791,8 @@ void Sema::ActOnMemInitializers(Decl *ConstructorDecl, DiagnoseBaseOrMemInitializerOrder(*this, Constructor, MemInits); SetCtorInitializers(Constructor, AnyErrors, MemInits); + + DiagnoseUnitializedFields(*this, Constructor); } void -- 2.40.0