https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53360
Eric Gallager <egallager at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |NEW Last reconfirmed| |2017-08-19 CC| |egallager at gcc dot gnu.org Summary|Problems with -std=gnu++0x |g++ prints 'invalid use of | |incomplete type' error when | |compiling code with | |-std=gnu++0x and newer Ever confirmed|0 |1 --- Comment #2 from Eric Gallager <egallager at gcc dot gnu.org> --- (In reply to Alex from comment #0) > I have such code: > > > template<class CppType> > struct make_literal; > > template<> > struct make_literal<int> { > typedef int type; > }; > > template<class T> > struct make_expression { > typedef typename make_literal<T>::type type; > }; > > struct column { > template<class T> > typename make_expression<T>::type operator= (const T& t) const { > return typename make_expression<T>::type(t); > } > }; > > struct expression : column > { > expression() { } > using column::operator =; > }; > > int main() > { > expression ex; > ex = 2; > > return 0; > } > > which failed to compile with such command line: > c++ -std=gnu++0x file.cpp > > Compiler produces such error: > bug.cpp: In instantiation of ‘make_expression<column>’: > bug.cpp:31:10: instantiated from here > bug.cpp:12:42: error: invalid use of incomplete type ‘struct > make_literal<column>’ > bug.cpp:3:8: error: declaration of ‘struct make_literal<column>’ (In reply to Marc Glisse from comment #1) > clang and gcc reject it, but intel and oracle accept it. The errors with gcc and clang are now: $ /usr/local/bin/g++ -c -Wall -Wextra -pedantic -std=gnu++0x 53360.cc 53360.cc: In instantiation of ‘struct make_expression<column>’: 53360.cc:16:36: required by substitution of ‘template<class T> typename make_expression<T>::type column::operator=(const T&) const [with T = column]’ 53360.cc:30:10: required from here 53360.cc:11:41: error: invalid use of incomplete type ‘struct make_literal<column>’ typedef typename make_literal<T>::type type; ^~~~ 53360.cc:2:8: note: declaration of ‘struct make_literal<column>’ struct make_literal; ^~~~~~~~~~~~ $ /sw/opt/llvm-3.1/bin/clang++ -c -Wall -Wextra -pedantic -std=gnu++0x 53360.cc 53360.cc:11:19: error: implicit instantiation of undefined template 'make_literal<column>' typedef typename make_literal<T>::type type; ^ 53360.cc:16:11: note: in instantiation of template class 'make_expression<column>' requested here typename make_expression<T>::type operator= (const T& t) const { ^ 53360.cc:16:36: note: while substituting deduced template arguments into function template 'operator=' [with T = column] typename make_expression<T>::type operator= (const T& t) const { ^ 53360.cc:2:8: note: template is declared here struct make_literal; ^ 1 error generated. $ Note that it also fails with gnu++14 and gnu++1z. When compiled with -std=gnu++98 and -Wc++11-compat, it prints no errors or warnings, which is odd, because if it were actually supposed to error out with gnu++11, you'd think -Wc++11-compat would at least warn about it. So, confirmed.