From 589973b097996bffb4f7d56af189f93c9d37b60a Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Mon, 8 Mar 2010 02:45:10 +0000 Subject: In C++98/03, an uninitialized variable that has POD class type will be uninitialized. This seems not to be the case in C++0x, where we still call the (trivial) default constructor for a POD class (!). Previously, we had implemented only the C++0x rules; now we implement both. Fixes PR6536. llvm-svn: 97928 --- clang/lib/Sema/SemaDecl.cpp | 44 +++++++++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 15 deletions(-) (limited to 'clang/lib/Sema/SemaDecl.cpp') diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 935adcf1b65..82dcd60aa06 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -3809,24 +3809,38 @@ void Sema::ActOnUninitializedDecl(DeclPtrTy dcl, return; } - InitializedEntity Entity = InitializedEntity::InitializeVariable(Var); - InitializationKind Kind - = InitializationKind::CreateDefault(Var->getLocation()); + const RecordType *Record + = Context.getBaseElementType(Type)->getAs(); + if (Record && getLangOptions().CPlusPlus && !getLangOptions().CPlusPlus0x && + cast(Record->getDecl())->isPOD()) { + // C++03 [dcl.init]p9: + // If no initializer is specified for an object, and the + // object is of (possibly cv-qualified) non-POD class type (or + // array thereof), the object shall be default-initialized; if + // the object is of const-qualified type, the underlying class + // type shall have a user-declared default + // constructor. Otherwise, if no initializer is specified for + // a non- static object, the object and its subobjects, if + // any, have an indeterminate initial value); if the object + // or any of its subobjects are of const-qualified type, the + // program is ill-formed. + // FIXME: DPG thinks it is very fishy that C++0x disables this. + } else { + InitializedEntity Entity = InitializedEntity::InitializeVariable(Var); + InitializationKind Kind + = InitializationKind::CreateDefault(Var->getLocation()); - InitializationSequence InitSeq(*this, Entity, Kind, 0, 0); - OwningExprResult Init = InitSeq.Perform(*this, Entity, Kind, - MultiExprArg(*this, 0, 0)); - if (Init.isInvalid()) - Var->setInvalidDecl(); - else { - if (Init.get()) + InitializationSequence InitSeq(*this, Entity, Kind, 0, 0); + OwningExprResult Init = InitSeq.Perform(*this, Entity, Kind, + MultiExprArg(*this, 0, 0)); + if (Init.isInvalid()) + Var->setInvalidDecl(); + else if (Init.get()) Var->setInit(MaybeCreateCXXExprWithTemporaries(Init.takeAs())); - - if (getLangOptions().CPlusPlus) - if (const RecordType *Record - = Context.getBaseElementType(Type)->getAs()) - FinalizeVarWithDestructor(Var, Record); } + + if (!Var->isInvalidDecl() && getLangOptions().CPlusPlus && Record) + FinalizeVarWithDestructor(Var, Record); } } -- cgit v1.2.3