blob: 36a7903234adf883274ac1ef565ecfa743969382 [file] [log] [blame]
/* PR c++/61339 - add mismatch between struct and class
Test to verify that -Wmismatched-tags is issued for declarations
of the same class using different class-ids.
{ dg-do compile }
{ dg-options "-Wmismatched-tags" } */
namespace Classes
{
class A;
class A;
struct B;
struct B;
union C;
union C;
struct D; // { dg-warning "Classes::D' declared with a mismatched class-key 'struct'" }
class D { }; // { dg-message "Classes::D' defined as 'class' here" }
class E; // { dg-warning "Classes::E' declared with a mismatched class-key 'class'" }
struct E { }; // { dg-message "Classes::E' defined as 'struct' here" }
class D;
struct E;
class D;
struct E;
struct D; // { dg-warning "Classes::D' declared with a mismatched class-key" }
class E; // { dg-warning "Classes::E' declared with a mismatched class-key" }
class F; // { dg-message "Classes::F' first declared as 'class' here" }
class F;
struct G { }; // { dg-message "Classes::G' defined as 'struct' here" }
} // namespace Classes
namespace Classes
{
class A;
struct B;
union C;
class D;
struct E;
struct F; // { dg-warning "Classes::F' declared with a mismatched class-key" }
struct G;
}
// Verify that the correct hint is provided, one to remove the class-key
// when it's redundant, and one to (only) replace it with the correct one
// when it's needed to disambiguate the reference to the class type.
namespace RemoveOrReplace
{
struct Func;
class Func; // { dg-warning "RemoveOrReplace::Func' declared with a mismatched class-key 'class'" }
// { dg-message "replace the class-key with 'struct'" "hint to remove" { target *-*-* } .-1 }
void Func ();
class Func; // { dg-warning "RemoveOrReplace::Func' declared with a mismatched class-key 'class'" }
// { dg-message "replace the class-key with 'struct'" "hint to replace" { target *-*-* } .-1 }
class Var;
struct Var; // { dg-warning "RemoveOrReplace::Var' declared with a mismatched class-key 'struct'" }
// { dg-message "replace the class-key with 'class'" "hint to remove" { target *-*-* } .-1 }
void f (struct Var*); // { dg-warning "RemoveOrReplace::Var' declared with a mismatched class-key 'struct'" }
// { dg-message "remove the class-key or replace it with 'class'" "hint to remove" { target *-*-* } .-1 }
int Var;
struct Var; // { dg-warning "RemoveOrReplace::Var' declared with a mismatched class-key 'struct'" }
// { dg-message "replace the class-key with 'class'" "hint to replace" { target *-*-* } .-1 }
}
namespace GlobalObjects
{
class A; // { dg-message "'GlobalObjects::A' first declared as 'class' here" }
struct B; // { dg-message "'GlobalObjects::B' first declared as 'struct' here" }
class C { }; // { dg-message "'GlobalObjects::C' defined as 'class' here" }
extern A a0;
extern class A a1;
extern class A a2;
extern B b0;
extern struct B b1;
extern struct B b2;
extern struct A a3; // { dg-warning "GlobalObjects::A' declared with a mismatched class-key" }
extern class A a4;
extern class B b3; // { dg-warning "GlobalObjects::B' declared with a mismatched class-key" }
extern struct B b4;
extern struct C c[]; // { dg-warning "GlobalObjects::C' declared with a mismatched class-key" }
// { dg-message "remove the class-key or replace it with 'class'" "hint to remove" { target *-*-* } .-1 }
extern char
arr[sizeof (struct C)]; // { dg-warning "GlobalObjects::C' declared with a mismatched class-key" }
// { dg-message "remove the class-key or replace it with 'class'" "hint to remove" { target *-*-* } .-1 }
} // namespace GlobalObjects
namespace LocalObjects
{
class A; // { dg-message "LocalObjects::A' first declared as 'class' here" }
struct B; // { dg-message "LocalObjects::B' first declared as 'struct' here" }
void f (A*, B&)
{
class A *a1;
class A *a2;
struct B *b1;
struct B *b2;
struct A *a3; // { dg-warning "LocalObjects::A' declared with a mismatched class-key" }
class A *a4;
class B *b3; // { dg-warning "LocalObjects::B' declared with a mismatched class-key" }
struct B *b4;
}
void g (struct A*); // { dg-warning "LocalObjects::A' declared with a mismatched class-key" }
} // namespace LocalObjects
namespace MemberClasses
{
struct A { struct B; };
struct C { struct D; struct D; struct D { }; };
struct E { class F; class F { }; class F; };
struct G {
struct H; // { dg-message "MemberClasses::G::H' first declared as 'struct' here" }
class H; // { dg-warning "MemberClasses::G::H' declared with a mismatched class-key" }
class I { }; // { dg-message "MemberClasses::G::I' defined as 'class' here" }
struct I; // { dg-warning "MemberClasses::G::I' declared with a mismatched class-key" }
};
} // namespace MemberClasses
namespace DataMembers
{
struct A { struct B *p; };
struct C { struct D *p; struct D *q; struct D { } d; };
struct E { class F &r; class F { } f; class F *p; };
class G; // { dg-message "DataMembers::G' first declared as 'class' here" }
struct H; // { dg-message "DataMembers::H' first declared as 'struct' here" }
struct I {
struct G *p0; // { dg-warning "DataMembers::G' declared with a mismatched class-key" }
class G *p1;
struct H &r0;
class H &r1; // { dg-warning "DataMembers::H' declared with a mismatched class-key" }
class J { }; // { dg-message "DataMembers::I::J' defined as 'class' here" }
struct K { }; // { dg-message "DataMembers::I::K' defined as 'struct' here" }
class J j0;
class K k0; // { dg-warning "DataMembers::I::K' declared with a mismatched class-key" }
struct J j1; // { dg-warning "DataMembers::I::J' declared with a mismatched class-key" }
struct K k1;
};
} // namespace DataMembers
namespace Templates
{
template <int> class A;
template <int> class A;
template <int> struct B;
template <int> struct B;
template <int> union C;
template <int> union C;
template <int> struct D; // { dg-warning "Templates::D\[^\n\r]*' declared with a mismatched class-key" }
template <int>
class D // { dg-message "Templates::D\[^\n\r]*' defined as 'class' here" }
{ public: D (); };
template <int> class E; // { dg-warning "Templates::E\[^\n\r]*' declared with a mismatched class-key" }
template <int>
struct E // { dg-message "Templates::E\[^\n\r]*' defined as 'struct' here" }
{ int i; };
template <int> class D;
template <int> struct E;
template <int>
struct D; // { dg-warning "Templates::D\[^\n\r]*' declared with a mismatched class-key" }
// { dg-message "replace the class-key with 'class'" "hint" { target *-*-* } .-1 }
} // namespace Templates
namespace ExplicitSpecializations
{
template <int> class A;
template <> class A<0>;
template <> struct A<1>;
template <> struct A<1> { };
template <int> struct B;
template <> struct B<0>;
template <> class B<1>;
template <> class B<2> { public: B (); };
template <int> union C;
template <> union C<0>;
template <int> class D;
template <> class D<0>; // { dg-warning "ExplicitSpecializations::D\[^\n\r]*' declared with a mismatched class-key " }
template <>
struct D<0> { }; // { dg-message "ExplicitSpecializations::D\[^\n\r]*' defined as 'struct' here" }
template <int> struct E;
template <> struct E<0>; // { dg-warning "ExplicitSpecializations::E\[^\n\r]*' declared with a mismatched class-key" }
template <>
class E<0> { }; // { dg-message "ExplicitSpecializations::E\[^\n\r]*' defined as 'class' here" }
template <int> struct F;
template <> class F<0> { }; // { dg-message "ExplicitSpecializations::F\[^\n\r]*' defined as 'class' here" }
template <>
struct F<0>; // { dg-warning "ExplicitSpecializations::F\[^\n\r]*' declared with a mismatched class-key" }
} // namespace ExplicitSpecializations
namespace PartialSpecializations
{
template <class> class A;
template <class T> struct A<const T>;
template <class T> struct A<volatile T>;
template <class> struct B;
template <class T> class B<const T>;
template <class T> class B<volatile T>;
template <class> class C { };
template <class T> struct C<const T> { };
template <class T> struct C<volatile T> { };
template <class> struct D { };
template <class T> class D<const T> { };
template <class T> class D<volatile T> { };
template <class> class E;
template <class T>
struct E<const T>; // { dg-message "PartialSpecializations::E<const T>' first declared as 'struct' here" }
template <class T>
class E<const T>; // { dg-warning "PartialSpecializations::E<const T>' declared with a mismatched class-key" }
template <class> class F;
template <class T>
class F<const T>; // { dg-message "PartialSpecializations::F<const T>' first declared as 'class' here" }
template <class T>
struct F<const T>; // { dg-warning "PartialSpecializations::F<const T>' declared with a mismatched class-key" }
} // namespace PartialSpecializations
namespace Classes
{
struct G;
class G; // { dg-warning "Classes::G' declared with a mismatched class-key 'class'" }
}