2

I have a working Spirit-X3 parser, that can parse two closely related grammars for setting up draughts and checkers positions. I define two variable templates specializations as parsers for the two dialects of the grammar:

// general variable template
template<class Format>
auto const position = []{};

// template specialization for algebraic notation (squares of the form "a1"-"h8")
template<>
auto const position<ast::ALG> = attribute_cast<ast::position<ast::ALG>> 
( 
    /* code depending on ast::ALG, omitted for brevity */
);

// template specialization for numeric notation (squares numbered 1 through N)  
template<>          
auto const position<ast::NUM> = attribute_cast<ast::position<ast::NUM>> 
( 
    /* code depending on ast::NUM, omitted for brevity */
);

This code compiles and correctly parses my test input, both on Clang and on g++.

Since the two variable template specializations depend on the template parameter in the exact same form, I want to consolidate them in a general variable template:

template<class Format>
auto const position = attribute_cast<ast::position<Format>> 
( 
    /* code depending on Format, omitted for brevity */
); 

This also compiles and parses correctly for g++. It also compiles for Clang, but it only parses correctly my input on Wandbox, and not on Coliru. On my own dev box, with clang-3.8.0 from apt.llvm.org, I get the same erroneous behavior as on Coliru.

Question: Is there a bug in Clang for variable template specializations? How can I configure Clang in the same way as on Wandbox in order to work around that bug? Or is it somehow a Spirit-X3 related bug?

TemplateRex
  • 69,038
  • 19
  • 164
  • 304

1 Answers1

1

After testing other compilers, this appears a variable template code generation bug in Clang, as the code correctly parses everything in g++.

In addition to the explicit specialization snafu above, Clang also chokes (i.e. compiles but emits incorrect code that can't parse the input) on variable template Spirit-X3 parsers that have not been explicitly specialized:

template<class Format>
auto piece_list = piece >> file >> rank;

template<>
auto const piece_list<ast::NUM> = piece >> square >> -('-' >> square);

Live Example here that only parses position strings in numeric form, and mishandles all algebraic strings (for which no explicit specialization was given).

and only works if the general variable template is specialized for all cases that will be called:

template<class Format>
auto piece_list = 0;

template<>
auto const piece_list<ast::ALG> = piece >> file >> rank;

template<>
auto const piece_list<ast::NUM> = piece >> square >> -('-' >> square);

I haven't been able to find a small reduced test case that isolates the Clang bug.

TemplateRex
  • 69,038
  • 19
  • 164
  • 304