http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49292
Summary: [c++0x] non_const_var_error ICE for error when mixing static_assert, template, and constexpr Product: gcc Version: 4.7.0 Status: UNCONFIRMED Severity: minor Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: lankyle...@gmail.com Created attachment 24439 --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=24439 Preprocessed code When trying to compile this code with SVN trunk revision 174633: template <int n, int min, int max> struct no_divisors_between { static constexpr bool v() { return (n % min) && no_divisors_between<n, min + 1, max>::v(); } }; template <int n, int k> struct no_divisors_between<n, k, k> { static constexpr bool v() { return n % random_undefined_symbol_which_should_be_k; } }; template <int size> class SillyHashTable { public: static constexpr bool get_good_size() { return m_good_size; } private: static const bool m_good_size = no_divisors_between<size, 2, size-1>::v(); }; int main() { const int hash_table_size = 5; static_assert(SillyHashTable<hash_table_size>::get_good_size(), "hash_table_size should be a prime."); } I get an internal compiler error: james@ubuntu:~/Desktop$ /home/james/programs/other/gcc_install/bin/g++ -v -save-temps -std=c++0x test.cc Using built-in specs. COLLECT_GCC=/home/james/programs/other/gcc_install/bin/g++ COLLECT_LTO_WRAPPER=/home/james/programs/other/gcc_install/libexec/gcc/x86_64-unknown-linux-gnu/4.7.0/lto-wrapper Target: x86_64-unknown-linux-gnu Configured with: ../gcc/configure --prefix=/home/james/programs/other/gcc_install/ --with-local-prefix=/home/james/programs/other/gcc_install/ --disable-bootstrap Thread model: posix gcc version 4.7.0 20110604 (experimental) (GCC) COLLECT_GCC_OPTIONS='-v' '-save-temps' '-std=c++0x' '-shared-libgcc' '-mtune=generic' '-march=x86-64' /home/james/programs/other/gcc_install/libexec/gcc/x86_64-unknown-linux-gnu/4.7.0/cc1plus -E -quiet -v -D_GNU_SOURCE test.cc -mtune=generic -march=x86-64 -std=c++0x -fpch-preprocess -o test.ii ignoring duplicate directory "/home/james/programs/other/gcc_install/include" ignoring nonexistent directory "/home/james/programs/other/gcc_install/lib/gcc/x86_64-unknown-linux-gnu/4.7.0/../../../../x86_64-unknown-linux-gnu/include" #include "..." search starts here: #include <...> search starts here: /home/james/programs/other/gcc_install/lib/gcc/x86_64-unknown-linux-gnu/4.7.0/../../../../include/c++/4.7.0 /home/james/programs/other/gcc_install/lib/gcc/x86_64-unknown-linux-gnu/4.7.0/../../../../include/c++/4.7.0/x86_64-unknown-linux-gnu /home/james/programs/other/gcc_install/lib/gcc/x86_64-unknown-linux-gnu/4.7.0/../../../../include/c++/4.7.0/backward /home/james/programs/other/gcc_install/lib/gcc/x86_64-unknown-linux-gnu/4.7.0/include /home/james/programs/other/gcc_install//include /home/james/programs/other/gcc_install/lib/gcc/x86_64-unknown-linux-gnu/4.7.0/include-fixed /usr/include End of search list. COLLECT_GCC_OPTIONS='-v' '-save-temps' '-std=c++0x' '-shared-libgcc' '-mtune=generic' '-march=x86-64' /home/james/programs/other/gcc_install/libexec/gcc/x86_64-unknown-linux-gnu/4.7.0/cc1plus -fpreprocessed test.ii -quiet -dumpbase test.cc -mtune=generic -march=x86-64 -auxbase test -std=c++0x -version -o test.s GNU C++ (GCC) version 4.7.0 20110604 (experimental) (x86_64-unknown-linux-gnu) compiled by GNU C version 4.7.0 20110604 (experimental), GMP version 4.3.2, MPFR version 2.4.2-p1, MPC version 0.8.1 GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096 GNU C++ (GCC) version 4.7.0 20110604 (experimental) (x86_64-unknown-linux-gnu) compiled by GNU C version 4.7.0 20110604 (experimental), GMP version 4.3.2, MPFR version 2.4.2-p1, MPC version 0.8.1 GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096 Compiler executable checksum: ce3a170bafb891f93f6be982ba0564e4 test.cc: In static member function ‘static constexpr bool no_divisors_between<n, k, k>::v()’: test.cc:14:28: error: ‘random_undefined_symbol_which_should_be_k’ was not declared in this scope test.cc: In static member function ‘static constexpr bool no_divisors_between<n, k, k>::v() [with int n = 5, int k = 4]’: test.cc:6:77: recursively instantiated from ‘static constexpr bool no_divisors_between<n, min, max>::v() [with int n = 5, int min = 3, int max = 4]’ test.cc:6:77: instantiated from ‘static constexpr bool no_divisors_between<n, min, max>::v() [with int n = 5, int min = 2, int max = 4]’ test.cc:27:81: instantiated from ‘const bool SillyHashTable<5>::m_good_size’ test.cc:24:24: instantiated from ‘static constexpr bool SillyHashTable<size>::get_good_size() [with int size = 5]’ test.cc:33:56: instantiated from here test.cc:15:9: error: body of constexpr function ‘static constexpr bool no_divisors_between<n, k, k>::v() [with int n = 5, int k = 4]’ not a return-statement test.cc: At global scope: test.cc: In instantiation of ‘const bool SillyHashTable<5>::m_good_size’: test.cc:24:24: instantiated from ‘static constexpr bool SillyHashTable<size>::get_good_size() [with int size = 5]’ test.cc:33:56: instantiated from here test.cc:27:81: error: non-constant in-class initialization invalid for static member ‘SillyHashTable<5>::m_good_size’ test.cc:27:81: error: (an out of class initialisation is required) test.cc:27:81: error: ‘SillyHashTable<5>::m_good_size’ cannot be initialised by a non-constant expression when being declared test.cc: In function ‘int main()’: test.cc:33:9: error: non-constant condition for static assertion test.cc:33:70: in constexpr expansion of ‘SillyHashTable<size>::get_good_size [with int size = 5]()’ test.cc:33:9: error: the value of ‘SillyHashTable<5>::m_good_size’ is not usable in a constant expression test.cc:33:9: internal compiler error: in non_const_var_error, at cp/semantics.c:6908 Please submit a full bug report, with preprocessed source if appropriate. See <http://gcc.gnu.org/bugs.html> for instructions. The code should not compile anyway: and the first compiler error explains why. I can't reproduce this ICE on similar code with the error fixed, so I've set this bug's severity to minor.