summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaExprCXX.cpp
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2018-03-08 00:14:34 +0000
committerReid Kleckner <rnk@google.com>2018-03-08 00:14:34 +0000
commitc2fd3529630d24e3b561f8d6dd5fca282616ad34 (patch)
treea6205b2ebc5e05721ab89ca9ab401ccc90655fa6 /clang/lib/Sema/SemaExprCXX.cpp
parentc4a13015fd6b83b802cd830f8adc9693d6392c48 (diff)
downloadbcm5719-llvm-c2fd3529630d24e3b561f8d6dd5fca282616ad34.tar.gz
bcm5719-llvm-c2fd3529630d24e3b561f8d6dd5fca282616ad34.zip
[Sema] Make getCurFunction() return null outside function parsing
Summary: Before this patch, Sema pre-allocated a FunctionScopeInfo and kept it in the first, always present element of the FunctionScopes stack. This meant that Sema::getCurFunction would return a pointer to this pre-allocated object when parsing code outside a function body. This is pretty much always a bug, so this patch moves the pre-allocated object into a separate unique_ptr. This should make bugs like PR36536 a lot more obvious. As you can see from this patch, there were a number of places that unconditionally assumed they were always called inside a function. However, there are also many places that null checked the result of getCurFunction(), so I think this is a reasonable direction. Reviewers: rsmith Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D44039 llvm-svn: 326965
Diffstat (limited to 'clang/lib/Sema/SemaExprCXX.cpp')
-rw-r--r--clang/lib/Sema/SemaExprCXX.cpp18
1 files changed, 8 insertions, 10 deletions
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index d3ab003a339..4baf52f5b78 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -1114,8 +1114,9 @@ bool Sema::CheckCXXThisCapture(SourceLocation Loc, const bool Explicit,
assert((!ByCopy || Explicit) && "cannot implicitly capture *this by value");
- const unsigned MaxFunctionScopesIndex = FunctionScopeIndexToStopAt ?
- *FunctionScopeIndexToStopAt : FunctionScopes.size() - 1;
+ const int MaxFunctionScopesIndex = FunctionScopeIndexToStopAt
+ ? *FunctionScopeIndexToStopAt
+ : FunctionScopes.size() - 1;
// Check that we can capture the *enclosing object* (referred to by '*this')
// by the capturing-entity/closure (lambda/block/etc) at
@@ -1141,7 +1142,7 @@ bool Sema::CheckCXXThisCapture(SourceLocation Loc, const bool Explicit,
unsigned NumCapturingClosures = 0;
- for (unsigned idx = MaxFunctionScopesIndex; idx != 0; idx--) {
+ for (int idx = MaxFunctionScopesIndex; idx >= 0; idx--) {
if (CapturingScopeInfo *CSI =
dyn_cast<CapturingScopeInfo>(FunctionScopes[idx])) {
if (CSI->CXXThisCaptureIndex != 0) {
@@ -1196,8 +1197,8 @@ bool Sema::CheckCXXThisCapture(SourceLocation Loc, const bool Explicit,
// FIXME: We need to delay this marking in PotentiallyPotentiallyEvaluated
// contexts.
QualType ThisTy = getCurrentThisType();
- for (unsigned idx = MaxFunctionScopesIndex; NumCapturingClosures;
- --idx, --NumCapturingClosures) {
+ for (int idx = MaxFunctionScopesIndex; NumCapturingClosures;
+ --idx, --NumCapturingClosures) {
CapturingScopeInfo *CSI = cast<CapturingScopeInfo>(FunctionScopes[idx]);
Expr *ThisExpr = nullptr;
@@ -7176,9 +7177,6 @@ static void CheckIfAnyEnclosingLambdasMustCaptureAnyPotentialCaptures(
const bool IsFullExprInstantiationDependent = FE->isInstantiationDependent();
- ArrayRef<const FunctionScopeInfo *> FunctionScopesArrayRef(
- S.FunctionScopes.data(), S.FunctionScopes.size());
-
// All the potentially captureable variables in the current nested
// lambda (within a generic outer lambda), must be captured by an
// outer lambda that is enclosed within a non-dependent context.
@@ -7207,7 +7205,7 @@ static void CheckIfAnyEnclosingLambdasMustCaptureAnyPotentialCaptures(
// capture the variable in that lambda (and all its enclosing lambdas).
if (const Optional<unsigned> Index =
getStackIndexOfNearestEnclosingCaptureCapableLambda(
- FunctionScopesArrayRef, Var, S)) {
+ S.FunctionScopes, Var, S)) {
const unsigned FunctionScopeIndexOfCapturableLambda = Index.getValue();
MarkVarDeclODRUsed(Var, VarExpr->getExprLoc(), S,
&FunctionScopeIndexOfCapturableLambda);
@@ -7243,7 +7241,7 @@ static void CheckIfAnyEnclosingLambdasMustCaptureAnyPotentialCaptures(
// 'this' in that lambda (and all its enclosing lambdas).
if (const Optional<unsigned> Index =
getStackIndexOfNearestEnclosingCaptureCapableLambda(
- FunctionScopesArrayRef, /*0 is 'this'*/ nullptr, S)) {
+ S.FunctionScopes, /*0 is 'this'*/ nullptr, S)) {
const unsigned FunctionScopeIndexOfCapturableLambda = Index.getValue();
S.CheckCXXThisCapture(CurrentLSI->PotentialThisCaptureLocation,
/*Explicit*/ false, /*BuildAndDiagnose*/ true,
OpenPOWER on IntegriCloud