blob: 6c3a94d487b7275cd054a699d618c92fb5e89ea7 [file] [log] [blame]
/* This testcase is part of GDB, the GNU debugger.
Copyright 2019-2021 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
class ByVal {
public:
ByVal (void);
int x;
};
ByVal::ByVal (void)
{
x = 2;
}
class ByRef {
public:
ByRef (void);
ByRef (const ByRef &rhs);
int x;
};
ByRef::ByRef (void)
{
x = 2;
}
ByRef::ByRef (const ByRef &rhs)
{
x = 3; /* ByRef-cctor */
}
class ArrayContainerByVal {
public:
ByVal items[2];
};
int
cbvArrayContainerByVal (ArrayContainerByVal arg)
{
arg.items[0].x += 4; // intentionally modify
return arg.items[0].x;
}
class ArrayContainerByRef {
public:
ByRef items[2];
};
int
cbvArrayContainerByRef (ArrayContainerByRef arg)
{
arg.items[0].x += 4; // intentionally modify
return arg.items[0].x;
}
class DynamicBase {
public:
DynamicBase (void);
virtual int get (void);
int x;
};
DynamicBase::DynamicBase (void)
{
x = 2;
}
int
DynamicBase::get (void)
{
return 42;
}
class Dynamic : public DynamicBase {
public:
virtual int get (void);
};
int
Dynamic::get (void)
{
return 9999;
}
int
cbvDynamic (DynamicBase arg)
{
arg.x += 4; // intentionally modify
return arg.x + arg.get ();
}
class Inlined {
public:
Inlined (void);
__attribute__((always_inline))
Inlined (const Inlined &rhs)
{
x = 3;
}
int x;
};
Inlined::Inlined (void)
{
x = 2;
}
int
cbvInlined (Inlined arg)
{
arg.x += 4; // intentionally modify
return arg.x;
}
class DtorDel {
public:
DtorDel (void);
~DtorDel (void) = delete;
int x;
};
DtorDel::DtorDel (void)
{
x = 2;
}
int
cbvDtorDel (DtorDel arg)
{
// Calling this method should be rejected
return arg.x;
}
class FourCCtor {
public:
FourCCtor (void);
FourCCtor (FourCCtor &rhs);
FourCCtor (const FourCCtor &rhs);
FourCCtor (volatile FourCCtor &rhs);
FourCCtor (const volatile FourCCtor &rhs);
int x;
};
FourCCtor::FourCCtor (void)
{
x = 2;
}
FourCCtor::FourCCtor (FourCCtor &rhs)
{
x = 3;
}
FourCCtor::FourCCtor (const FourCCtor &rhs)
{
x = 4;
}
FourCCtor::FourCCtor (volatile FourCCtor &rhs)
{
x = 5;
}
FourCCtor::FourCCtor (const volatile FourCCtor &rhs)
{
x = 6;
}
int
cbvFourCCtor (FourCCtor arg)
{
arg.x += 10; // intentionally modify
return arg.x;
}
class TwoMCtor {
public:
TwoMCtor (void);
/* Even though one move ctor is defaulted, the other
is explicit. */
TwoMCtor (const TwoMCtor &&rhs);
TwoMCtor (TwoMCtor &&rhs) = default;
int x;
};
TwoMCtor::TwoMCtor (void)
{
x = 2;
}
TwoMCtor::TwoMCtor (const TwoMCtor &&rhs)
{
x = 3;
}
int
cbvTwoMCtor (TwoMCtor arg)
{
arg.x += 10; // intentionally modify
return arg.x;
}
class TwoMCtorAndCCtor {
public:
TwoMCtorAndCCtor (void);
TwoMCtorAndCCtor (const TwoMCtorAndCCtor &rhs) = default;
/* Even though one move ctor is defaulted, the other
is explicit. This makes the type pass-by-ref. */
TwoMCtorAndCCtor (const TwoMCtorAndCCtor &&rhs);
TwoMCtorAndCCtor (TwoMCtorAndCCtor &&rhs) = default;
int x;
};
TwoMCtorAndCCtor::TwoMCtorAndCCtor (void)
{
x = 2;
}
TwoMCtorAndCCtor::TwoMCtorAndCCtor (const TwoMCtorAndCCtor &&rhs)
{
x = 4;
}
int
cbvTwoMCtorAndCCtor (TwoMCtorAndCCtor arg)
{
arg.x += 10; // intentionally modify
return arg.x;
}
ArrayContainerByVal arrayContainerByVal;
ArrayContainerByRef arrayContainerByRef;
Dynamic dynamic;
Inlined inlined;
// Cannot stack-allocate DtorDel
DtorDel *dtorDel;
FourCCtor fourCctor_c0v0;
const FourCCtor fourCctor_c1v0;
volatile FourCCtor fourCctor_c0v1;
const volatile FourCCtor fourCctor_c1v1;
TwoMCtor twoMctor;
TwoMCtorAndCCtor twoMctorAndCctor;
int
main (void)
{
int v;
dtorDel = new DtorDel;
/* Explicitly call the cbv function to make sure the compiler
will not omit any code in the binary. */
v = cbvArrayContainerByVal (arrayContainerByVal);
v = cbvArrayContainerByRef (arrayContainerByRef);
v = cbvDynamic (dynamic);
v = cbvInlined (inlined);
v = cbvFourCCtor (fourCctor_c0v0);
v = cbvFourCCtor (fourCctor_c1v0);
v = cbvFourCCtor (fourCctor_c0v1);
v = cbvFourCCtor (fourCctor_c1v1);
/* v = cbvTwoMCtor (twoMctor); */ // This is illegal, cctor is deleted
v = cbvTwoMCtorAndCCtor (twoMctorAndCctor);
/* stop here */
return 0;
}