[cfe-commits] r131796 - in /cfe/trunk: lib/Sema/SemaDecl.cpp test/CXX/basic/basic.lookup/basic.lookup.argdep/p4.cpp test/CXX/dcl.decl/dcl.init/p6.cpp
Douglas Gregor
dgregor at apple.com
Sat May 21 10:52:48 PDT 2011
Author: dgregor
Date: Sat May 21 12:52:48 2011
New Revision: 131796
URL: http://llvm.org/viewvc/llvm-project?rev=131796&view=rev
Log:
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>.
Modified:
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.argdep/p4.cpp
cfe/trunk/test/CXX/dcl.decl/dcl.init/p6.cpp
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=131796&r1=131795&r2=131796&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Sat May 21 12:52:48 2011
@@ -5616,55 +5616,53 @@
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);
}
Modified: cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.argdep/p4.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.argdep/p4.cpp?rev=131796&r1=131795&r2=131796&view=diff
==============================================================================
--- cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.argdep/p4.cpp (original)
+++ cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.argdep/p4.cpp Sat May 21 12:52:48 2011
@@ -45,6 +45,9 @@
namespace test1 {
template <class T> class A {
template <class U> friend void foo(A &, U); // expected-note {{not viable: 1st argument ('const A<int>') would lose const qualifier}}
+
+ public:
+ A();
};
void test() {
Modified: cfe/trunk/test/CXX/dcl.decl/dcl.init/p6.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.decl/dcl.init/p6.cpp?rev=131796&r1=131795&r2=131796&view=diff
==============================================================================
--- cfe/trunk/test/CXX/dcl.decl/dcl.init/p6.cpp (original)
+++ cfe/trunk/test/CXX/dcl.decl/dcl.init/p6.cpp Sat May 21 12:52:48 2011
@@ -14,3 +14,15 @@
const HasUserDefault x2;
const int x3; // expected-error{{default initialization of an object of const type 'const int'}}
}
+
+// rdar://8501008
+struct s0 {};
+struct s1 { static const s0 foo; };
+const struct s0 s1::foo; // expected-error{{default initialization of an object of const type 'const struct s0' requires a user-provided default constructor}}
+
+template<typename T>
+struct s2 {
+ static const s0 foo;
+};
+
+template<> const struct s0 s2<int>::foo; // okay
More information about the cfe-commits
mailing list