// generic error tests for generalized contract redecls // { dg-do compile } // { dg-options "-std=c++2a -fcontracts" } // 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 ]]; // can add to non-virtual methods struct G0 { int f(int a); }; int G0::f(int a) [[ pre: a > 0 ]] { return -a; } struct G1 { int f(int a); }; int G1::f(int a) [[ pre: a > 0 ]]; int G1::f(int a) { return -a; } // allowed to redeclare even without contracts struct G2 { int f(int a); }; int G2::f(int a); 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; } // cannot "re"declare members of a forward declared class struct F2; int F2::test(); // { dg-error "no declaration matches" } int F2::test2() [[ pre: true ]]; // { dg-error "no declaration matches" } // can only redeclare member functions struct F3 { int x; typedef int my_int; struct Inner0; struct Inner1; enum my_enum0; // { dg-error "use of enum.*without previous decl" } enum my_enum1 { E1, E2 }; int test0(); int test1(); int test2(); }; int F3::x{-1}; // { dg-error "is not a static data member" } typedef double F3::my_int; // { dg-error "typedef name may not be a nested-name-specifier" } struct F3::Inner0; // { dg-warning "declaration.*does not declare anything" } struct F3::Inner1 { }; enum F3::my_enum1 { E0, E1, END }; // { dg-error "multiple definition" } struct F4 { int test0(); int F3::test0() [[ pre: true ]]; // { dg-error "cannot declare member function" } friend int F3::test1(); friend int F3::test2(); }; int F3::test2() [[ pre: true ]] { return -1; } void dummy0() { int F4::test0() [[ pre: true ]]; // { dg-error "qualified-id in declaration" } } namespace ns0 { typedef int value; struct X { int test1(value); typedef double value; int test2(value); }; int X::test1(value); // { dg-error "no declaration matches" } int X::test2(value); }