Review Request 126154: Clang: fix crash when editing variadic template "recursive" class

Maciej Cencora m.cencora at gmail.com
Thu Dec 3 10:49:56 UTC 2015



> On Lis 24, 2015, 2:23 po poĊ‚udniu, Milian Wolff wrote:
> > Can you create a unit test for this issue please?
> > 
> > Also, couldn't this happen with more indirection in-between as well? I.e. is it safe enough to check the direct parent? Don't we need to check against a stack of parents to prevent recursion in all cases?
> 
> Maciej Cencora wrote:
>     I could if you point me on how to do it, because at first I tried to create new test in test_codecompletion.cpp but following code does not trigger the bug
>     template <typename Head, typename ...Tail>
>     "struct my_class : Head, my_class<Tail...>
>     {
>         using base ="
>     
>     One need to insert a type, and then change it to reproduce the crash and I don't know how to do it in UTs.
>     
>     As for the in-direction, I guess it is possible - I will give it a try. I am not sure how to detect it though, I couldn't find an API in clang for directly accessing the base classes - only through visitation.
> 
> Milian Wolff wrote:
>     Can you first try a simple test:
>     
>     - copy the code in the smaller `executeCompletionTest` into a new test function
>     - add a `file.setFileContents(...)` with the new contents after the `parseAndWait`
>     - add another `parseAndWait`
>     - call the bigger `executeCompletionTest` with the correct parameters
>     
>     Does that work? If not, it's going to be a bit involved to write the test, but certainly possible and still really important to have:
>     
>     Look at `executeMemberAccessReplacerTest()`, it shows you how to get your hands on a document and view and how to run code completion.
>     That could then be used to do all your steps, including marking a word, removing it, and then requesting code completion, potentially
>     with delays in-between.
> 
> Milian Wolff wrote:
>     Oh and btw: I can reproduce this issue :) So if you have problems with the unit test, tell me.

In the end I managed to easily reproduce the bug in testClangCodeCompletion with completed class like this (code completion invoked after the '='):

template <typename Head, typename ...Tail>
struct my_class : Head, my_class<Tail...>
{
    using base = Head;
};

instead of incomplete:

