diff options
author | John McCall <rjmccall@apple.com> | 2011-02-02 13:00:07 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2011-02-02 13:00:07 +0000 |
commit | 469a1eb996e1cb0be54f9b210f836afbddcbb2cc (patch) | |
tree | d80fe9f7fd892e6713f33d29ee26aa0270db925a /lib/Sema/SemaExprCXX.cpp | |
parent | 5b5828b74c758d7babffb2407464507fa004b157 (diff) |
An insomniac stab at making block declarations list the variables they close
on, as well as more reliably limiting invalid references to locals from
nested scopes.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@124721 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExprCXX.cpp')
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 7bc9af1191..73e9778a74 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -16,6 +16,7 @@ #include "clang/Sema/Initialization.h" #include "clang/Sema/Lookup.h" #include "clang/Sema/ParsedTemplate.h" +#include "clang/Sema/ScopeInfo.h" #include "clang/Sema/TemplateDeduction.h" #include "clang/AST/ASTContext.h" #include "clang/AST/CXXInheritance.h" @@ -563,14 +564,23 @@ ExprResult Sema::ActOnCXXThis(SourceLocation ThisLoc) { /// is a non-lvalue expression whose value is the address of the object for /// which the function is called. - DeclContext *DC = getFunctionLevelDeclContext(); - if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(DC)) - if (MD->isInstance()) - return Owned(new (Context) CXXThisExpr(ThisLoc, - MD->getThisType(Context), - /*isImplicit=*/false)); + // Ignore block scopes (but nothing else). + DeclContext *DC = CurContext; + while (isa<BlockDecl>(DC)) DC = cast<BlockDecl>(DC)->getDeclContext(); - return ExprError(Diag(ThisLoc, diag::err_invalid_this_use)); + // If we're not an instance method, error out. + CXXMethodDecl *method = dyn_cast<CXXMethodDecl>(DC); + if (!method || !method->isInstance()) + return ExprError(Diag(ThisLoc, diag::err_invalid_this_use)); + + // Mark that we're closing on 'this' in all the block scopes, if applicable. + for (unsigned idx = FunctionScopes.size() - 1; + isa<BlockScopeInfo>(FunctionScopes[idx]); + --idx) + cast<BlockScopeInfo>(FunctionScopes[idx])->CapturesCXXThis = true; + + return Owned(new (Context) CXXThisExpr(ThisLoc, method->getThisType(Context), + /*isImplicit=*/false)); } ExprResult |