From c2fd3529630d24e3b561f8d6dd5fca282616ad34 Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Thu, 8 Mar 2018 00:14:34 +0000 Subject: [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 --- clang/lib/Sema/SemaDecl.cpp | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'clang/lib/Sema/SemaDecl.cpp') diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 036082c9412..6d7dc677f1c 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -5747,7 +5747,7 @@ Sema::CheckTypedefForVariablyModifiedType(Scope *S, TypedefNameDecl *NewTD) { TypeSourceInfo *TInfo = NewTD->getTypeSourceInfo(); QualType T = TInfo->getType(); if (T->isVariablyModifiedType()) { - getCurFunction()->setHasBranchProtectedScope(); + setFunctionHasBranchProtectedScope(); if (S->getFnParent() == nullptr) { bool SizeIsNegative; @@ -7407,7 +7407,7 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) { bool isVM = T->isVariablyModifiedType(); if (isVM || NewVD->hasAttr() || NewVD->hasAttr()) - getCurFunction()->setHasBranchProtectedScope(); + setFunctionHasBranchProtectedScope(); if ((isVM && NewVD->hasLinkage()) || (T->isVariableArrayType() && NewVD->hasGlobalStorage())) { @@ -10644,7 +10644,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) { } if (VDecl->hasLocalStorage()) - getCurFunction()->setHasBranchProtectedScope(); + setFunctionHasBranchProtectedScope(); if (DiagnoseUnexpandedParameterPack(Init, UPPC_Initializer)) { VDecl->setInvalidDecl(); @@ -11178,11 +11178,11 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl) { if (const RecordType *Record = Context.getBaseElementType(Type)->getAs()) { CXXRecordDecl *CXXRecord = cast(Record->getDecl()); - // Mark the function for further checking even if the looser rules of - // C++11 do not require such checks, so that we can diagnose - // incompatibilities with C++98. + // Mark the function (if we're in one) for further checking even if the + // looser rules of C++11 do not require such checks, so that we can + // diagnose incompatibilities with C++98. if (!CXXRecord->isPOD()) - getCurFunction()->setHasBranchProtectedScope(); + setFunctionHasBranchProtectedScope(); } } @@ -11318,13 +11318,14 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) { case Qualifiers::OCL_Weak: case Qualifiers::OCL_Strong: - getCurFunction()->setHasBranchProtectedScope(); + setFunctionHasBranchProtectedScope(); break; } } - if (var->getType().isDestructedType() == QualType::DK_nontrivial_c_struct) - getCurFunction()->setHasBranchProtectedScope(); + if (var->hasLocalStorage() && + var->getType().isDestructedType() == QualType::DK_nontrivial_c_struct) + setFunctionHasBranchProtectedScope(); // Warn about externally-visible variables being defined without a // prior declaration. We only want to do this for global -- cgit v1.2.3