<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body dir="auto">
<div>Hi Ahmed, thanks for the info. Will fix it ASAP. <br>
<br>
Best regards,
<div>Alexey Bataev</div>
</div>
<div><br>
26 апр. 2017 г., в 22:00, Ahmed Bougacha <<a href="mailto:ahmed.bougacha@gmail.com">ahmed.bougacha@gmail.com</a>> написал(а):<br>
<br>
</div>
<blockquote type="cite">
<div>
<div dir="ltr">Hey Alexey,<br>
<br>
This is causing asan errors, e.g.:<br>
<br>
==4735==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x61f000000e70 at pc 0x00010a8a7f4a bp 0x7fff5c57a390 sp 0x7fff5c57a388<br>
READ of size 4 at 0x61f000000e70 thread T0<br>
#0 0x10a8a7f49 in (anonymous namespace)::DSAStackTy::hasDSA(clang::ValueDecl*, llvm::function_ref<bool (clang::OpenMPClauseKind)> const&, llvm::function_ref<bool (clang::OpenMPDirectiveKind)> const&, bool) SemaOpenMP.cpp:836<br>
#1 0x10a8a4560 in clang::Sema::IsOpenMPCapturedDecl(clang::ValueDecl*) SemaOpenMP.cpp:1107
<div> #2 0x10a575739 in clang::Sema::tryCaptureVariable(clang::VarDecl*, clang::SourceLocation, clang::Sema::TryCaptureKind, clang::SourceLocation, bool, clang::QualType&, clang::QualType&, unsigned int const*) SemaExpr.cpp:14005<br>
...<br>
<br>
0x61f000000e70 is located 16 bytes to the left of 3440-byte region [0x61f000000e80,0x61f000001bf0) allocated by thread T0 here:<br>
#0 0x116f036d2 in wrap__Znwm (libclang_rt.asan_osx_dynamic.dylib:x86_64+0x656d2)<br>
#1 0x10a8a1642 in clang::Sema::InitDataSharingAttributesStack() SemaOpenMP.cpp:914<br>
#2 0x109fc8585 in clang::Sema::Sema(clang::Preprocessor&, clang::ASTContext&, clang::ASTConsumer&, clang::TranslationUnitKind, clang::CodeCompleteConsumer*) Sema.cpp:125<br>
...<br>
<br>
SUMMARY: AddressSanitizer: heap-buffer-overflow SemaOpenMP.cpp:836 in (anonymous namespace)::DSAStackTy::hasDSA(clang::ValueDecl*, llvm::function_ref<bool (clang::OpenMPClauseKind)> const&, llvm::function_ref<bool (clang::OpenMPDirectiveKind)> const&, bool)<br>
<br>
<br>
<a href="http://green.lab.llvm.org/green/job/clang-stage2-cmake-RgSan_check/3344/testReport/junit/Clang/OpenMP/atomic_codegen_cpp/">http://green.lab.llvm.org/green/job/clang-stage2-cmake-RgSan_check/3344/testReport/junit/Clang/OpenMP/atomic_codegen_cpp/</a><br>
<br>
Can you have a look?<br>
Thanks!<br>
-Ahmed<br>
<br>
<br>
On Wed, Apr 26, 2017 at 7:24 AM, Alexey Bataev via cfe-commits<br>
<<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a>> wrote:<br>
> Author: abataev<br>
> Date: Wed Apr 26 09:24:21 2017<br>
> New Revision: 301410<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=301410&view=rev">http://llvm.org/viewvc/llvm-project?rev=301410&view=rev</a><br>
> Log:<br>
> [OPENMP] Move handling of threadprivate vars from the stack, NFC.<br>
><br>
> Threadprivate variables do no need to be handled in the Stack of all<br>
> directives, moving it out for better performance and memory.<br>
><br>
> Modified:<br>
> cfe/trunk/lib/Sema/SemaOpenMP.cpp<br>
><br>
> Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=301410&r1=301409&r2=301410&view=diff">
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=301410&r1=301409&r2=301410&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)<br>
> +++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Wed Apr 26 09:24:21 2017<br>
> @@ -118,6 +118,7 @@ private:<br>
> typedef SmallVector<SharingMapTy, 4> StackTy;<br>
><br>
> /// \brief Stack of used declaration and their data-sharing attributes.<br>
> + DeclSAMapTy Threadprivates;<br>
> StackTy Stack;<br>
> /// \brief true, if check for DSA must be from parent directive, false, if<br>
> /// from current directive.<br>
> @@ -134,7 +135,7 @@ private:<br>
> bool isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter);<br>
><br>
> public:<br>
> - explicit DSAStackTy(Sema &S) : Stack(1), SemaRef(S) {}<br>
> + explicit DSAStackTy(Sema &S) : SemaRef(S) {}<br>
><br>
> bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; }<br>
> void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; }<br>
> @@ -149,7 +150,7 @@ public:<br>
> }<br>
><br>
> void pop() {<br>
> - assert(Stack.size() > 1 && "Data-sharing attributes stack is empty!");<br>
> + assert(!Stack.empty() && "Data-sharing attributes stack is empty!");<br>
> Stack.pop_back();<br>
> }<br>
><br>
> @@ -229,11 +230,11 @@ public:<br>
><br>
> /// \brief Returns currently analyzed directive.<br>
> OpenMPDirectiveKind getCurrentDirective() const {<br>
> - return Stack.back().Directive;<br>
> + return Stack.empty() ? OMPD_unknown : Stack.back().Directive;<br>
> }<br>
> /// \brief Returns parent directive.<br>
> OpenMPDirectiveKind getParentDirective() const {<br>
> - if (Stack.size() > 2)<br>
> + if (Stack.size() > 1)<br>
> return Stack[Stack.size() - 2].Directive;<br>
> return OMPD_unknown;<br>
> }<br>
> @@ -250,10 +251,10 @@ public:<br>
> }<br>
><br>
> DefaultDataSharingAttributes getDefaultDSA() const {<br>
> - return Stack.back().DefaultAttr;<br>
> + return Stack.empty() ? DSA_unspecified : Stack.back().DefaultAttr;<br>
> }<br>
> SourceLocation getDefaultDSALocation() const {<br>
> - return Stack.back().DefaultAttrLoc;<br>
> + return Stack.empty() ? SourceLocation() : Stack.back().DefaultAttrLoc;<br>
> }<br>
><br>
> /// \brief Checks if the specified variable is a threadprivate.<br>
> @@ -270,13 +271,13 @@ public:<br>
> /// \brief Returns true, if parent region is ordered (has associated<br>
> /// 'ordered' clause), false - otherwise.<br>
> bool isParentOrderedRegion() const {<br>
> - if (Stack.size() > 2)<br>
> + if (Stack.size() > 1)<br>
> return Stack[Stack.size() - 2].OrderedRegion.getInt();<br>
> return false;<br>
> }<br>
> /// \brief Returns optional parameter for the ordered region.<br>
> Expr *getParentOrderedRegionParam() const {<br>
> - if (Stack.size() > 2)<br>
> + if (Stack.size() > 1)<br>
> return Stack[Stack.size() - 2].OrderedRegion.getPointer();<br>
> return nullptr;<br>
> }<br>
> @@ -287,28 +288,32 @@ public:<br>
> /// \brief Returns true, if parent region is nowait (has associated<br>
> /// 'nowait' clause), false - otherwise.<br>
> bool isParentNowaitRegion() const {<br>
> - if (Stack.size() > 2)<br>
> + if (Stack.size() > 1)<br>
> return Stack[Stack.size() - 2].NowaitRegion;<br>
> return false;<br>
> }<br>
> /// \brief Marks parent region as cancel region.<br>
> void setParentCancelRegion(bool Cancel = true) {<br>
> - if (Stack.size() > 2)<br>
> + if (Stack.size() > 1)<br>
> Stack[Stack.size() - 2].CancelRegion =<br>
> Stack[Stack.size() - 2].CancelRegion || Cancel;<br>
> }<br>
> /// \brief Return true if current region has inner cancel construct.<br>
> - bool isCancelRegion() const { return Stack.back().CancelRegion; }<br>
> + bool isCancelRegion() const {<br>
> + return Stack.empty() ? false : Stack.back().CancelRegion;<br>
> + }<br>
><br>
> /// \brief Set collapse value for the region.<br>
> void setAssociatedLoops(unsigned Val) { Stack.back().AssociatedLoops = Val; }<br>
> /// \brief Return collapse value for region.<br>
> - unsigned getAssociatedLoops() const { return Stack.back().AssociatedLoops; }<br>
> + unsigned getAssociatedLoops() const {<br>
> + return Stack.empty() ? 0 : Stack.back().AssociatedLoops;<br>
> + }<br>
><br>
> /// \brief Marks current target region as one with closely nested teams<br>
> /// region.<br>
> void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) {<br>
> - if (Stack.size() > 2)<br>
> + if (Stack.size() > 1)<br>
> Stack[Stack.size() - 2].InnerTeamsRegionLoc = TeamsRegionLoc;<br>
> }<br>
> /// \brief Returns true, if current region has closely nested teams region.<br>
> @@ -317,14 +322,18 @@ public:<br>
> }<br>
> /// \brief Returns location of the nested teams region (if any).<br>
> SourceLocation getInnerTeamsRegionLoc() const {<br>
> - if (Stack.size() > 1)<br>
> - return Stack.back().InnerTeamsRegionLoc;<br>
> - return SourceLocation();<br>
> + return Stack.empty() ? SourceLocation() : Stack.back().InnerTeamsRegionLoc;<br>
> }<br>
><br>
> - Scope *getCurScope() const { return Stack.back().CurScope; }<br>
> - Scope *getCurScope() { return Stack.back().CurScope; }<br>
> - SourceLocation getConstructLoc() { return Stack.back().ConstructLoc; }<br>
> + Scope *getCurScope() const {<br>
> + return Stack.empty() ? nullptr : Stack.back().CurScope;<br>
> + }<br>
> + Scope *getCurScope() {<br>
> + return Stack.empty() ? nullptr : Stack.back().CurScope;<br>
> + }<br>
> + SourceLocation getConstructLoc() {<br>
> + return Stack.empty() ? SourceLocation() : Stack.back().ConstructLoc;<br>
> + }<br>
><br>
> /// Do the check specified in \a Check to all component lists and return true<br>
> /// if any issue is found.<br>
> @@ -361,7 +370,7 @@ public:<br>
> ValueDecl *VD,<br>
> OMPClauseMappableExprCommon::MappableExprComponentListRef Components,<br>
> OpenMPClauseKind WhereFoundClauseKind) {<br>
> - assert(Stack.size() > 1 &&<br>
> + assert(!Stack.empty() &&<br>
> "Not expecting to retrieve components from a empty stack!");<br>
> auto &MEC = Stack.back().MappedExprComponents[VD];<br>
> // Create new entry and append the new components there.<br>
> @@ -371,23 +380,23 @@ public:<br>
> }<br>
><br>
> unsigned getNestingLevel() const {<br>
> - assert(Stack.size() > 1);<br>
> - return Stack.size() - 2;<br>
> + assert(!Stack.empty());<br>
> + return Stack.size() - 1;<br>
> }<br>
> void addDoacrossDependClause(OMPDependClause *C, OperatorOffsetTy &OpsOffs) {<br>
> - assert(Stack.size() > 2);<br>
> + assert(Stack.size() > 1);<br>
> assert(isOpenMPWorksharingDirective(Stack[Stack.size() - 2].Directive));<br>
> Stack[Stack.size() - 2].DoacrossDepends.insert({C, OpsOffs});<br>
> }<br>
> llvm::iterator_range<DoacrossDependMapTy::const_iterator><br>
> getDoacrossDependClauses() const {<br>
> - assert(Stack.size() > 1);<br>
> - if (isOpenMPWorksharingDirective(Stack[Stack.size() - 1].Directive)) {<br>
> - auto &Ref = Stack[Stack.size() - 1].DoacrossDepends;<br>
> + assert(!Stack.empty());<br>
> + if (isOpenMPWorksharingDirective(Stack.back().Directive)) {<br>
> + auto &Ref = Stack.back().DoacrossDepends;<br>
> return llvm::make_range(Ref.begin(), Ref.end());<br>
> }<br>
> - return llvm::make_range(Stack[0].DoacrossDepends.end(),<br>
> - Stack[0].DoacrossDepends.end());<br>
> + return llvm::make_range(Stack.back().DoacrossDepends.end(),<br>
> + Stack.back().DoacrossDepends.end());<br>
> }<br>
> };<br>
> bool isParallelOrTaskRegion(OpenMPDirectiveKind DKind) {<br>
> @@ -416,7 +425,7 @@ DSAStackTy::DSAVarData DSAStackTy::getDS<br>
> auto *VD = dyn_cast<VarDecl>(D);<br>
> auto *FD = dyn_cast<FieldDecl>(D);<br>
> DSAVarData DVar;<br>
> - if (Iter == std::prev(Stack.rend())) {<br>
> + if (Iter == Stack.rend()) {<br>
> // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced<br>
> // in a region but not in construct]<br>
> // File-scope or namespace-scope variables referenced in called routines<br>
> @@ -490,8 +499,9 @@ DSAStackTy::DSAVarData DSAStackTy::getDS<br>
> // bound to the current team is shared.<br>
> if (isOpenMPTaskingDirective(DVar.DKind)) {<br>
> DSAVarData DVarTemp;<br>
> - for (StackTy::reverse_iterator I = std::next(Iter), EE = Stack.rend();<br>
> - I != EE; ++I) {<br>
> + auto I = Iter, E = Stack.rend();<br>
> + do {<br>
> + ++I;<br>
> // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables<br>
> // Referenced in a Construct, implicitly determined, p.6]<br>
> // In a task construct, if no default clause is present, a variable<br>
> @@ -503,9 +513,7 @@ DSAStackTy::DSAVarData DSAStackTy::getDS<br>
> DVar.CKind = OMPC_firstprivate;<br>
> return DVar;<br>
> }<br>
> - if (isParallelOrTaskRegion(I->Directive))<br>
> - break;<br>
> - }<br>
> + } while (I != E && !isParallelOrTaskRegion(I->Directive));<br>
> DVar.CKind =<br>
> (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;<br>
> return DVar;<br>
> @@ -520,7 +528,7 @@ DSAStackTy::DSAVarData DSAStackTy::getDS<br>
> }<br>
><br>
> Expr *DSAStackTy::addUniqueAligned(ValueDecl *D, Expr *NewDE) {<br>
> - assert(Stack.size() > 1 && "Data sharing attributes stack is empty");<br>
> + assert(!Stack.empty() && "Data sharing attributes stack is empty");<br>
> D = getCanonicalDecl(D);<br>
> auto It = Stack.back().AlignedMap.find(D);<br>
> if (It == Stack.back().AlignedMap.end()) {<br>
> @@ -535,21 +543,21 @@ Expr *DSAStackTy::addUniqueAligned(Value<br>
> }<br>
><br>
> void DSAStackTy::addLoopControlVariable(ValueDecl *D, VarDecl *Capture) {<br>
> - assert(Stack.size() > 1 && "Data-sharing attributes stack is empty");<br>
> + assert(!Stack.empty() && "Data-sharing attributes stack is empty");<br>
> D = getCanonicalDecl(D);<br>
> Stack.back().LCVMap.insert(<br>
> - std::make_pair(D, LCDeclInfo(Stack.back().LCVMap.size() + 1, Capture)));<br>
> + {D, LCDeclInfo(Stack.back().LCVMap.size() + 1, Capture)});<br>
> }<br>
><br>
> DSAStackTy::LCDeclInfo DSAStackTy::isLoopControlVariable(ValueDecl *D) {<br>
> - assert(Stack.size() > 1 && "Data-sharing attributes stack is empty");<br>
> + assert(!Stack.empty() && "Data-sharing attributes stack is empty");<br>
> D = getCanonicalDecl(D);<br>
> return Stack.back().LCVMap.count(D) > 0 ? Stack.back().LCVMap[D]<br>
> : LCDeclInfo(0, nullptr);<br>
> }<br>
><br>
> DSAStackTy::LCDeclInfo DSAStackTy::isParentLoopControlVariable(ValueDecl *D) {<br>
> - assert(Stack.size() > 2 && "Data-sharing attributes stack is empty");<br>
> + assert(Stack.size() > 1 && "Data-sharing attributes stack is empty");<br>
> D = getCanonicalDecl(D);<br>
> return Stack[Stack.size() - 2].LCVMap.count(D) > 0<br>
> ? Stack[Stack.size() - 2].LCVMap[D]<br>
> @@ -557,7 +565,7 @@ DSAStackTy::LCDeclInfo DSAStackTy::isPar<br>
> }<br>
><br>
> ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) {<br>
> - assert(Stack.size() > 2 && "Data-sharing attributes stack is empty");<br>
> + assert(Stack.size() > 1 && "Data-sharing attributes stack is empty");<br>
> if (Stack[Stack.size() - 2].LCVMap.size() < I)<br>
> return nullptr;<br>
> for (auto &Pair : Stack[Stack.size() - 2].LCVMap) {<br>
> @@ -571,12 +579,12 @@ void DSAStackTy::addDSA(ValueDecl *D, Ex<br>
> DeclRefExpr *PrivateCopy) {<br>
> D = getCanonicalDecl(D);<br>
> if (A == OMPC_threadprivate) {<br>
> - auto &Data = Stack[0].SharingMap[D];<br>
> + auto &Data = Threadprivates[D];<br>
> Data.Attributes = A;<br>
> Data.RefExpr.setPointer(E);<br>
> Data.PrivateCopy = nullptr;<br>
> } else {<br>
> - assert(Stack.size() > 1 && "Data-sharing attributes stack is empty");<br>
> + assert(!Stack.empty() && "Data-sharing attributes stack is empty");<br>
> auto &Data = Stack.back().SharingMap[D];<br>
> assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||<br>
> (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||<br>
> @@ -602,19 +610,17 @@ void DSAStackTy::addDSA(ValueDecl *D, Ex<br>
><br>
> bool DSAStackTy::isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter) {<br>
> D = D->getCanonicalDecl();<br>
> - if (Stack.size() > 2) {<br>
> - reverse_iterator I = Iter, E = std::prev(Stack.rend());<br>
> + if (Stack.size() > 1) {<br>
> + reverse_iterator I = Iter, E = Stack.rend();<br>
> Scope *TopScope = nullptr;<br>
> - while (I != E && !isParallelOrTaskRegion(I->Directive)) {<br>
> + while (I != E && !isParallelOrTaskRegion(I->Directive))<br>
> ++I;<br>
> - }<br>
> if (I == E)<br>
> return false;<br>
> TopScope = I->CurScope ? I->CurScope->getParent() : nullptr;<br>
> Scope *CurScope = getCurScope();<br>
> - while (CurScope != TopScope && !CurScope->isDeclScope(D)) {<br>
> + while (CurScope != TopScope && !CurScope->isDeclScope(D))<br>
> CurScope = CurScope->getParent();<br>
> - }<br>
> return CurScope != TopScope;<br>
> }<br>
> return false;<br>
> @@ -665,16 +671,16 @@ DSAStackTy::DSAVarData DSAStackTy::getTo<br>
> D->getLocation()),<br>
> OMPC_threadprivate);<br>
> }<br>
> - if (Stack[0].SharingMap.count(D)) {<br>
> - DVar.RefExpr = Stack[0].SharingMap[D].RefExpr.getPointer();<br>
> + auto TI = Threadprivates.find(D);<br>
> + if (TI != Threadprivates.end()) {<br>
> + DVar.RefExpr = TI->getSecond().RefExpr.getPointer();<br>
> DVar.CKind = OMPC_threadprivate;<br>
> return DVar;<br>
> }<br>
><br>
> - if (Stack.size() == 1) {<br>
> + if (Stack.empty())<br>
> // Not in OpenMP execution region and top scope was already checked.<br>
> return DVar;<br>
> - }<br>
><br>
> // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced<br>
> // in a Construct, C/C++, predetermined, p.4]<br>
> @@ -723,10 +729,9 @@ DSAStackTy::DSAVarData DSAStackTy::getTo<br>
> // Explicitly specified attributes and local variables with predetermined<br>
> // attributes.<br>
> auto StartI = std::next(Stack.rbegin());<br>
> - auto EndI = std::prev(Stack.rend());<br>
> - if (FromParent && StartI != EndI) {<br>
> + auto EndI = Stack.rend();<br>
> + if (FromParent && StartI != EndI)<br>
> StartI = std::next(StartI);<br>
> - }<br>
> auto I = std::prev(StartI);<br>
> if (I->SharingMap.count(D)) {<br>
> DVar.RefExpr = I->SharingMap[D].RefExpr.getPointer();<br>
> @@ -742,10 +747,9 @@ DSAStackTy::DSAVarData DSAStackTy::getIm<br>
> bool FromParent) {<br>
> D = getCanonicalDecl(D);<br>
> auto StartI = Stack.rbegin();<br>
> - auto EndI = std::prev(Stack.rend());<br>
> - if (FromParent && StartI != EndI) {<br>
> + auto EndI = Stack.rend();<br>
> + if (FromParent && StartI != EndI)<br>
> StartI = std::next(StartI);<br>
> - }<br>
> return getDSA(StartI, D);<br>
> }<br>
><br>
> @@ -757,17 +761,20 @@ DSAStackTy::hasDSA(ValueDecl *D,<br>
> D = getCanonicalDecl(D);<br>
> auto StartI = std::next(Stack.rbegin());<br>
> auto EndI = Stack.rend();<br>
> - if (FromParent && StartI != EndI) {<br>
> + if (FromParent && StartI != EndI)<br>
> StartI = std::next(StartI);<br>
> - }<br>
> - for (auto I = StartI, EE = EndI; I != EE; ++I) {<br>
> + if (StartI == EndI)<br>
> + return {};<br>
> + auto I = std::prev(StartI);<br>
> + do {<br>
> + ++I;<br>
> if (!DPred(I->Directive) && !isParallelOrTaskRegion(I->Directive))<br>
> continue;<br>
> DSAVarData DVar = getDSA(I, D);<br>
> if (CPred(DVar.CKind))<br>
> return DVar;<br>
> - }<br>
> - return DSAVarData();<br>
> + } while (I != EndI);<br>
> + return {};<br>
> }<br>
><br>
> DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(<br>
> @@ -791,7 +798,7 @@ bool DSAStackTy::hasExplicitDSA(<br>
> if (CPred(ClauseKindMode))<br>
> return true;<br>
> D = getCanonicalDecl(D);<br>
> - auto StartI = std::next(Stack.begin());<br>
> + auto StartI = Stack.begin();<br>
> auto EndI = Stack.end();<br>
> if (std::distance(StartI, EndI) <= (int)Level)<br>
> return false;<br>
> @@ -805,7 +812,7 @@ bool DSAStackTy::hasExplicitDSA(<br>
> bool DSAStackTy::hasExplicitDirective(<br>
> const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred,<br>
> unsigned Level) {<br>
> - auto StartI = std::next(Stack.begin());<br>
> + auto StartI = Stack.begin();<br>
> auto EndI = Stack.end();<br>
> if (std::distance(StartI, EndI) <= (int)Level)<br>
> return false;<br>
> @@ -819,13 +826,12 @@ bool DSAStackTy::hasDirective(<br>
> &DPred,<br>
> bool FromParent) {<br>
> // We look only in the enclosing region.<br>
> - if (Stack.size() < 2)<br>
> + if (Stack.size() < 1)<br>
> return false;<br>
> auto StartI = std::next(Stack.rbegin());<br>
> - auto EndI = std::prev(Stack.rend());<br>
> - if (FromParent && StartI != EndI) {<br>
> + auto EndI = Stack.rend();<br>
> + if (FromParent && StartI != EndI)<br>
> StartI = std::next(StartI);<br>
> - }<br>
> for (auto I = StartI, EE = EndI; I != EE; ++I) {<br>
> if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))<br>
> return true;<br>
><br>
><br>
> _______________________________________________<br>
> cfe-commits mailing list<br>
> <a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br>
</div>
</div>
</div>
</blockquote>
</body>
</html>