diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7b7f692228b..383366743a7 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2004-01-29 Giovanni Bajo + + * g++.dg/tc1: New directory. + * g++.dg/tc1/dr108.C, g++.dg/tc1/dr128.C, g++.dg/tc1/dr147.C, + g++.dg/tc1/dr179.C, g++.dg/tc1/dr1.C, g++.dg/tc1/dr213.C, + g++.dg/tc1/dr74.C, g++.dg/tc1/dr90.C, g++.dg/tc1/dr127.C, + g++.dg/tc1/dr137.C, g++.dg/tc1/dr164.C, g++.dg/tc1/dr185.C, + g++.dg/tc1/dr20.C, g++.dg/tc1/dr52.C, g++.dg/tc1/dr85.C: New tests. + 2004-01-28 Giovanni Bajo * g++.dg/parse/error11.C: New test. diff --git a/gcc/testsuite/g++.dg/tc1/dr1.C b/gcc/testsuite/g++.dg/tc1/dr1.C new file mode 100644 index 00000000000..9196218f119 --- /dev/null +++ b/gcc/testsuite/g++.dg/tc1/dr1.C @@ -0,0 +1,18 @@ +// { dg-do compile } +// Origin: Giovanni Bajo +// DR1: What if two using-declarations refer to the same function but the +// declarations introduce different default-arguments? + +namespace A { + extern "C" void f(int = 5); +} +namespace B { + extern "C" void f(int = 5); +} +using A::f; +using B::f; + +void use() { + f(3); + f(); // { dg-error "" "" { xfail *-*-* } } +} diff --git a/gcc/testsuite/g++.dg/tc1/dr108.C b/gcc/testsuite/g++.dg/tc1/dr108.C new file mode 100644 index 00000000000..f7848ec74b6 --- /dev/null +++ b/gcc/testsuite/g++.dg/tc1/dr108.C @@ -0,0 +1,15 @@ +// { dg-do compile } +// Origin: Giovanni Bajo +// DR108: Are classes nested in templates dependent? + +template struct S { + struct I1 { + typedef int X; + }; + struct I2 : public I1 { + X x; // { dg-error "does not name a type" } + }; +}; + +// Additional notes on the same line are allowed +// { dg-error "" "" { target *-*-* } 10 } diff --git a/gcc/testsuite/g++.dg/tc1/dr127.C b/gcc/testsuite/g++.dg/tc1/dr127.C new file mode 100644 index 00000000000..4dddc6d7778 --- /dev/null +++ b/gcc/testsuite/g++.dg/tc1/dr127.C @@ -0,0 +1,28 @@ +// { dg-do link } +// Origin: Giovanni Bajo +// DR127: Ambiguity in description of matching deallocation function + +#include +#include + +struct A +{ + // placement new, but can be called through normal new syntax. + void* operator new(std::size_t size, float = 0.0f) + { + return ::operator new(size); + } + + // The matching deallocation function must be called, which means + // the placemente delete. + void operator delete(void*); + void operator delete(void*, float) {} + + A() + { throw 5; } +}; + +int main() +{ + (void)new A; +} diff --git a/gcc/testsuite/g++.dg/tc1/dr128.C b/gcc/testsuite/g++.dg/tc1/dr128.C new file mode 100644 index 00000000000..4dd78d57f5c --- /dev/null +++ b/gcc/testsuite/g++.dg/tc1/dr128.C @@ -0,0 +1,17 @@ +// { dg-do run } +// Origin: Giovanni Bajo +// DR128: Casting between enum types + +extern "C" void abort(void); + +enum E1 { BLACK = 0, RED = 1 }; +enum E2 { WHITE = 0, YELLOW = 1}; + +int main(void) +{ + E1 e1 = RED; + E2 e2 = static_cast(e1); + if (e2 != YELLOW) + abort(); + return 0; +} diff --git a/gcc/testsuite/g++.dg/tc1/dr137.C b/gcc/testsuite/g++.dg/tc1/dr137.C new file mode 100644 index 00000000000..bc1beb021bb --- /dev/null +++ b/gcc/testsuite/g++.dg/tc1/dr137.C @@ -0,0 +1,13 @@ +// { dg-do compile } +// Origin: Giovanni Bajo +// DR137: static_cast of cv void* + +struct A; + +const void* v; + +void foo(void) +{ + (void)static_cast(v); + (void)static_cast(v); // { dg-error "" "static_cast cannot remove cv qualifiers" } +} diff --git a/gcc/testsuite/g++.dg/tc1/dr147.C b/gcc/testsuite/g++.dg/tc1/dr147.C new file mode 100644 index 00000000000..268f9f95e58 --- /dev/null +++ b/gcc/testsuite/g++.dg/tc1/dr147.C @@ -0,0 +1,31 @@ +// { dg-do compile } +// Origin: Giovanni Bajo +// DR147: Naming the constructor + +namespace N1 { + +struct A { A(); }; +struct B: public A { B(); }; + +A::A() { } +B::B() { } + +B::A ba; +A::A a; // { dg-error "" "the injected-class-name can never be found through qualified lookup" { xfail *-*-* } } + +} + +namespace N2 { + +// This is nasty: if we allowed the injected-class-name to be looked as a +// qualified type, then the following code would be well-formed. Basically +// the last line is defining the static member (with redundant parenthesis). +// Instead, it should be rejected as a malformed constructor declaration. + +template struct A { + template A(T2); + static A x; +}; +template<> A::A(A::x); // { dg-error "" "this is an invalid declaration of the constructor" { xfail *-*-* } } + +} diff --git a/gcc/testsuite/g++.dg/tc1/dr164.C b/gcc/testsuite/g++.dg/tc1/dr164.C new file mode 100644 index 00000000000..026ec096fb3 --- /dev/null +++ b/gcc/testsuite/g++.dg/tc1/dr164.C @@ -0,0 +1,17 @@ +// { dg-do link } +// Origin: Giovanni Bajo +// DR164: Overlap between Koenig and normal lookup + +void f(int); + +template void g(T t) { + f(t); +} + +enum E { e }; + +void f(E) {} + +int main() { + g(e); +} diff --git a/gcc/testsuite/g++.dg/tc1/dr179.C b/gcc/testsuite/g++.dg/tc1/dr179.C new file mode 100644 index 00000000000..39e4164d2a9 --- /dev/null +++ b/gcc/testsuite/g++.dg/tc1/dr179.C @@ -0,0 +1,13 @@ +// { dg-do compile } +// Origin: Giovanni Bajo +// DR179: Function pointers and subtraction + +void foo(void); +typedef void (*fp)(void); + +int main() +{ + fp f1 = foo; + fp f2 = foo; + (void)f2-f1; // { dg-error "" "cannot subtract pointers to function" } +} diff --git a/gcc/testsuite/g++.dg/tc1/dr185.C b/gcc/testsuite/g++.dg/tc1/dr185.C new file mode 100644 index 00000000000..2cd4e397f93 --- /dev/null +++ b/gcc/testsuite/g++.dg/tc1/dr185.C @@ -0,0 +1,26 @@ +// { dg-do run } +// Origin: Giovanni Bajo +// DR185: "Named" temporaries and copy elision + +extern "C" void abort(void); + +struct A { + mutable int value; + explicit A(int i) : value(i) {} + void mutate(int i) const { value = i; } +}; + +int foo() { + A const& t = A(1); + A n(t); // can this copy be elided? NO! + t.mutate(2); + return n.value; // can this return 2? NO! +} + +int main() +{ + int x = foo(); + if (x != 1) + abort(); + return 0; +} diff --git a/gcc/testsuite/g++.dg/tc1/dr20.C b/gcc/testsuite/g++.dg/tc1/dr20.C new file mode 100644 index 00000000000..fe586212995 --- /dev/null +++ b/gcc/testsuite/g++.dg/tc1/dr20.C @@ -0,0 +1,34 @@ +// { dg-do run } +// Origin: Giovanni Bajo +// DR20: Some clarifications needed for 12.8 para 15 + +extern "C" void printf(const char*, ...); +extern "C" void abort(void); + +int count = 0; + +class Thing { +public: + Thing() { + } + ~Thing() { + } + Thing(const Thing&) + { + count += 1; + } +}; + +Thing f() { + Thing t; + return t; +} + +int main(void) +{ + Thing t2 = f(); + printf("%d %x\n", count, &t2); + if (count != 0) + abort(); + return 0; +} diff --git a/gcc/testsuite/g++.dg/tc1/dr213.C b/gcc/testsuite/g++.dg/tc1/dr213.C new file mode 100644 index 00000000000..a8961655b7a --- /dev/null +++ b/gcc/testsuite/g++.dg/tc1/dr213.C @@ -0,0 +1,27 @@ +// { dg-do compile } +// Origin: Giovanni Bajo +// DR213: Lookup in dependent base classes + +// We should emit an error at *instantiation* time because g(t) can't be +// resolved to any function. + +template struct A : T { + void h(T t) { + f(t); + g(t); // { dg-error "" "" { xfail *-*-* } } + } +}; + +struct B { + void f(B); + void g(B) {}; +}; + +void f(B) {} + +int main() +{ + A ab; // { dg-error "" "" { xfail *-*-* } } + B b; + ab.h(b); +} diff --git a/gcc/testsuite/g++.dg/tc1/dr52.C b/gcc/testsuite/g++.dg/tc1/dr52.C new file mode 100644 index 00000000000..b0896d73fa7 --- /dev/null +++ b/gcc/testsuite/g++.dg/tc1/dr52.C @@ -0,0 +1,34 @@ +// { dg-do compile } +// Origin: Giovanni Bajo +// DR52: Non-static members, member selection and access checking + +struct A +{ + void foo(void); +}; + +struct B +{ +private: + void foo(void); +}; + +struct B1 : B {}; +struct B2 : B {}; + +struct C +{ + void foo(void); +}; + +struct D : private C {}; + +struct X: A, B1, B2, D +{ +public: + void bar(void) + { + this->B::foo(); // { dg-error "" } + this->C::foo(); // { dg-error "" } + } +}; diff --git a/gcc/testsuite/g++.dg/tc1/dr74.C b/gcc/testsuite/g++.dg/tc1/dr74.C new file mode 100644 index 00000000000..155c7981b52 --- /dev/null +++ b/gcc/testsuite/g++.dg/tc1/dr74.C @@ -0,0 +1,9 @@ +// { dg-do compile } +// Origin: Giovanni Bajo +// DR74: Enumeration value in direct-new-declarator + +struct A {}; +enum E1 { COUNT = 10 }; + +A* a = new A[COUNT]; + diff --git a/gcc/testsuite/g++.dg/tc1/dr85.C b/gcc/testsuite/g++.dg/tc1/dr85.C new file mode 100644 index 00000000000..31dde8cbb5d --- /dev/null +++ b/gcc/testsuite/g++.dg/tc1/dr85.C @@ -0,0 +1,8 @@ +// { dg-do compile } +// Origin: Giovanni Bajo +// DR85: Redeclaration of member class + +struct Base { + struct Data {}; + struct Data; // { dg-error "" "redeclaration of nested class is invalid" { xfail *-*-* } } +}; diff --git a/gcc/testsuite/g++.dg/tc1/dr90.C b/gcc/testsuite/g++.dg/tc1/dr90.C new file mode 100644 index 00000000000..b6ec24cc849 --- /dev/null +++ b/gcc/testsuite/g++.dg/tc1/dr90.C @@ -0,0 +1,20 @@ +// { dg-do compile } +// Origin: Giovanni Bajo +// DR90: Should the enclosing class be an "associated class" too? + +struct A { + union U {}; + friend void f(U); +}; + +struct B { + struct S {}; + friend void f(S); +}; + +int main() { + A::U u; + f(u); + B::S s; + f(s); +}