diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-05-21 17:52:48 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-05-21 17:52:48 +0000 |
commit | 4337dc776074ac0143b49823890303f952d3d9ae (patch) | |
tree | 7d625e8cbfce702f6a29a2907b04a353df424c94 /lib/Sema/SemaDecl.cpp | |
parent | c9471b0ff1815ed0149dbfcad0f385ed8648eeb0 (diff) |
Teach Sema::ActOnUninitializedDecl() not to try to interpret when one
should use a constructor to default-initialize a
variable. InitializationSequence knows the rules for default
initialization, better. Fixes <rdar://problem/8501008>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@131796 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 88 |
1 files changed, 43 insertions, 45 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 2501e7f4d4..a5a494877f 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -5616,55 +5616,53 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl, return; } - 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. - // C++0x [dcl.init]p11: - // If no initializer is specified for an object, the object is - // default-initialized; [...]. - } else { - // Check for jumps past the implicit initializer. C++0x - // clarifies that this applies to a "variable with automatic - // storage duration", not a "local variable". - // C++0x [stmt.dcl]p3 - // A program that jumps from a point where a variable with automatic - // storage duration is not ins cope to a point where it is in scope is - // ill-formed unless the variable has scalar type, class type with a - // trivial defautl constructor and a trivial destructor, a cv-qualified - // version of one of these types, or an array of one of the preceding - // types and is declared without an initializer. - if (getLangOptions().CPlusPlus && Var->hasLocalStorage() && Record) { + // Check for jumps past the implicit initializer. C++0x + // clarifies that this applies to a "variable with automatic + // storage duration", not a "local variable". + // C++0x [stmt.dcl]p3 + // A program that jumps from a point where a variable with automatic + // storage duration is not in scope to a point where it is in scope is + // ill-formed unless the variable has scalar type, class type with a + // trivial default constructor and a trivial destructor, a cv-qualified + // version of one of these types, or an array of one of the preceding + // types and is declared without an initializer. + if (getLangOptions().CPlusPlus && Var->hasLocalStorage()) { + if (const RecordType *Record + = Context.getBaseElementType(Type)->getAs<RecordType>()) { CXXRecordDecl *CXXRecord = cast<CXXRecordDecl>(Record->getDecl()); - if (!getLangOptions().CPlusPlus0x || - !CXXRecord->hasTrivialDefaultConstructor() || - !CXXRecord->hasTrivialDestructor()) + if ((!getLangOptions().CPlusPlus0x && !CXXRecord->isPOD()) || + (getLangOptions().CPlusPlus0x && + (!CXXRecord->hasTrivialDefaultConstructor() || + (!CXXRecord->hasTrivialDestructor())))) getCurFunction()->setHasBranchProtectedScope(); } - - InitializedEntity Entity = InitializedEntity::InitializeVariable(Var); - InitializationKind Kind - = InitializationKind::CreateDefault(Var->getLocation()); - - InitializationSequence InitSeq(*this, Entity, Kind, 0, 0); - ExprResult Init = InitSeq.Perform(*this, Entity, Kind, - MultiExprArg(*this, 0, 0)); - if (Init.isInvalid()) - Var->setInvalidDecl(); - else if (Init.get()) - Var->setInit(MaybeCreateExprWithCleanups(Init.get())); } + + // 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. + // C++0x [dcl.init]p11: + // If no initializer is specified for an object, the object is + // default-initialized; [...]. + InitializedEntity Entity = InitializedEntity::InitializeVariable(Var); + InitializationKind Kind + = InitializationKind::CreateDefault(Var->getLocation()); + + InitializationSequence InitSeq(*this, Entity, Kind, 0, 0); + ExprResult Init = InitSeq.Perform(*this, Entity, Kind, + MultiExprArg(*this, 0, 0)); + if (Init.isInvalid()) + Var->setInvalidDecl(); + else if (Init.get()) + Var->setInit(MaybeCreateExprWithCleanups(Init.get())); CheckCompleteVariableDeclaration(Var); } |