[cfe-commits] r123818 - in /cfe/trunk: include/clang/Sema/Sema.h lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp test/SemaObjCXX/blocks.mm
John McCall
rjmccall at apple.com
Wed Jan 19 03:48:09 PST 2011
Author: rjmccall
Date: Wed Jan 19 05:48:09 2011
New Revision: 123818
URL: http://llvm.org/viewvc/llvm-project?rev=123818&view=rev
Log:
When building the copy expression for a __block variable, make sure
there's a respectable point of instantiation. Also, make sure we do
this operation even when instantiating a dependently-typed variable.
Modified:
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/test/SemaObjCXX/blocks.mm
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=123818&r1=123817&r2=123818&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Wed Jan 19 05:48:09 2011
@@ -716,6 +716,7 @@
bool &Redeclaration);
void CheckVariableDeclaration(VarDecl *NewVD, LookupResult &Previous,
bool &Redeclaration);
+ void CheckCompleteVariableDeclaration(VarDecl *var);
NamedDecl* ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
QualType R, TypeSourceInfo *TInfo,
LookupResult &Previous,
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=123818&r1=123817&r2=123818&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Jan 19 05:48:09 2011
@@ -3056,26 +3056,6 @@
if (isExplicitSpecialization && !NewVD->isInvalidDecl() &&
CheckMemberSpecialization(NewVD, Previous))
NewVD->setInvalidDecl();
- // For variables declared as __block which require copy construction,
- // must capture copy initialization expression here.
- if (!NewVD->isInvalidDecl() && NewVD->hasAttr<BlocksAttr>()) {
- QualType T = NewVD->getType();
- if (!T->isDependentType() && !T->isReferenceType() &&
- T->getAs<RecordType>() && !T->isUnionType()) {
- Expr *E = new (Context) DeclRefExpr(NewVD, T,
- VK_LValue, SourceLocation());
- ExprResult Res = PerformCopyInitialization(
- InitializedEntity::InitializeBlock(NewVD->getLocation(),
- T, false),
- SourceLocation(),
- Owned(E));
- if (!Res.isInvalid()) {
- Res = MaybeCreateExprWithCleanups(Res);
- Expr *Init = Res.takeAs<Expr>();
- Context.setBlockVarCopyInits(NewVD, Init);
- }
- }
- }
}
// attributes declared post-definition are currently ignored
@@ -4712,24 +4692,7 @@
// Attach the initializer to the decl.
VDecl->setInit(Init);
- if (getLangOptions().CPlusPlus) {
- if (!VDecl->isInvalidDecl() &&
- !VDecl->getDeclContext()->isDependentContext() &&
- VDecl->hasGlobalStorage() && !VDecl->isStaticLocal() &&
- !Init->isConstantInitializer(Context,
- VDecl->getType()->isReferenceType()))
- Diag(VDecl->getLocation(), diag::warn_global_constructor)
- << Init->getSourceRange();
-
- // Make sure we mark the destructor as used if necessary.
- QualType InitType = VDecl->getType();
- while (const ArrayType *Array = Context.getAsArrayType(InitType))
- InitType = Context.getBaseElementType(Array);
- if (const RecordType *Record = InitType->getAs<RecordType>())
- FinalizeVarWithDestructor(VDecl, Record);
- }
-
- return;
+ CheckCompleteVariableDeclaration(VDecl);
}
/// ActOnInitializerError - Given that there was an error parsing an
@@ -4923,20 +4886,60 @@
MultiExprArg(*this, 0, 0));
if (Init.isInvalid())
Var->setInvalidDecl();
- else if (Init.get()) {
+ else if (Init.get())
Var->setInit(MaybeCreateExprWithCleanups(Init.get()));
+ }
+
+ CheckCompleteVariableDeclaration(Var);
+ }
+}
+
+void Sema::CheckCompleteVariableDeclaration(VarDecl *var) {
+ if (var->isInvalidDecl()) return;
+
+ // All the following checks are C++ only.
+ if (!getLangOptions().CPlusPlus) return;
+
+ QualType baseType = Context.getBaseElementType(var->getType());
+ if (baseType->isDependentType()) return;
- if (getLangOptions().CPlusPlus && !Var->isInvalidDecl() &&
- Var->hasGlobalStorage() && !Var->isStaticLocal() &&
- !Var->getDeclContext()->isDependentContext() &&
- !Var->getInit()->isConstantInitializer(Context, false))
- Diag(Var->getLocation(), diag::warn_global_constructor);
+ // __block variables might require us to capture a copy-initializer.
+ if (var->hasAttr<BlocksAttr>()) {
+ // It's currently invalid to ever have a __block variable with an
+ // array type; should we diagnose that here?
+
+ // Regardless, we don't want to ignore array nesting when
+ // constructing this copy.
+ QualType type = var->getType();
+
+ if (type->isStructureOrClassType()) {
+ SourceLocation poi = var->getLocation();
+ Expr *varRef = new (Context) DeclRefExpr(var, type, VK_LValue, poi);
+ ExprResult result =
+ PerformCopyInitialization(
+ InitializedEntity::InitializeBlock(poi, type, false),
+ poi, Owned(varRef));
+ if (!result.isInvalid()) {
+ result = MaybeCreateExprWithCleanups(result);
+ Expr *init = result.takeAs<Expr>();
+ Context.setBlockVarCopyInits(var, init);
}
}
-
- if (!Var->isInvalidDecl() && getLangOptions().CPlusPlus && Record)
- FinalizeVarWithDestructor(Var, Record);
}
+
+ // Check for global constructors.
+ if (!var->getDeclContext()->isDependentContext() &&
+ var->hasGlobalStorage() &&
+ !var->isStaticLocal() &&
+ var->getInit() &&
+ !var->getInit()->isConstantInitializer(Context,
+ baseType->isReferenceType()))
+ Diag(var->getLocation(), diag::warn_global_constructor)
+ << var->getInit()->getSourceRange();
+
+ // Require the destructor.
+ if (const RecordType *recordType = baseType->getAs<RecordType>())
+ FinalizeVarWithDestructor(var, recordType);
}
Sema::DeclGroupPtrTy
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=123818&r1=123817&r2=123818&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Wed Jan 19 05:48:09 2011
@@ -5641,16 +5641,7 @@
VDecl->setInit(Result.takeAs<Expr>());
VDecl->setCXXDirectInitializer(true);
- if (!VDecl->isInvalidDecl() &&
- !VDecl->getDeclContext()->isDependentContext() &&
- VDecl->hasGlobalStorage() && !VDecl->isStaticLocal() &&
- !VDecl->getInit()->isConstantInitializer(Context,
- VDecl->getType()->isReferenceType()))
- Diag(VDecl->getLocation(), diag::warn_global_constructor)
- << VDecl->getInit()->getSourceRange();
-
- if (const RecordType *Record = VDecl->getType()->getAs<RecordType>())
- FinalizeVarWithDestructor(VDecl, Record);
+ CheckCompleteVariableDeclaration(VDecl);
}
/// \brief Given a constructor and the set of arguments provided for the
Modified: cfe/trunk/test/SemaObjCXX/blocks.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjCXX/blocks.mm?rev=123818&r1=123817&r2=123818&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjCXX/blocks.mm (original)
+++ cfe/trunk/test/SemaObjCXX/blocks.mm Wed Jan 19 05:48:09 2011
@@ -74,3 +74,23 @@
});
}
}
+
+// Make sure we successfully instantiate the copy constructor of a
+// __block variable's type.
+namespace N2 {
+ template <int n> struct A {
+ A() {}
+ A(const A &other) {
+ int invalid[-n]; // expected-error 2 {{array with a negative size}}
+ }
+ };
+
+ void test1() {
+ __block A<1> x; // expected-note {{requested here}}
+ }
+
+ template <int n> void test2() {
+ __block A<n> x; // expected-note {{requested here}}
+ }
+ template void test2<2>();
+}
More information about the cfe-commits
mailing list