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 | 589973b097996bffb4f7d56af189f93c9d37b60a (patch) | |
| tree | 4aaccbd2faa6f170256f892ea303946d559ff84a /clang/lib/Sema/SemaDecl.cpp | |
| parent | 104ee00181f90735eaa945ac628d594e483edbcc (diff) | |
| download | bcm5719-llvm-589973b097996bffb4f7d56af189f93c9d37b60a.tar.gz bcm5719-llvm-589973b097996bffb4f7d56af189f93c9d37b60a.zip | |
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
Diffstat (limited to 'clang/lib/Sema/SemaDecl.cpp')
| -rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 44 | 
1 files changed, 29 insertions, 15 deletions
| 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<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);    }  } | 

