diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-03-08 02:45:10 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-03-08 02:45:10 +0000 |
commit | 516a6bc399f1f4595423e80c9d4bc687f870acd1 (patch) | |
tree | 848ac6a7240e4b597359ca5c0bdf8f5736a8ff31 /lib | |
parent | a2762918ecc636c9af207ce2a9ce705edad2a444 (diff) |
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.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@97928 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 44 |
1 files changed, 29 insertions, 15 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 935adcf1b6..82dcd60aa0 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/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<RecordType>(); + if (Record && getLangOptions().CPlusPlus && !getLangOptions().CPlusPlus0x && + cast<CXXRecordDecl>(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<Expr>())); - - if (getLangOptions().CPlusPlus) - if (const RecordType *Record - = Context.getBaseElementType(Type)->getAs<RecordType>()) - FinalizeVarWithDestructor(Var, Record); } + + if (!Var->isInvalidDecl() && getLangOptions().CPlusPlus && Record) + FinalizeVarWithDestructor(Var, Record); } } |