Details
Description
hi -
I was seeing a SEGV running genreflex in a build of root 6.06/02 done
with gcc6. I got the crash running
genreflex x.h --selection_file=x.xml -o x_gen.cxx
|
with x.h:
#include <map>
|
#include <vector>
|
|
typedef std::map<unsigned int, std::vector<const void*> >
|
AttrListCVMap;
|
|
void makeIndex()
|
{
|
std::pair<AttrListCVMap::iterator,bool> res;
|
}
|
and x.xml:
<lcgdict>
|
<class pattern="*iterator<*pair<const*,const*"/>
|
</lcgdict>
|
I did not reproduce this crash with the builds on lxplus or with a build
with clang.
The crash was in ForwardDeclPrinter::Visit(clang::Decl*) because the pointer
passed in was not actually to a Decl (the first word of the structure
was 0x1, but it should have been a vtable pointer).
#0 0x0000000000a7e491 in clang::Decl::getCanonicalDecl (this=0x3b1d548)
|
at /home/sss/root/root-6.06.02/src/root/interpreter/llvm/inst/include/clang/AST/DeclBase.h:712
|
#1 0x0000000000b6c24d in cling::ForwardDeclPrinter::getCanonicalOrNamespace (
|
this=0x7fffffff9900, D=0x3b1d548)
|
at /home/sss/root/root-6.06.02/src/root/interpreter/cling/lib/Interpreter/ForwardDeclPrinter.h:248
|
#2 0x0000000000b6456f in cling::ForwardDeclPrinter::Visit (
|
this=0x7fffffff9900, D=0x3b1d548)
|
at /home/sss/root/root-6.06.02/src/root/interpreter/cling/lib/Interpreter/ForwardDeclPrinter.cpp:115
|
#3 0x0000000000b69279 in cling::ForwardDeclPrinter::VisitTemplateName (
|
this=0x7fffffff9900, TN=...)
|
at /home/sss/root/root-6.06.02/src/root/interpreter/cling/lib/Interpreter/ForwardDeclPrinter.cpp:1125
|
#4 0x0000000000b6913c in cling::ForwardDeclPrinter::VisitTemplateArgument (
|
this=0x7fffffff9900, TA=...)
|
at /home/sss/root/root-6.06.02/src/root/interpreter/cling/lib/Interpreter/ForwardDeclPrinter.cpp:1100
|
#5 0x0000000000b68ad2 in cling::ForwardDeclPrinter::VisitClassTemplateSpecializationDecl (this=0x7fffffff9900, D=0x3b1d560)
|
at /home/sss/root/root-6.06.02/src/root/interpreter/cling/lib/Interpreter/ForwardDeclPrinter.cpp:989
|
I think the problem is actually a couple frames up,
in ForwardDeclPrinter::VisitTemplateArgument, we have:
case clang::TemplateArgument::Template: // intentional fall-through:
|
case clang::TemplateArgument::Pack:
|
VisitTemplateName(TA.getAsTemplateOrTemplatePattern());
|
break;
|
The argument here is:
$8 = (const clang::TemplateArgument &) @0x3b1d650: {{DeclArg = {Kind = 8,
|
QT = 0x3b1d548, D = 0x321d570}, Integer = {Kind = 8, BitWidth = 1,
|
IsUnsigned = 0, {VAL = 61986120, pVal = 0x3b1d548}, Type = 0x321d570},
|
Args = {Kind = 8, NumArgs = 1, Args = 0x3b1d548}, TemplateArg = {Kind = 8,
|
NumExpansions = 1, Name = 0x3b1d548}, TypeOrValue = {Kind = 8,
|
V = 61986120}}}
|
Kind==8 is Pack, so we hit this arm of the switch. However,
getAsTemplateOrTemplatePattern is:
TemplateName getAsTemplateOrTemplatePattern() const {
|
assert((getKind() == Template || getKind() == TemplateExpansion) &&
|
"Unexpected kind");
|
|
return TemplateName::getFromVoidPointer(TemplateArg.Name);
|
}
|
... so this function cannot be called for a Pack.
(Evidently, assertions get disabled in the build...)
I tried this change, which i'm not at all sure is correct, but gets
genreflex functioning correctly for the cases i'm seeing.
diff --git a/interpreter/cling/lib/Interpreter/ForwardDeclPrinter.cpp b/interpre
|
ter/cling/lib/Interpreter/ForwardDeclPrinter.cpp
|
index d7a652e..9d4a2fc 100644
|
--- a/interpreter/cling/lib/Interpreter/ForwardDeclPrinter.cpp
|
+++ b/interpreter/cling/lib/Interpreter/ForwardDeclPrinter.cpp
|
@@ -1096,9 +1096,12 @@ namespace cling {
|
Visit(TA.getAsDecl());
|
break;
|
case clang::TemplateArgument::Template: // intentional fall-through:
|
- case clang::TemplateArgument::Pack:
|
VisitTemplateName(TA.getAsTemplateOrTemplatePattern());
|
break;
|
+ case clang::TemplateArgument::Pack:
|
+ for (const auto& arg : TA.pack_elements())
|
+ VisitTemplateArgument (arg);
|
+ break;
|
case clang::TemplateArgument::Expression:
|
{
|
Expr* TAExpr = TA.getAsExpr();
|