[cfe-dev] lower bound error searching for module preprocessing entities within a source range
Nico Weber
thakis at chromium.org
Sun Sep 22 15:53:09 PDT 2013
Is it possible to write a test for this?
On Thu, Sep 19, 2013 at 7:33 AM, Tom Honermann <thonermann at coverity.com>wrote:
> Could someone please review/comment/commit this patch?
>
> Tom.
>
>
> On 08/28/2013 06:19 PM, Tom Honermann wrote:
>
>> Attached is a patch to correct a lower bound search error that occurs
>> when searching for module preprocessing entities within a source range.
>>
>> The test case I've been using for this is:
>>
>> $ cat t.c
>> #if __GNUC__
>> #endif
>> void f(void) {
>> }
>>
>> The problem I was having was that a query for macro expansions occurring
>> within the definition of f() (source range 3:1-4:1) was returning the
>> expansion of __GNUC__ occurring at line 1:5. Clearly, no expansions
>> should be found for that source range.
>>
>> The problem was due to lines 4315-4316 below. The loop progressively
>> reduces a half open range indicated by [First,First+Count) with PPI
>> pointing to an element in the middle of that range. Note that PPI is
>> always dereferenceable - it is not a past-the-end iterator (indeed, it
>> is unconditionally dereferenced at line 4313).
>>
>> If all of the source locations for the preprocessed entities precede the
>> specified source location, then the loop will exit with PPI pointing to
>> the last element in the range [pp_begin,pp_end). However, the intention
>> is that, if all entities precede the specified source location, then PPI
>> is expected to point to pp_end (a past-the-end iterator) when the loop
>> exits (see line 4322). When the loop exits with PPI not set to pp_end,
>> then it is interpreted as pointing to the first preprocessed entity with
>> a source location following the specified location. This is why my
>> query is incorrectly including the preceding macro expansion.
>>
>> The attached patch against trunk (revision 189518) modifies lines
>> 4315-4316 to first increment PPI, and then to assign First to PPI. This
>> causes PPI to be advanced appropriately to satisfy the comparison at
>> line 4322 when all entities precede the specified source location.
>>
>> I looked for a simple way to provide a test for this behavior, but I
>> wasn't able to find one. It seems there may be some way to test this
>> with c-index-test, but I wasn't able to figure out a way to do so (the
>> problem only occurs when the relevant code is loaded from a PCH file).
>> I'm afraid I'm not very familiar with the existing tests. I did run the
>> Clang test suite (make test) and no regressions were reported.
>>
>> lib/Serialization/ASTReader.**cpp:
>> 4280 /// \brief Returns the first preprocessed entity ID that ends after
>> \arg BLoc.
>> 4281 PreprocessedEntityID
>> 4282 ASTReader::**findBeginPreprocessedEntity(**SourceLocation BLoc)
>> const {
>> 4283 if (SourceMgr.**isLocalSourceLocation(BLoc))
>> 4284 return getTotalNumPreprocessedEntitie**s();
>> 4285
>> 4286 GlobalSLocOffsetMapType::**const_iterator
>> 4287 SLocMapI =
>> GlobalSLocOffsetMap.find(**SourceManager::MaxLoadedOffset -
>> 4288 BLoc.getOffset() - 1);
>> 4289 assert(SLocMapI != GlobalSLocOffsetMap.end() &&
>> 4290 "Corrupted global sloc offset map");
>> 4291
>> 4292 if (SLocMapI->second->**NumPreprocessedEntities == 0)
>> 4293 return findNextPreprocessedEntity(**SLocMapI);
>> 4294
>> 4295 ModuleFile &M = *SLocMapI->second;
>> 4296 typedef const PPEntityOffset *pp_iterator;
>> 4297 pp_iterator pp_begin = M.PreprocessedEntityOffsets;
>> 4298 pp_iterator pp_end = pp_begin + M.NumPreprocessedEntities;
>> 4299
>> 4300 size_t Count = M.NumPreprocessedEntities;
>> 4301 size_t Half;
>> 4302 pp_iterator First = pp_begin;
>> 4303 pp_iterator PPI;
>> 4304
>> 4305 // Do a binary search manually instead of using std::lower_bound
>> because
>> 4306 // The end locations of entities may be unordered (when a macro
>> expansion
>> 4307 // is inside another macro argument), but for this case it is not
>> important
>> 4308 // whether we get the first macro expansion or its containing
>> macro.
>> 4309 while (Count > 0) {
>> 4310 Half = Count/2;
>> 4311 PPI = First;
>> 4312 std::advance(PPI, Half);
>> 4313 if (SourceMgr.**isBeforeInTranslationUnit(**
>> ReadSourceLocation(M,
>> PPI->End),
>> 4314 BLoc)){
>> 4315 First = PPI;
>> 4316 ++First;
>> 4317 Count = Count - Half - 1;
>> 4318 } else
>> 4319 Count = Half;
>> 4320 }
>> 4321
>> 4322 if (PPI == pp_end)
>> 4323 return findNextPreprocessedEntity(**SLocMapI);
>> 4324
>> 4325 return M.BasePreprocessedEntityID + (PPI - pp_begin);
>> 4326 }
>>
>> Tom.
>>
>>
>> ______________________________**_________________
>> cfe-dev mailing list
>> cfe-dev at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/**mailman/listinfo/cfe-dev<http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev>
>>
>>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20130922/f6b416a7/attachment.html>
More information about the cfe-dev
mailing list