abduld / include-what-you-use

Automatically exported from code.google.com/p/include-what-you-use
Other
0 stars 0 forks source link

Assertion failed: class_decl && "TemplateSpecializationType is not a TplSpecDecl?" #150

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
I'm trying to use iwyu with http://github.com/mapbox/mapbox-gl-native on OS X 
10.9. I compiled iwyu against a clang 3.4.2 final stable.

I'm running this command:

CXX="include-what-you-use -Xiwyu --verbose=3 -isystem\"`xcode-select 
-p`/Toolchains/XcodeDefault.xctoolchain/usr/lib/c++/v1\"" make linux

and the first command gyp generates is

  include-what-you-use -Xiwyu --verbose=3 -isystem"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/c++/v1" '-DNDEBUG' -I../../include -I../Release/obj/gen/include  -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk -fasm-blocks -mpascal-strings -O3 -mmacosx-version-min=10.9 -arch x86_64 -std=c++11 -stdlib=libc++ -fvisibility-inlines-hidden -Wall -Wextra -I/usr/local/Cellar/libpng/1.6.10/include/libpng16 -I/usr/local/include -I/Users/kkaefer/Code/gl/native/mapnik-packaging/osx/out/build-cpp11-libcpp-universal/include -MMD -MF ../Release/.deps/../Release/obj.target/llmr-x86/src/clipper/clipper.o.d.raw  -c -o ../Release/obj.target/llmr-x86/src/clipper/clipper.o ../../src/clipper/clipper.cpp

which fails with

/Users/kkaefer/Code/include-what-you-use/iwyu.cc:3081: Assertion failed: 
class_decl && "TemplateSpecializationType is not a TplSpecDecl?"
make[1]: *** [../Release/obj.target/llmr-x86/src/clipper/clipper.o] Abort trap: 
6

Original issue reported on code.google.com by m...@kkaefer.com on 17 Jun 2014 at 2:38

GoogleCodeExporter commented 9 years ago
Can you please try to run IWYU in mapbox-gl-native on clipper.cpp without 
additional flags?  Something like

    $ path/to/include-what-you-use -I ./include src/clipper/clipper.cpp

I've tried the command above with IWYU in trunk and haven't hit any assertion 
failure.  I want to diagnose
- if the problem is present in trunk;
- if the problem is caused by other compiler arguments.

Original comment by vsap...@gmail.com on 18 Jun 2014 at 1:29

GoogleCodeExporter commented 9 years ago
I'm also hitting this with latest clang++/llvm from master and iwyu from 
master/svn trunk. It appears that it is related the flag: `-std=c++11`. If I 
remove that flag the assertion goes away.

Original comment by d...@mapbox.com on 19 Jun 2014 at 5:35

GoogleCodeExporter commented 9 years ago
I'll add that I am having to also add 
`-I/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchai
n/usr/lib/c++/v1/` to my compile lines, otherwise the C++11 headers are not 
available and I get errors like `'cstddef' file not found`.  If I use 
`-I/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchai
n/usr/lib/c++/v1/` without adding the `-std=c_++11` flag iwyu works without 
errors. If I keep `-std=c++11` but remove the custom path to c++ headers then 
after the error about `'cstddef' file not found` iwyu still finishes without 
the assertion and prints the headers to be removed/added/

Original comment by d...@mapbox.com on 19 Jun 2014 at 5:39

GoogleCodeExporter commented 9 years ago
For reference, here is how I am setting up llvm/iwyu:

git clone http://llvm.org/git/llvm.git
cd llvm/tools
git clone http://llvm.org/git/clang.git
cd tools
git clone http://llvm.org/git/clang-tools-extra.git
svn co http://include-what-you-use.googlecode.com/svn/trunk/ 
include-what-you-use
perl -p -i -e 's/diagtool/diagtool include-what-you-use/g' Makefile
cd ../../../
cd ./projects
git clone http://llvm.org/git/compiler-rt.git
cd ../
git config branch.master.rebase true
./configure --prefix=/opt/llvm/ --enable-clang-static-analyzer 
--enable-optimized
make && make install

Original comment by d...@mapbox.com on 19 Jun 2014 at 5:44

GoogleCodeExporter commented 9 years ago
Thanks, Konstantin and Dane, great catch.  Can reproduce assertion failure with 
-std=c++11.

Original comment by vsap...@gmail.com on 19 Jun 2014 at 6:17

GoogleCodeExporter commented 9 years ago
It all boils down to embarrassingly small test case

    #include <vector>
    struct Foo {};
    std::vector<Foo> foos;

And IWYU trips somewhere in v1/memory on rebind<void>.

Original comment by vsap...@gmail.com on 19 Jun 2014 at 9:57

GoogleCodeExporter commented 9 years ago
Thanks for looking into this!

Original comment by d...@mapbox.com on 21 Jun 2014 at 7:19

GoogleCodeExporter commented 9 years ago
Actually the assertion failure is caused by alias templates introduced in 
C++11.  The failure can be reproduced with the following test case

    template <class T> using Pointer = T*;
    typedef Pointer<void> VoidPointer;

There was a problem with std::vector<Foo> because std::vector instantiates 
__void_pointer [1] from <memory> from libc++.  Pay attention to "#ifndef 
_LIBCPP_HAS_NO_TEMPLATE_ALIASES" in __void_pointer [2] and in pointer_traits 
[3].  You can see that for C++11 language libc++ uses alias templates.  As the 
result, in TraverseDataAndTypeMembersOfClassHelper(type) argument type is type 
alias and TypeToDeclAsWritten(type) returns clang::TypeAliasTemplateDecl [4] 
which cannot be casted to clang::ClassTemplateSpecializationDecl causing 
assertion failure.

I had an idea to fix this issue by peeling off all aliases and using non-alias 
TemplateSpecializationType.  Corresponding patch is attached.  Though this 
patch fixes assertion failure, I have doubts regarding its correctness.

[1] 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/memory?revision=210211&
view=markup#l1001
[2] 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/memory?revision=210211&
view=markup#l1004
[3] 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/memory?revision=210211&
view=markup#l905
[4] http://clang.llvm.org/doxygen/classclang_1_1TypeAliasTemplateDecl.html

Original comment by vsap...@gmail.com on 21 Jun 2014 at 10:01

Attachments:

GoogleCodeExporter commented 9 years ago
I think the patch makes sense.

I've experimented with various combinations of alias templates and 
specializations and it gives results that are intuitive to me (I don't know 
very much about alias templates, though, so my intuition may be off.)

Here's my feeble test case:

  template<class T>
  struct Foo {};

  // This falls through the loop because Foo<T> is
  // itself a specialization when Bar is specialized.
  template<class T> using Bar = Foo<T>;

  // This triggers the early exit, because T* is not
  // a specialization.
  template<class T> using Pointer = T*;

  // The typedefs trigger specializations.  
  typedef Bar<int> bar_int;
  typedef Pointer<int> int_ptr;

There may be further complications if any of these aliases live in separate 
headers, but I think we can cross that bridge when we get there.

Do you feel comfortable adding a few test cases around alias templates to 
template_specialization and mark it with -std=c++11?

Original comment by kim.gras...@gmail.com on 22 Jun 2014 at 7:34

GoogleCodeExporter commented 9 years ago
Sorry, I cannot check the suggested test case in detail now.  I hope to get to 
it on the next weekend (July 5-6).

It makes sense to add new cases to template_specialization and I'm OK with 
adding -std=c++11 for it.  What if we add test alias_template.cc?  What about 
adding test directory tests/cxx11?

Original comment by vsap...@gmail.com on 26 Jun 2014 at 2:09

GoogleCodeExporter commented 9 years ago
Nice test case, Kim.  I can see in debugger that in one case aliased type is 
TemplateSpecializationType and in another case it isn't.  I would add an alias 
template chain, i.e. alias pointing to alias.  This will justify 'while' cycle.

Also I am trying to modify the test case, so it will catch incorrect fix

    if (type->isTypeAlias())
      return true;

Original comment by vsap...@gmail.com on 7 Jul 2014 at 3:11

GoogleCodeExporter commented 9 years ago
New patch with updated test case is attached.  I've looked more carefully at 
template_specialization.cc and it looks like it is more about explicit 
specializations, not about specializations in general.  That's why I think, 
alias templates deserve a separate test file.

I've looked at all places where TemplateSpecializationType is used.  And I 
haven't found any obvious problems, though I suspect there are problems with 
type aliases and de-, resugaring.

Original comment by vsap...@gmail.com on 13 Jul 2014 at 6:34

Attachments:

GoogleCodeExporter commented 9 years ago
Looks good to me!

It builds and all expected tests pass on Windows, please commit!

Original comment by kim.gras...@gmail.com on 14 Jul 2014 at 5:11

GoogleCodeExporter commented 9 years ago
The fix is committed in r559.  Konstantin and Dane, can you verify the fix, 
please?

Original comment by vsap...@gmail.com on 15 Jul 2014 at 6:22