// generic error tests for generalized contract redecls // we also test for the warning diagnostic for strict redecl // { dg-do compile } // { dg-options "-std=c++2a -fcontracts -fcontract-strict-declarations=on" } // allowed to repeat contracts or omit them int g0(int a) [[ pre: a > 0 ]]; int g0(int a) [[ pre: a > 0 ]]; int g1(int a) [[ pre: a > 0 ]]; int g1(int a); // allowed to add from none if generalized redecl is on (by default) int g2(int a); int g2(int a) [[ pre: a > 0 ]]; // { dg-warning "adds contracts" } int g2(int a) [[ pre: a > 0 ]]; // { dg-bogus "adds contracts" } // can add to non-virtual methods struct G0 { int f(int a); }; int G0::f(int a) [[ pre: a > 0 ]] // { dg-warning "adds contracts" } { return -a; } struct G1 { int f(int a); }; int G1::f(int a) [[ pre: a > 0 ]]; // { dg-warning "adds contracts" } // { dg-warning "outside of class is not definition" "" { target *-*-* } .-1 } int G1::f(int a); // { dg-warning "outside of class is not definition" "" { target *-*-* } .-1 } int G1::f(int a) [[ pre: a > 0 ]]; // { dg-warning "outside of class is not definition" "" { target *-*-* } .-1 } int G1::f(int a) { return -a; } // allowed to redeclare even without contracts struct G2 { int f(int a); }; int G2::f(int a); // { dg-warning "outside of class is not definition" } int f0(int a) [[ pre: a > 0 ]]; int f0(int a) [[ pre: a > 0 ]] [[ pre: a > 10 ]]; // { dg-error "different number of contracts" } int f1(int a) [[ pre: a > 0 ]]; int f1(int a) [[ pre: a < 0 ]]; // { dg-error "mismatched contract" } int f2(int a) { return a; } int f2(int a) [[ pre: a < 0 ]]; // { dg-error "cannot add contracts after definition" } struct Base { virtual int f(int a) [[ pre: a > 0 ]]; }; struct Child : Base { int f(int a) [[ pre: a < 0 ]]; // { dg-error "mismatched contract" } }; // the initial decl of a guarded member must appear inside the class struct F2 { int f(int a); }; int F2::g(int a) [[ pre: a > 0 ]]; // { dg-error "no declaration matches" } // FIXME if we move F2 down then a different error makes F2 undeclared struct F0 { virtual int f(int a); }; int F0::f(int a); // { dg-error "declaration.*is not definition" } struct F1 { virtual int f(int a); }; int F1::f(int a) [[ pre: a > 0 ]] // { dg-error "cannot add" } { return -a; }