Tencent / rapidjson

A fast JSON parser/generator for C++ with both SAX/DOM style API
http://rapidjson.org/
Other
14.04k stars 3.51k forks source link

Failed to compile due to compiler bug #1338

Open XZiar opened 5 years ago

XZiar commented 5 years ago

Compiler: GCC7.3.0 Environment: WSL (ubuntu 18.04)

example:

#include "rapidjson/stringbuffer.h"
#include "rapidjson/prettywriter.h"
int main()
{
    rapidjson::StringBuffer strBuf;
    rapidjson::PrettyWriter writer(strBuf);
    return 1;
}

g++ -std=c++17 test.cpp test.cpp: In constructor ‘rapidjson::PrettyWriter<OutputStream, SourceEncoding, TargetEncoding, StackAllocator, writeFlags>::PrettyWriter(OutputStream&, StackAllocator*, std::size_t)’: test.cpp:7:42: internal compiler error: unexpected expression ‘writeFlags’ of kind template_parm_index rapidjson::PrettyWriter writer(strBuf); ^ Please submit a full bug report, with preprocessed source if appropriate. See file:///usr/share/doc/gcc-7/README.Bugs for instructions.

It seems to be a bug of GCC and is affecting GCC7.3.1 and GCC8.1 as well. See mpark/variant#43 and https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84785

Is there any workaround to fix it?

ShigekiKarita commented 5 years ago

Hi, I met this problem too with GCC8.1.0. It did not tell me that it was ICT.

$ g++-8 tmp.cpp -std=c++17
tmp.cpp: In function ‘PrettyWriter(OutputStream&, StackAllocator*, std::size_t)-> rapidjson::PrettyWriter<OutputStream, SourceEncoding, TargetEncoding, StackAllocator, writeFlags> [with OutputStream = rapidjson::GenericStringBuffer<rapidjson::UTF8<> >; SourceEncoding = rapidjson::UTF8<>; TargetEncoding = rapidjson::UTF8<>; StackAllocator = rapidjson::CrtAllocator; unsigned int writeFlags = 0; std::size_t = long unsigned int]’:
tmp.cpp:6:42: error: ‘const size_t rapidjson::Writer<rapidjson::GenericStringBuffer<rapidjson::UTF8<> > >::kDefaultLevelDepth’ is protected within this context
     rapidjson::PrettyWriter writer(strBuf);
                                          ^
In file included from rapidjson/prettywriter.h:18,
                 from tmp.cpp:2:
rapidjson/writer.h:262:25: note: declared protected here
     static const size_t kDefaultLevelDepth = 32;
ShigekiKarita commented 5 years ago

After several trials, I expect that the problem is caused by c++17 class template deduction in GCC7/8. My workaround is just specify the template parameter.

#include "rapidjson/stringbuffer.h"
#include "rapidjson/prettywriter.h"
int main()
{
    rapidjson::StringBuffer strBuf;
    rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(strBuf);
    return 1;
}

In my env, GCC7.4 and GCC8.1 both work well after this modification.

pah commented 5 years ago

You can try adding explicit deduction guides to work around this compiler bug (untested):

namespace rapidjson {
template<typename OutputStream>
PrettyWriter(OutputStream&) -> PrettyWriter<OutputStream, UTF8<>, UTF8<>, CrtAllocator, kWriteDefaultFlags>;
template<typename OutputStream, typename StackAllocator>
PrettyWriter(OutputStream&, StackAllocator*) -> PrettyWriter<OutputStream, UTF8<>, UTF8<>, StackAllocator, kWriteDefaultFlags>;
template<typename OutputStream, typename StackAllocator>
PrettyWriter(OutputStream&, StackAllocator*, size_t) -> PrettyWriter<OutputStream, UTF8<>, UTF8<>, StackAllocator, kWriteDefaultFlags>;
}  // namespace rapidjson
XZiar commented 5 years ago

After several trials, I expect that the problem is caused by c++17 class template deduction in GCC7/8. My workaround is just specify the template parameter.

#include "rapidjson/stringbuffer.h"
#include "rapidjson/prettywriter.h"
int main()
{
    rapidjson::StringBuffer strBuf;
    rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(strBuf);
    return 1;
}

In my env, GCC7.4 and GCC8.1 both work well after this modification.

@ShigekiKarita Explicitly adding template parameter do solve the issue on my GCC 8.2.0 Thanks.

ShigekiKarita commented 5 years ago

@pah Thanks for your support. As you expected, the guides work pretty well. How about PR on pretty.h (and writer.h) with some C++17 if block?

#if __cplusplus > 201703L
// the guides
#endif