template <typename Head, typename ...Tail>
struct my_class : Head, my_class<Tail...>
{
    using base =
 
What should be the expected list of completions? I'd say 'Head' maybe additionally 'my_class<Tail...>' if any at all.
Unfortunately the code completion seems to be broken now and reports "Head", "KDevelopClangGccCompat", "Tail", "__m128", "__m128d", "__m128i", "__m256", "__m256d", "__m256i", "__m512", "__m512d", "__m512i", "__m64", "__mmask16", "__mmask32", "__mmask64", "__mmask8", "my_class".

Also some other completion tests fail because the completion list contains around 1000!! entries like following "__builtin_ia32_addpd256_mask", "__builtin_ia32_addpd512_mask", "__builtin_ia32_addps128_mask".


- Maciej


-----------------------------------------------------------
This is an automatically generated e-mail. To reply, visit:
https://git.reviewboard.kde.org/r/126154/#review88760
-----------------------------------------------------------


On Lis 25, 2015, 10:16 rano, Maciej Cencora wrote:
> 
> -----------------------------------------------------------
> This is an automatically generated e-mail. To reply, visit:
> https://git.reviewboard.kde.org/r/126154/
> -----------------------------------------------------------
> 
> (Updated Lis 25, 2015, 10:16 rano)
> 
> 
> Review request for KDevelop.
> 
> 
> Repository: kdevelop
> 
> 
> Description
> -------
> 
> The crash cannot be reproduced on completion, only when editing such class.
> To reproduce:
> 1) create and save file with following content
> template <typename Head, typename ...Tail>
> struct my_class : Head, my_class<Tail...>
> {
>     using base = Head;
> };
> 2) in line with 'using' statement, mark the 'Head' text
> 3) delete text
> 4) write something (e.g. press letter 'a')
> 
> Not sure whether this is proper fix, but backtrace shows infinite recursion.
> #0  clang::operator<< (OS=..., N=...) at /build/llvm-toolchain-3.6-18MJNr/llvm-toolchain-3.6-3.6.2/tools/clang/lib/AST/DeclarationName.cpp:136
> #1  0x00007fff7d266e9d in clang::NamedDecl::printName (this=<optimized out>, os=...) at /build/llvm-toolchain-3.6-18MJNr/llvm-toolchain-3.6-3.6.2/tools/clang/tools/libclang/../../include/clang/AST/Decl.h:150
> #2  getDeclSpelling (D=0x7fff9403bd00) at /build/llvm-toolchain-3.6-18MJNr/llvm-toolchain-3.6-3.6.2/tools/clang/tools/libclang/CIndex.cpp:3491
> #3  0x00007fff7d267686 in clang_getCursorSpelling (C=...) at /build/llvm-toolchain-3.6-18MJNr/llvm-toolchain-3.6-3.6.2/tools/clang/tools/libclang/CIndex.cpp:3625
> #4  0x00007fff7deb2e51 in (anonymous namespace)::baseClassVisitor (cursor=..., parent=..., data=0x7fff7c8f5090) at /home/mcencora/tmp/kdevelop/languages/clang/codecompletion/completionhelper.cpp:158
> #5  0x00007fff7d259add in clang::cxcursor::CursorVisitor::Visit (this=this at entry=0x7fff7c8f4f10, Cursor=..., CheckedRegionOfInterest=CheckedRegionOfInterest at entry=false)
>     at /build/llvm-toolchain-3.6-18MJNr/llvm-toolchain-3.6-3.6.2/tools/clang/tools/libclang/CIndex.cpp:210
> #6  0x00007fff7d25bc34 in clang::cxcursor::CursorVisitor::VisitTemplateParameters (this=this at entry=0x7fff7c8f4f10, Params=<optimized out>) at /build/llvm-toolchain-3.6-18MJNr/llvm-toolchain-3.6-3.6.2/tools/clang/tools/libclang/CIndex.cpp:1321
> #7  0x00007fff7d259235 in clang::cxcursor::CursorVisitor::VisitClassTemplateDecl (this=0x7fff7c8f4f10, D=0x7fff9403bef0) at /build/llvm-toolchain-3.6-18MJNr/llvm-toolchain-3.6-3.6.2/tools/clang/tools/libclang/CIndex.cpp:903
> #8  0x00007fff7d2595db in clang::cxcursor::CursorVisitor::VisitChildren (this=this at entry=0x7fff7c8f4f10, Cursor=...) at /build/llvm-toolchain-3.6-18MJNr/llvm-toolchain-3.6-3.6.2/tools/clang/tools/libclang/CIndex.cpp:500
> #9  0x00007fff7d260024 in clang_visitChildren (parent=..., visitor=0x7fff7deb2ddf <(anonymous namespace)::baseClassVisitor(CXCursor, CXCursor, CXClientData)>, client_data=0x7fff7c8f5090)
>     at /build/llvm-toolchain-3.6-18MJNr/llvm-toolchain-3.6-3.6.2/tools/clang/tools/libclang/CIndex.cpp:3419
> #10 0x00007fff7deb2dac in (anonymous namespace)::processBaseClass (cursor=..., parent=..., functionList=0x7fff74003590) at /home/mcencora/tmp/kdevelop/languages/clang/codecompletion/completionhelper.cpp:148
> #11 0x00007fff7deb2f42 in (anonymous namespace)::baseClassVisitor (cursor=..., parent=..., data=0x7fff7c8f5580) at /home/mcencora/tmp/kdevelop/languages/clang/codecompletion/completionhelper.cpp:166
> #12 0x00007fff7d259add in clang::cxcursor::CursorVisitor::Visit (this=this at entry=0x7fff7c8f5400, Cursor=..., CheckedRegionOfInterest=CheckedRegionOfInterest at entry=false)
>     at /build/llvm-toolchain-3.6-18MJNr/llvm-toolchain-3.6-3.6.2/tools/clang/tools/libclang/CIndex.cpp:210
> #13 0x00007fff7d25919a in clang::cxcursor::CursorVisitor::VisitCXXRecordDecl (this=0x7fff7c8f5400, D=0x7fff9403be60) at /build/llvm-toolchain-3.6-18MJNr/llvm-toolchain-3.6-3.6.2/tools/clang/tools/libclang/CIndex.cpp:1672
> #14 0x00007fff7d2595db in clang::cxcursor::CursorVisitor::VisitChildren (this=this at entry=0x7fff7c8f5400, Cursor=...) at /build/llvm-toolchain-3.6-18MJNr/llvm-toolchain-3.6-3.6.2/tools/clang/tools/libclang/CIndex.cpp:500
> #15 0x00007fff7d260024 in clang_visitChildren (parent=..., visitor=0x7fff7deb2ddf <(anonymous namespace)::baseClassVisitor(CXCursor, CXCursor, CXClientData)>, client_data=0x7fff7c8f5580)
>     at /build/llvm-toolchain-3.6-18MJNr/llvm-toolchain-3.6-3.6.2/tools/clang/tools/libclang/CIndex.cpp:3419
> #16 0x00007fff7deb2dac in (anonymous namespace)::processBaseClass (cursor=..., parent=..., functionList=0x7fff74003590) at /home/mcencora/tmp/kdevelop/languages/clang/codecompletion/completionhelper.cpp:148
> #17 0x00007fff7deb2f42 in (anonymous namespace)::baseClassVisitor (cursor=..., parent=..., data=0x7fff7c8f5a70) at /home/mcencora/tmp/kdevelop/languages/clang/codecompletion/completionhelper.cpp:166
> #18 0x00007fff7d259add in clang::cxcursor::CursorVisitor::Visit (this=this at entry=0x7fff7c8f58f0, Cursor=..., CheckedRegionOfInterest=CheckedRegionOfInterest at entry=false)
>     at /build/llvm-toolchain-3.6-18MJNr/llvm-toolchain-3.6-3.6.2/tools/clang/tools/libclang/CIndex.cpp:210
> #19 0x00007fff7d25919a in clang::cxcursor::CursorVisitor::VisitCXXRecordDecl (this=0x7fff7c8f58f0, D=0x7fff9403be60) at /build/llvm-toolchain-3.6-18MJNr/llvm-toolchain-3.6-3.6.2/tools/clang/tools/libclang/CIndex.cpp:1672
> #20 0x00007fff7d2595db in clang::cxcursor::CursorVisitor::VisitChildren (this=this at entry=0x7fff7c8f58f0, Cursor=...) at /build/llvm-toolchain-3.6-18MJNr/llvm-toolchain-3.6-3.6.2/tools/clang/tools/libclang/CIndex.cpp:500
> #21 0x00007fff7d260024 in clang_visitChildren (parent=..., visitor=0x7fff7deb2ddf <(anonymous namespace)::baseClassVisitor(CXCursor, CXCursor, CXClientData)>, client_data=0x7fff7c8f5a70)
>     at /build/llvm-toolchain-3.6-18MJNr/llvm-toolchain-3.6-3.6.2/tools/clang/tools/libclang/CIndex.cpp:3419
> #22 0x00007fff7deb2dac in (anonymous namespace)::processBaseClass (cursor=..., parent=..., functionList=0x7fff74003590) at /home/mcencora/tmp/kdevelop/languages/clang/codecompletion/completionhelper.cpp:148
> #23 0x00007fff7deb2f42 in (anonymous namespace)::baseClassVisitor (cursor=..., parent=..., data=0x7fff7c8f5f60) at /home/mcencora/tmp/kdevelop/languages/clang/codecompletion/completionhelper.cpp:166
> #24 0x00007fff7d259add in clang::cxcursor::CursorVisitor::Visit (this=this at entry=0x7fff7c8f5de0, Cursor=..., CheckedRegionOfInterest=CheckedRegionOfInterest at entry=false)
>     at /build/llvm-toolchain-3.6-18MJNr/llvm-toolchain-3.6-3.6.2/tools/clang/tools/libclang/CIndex.cpp:210
> #25 0x00007fff7d25919a in clang::cxcursor::CursorVisitor::VisitCXXRecordDecl (this=0x7fff7c8f5de0, D=0x7fff9403be60) at /build/llvm-toolchain-3.6-18MJNr/llvm-toolchain-3.6-3.6.2/tools/clang/tools/libclang/CIndex.cpp:1672
> #26 0x00007fff7d2595db in clang::cxcursor::CursorVisitor::VisitChildren (this=this at entry=0x7fff7c8f5de0, Cursor=...) at /build/llvm-toolchain-3.6-18MJNr/llvm-toolchain-3.6-3.6.2/tools/clang/tools/libclang/CIndex.cpp:500
> #27 0x00007fff7d260024 in clang_visitChildren (parent=..., visitor=0x7fff7deb2ddf <(anonymous namespace)::baseClassVisitor(CXCursor, CXCursor, CXClientData)>, client_data=0x7fff7c8f5f60)
>     at /build/llvm-toolchain-3.6-18MJNr/llvm-toolchain-3.6-3.6.2/tools/clang/tools/libclang/CIndex.cpp:3419
> 
> ... and this goes on for 39K frames
> 
> 
> Diffs
> -----
> 
>   languages/clang/codecompletion/completionhelper.cpp ac307ef 
> 
> Diff: https://git.reviewboard.kde.org/r/126154/diff/
> 
> 
> Testing
> -------
> 
> Manual.
> 
> 
> Thanks,
> 
> Maciej Cencora
> 
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.kde.org/pipermail/kdevelop-devel/attachments/20151203/f53a5d56/attachment-0001.html>


More information about the KDevelop-devel mailing list