aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-03-08 02:45:10 +0000
committerDouglas Gregor <dgregor@apple.com>2010-03-08 02:45:10 +0000
commit516a6bc399f1f4595423e80c9d4bc687f870acd1 (patch)
tree848ac6a7240e4b597359ca5c0bdf8f5736a8ff31 /lib
parenta2762918ecc636c9af207ce2a9ce705edad2a444 (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.cpp44
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);
}
}