// basic test to ensure contracts work for class and member specializations // { dg-do run } // { dg-options "-std=c++2a -fcontracts -fcontract-continuation-mode=on -fsigned-char" } #include // template specializations can have differing contracts template int body(int a) [[ pre: a > 0 ]] { T t = a * 2.5; return t; } template<> int body(int a) [[ pre: a > 1 ]] { double t = a * 3.3; return t; } template int none(int a) [[ pre: a > 0 ]] { return -a; } template<> int none(int a) [[ pre: a > 1 ]] { return a - 100; } template int arg0(T t) [[ pre: t > 0 ]] { return -t - 10; } template<> int arg0(double t) [[ pre: t > 1 ]] { return -t + 10; } template int arg1(int a, T t) [[ pre: a > 0 ]] [[ pre: t > 0 ]] { return -t * a; } template<> int arg1(int a, double t) [[ pre: a > 1 ]] [[ pre: t > 1 ]] { return -t * a + 17; } template T ret(int a) [[ pre: a > 0 ]] { return -a; } template<> double ret(int a) [[ pre: a > 1 ]] { return -a * 3.3; } // template specializations can have no contracts template int g1(T t) [[ pre: t > 0 ]] { return (int)t; } template<> int g1(double t) { return (int)t; } // template specializations can have no contracts in the first decl but add // them later template int g2(T t) [[ pre: t > 0 ]] { return (int)t; } template<> int g2(double t); template<> int g2(double t) [[ pre: t < 0 ]] { return (int)t; } template<> int g2(char t) [[ pre: t < 'c' ]] { return (int)t; } // contracts can be different on the general template, partial and full specs template struct G3 { void f(T t, S s) [[ pre: t > 0 ]] [[ pre: s > 0 ]] { printf ("G3 general T S\n"); } }; template struct G3 { void f(int t, S s); }; template void G3::f(int t, S s) [[ pre: t > 1 ]] [[ pre: s > 1 ]] { printf ("G3 partial int S\n"); } template<> void G3::f(int t, double s) [[ pre: t > 2 ]] [[ pre: s > 2 ]] { printf ("G3 full int double\n"); } struct C { bool operator>(int rhs) { return false; } }; // deletes contracts template<> void G3::f(int t, C s); template<> void G3::f(int t, C s) { printf ("G3 full int C\n"); }; // specialized ctors template struct G4 { G4(T t, S s) [[ pre: t > 0 ]] [[ pre: s > 0 ]] [[ post: x > 0 ]] { printf ("G4 general T S\n"); return; } int x{-1}; }; template struct G4 { G4(char t, S s) [[ pre: t > 'c' ]] [[ pre: s > 3 ]] [[ post: x2 > 3 ]] { printf ("G4 partial char S\n"); return; } int x2{-1}; }; template<> G4::G4(double, double) { printf ("G4 full double double\n"); return; } template<> G4::G4(double a, char b) [[ pre: a > 0 ]] [[ pre: b > 'b' ]] [[ post: x > 1 ]] { printf ("G4 full double char\n"); return; } // crossover of template classes and template members ok template struct G5 { template void f(T t, S s, P r) [[ pre: t > 0 ]] [[ pre: s > 0 ]] [[ pre: r > 0 ]] { printf ("G5 gen T S, f gen R\n"); } }; template struct G5 { template void f(char x, S y, R z) [[ pre: x > 'z' ]] [[ pre: y > 1 ]] [[ pre: z > 1 ]] { printf ("G5 partial char S, f gen R\n"); } }; template<> template void G5::f(double a, double b, Q c) [[ pre: a > 2 ]] [[ pre: b > 2 ]] [[ pre: c > 2 ]] { printf ("G5 full double double, f gen R\n"); } int main(int, char**) { printf("%d\n", body(-1)); printf("%d\n", body(-1)); printf("%d\n", none(-1)); printf("%d\n", none(-1)); printf("%d\n", arg0(-1)); printf("%d\n", arg0(-1.0)); printf("%d\n", arg1(-3, -1)); printf("%d\n", arg1(-3, -1.0)); printf("%d\n", (int)ret(-1)); printf("%d\n", (int)ret(-1)); printf("%f\n", ret(-1)); printf("%d\n", g1(-1)); printf("%d\n", g1(-1.0)); printf("%d\n", g2(-1)); printf("%d\n", g2(1.0)); printf("%d\n", g2('d')); G3 g3_gen; G3 g3_partial; G3 g3_full; g3_gen.f(-1.0, -1.0); // general g3_partial.f(-2, -2); // partial spec g3_full.f(-3, -3.0); // full spec G3 g3_gen2; G3 g3_partial2; g3_gen2.f((char)-1, (char)-1); g3_partial2.f(-1, (char)-1); G3 g3_full2; g3_full2.f(5, C{}); g3_full2.f(-5, C{}); G4 g4_gen{-1, -1}; G4 g4_full1{-1.0, -1.0}; G4 g4_full2{-1.0, (char)'b'}; G4 g4_partial{(char)'c', -5}; G5 g5_gen; g5_gen.f(-1, -1, -2); g5_gen.f(-1, -1, -2.0); G5 g5_part; g5_part.f('a', -1, -2); g5_part.f('a', -1, -2.1); G5 g5_full; g5_full.f(-1.0, -1.0, -2); g5_full.f(-1.0, -1.0, -2.1); return 0; } // { dg-skip-if "requires hosted libstdc++ for cstdio" { ! hostedlib } } // { dg-output {contract violation in function body at .*:9: a > 0(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {-2(\n|\r\n|\r)} } // { dg-output {contract violation in function body at .*:17: a > 1(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {-3(\n|\r\n|\r)} } // { dg-output {contract violation in function none at .*:25: a > 0(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {1(\n|\r\n|\r)} } // { dg-output {contract violation in function none at .*:32: a > 1(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {-101(\n|\r\n|\r)} } // { dg-output {contract violation in function arg0 at .*:39: t > 0(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {-9(\n|\r\n|\r)} } // { dg-output {contract violation in function arg0 at .*:46: t > 1(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {11(\n|\r\n|\r)} } // { dg-output {contract violation in function arg1 at .*:53: a > 0(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {contract violation in function arg1 at .*:54: t > 0(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {-3(\n|\r\n|\r)} } // { dg-output {contract violation in function arg1 at .*:61: a > 1(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {contract violation in function arg1 at .*:62: t > 1(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {14(\n|\r\n|\r)} } // { dg-output {contract violation in function ret at .*:69: a > 0(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {1(\n|\r\n|\r)} } // { dg-output {contract violation in function ret at .*:76: a > 1(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {3(\n|\r\n|\r)} } // { dg-output {contract violation in function ret at .*:76: a > 1(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {3.300000(\n|\r\n|\r)} } // { dg-output {contract violation in function g1 at .*:83: t > 0(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {-1(\n|\r\n|\r)} } // { dg-output {-1(\n|\r\n|\r)} } // { dg-output {contract violation in function g2 at .*:97: t > 0(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {-1(\n|\r\n|\r)} } // { dg-output {contract violation in function g2 at .*:107: t < 0(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {1(\n|\r\n|\r)} } // { dg-output {contract violation in function g2 at .*:114: t < 'c'(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {100(\n|\r\n|\r)} } // { dg-output {contract violation in function G3::f at .*:124: t > 0(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {contract violation in function G3::f at .*:125: s > 0(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {G3 general T S(\n|\r\n|\r)} } // { dg-output {contract violation in function G3::f at .*:139: t > 1(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {contract violation in function G3::f at .*:140: s > 1(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {G3 partial int S(\n|\r\n|\r)} } // { dg-output {contract violation in function G3::f at .*:147: t > 2(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {contract violation in function G3::f at .*:148: s > 2(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {G3 full int double(\n|\r\n|\r)} } // { dg-output {contract violation in function G3::f at .*:124: t > 0(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {contract violation in function G3::f at .*:125: s > 0(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {G3 general T S(\n|\r\n|\r)} } // { dg-output {contract violation in function G3::f at .*:139: t > 1(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {contract violation in function G3::f at .*:140: s > 1(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {G3 partial int S(\n|\r\n|\r)} } // { dg-output {G3 full int C(\n|\r\n|\r)} } // { dg-output {G3 full int C(\n|\r\n|\r)} } // { dg-output {contract violation in function G4::G4 at .*:173: t > 0(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {contract violation in function G4::G4 at .*:174: s > 0(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {G4 general T S(\n|\r\n|\r)} } // { dg-output {contract violation in function G4::G4 at .*:175: x > 0(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {G4 full double double(\n|\r\n|\r)} } // { dg-output {contract violation in function G4::G4 at .*:206: a > 0(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {contract violation in function G4::G4 at .*:207: b > 'b'(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {G4 full double char(\n|\r\n|\r)} } // { dg-output {contract violation in function G4::G4 at .*:208: x > 1(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {contract violation in function G4::G4 at .*:187: t > 'c'(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {contract violation in function G4::G4 at .*:188: s > 3(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {G4 partial char S(\n|\r\n|\r)} } // { dg-output {contract violation in function G4::G4 at .*:189: x2 > 3(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {contract violation in function G5::f at .*:220: t > 0(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {contract violation in function G5::f at .*:221: s > 0(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {contract violation in function G5::f at .*:222: r > 0(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {G5 gen T S, f gen R(\n|\r\n|\r)} } // { dg-output {contract violation in function G5::f at .*:220: t > 0(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {contract violation in function G5::f at .*:221: s > 0(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {contract violation in function G5::f at .*:222: r > 0(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {G5 gen T S, f gen R(\n|\r\n|\r)} } // { dg-output {contract violation in function G5::f at .*:233: x > 'z'(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {contract violation in function G5::f at .*:234: y > 1(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {contract violation in function G5::f at .*:235: z > 1(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {G5 partial char S, f gen R(\n|\r\n|\r)} } // { dg-output {contract violation in function G5::f at .*:233: x > 'z'(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {contract violation in function G5::f at .*:234: y > 1(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {contract violation in function G5::f at .*:235: z > 1(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {G5 partial char S, f gen R(\n|\r\n|\r)} } // { dg-output {contract violation in function G5::f at .*:244: a > 2(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {contract violation in function G5::f at .*:245: b > 2(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {contract violation in function G5::f at .*:246: c > 2(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {G5 full double double, f gen R(\n|\r\n|\r)} } // { dg-output {contract violation in function G5::f at .*:244: a > 2(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {contract violation in function G5::f at .*:245: b > 2(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {contract violation in function G5::f at .*:246: c > 2(\n|\r\n|\r)} } // { dg-output {\[continue:on\](\n|\r\n|\r)} } // { dg-output {G5 full double double, f gen R(\n|\r\n|\r)} }