blob: 933adce79f9fad9241a5a2e57c4a8b3de4a109e2 [file] [log] [blame]
// test that contracts are matched on friend decls when the type is complete
// { dg-do compile }
// { dg-options "-std=c++2a -fcontracts" }
struct T;
int both(int x, T *t) [[ pre: x > 0 ]] { return 0; }
int both2(int x, T *t) [[ pre: x > 0 ]];
template<typename Z>
int fn(int x, Z *z) [[ pre: x > 0 ]];
template<typename Z>
int fn2(int x, Z *z);
template<typename Z>
int fn3(int x, Z *z) [[ pre: x > 0 ]];
template<>
int fn3<T>(int x, T *z) [[ pre: x > 1 ]];
struct T
{
friend int both2(int x, T *t) [[ pre: x > 1 ]] // { dg-error "mismatched" }
{
return 0;
}
friend int hidden(int x, T *t)
[[ pre: x > 1 ]] [[ pre: t->pri > 0 ]]
{
return x;
}
/* cannot define friend spec, so we never get to matching contracts
friend int fn<T>(int x, T *t)
[[ pre: t->pri > 0 ]] { return 0; } // error defining explicit spec friend
*/
// bad, general contracts must match general
template<typename Z>
friend int fn(int x, Z *z)
[[ pre: z->pri > 1 ]] { return 0; } // { dg-error "mismatched" }
// fine, can add contracts
template<typename Z>
friend int fn2(int x, Z *z)
[[ pre: z->pri > 1 ]] { return 0; } // { dg-bogus "mismatched" }
/* cannot declare without definition, so dup friend can't occur:
friend int dup(int x, T *t)
[[ pre: t->pri > 0 ]]; // error non-defining friend with contracts
friend int dup(int x, T *t)
[[ pre: t->pri > 1 ]]; // error non-defining friend with contracts
*/
int x{1};
private:
int pri{-10};
};
int hidden(int x, T *t)
[[ pre: x > 0 ]] [[ pre: t->pri > 1 ]]; // { dg-error "mismatched" }