// ensure no errors are thrown for various combinations of class templates // with guarded members // { dg-do run } // { dg-options "-std=c++2a -fcontracts -fcontract-continuation-mode=on" } template<typename T> struct S { int f(int a) [[ pre: a > 0 ]]; int g(int a) [[ pre: a > 0 ]]; }; template<typename T> int S<T>::f(int a) [[ pre: a > 0 ]] { return -a; } template<typename T> int S<T>::g(int a) // Contract is inherited (error from line 10). { return -a; } template<typename T> struct S_arg { int f(T a) [[ pre: a > 0 ]]; int g(T a) [[ pre: a > 0 ]]; }; template<typename T> int S_arg<T>::f(T a) [[ pre: a > 0 ]] { return -a; } template<typename T> int S_arg<T>::g(T a) // Contract is inherited (error from line 29). { return -a; } template<typename T> struct S_ret { T f(int a) [[ pre: a > 0 ]]; T g(int a) [[ pre: a > 0 ]]; }; template<typename T> T S_ret<T>::f(int a) [[ pre: a > 0 ]] { return -a; } template<typename T> T S_ret<T>::g(int a) // Contract is inherited (error from line 48). { return -a; } #include <cstdio> int main(int, char**) { { S<int> s_int; printf ("s_int.f(-10): %d\n", s_int.f(-10)); printf ("s_int.g(-10): %d\n", s_int.g(-10)); printf ("s_int.f(10): %d\n", s_int.f(10)); printf ("s_int.g(10): %d\n", s_int.g(10)); S<double> s_double; printf ("s_double.f(-10.5): %d\n", s_double.f(-10.5)); printf ("s_double.g(-10.5): %d\n", s_double.g(-10.5)); printf ("s_double.f(10.5): %d\n", s_double.f(10.5)); printf ("s_double.g(10.5): %d\n", s_double.g(10.5)); } { S_arg<int> s_arg_int; printf ("s_arg_int.f(-10): %d\n", s_arg_int.f(-10)); printf ("s_arg_int.g(-10): %d\n", s_arg_int.g(-10)); printf ("s_arg_int.f(10): %d\n", s_arg_int.f(10)); printf ("s_arg_int.g(10): %d\n", s_arg_int.g(10)); S_arg<double> s_arg_double; printf ("s_arg_double.f(-10): %d\n", s_arg_double.f(-10)); printf ("s_arg_double.g(-10): %d\n", s_arg_double.g(-10)); printf ("s_arg_double.f(10): %d\n", s_arg_double.f(10)); printf ("s_arg_double.g(10): %d\n", s_arg_double.g(10)); } { S_ret<int> s_ret_int; printf ("s_ret_int.f(-10): %d\n", s_ret_int.f(-10)); printf ("s_ret_int.g(-10): %d\n", s_ret_int.g(-10)); printf ("s_ret_int.f(10): %d\n", s_ret_int.f(10)); printf ("s_ret_int.g(10): %d\n", s_ret_int.g(10)); S_ret<double> s_ret_double; printf ("s_ret_double.f(-10): %f\n", s_ret_double.f(-10)); printf ("s_ret_double.g(-10): %f\n", s_ret_double.g(-10)); printf ("s_ret_double.f(10): %f\n", s_ret_double.f(10)); printf ("s_ret_double.g(10): %f\n", s_ret_double.g(10)); } return 0; } // { dg-skip-if "requires hosted libstdc++ for cstdio" { ! hostedlib } } // { dg-output "contract violation in function S<int>::f at .*.C:14: .*(\n|\r\n|\r)" } // { dg-output "s_int.f.-10.: 10(\n|\r\n|\r)" } // { dg-output "contract violation in function S<int>::g at .*.C:10: .*(\n|\r\n|\r)" } // { dg-output "s_int.g.-10.: 10(\n|\r\n|\r)" } // { dg-output "s_int.f.10.: -10(\n|\r\n|\r)" } // { dg-output "s_int.g.10.: -10(\n|\r\n|\r)" } // { dg-output "contract violation in function S<double>::f at .*.C:14: .*(\n|\r\n|\r)" } // { dg-output "s_double.f.-10.5.: 10(\n|\r\n|\r)" } // { dg-output "contract violation in function S<double>::g at .*.C:10: .*(\n|\r\n|\r)" } // { dg-output "s_double.g.-10.5.: 10(\n|\r\n|\r)" } // { dg-output "s_double.f.10.5.: -10(\n|\r\n|\r)" } // { dg-output "s_double.g.10.5.: -10(\n|\r\n|\r)" } // { dg-output "contract violation in function S_arg<int>::f at .*.C:33: .*(\n|\r\n|\r)" } // { dg-output "s_arg_int.f.-10.: 10(\n|\r\n|\r)" } // { dg-output "contract violation in function S_arg<int>::g at .*.C:29: .*(\n|\r\n|\r)" } // { dg-output "s_arg_int.g.-10.: 10(\n|\r\n|\r)" } // { dg-output "s_arg_int.f.10.: -10(\n|\r\n|\r)" } // { dg-output "s_arg_int.g.10.: -10(\n|\r\n|\r)" } // { dg-output "contract violation in function S_arg<double>::f at .*.C:33: .*(\n|\r\n|\r)" } // { dg-output "s_arg_double.f.-10.: 10(\n|\r\n|\r)" } // { dg-output "contract violation in function S_arg<double>::g at .*.C:29: .*(\n|\r\n|\r)" } // { dg-output "s_arg_double.g.-10.: 10(\n|\r\n|\r)" } // { dg-output "s_arg_double.f.10.: -10(\n|\r\n|\r)" } // { dg-output "s_arg_double.g.10.: -10(\n|\r\n|\r)" } // { dg-output "contract violation in function S_ret<int>::f at .*.C:52: .*(\n|\r\n|\r)" } // { dg-output "s_ret_int.f.-10.: 10(\n|\r\n|\r)" } // { dg-output "contract violation in function S_ret<int>::g at .*.C:48: .*(\n|\r\n|\r)" } // { dg-output "s_ret_int.g.-10.: 10(\n|\r\n|\r)" } // { dg-output "s_ret_int.f.10.: -10(\n|\r\n|\r)" } // { dg-output "s_ret_int.g.10.: -10(\n|\r\n|\r)" } // { dg-output "contract violation in function S_ret<double>::f at .*.C:52: .*(\n|\r\n|\r)" } // { dg-output "s_ret_double.f.-10.: 10.000000(\n|\r\n|\r)" } // { dg-output "contract violation in function S_ret<double>::g at .*.C:48: .*(\n|\r\n|\r)" } // { dg-output "s_ret_double.g.-10.: 10.000000(\n|\r\n|\r)" } // { dg-output "s_ret_double.f.10.: -10.000000(\n|\r\n|\r)" } // { dg-output "s_ret_double.g.10.: -10.000000(\n|\r\n|\r)" }