summaryrefslogtreecommitdiff
path: root/gcc/testsuite
diff options
context:
space:
mode:
authorbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2010-11-29 13:20:50 +0000
committerbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2010-11-29 13:20:50 +0000
commite06eeab986ad016975b1380e3cc9556ce382f1d8 (patch)
tree14f34f69902595b73b37712155769ec5ea51680e /gcc/testsuite
parent1852c1a4d9758d3dc7e90e692c891ee62013a47a (diff)
downloadgcc-e06eeab986ad016975b1380e3cc9556ce382f1d8.tar.gz
2010-11-29 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 167237 git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@167240 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/testsuite')
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr46637.c11
-rwxr-xr-xgcc/testsuite/gcc.dg/dll-8.c14
-rw-r--r--gcc/testsuite/gcc.dg/lto/20101125-1_0.c24
-rw-r--r--gcc/testsuite/gcc.dg/lto/20101125-1_1.c17
-rw-r--r--gcc/testsuite/gcc.dg/pr46585.c11
-rw-r--r--gcc/testsuite/gcc.dg/pr46647.c29
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-vzeroupper-20.c13
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-vzeroupper-21.c14
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-vzeroupper-22.c18
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-vzeroupper-23.c13
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-vzeroupper-24.c38
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-vzeroupper-25.c14
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-vzeroupper-26.c16
-rw-r--r--gcc/testsuite/gcc.target/i386/pr46647.c44
-rw-r--r--gcc/testsuite/gfortran.dg/arith_divide.f15
-rw-r--r--gcc/testsuite/gfortran.dg/arith_divide_no_check.f17
-rw-r--r--gcc/testsuite/gfortran.dg/old_style_init.f9015
-rw-r--r--gcc/testsuite/gfortran.dg/pr46519-1.f46
-rw-r--r--gcc/testsuite/gfortran.dg/pr46665.f9036
-rw-r--r--gcc/testsuite/gfortran.dg/proc_ptr_comp_pass_7.f9065
-rw-r--r--gcc/testsuite/gfortran.dg/realloc_on_assign_1.f0380
-rw-r--r--gcc/testsuite/gfortran.dg/realloc_on_assign_2.f03143
-rw-r--r--gcc/testsuite/gfortran.dg/select_type_19.f0323
-rw-r--r--gcc/testsuite/obj-c++.dg/exceptions-1.mm42
-rw-r--r--gcc/testsuite/obj-c++.dg/exceptions-2.mm54
-rw-r--r--gcc/testsuite/obj-c++.dg/exceptions-3.mm114
-rw-r--r--gcc/testsuite/obj-c++.dg/exceptions-4.mm64
-rw-r--r--gcc/testsuite/obj-c++.dg/exceptions-5.mm114
-rw-r--r--gcc/testsuite/obj-c++.dg/ivar-problem-1.mm66
-rw-r--r--gcc/testsuite/obj-c++.dg/property/at-property-24.mm118
-rw-r--r--gcc/testsuite/obj-c++.dg/property/at-property-25.mm87
-rw-r--r--gcc/testsuite/obj-c++.dg/protocol-qualifier-1.mm33
-rw-r--r--gcc/testsuite/obj-c++.dg/protocol-qualifier-2.mm31
-rw-r--r--gcc/testsuite/objc.dg/exceptions-1.m42
-rw-r--r--gcc/testsuite/objc.dg/exceptions-2.m52
-rw-r--r--gcc/testsuite/objc.dg/exceptions-3.m114
-rw-r--r--gcc/testsuite/objc.dg/exceptions-4.m64
-rw-r--r--gcc/testsuite/objc.dg/exceptions-5.m114
-rw-r--r--gcc/testsuite/objc.dg/ivar-problem-1.m65
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-24.m118
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-25.m87
-rw-r--r--gcc/testsuite/objc.dg/protocol-qualifier-1.m33
-rw-r--r--gcc/testsuite/objc.dg/protocol-qualifier-2.m31
43 files changed, 2159 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr46637.c b/gcc/testsuite/gcc.c-torture/compile/pr46637.c
new file mode 100644
index 00000000000..c765949e8ad
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr46637.c
@@ -0,0 +1,11 @@
+/* PR middle-end/46637 */
+
+struct S { int s[5]; } *p;
+
+void
+foo (long x)
+{
+ long a = x == 1 ? 4L : 1L;
+ asm ("" : "+m" (p->s[a]));
+ p->s[0]++;
+}
diff --git a/gcc/testsuite/gcc.dg/dll-8.c b/gcc/testsuite/gcc.dg/dll-8.c
new file mode 100755
index 00000000000..98afba8d0d2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dll-8.c
@@ -0,0 +1,14 @@
+/* { dg-do compile { target i?86-pc-cygwin } } */
+/* { dg-do compile { target i?86-*-mingw* x86_64-*-mingw*} } */
+/* { dg-options "-O3 -fwhole-program" } */
+/* { dg-final { scan-assembler "foo1" } } */
+/* { dg-final { scan-assembler-not "foo2" } } */
+/* { dg-final { scan-assembler "doo1" } } */
+/* { dg-final { scan-assembler-not "doo2" } } */
+
+__declspec(dllexport) int doo1 = 2;
+int doo2 = 3;
+__declspec(dllexport) int foo1 (void) { return 0; }
+int foo2 (void) { return 1; }
+int main() { return 0; }
+
diff --git a/gcc/testsuite/gcc.dg/lto/20101125-1_0.c b/gcc/testsuite/gcc.dg/lto/20101125-1_0.c
new file mode 100644
index 00000000000..662dd243dc7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/20101125-1_0.c
@@ -0,0 +1,24 @@
+/* { dg-lto-do link } */
+
+struct X {
+ int i;
+};
+
+struct W {
+ struct U *p;
+ struct X *q;
+};
+
+struct U {
+ struct W a[1];
+};
+
+void foo(struct U *ptr)
+{
+ ptr->a[0].p = 0;
+}
+
+int main(void)
+{
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/lto/20101125-1_1.c b/gcc/testsuite/gcc.dg/lto/20101125-1_1.c
new file mode 100644
index 00000000000..2924e3f26be
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/20101125-1_1.c
@@ -0,0 +1,17 @@
+struct X {
+ char i;
+};
+
+struct W {
+ struct U *p;
+ struct X *q;
+};
+
+struct U {
+ struct W a[1];
+};
+
+void bar(struct U *ptr)
+{
+ ptr->a[0].p = 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pr46585.c b/gcc/testsuite/gcc.dg/pr46585.c
new file mode 100644
index 00000000000..32befdfb069
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr46585.c
@@ -0,0 +1,11 @@
+/* { dg-do compile { target powerpc*-*-* ia64-*-* i?86-*-* x86_64-*-* } } */
+/* { dg-options "-fno-dce -fschedule-insns -fselective-scheduling" } */
+void
+foo (void)
+{
+ switch (0)
+ {
+ default:
+ break;
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/pr46647.c b/gcc/testsuite/gcc.dg/pr46647.c
new file mode 100644
index 00000000000..ab85e17a081
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr46647.c
@@ -0,0 +1,29 @@
+/* PR middle-end/46647 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int a;
+
+int
+func1 (void)
+{
+ __builtin_memset (&a, -1, sizeof (a));
+ return 0;
+}
+
+int
+func2 (void)
+{
+ __builtin_memset (&a, 123, sizeof (a));
+ return 0;
+}
+
+int
+func3 (void)
+{
+ __builtin_memset (&a, 0, sizeof (a));
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-not "memset" "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx-vzeroupper-20.c b/gcc/testsuite/gcc.target/i386/avx-vzeroupper-20.c
new file mode 100644
index 00000000000..33010839e9c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx-vzeroupper-20.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -mavx -mtune=generic -dp" } */
+
+extern void free (void *);
+void
+bar (void *ncstrp)
+{
+ if(ncstrp==((void *)0))
+ return;
+ free(ncstrp);
+}
+
+/* { dg-final { scan-assembler-not "avx_vzeroupper" } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx-vzeroupper-21.c b/gcc/testsuite/gcc.target/i386/avx-vzeroupper-21.c
new file mode 100644
index 00000000000..6dea0552fa3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx-vzeroupper-21.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx -mtune=generic -dp" } */
+
+extern void exit (int) __attribute__ ((__noreturn__));
+
+int
+foo (int i)
+{
+ if (i == 0)
+ exit (1);
+ return 0;
+}
+
+/* { dg-final { scan-assembler-not "avx_vzeroupper" } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx-vzeroupper-22.c b/gcc/testsuite/gcc.target/i386/avx-vzeroupper-22.c
new file mode 100644
index 00000000000..b4e4a5806b0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx-vzeroupper-22.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx -mtune=generic -dp" } */
+
+extern void exit (int) __attribute__ ((__noreturn__));
+extern void bar (void);
+
+int
+foo (int i)
+{
+ if (i == 0)
+ {
+ bar ();
+ exit (1);
+ }
+ return 0;
+}
+
+/* { dg-final { scan-assembler-not "avx_vzeroupper" } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx-vzeroupper-23.c b/gcc/testsuite/gcc.target/i386/avx-vzeroupper-23.c
new file mode 100644
index 00000000000..66df800e919
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx-vzeroupper-23.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx -mtune=generic -dp" } */
+
+extern void fatal (void) __attribute__ ((__noreturn__));
+extern void exit (int) __attribute__ ((__noreturn__));
+
+void
+fatal (void)
+{
+ exit (1);
+}
+
+/* { dg-final { scan-assembler-not "avx_vzeroupper" } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx-vzeroupper-24.c b/gcc/testsuite/gcc.target/i386/avx-vzeroupper-24.c
new file mode 100644
index 00000000000..4fdd374467e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx-vzeroupper-24.c
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx -mtune=generic -dp" } */
+
+typedef struct bitmap_element_def {
+ struct bitmap_element_def *next;
+ unsigned int indx;
+} bitmap_element;
+typedef struct bitmap_head_def {
+ bitmap_element *first;
+ bitmap_element *current;
+ unsigned int indx;
+} bitmap_head;
+typedef struct bitmap_head_def *bitmap;
+typedef const struct bitmap_head_def *const_bitmap;
+extern void bar (void) __attribute__ ((__noreturn__));
+unsigned char
+bitmap_and_compl_into (bitmap a, const_bitmap b)
+{
+ bitmap_element *a_elt = a->first;
+ const bitmap_element *b_elt = b->first;
+ if (a == b)
+ {
+ if ((!(a)->first))
+ return 0;
+ else
+ return 1;
+ }
+ while (a_elt && b_elt)
+ {
+ if (a_elt->indx < b_elt->indx)
+ a_elt = a_elt->next;
+ }
+ if (a->indx == a->current->indx)
+ bar ();
+ return 0;
+}
+
+/* { dg-final { scan-assembler-not "avx_vzeroupper" } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx-vzeroupper-25.c b/gcc/testsuite/gcc.target/i386/avx-vzeroupper-25.c
new file mode 100644
index 00000000000..5ef49c7d32d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx-vzeroupper-25.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O0 -mavx -mtune=generic -dp" } */
+
+#include <immintrin.h>
+
+extern __m256 x, y;
+
+void
+foo ()
+{
+ x = y;
+}
+
+/* { dg-final { scan-assembler-not "avx_vzeroupper" } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx-vzeroupper-26.c b/gcc/testsuite/gcc.target/i386/avx-vzeroupper-26.c
new file mode 100644
index 00000000000..96e9190fa81
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx-vzeroupper-26.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-Os -mavx -mtune=generic -dp" } */
+
+#include <immintrin.h>
+
+extern __m256 x, y;
+extern void (*bar) (void);
+
+void
+foo ()
+{
+ x = y;
+ bar ();
+}
+
+/* { dg-final { scan-assembler-not "avx_vzeroupper" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr46647.c b/gcc/testsuite/gcc.target/i386/pr46647.c
new file mode 100644
index 00000000000..c7e1542873b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr46647.c
@@ -0,0 +1,44 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mtune=generic" } */
+
+char a[5];
+int
+func1 (void)
+{
+ __builtin_memset (a,-1,sizeof (a));
+ return 0;
+}
+
+int a2[5];
+int
+func2 (void)
+{
+ __builtin_memset (a2,-1,sizeof (a2));
+ return 0;
+}
+
+char a3[5];
+int
+func3 (void)
+{
+ __builtin_memset (a3,0x8fffffff,sizeof (a3));
+ return 0;
+}
+
+char a4[5];
+int
+func4 (void)
+{
+ __builtin_memset (a4,0x8fffff00,sizeof (a4));
+ return 0;
+}
+
+int a5[5];
+int
+func5 (void)
+{
+ __builtin_memset (a5,0x8fffffff,sizeof (a5));
+ return 0;
+}
+
+/* { dg-final { scan-assembler-not "call\[\\t \]*_?memset" } } */
diff --git a/gcc/testsuite/gfortran.dg/arith_divide.f b/gcc/testsuite/gfortran.dg/arith_divide.f
new file mode 100644
index 00000000000..5140e2c7708
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/arith_divide.f
@@ -0,0 +1,15 @@
+! { dg-do compile }
+! This test executes all code paths in gfc_arith_divide
+! when executed along with it's companion test
+! arith_divide_no_check.f
+ implicit none
+ integer i,j
+ real a,b
+ complex c,d
+ i = 10/40
+ j = 10/0! { dg-error "Division by zero at" }
+ a = 10.0/40.0
+ b = 10.0/0.0! { dg-error "Division by zero at" }
+ c = (1.0,1.0)/(10.0,40.0) ! Not division by zero
+ d = (1.0,10.)/(0.0,0.0)! { dg-error "Division by zero at" }
+ end
diff --git a/gcc/testsuite/gfortran.dg/arith_divide_no_check.f b/gcc/testsuite/gfortran.dg/arith_divide_no_check.f
new file mode 100644
index 00000000000..82ef1c35990
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/arith_divide_no_check.f
@@ -0,0 +1,17 @@
+! { dg-do compile }
+! { dg-options "-fno-range-check" }
+! This test executes all code paths in gfc_arith_divide
+! when executed along with it's companion test
+! arith_divide.f
+
+ implicit none
+ integer i,j
+ real a,b
+ complex c,d
+ i = 10/40
+ j = 10/0! { dg-error "Division by zero at" }
+ a = 10.0/40.0
+ b = 10.0/0.0
+ c = (1.0,1.0)/(10.0,40.0)
+ d = (1.0,10.)/(0.0,0.0)
+ end
diff --git a/gcc/testsuite/gfortran.dg/old_style_init.f90 b/gcc/testsuite/gfortran.dg/old_style_init.f90
new file mode 100644
index 00000000000..5319917f7a8
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/old_style_init.f90
@@ -0,0 +1,15 @@
+!{ dg-do compile }
+! this routine tests all the execution paths
+! through the routine known as match_old_style_init()
+! it does not make sense in any other context !!
+ subroutine sub1(Z) !{ dg-error "DATA attribute conflicts" }
+ integer Z/10/!{ dg-error "DATA"}
+ end
+ pure function pi(k)
+ integer ,intent(in) :: k
+ integer i / 10 / !{ dg-error "Initialization at " }
+ pi=3.0
+ end function pi
+ subroutine sub2
+ integer I / /!{ dg-error "Syntax error in DATA" }
+ end
diff --git a/gcc/testsuite/gfortran.dg/pr46519-1.f b/gcc/testsuite/gfortran.dg/pr46519-1.f
new file mode 100644
index 00000000000..51c64b87d28
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr46519-1.f
@@ -0,0 +1,46 @@
+! { dg-do compile { target i?86-*-* x86_64-*-* } }
+! { dg-options "-O3 -mavx -mvzeroupper -mtune=generic -dp" }
+
+ PROGRAM MG3XDEMO
+ INTEGER LM, NM, NV, NR, NIT
+
+
+ PARAMETER( LM=7 )
+C PARAMETER( NIT=40 )
+ PARAMETER( NM=2+2**LM, NV=NM**3 )
+ PARAMETER( NR = (8*(NM**3+NM**2+5*NM-23+7*LM))/7 )
+C
+C
+C If commented line is used than there is no penalty
+C COMMON /X/ U, V, R, A, C, IR, MM
+ COMMON /X/ A, C, IR, MM
+ REAL*8 A(0:3),C(0:3)
+
+ INTEGER IT, N
+ INTEGER LMI, MTIME, NTIMES
+C
+ READ *,LMI
+ READ *,NIT
+ READ *,NTIMES
+ READ *,U0
+
+ READ 9004, A
+ READ 9004, C
+9004 FORMAT (4D8.0)
+
+ DO I = 0, 3
+ A(I) = A(I)/3.0D0
+ C(I) = C(I)/64.0D0
+ ENDDO
+C
+ N = 2 + 2**LMI
+
+ WRITE(6,7)N-2,N-2,N-2,NIT
+ 6 FORMAT( I4, 2E19.12)
+ 7 FORMAT(/,' KERNEL B: SOLVING A POISSON PROBLEM ON A ',I6,' BY ',
+ > I6,' BY ',I6,' GRID,',/,' USING ',I6,' MULTIGRID ITERATIONS.',/)
+C
+ STOP
+ END
+
+! { dg-final { scan-assembler-times "avx_vzeroupper" 1 } }
diff --git a/gcc/testsuite/gfortran.dg/pr46665.f90 b/gcc/testsuite/gfortran.dg/pr46665.f90
new file mode 100644
index 00000000000..c59e7eaf5d8
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr46665.f90
@@ -0,0 +1,36 @@
+! { dg-do run }
+! { dg-options "-fipa-pta -fno-tree-ccp -fno-tree-forwprop -g" }
+
+program main
+ implicit none
+ call test ((/ 3, 4, 5 /), f ((/ 3, 4, 5 /)))
+contains
+ subroutine test (expected, x)
+ integer, dimension (:,:,:) :: x
+ integer, dimension (3) :: expected
+ integer :: i, i1, i2, i3
+ do i = 1, 3
+ if (size (x, i) .ne. expected (i)) call abort
+ end do
+ do i1 = 1, expected (1)
+ do i2 = 1, expected (2)
+ do i3 = 1, expected (3)
+ if (x (i1, i2, i3) .ne. i1 + i2 * 10 + i3 * 100) call abort
+ end do
+ end do
+ end do
+ end subroutine test
+
+ function f (x)
+ integer, dimension (3) :: x
+ integer, dimension (x(1), x(2), x(3)) :: f
+ integer :: i1, i2, i3
+ do i1 = 1, x(1)
+ do i2 = 1, x(2)
+ do i3 = 1, x(3)
+ f (i1, i2, i3) = i1 + i2 * 10 + i3 * 100
+ end do
+ end do
+ end do
+ end function f
+end program main
diff --git a/gcc/testsuite/gfortran.dg/proc_ptr_comp_pass_7.f90 b/gcc/testsuite/gfortran.dg/proc_ptr_comp_pass_7.f90
new file mode 100644
index 00000000000..a15018db345
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/proc_ptr_comp_pass_7.f90
@@ -0,0 +1,65 @@
+! { dg-do compile }
+!
+! PR 46662: [OOP] gfortran accepts "CALL polymorphic%abstract_type%ppc()"
+!
+! Contributed by Wolfgang Kilian <kilian@hep.physik.uni-siegen.de>
+! cf. http://groups.google.com/group/comp.lang.fortran/browse_thread/thread/a0857fa4a692d518
+
+module types
+ implicit none
+
+ type, abstract :: base_t
+ integer :: i = 0
+ procedure(base_write_i), pointer :: write_procptr
+ contains
+ procedure :: write_i => base_write_i
+ end type base_t
+
+ type, extends (base_t) :: t
+ end type t
+
+contains
+
+ subroutine base_write_i (obj)
+ class (base_t), intent(in) :: obj
+ print *, obj%i
+ end subroutine base_write_i
+
+end module types
+
+
+program main
+ use types
+ implicit none
+
+ type(t) :: obj
+
+ print *, "Direct printing"
+ obj%i = 1
+ print *, obj%i
+
+ print *, "Direct printing via parent"
+ obj%base_t%i = 2
+ print *, obj%base_t%i
+
+ print *, "Printing via TBP"
+ obj%i = 3
+ call obj%write_i
+
+ print *, "Printing via parent TBP"
+ obj%base_t%i = 4
+ call obj%base_t%write_i ! { dg-error "is of ABSTRACT type" }
+
+ print *, "Printing via OBP"
+ obj%i = 5
+ obj%write_procptr => base_write_i
+ call obj%write_procptr
+
+ print *, "Printing via parent OBP"
+ obj%base_t%i = 6
+ obj%base_t%write_procptr => base_write_i
+ call obj%base_t%write_procptr ! { dg-error "is of ABSTRACT type" }
+
+end program main
+
+! { dg-final { cleanup-modules "types" } }
diff --git a/gcc/testsuite/gfortran.dg/realloc_on_assign_1.f03 b/gcc/testsuite/gfortran.dg/realloc_on_assign_1.f03
new file mode 100644
index 00000000000..e80084d97f2
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/realloc_on_assign_1.f03
@@ -0,0 +1,80 @@
+! { dg-do run }
+! Tests the patch that implements F2003 automatic allocation and
+! reallocation of allocatable arrays on assignment.
+!
+! Contributed by Paul Thomas <pault@gcc.gnu.org>
+!
+ integer(4), allocatable :: a(:), b(:), c(:,:)
+ integer(4) :: j
+ integer(4) :: src(2:5) = [11,12,13,14]
+ integer(4) :: mat(2:3,5:6)
+ character(4), allocatable :: chr1(:)
+ character(4) :: chr2(2) = ["abcd", "wxyz"]
+
+ allocate(a(1))
+ mat = reshape (src, [2,2])
+
+ a = [4,3,2,1]
+ if (size(a, 1) .ne. 4) call abort
+ if (any (a .ne. [4,3,2,1])) call abort
+
+ a = [((42 - i), i = 1, 10)]
+ if (size(a, 1) .ne. 10) call abort
+ if (any (a .ne. [((42 - i), i = 1, 10)])) call abort
+
+ b = a
+ if (size(b, 1) .ne. 10) call abort
+ if (any (b .ne. a)) call abort
+
+ a = [4,3,2,1]
+ if (size(a, 1) .ne. 4) call abort
+ if (any (a .ne. [4,3,2,1])) call abort
+
+ a = b
+ if (size(a, 1) .ne. 10) call abort
+ if (any (a .ne. [((42 - i), i = 1, 10)])) call abort
+
+ j = 20
+ a = [(i, i = 1, j)]
+ if (size(a, 1) .ne. j) call abort
+ if (any (a .ne. [(i, i = 1, j)])) call abort
+
+ a = foo (15)
+ if (size(a, 1) .ne. 15) call abort
+ if (any (a .ne. [((i + 15), i = 1, 15)])) call abort
+
+ a = src
+ if (lbound(a, 1) .ne. lbound(src, 1)) call abort
+ if (ubound(a, 1) .ne. ubound(src, 1)) call abort
+ if (any (a .ne. [11,12,13,14])) call abort
+
+ k = 7
+ a = b(k:8)
+ if (lbound(a, 1) .ne. lbound (b(k:8), 1)) call abort
+ if (ubound(a, 1) .ne. ubound (b(k:8), 1)) call abort
+ if (any (a .ne. [35,34])) call abort
+
+ c = mat
+ if (any (lbound (c) .ne. lbound (mat))) call abort
+ if (any (ubound (c) .ne. ubound (mat))) call abort
+ if (any (c .ne. mat)) call abort
+
+ deallocate (c)
+ c = mat(2:,:)
+ if (any (lbound (c) .ne. lbound (mat(2:,:)))) call abort
+
+ chr1 = chr2(2:1:-1)
+ if (lbound(chr1, 1) .ne. 1) call abort
+ if (any (chr1 .ne. chr2(2:1:-1))) call abort
+
+ b = c(1, :) + c(2, :)
+ if (lbound(b, 1) .ne. lbound (c(1, :) + c(2, :), 1)) call abort
+ if (any (b .ne. c(1, :) + c(2, :))) call abort
+contains
+ function foo (n) result(res)
+ integer(4), allocatable, dimension(:) :: res
+ integer(4) :: n
+ allocate (res(n))
+ res = [((i + 15), i = 1, n)]
+ end function foo
+end
diff --git a/gcc/testsuite/gfortran.dg/realloc_on_assign_2.f03 b/gcc/testsuite/gfortran.dg/realloc_on_assign_2.f03
new file mode 100644
index 00000000000..d2a63318f85
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/realloc_on_assign_2.f03
@@ -0,0 +1,143 @@
+! { dg-do run }
+! Tests the patch that implements F2003 automatic allocation and
+! reallocation of allocatable arrays on assignment. The tests
+! below were generated in the final stages of the development of
+! this patch.
+!
+! Contributed by Dominique Dhumieres <dominiq@lps.ens.fr>
+! and Tobias Burnus <burnus@gcc.gnu.org>
+!
+ integer :: nglobal
+ call test1
+ call test2
+ call test3
+ call test4
+ call test5
+ call test6
+ call test7
+ call test8
+contains
+ subroutine test1
+!
+! Check that the bounds are set correctly, when assigning
+! to an array that already has the correct shape.
+!
+ real :: a(10) = 1, b(51:60) = 2
+ real, allocatable :: c(:), d(:)
+ c=a
+ if (lbound (c, 1) .ne. lbound(a, 1)) call abort
+ if (ubound (c, 1) .ne. ubound(a, 1)) call abort
+ c=b
+ if (lbound (c, 1) .ne. lbound(b, 1)) call abort
+ if (ubound (c, 1) .ne. ubound(b, 1)) call abort
+ d=b
+ if (lbound (d, 1) .ne. lbound(b, 1)) call abort
+ if (ubound (d, 1) .ne. ubound(b, 1)) call abort
+ d=a
+ if (lbound (d, 1) .ne. lbound(a, 1)) call abort
+ if (ubound (d, 1) .ne. ubound(a, 1)) call abort
+ end subroutine
+ subroutine test2
+!
+! Check that the bounds are set correctly, when making an
+! assignment with an implicit conversion. First with a
+! non-descriptor variable....
+!
+ integer(4), allocatable :: a(:)
+ integer(8) :: b(5:6)
+ a = b
+ if (lbound (a, 1) .ne. lbound(b, 1)) call abort
+ if (ubound (a, 1) .ne. ubound(b, 1)) call abort
+ end subroutine
+ subroutine test3
+!
+! ...and now a descriptor variable.
+!
+ integer(4), allocatable :: a(:)
+ integer(8), allocatable :: b(:)
+ allocate (b(7:11))
+ a = b
+ if (lbound (a, 1) .ne. lbound(b, 1)) call abort
+ if (ubound (a, 1) .ne. ubound(b, 1)) call abort
+ end subroutine
+ subroutine test4
+!
+! Check assignments of the kind a = f(...)
+!
+ integer, allocatable :: a(:)
+ integer, allocatable :: c(:)
+ a = f()
+ if (any (a .ne. [1, 2, 3, 4])) call abort
+ c = a + 8
+ a = f (c)
+ if (any ((a - 8) .ne. [1, 2, 3, 4])) call abort
+ deallocate (c)
+ a = f (c)
+ if (any ((a - 4) .ne. [1, 2, 3, 4])) call abort
+ end subroutine
+ function f(b)
+ integer, allocatable, optional :: b(:)
+ integer :: f(4)
+ if (.not.present (b)) then
+ f = [1,2,3,4]
+ elseif (.not.allocated (b)) then
+ f = [5,6,7,8]
+ else
+ f = b
+ end if
+ end function f
+
+ subroutine test5
+!
+! Extracted from rnflow.f90, Polyhedron benchmark suite,
+! http://www.polyhedron.com
+!
+ integer, parameter :: ncls = 233, ival = 16, ipic = 17
+ real, allocatable, dimension (:,:) :: utrsft
+ real, allocatable, dimension (:,:) :: dtrsft
+ real, allocatable, dimension (:,:) :: xwrkt
+ allocate (utrsft(ncls, ncls), dtrsft(ncls, ncls))
+ nglobal = 0
+ xwrkt = trs2a2 (ival, ipic, ncls)
+ if (any (shape (xwrkt) .ne. [ncls, ncls])) call abort
+ xwrkt = invima (xwrkt, ival, ipic, ncls)
+ if (nglobal .ne. 1) call abort
+ if (sum(xwrkt) .ne. xwrkt(ival, ival)) call abort
+ end subroutine
+ function trs2a2 (j, k, m)
+ real, dimension (1:m,1:m) :: trs2a2
+ integer, intent (in) :: j, k, m
+ nglobal = nglobal + 1
+ trs2a2 = 0.0
+ end function trs2a2
+ function invima (a, j, k, m)
+ real, dimension (1:m,1:m) :: invima
+ real, dimension (1:m,1:m), intent (in) :: a
+ integer, intent (in) :: j, k
+ invima (j, j) = 1.0 / (1.0 - a (j, j))
+ end function invima
+ subroutine test6
+ character(kind=1, len=100), allocatable, dimension(:) :: str
+ str = [ "abc" ]
+ if (TRIM(str(1)) .ne. "abc") call abort
+ if (len(str) .ne. 100) call abort
+ end subroutine
+ subroutine test7
+ character(kind=4, len=100), allocatable, dimension(:) :: str
+ character(kind=4, len=3) :: test = "abc"
+ str = [ "abc" ]
+ if (TRIM(str(1)) .ne. test) call abort
+ if (len(str) .ne. 100) call abort
+ end subroutine
+ subroutine test8
+ type t
+ integer, allocatable :: a(:)
+ end type t
+ type(t) :: x
+ x%a= [1,2,3]
+ if (any (x%a .ne. [1,2,3])) call abort
+ x%a = [4]
+ if (any (x%a .ne. [4])) call abort
+ end subroutine
+end
+
diff --git a/gcc/testsuite/gfortran.dg/select_type_19.f03 b/gcc/testsuite/gfortran.dg/select_type_19.f03
new file mode 100644
index 00000000000..0ae2e1ce2fe
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/select_type_19.f03
@@ -0,0 +1,23 @@
+! { dg-do run }
+!
+! PR 46581: [4.6 Regression] [OOP] segfault in SELECT TYPE with associate-name
+!
+! Contributed by Salvatore Filippone <sfilippone@uniroma2.it>
+
+
+ implicit none
+
+ type :: t1
+ integer, allocatable :: ja(:)
+ end type
+
+ class(t1), allocatable :: a
+
+ allocate(a)
+
+ select type (aa=>a)
+ type is (t1)
+ if (allocated(aa%ja)) call abort()
+ end select
+
+end
diff --git a/gcc/testsuite/obj-c++.dg/exceptions-1.mm b/gcc/testsuite/obj-c++.dg/exceptions-1.mm
new file mode 100644
index 00000000000..0f3b7e8ae14
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/exceptions-1.mm
@@ -0,0 +1,42 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-options "-fobjc-exceptions" } */
+/* { dg-do compile } */
+
+/* This test checks the syntax @catch (...) which catches any
+ exceptions. At the moment, @catch (...) is identical to @catch (id
+ exception). */
+
+#include <objc/objc.h>
+
+@interface MyObject
+{
+ Class isa;
+}
+@end
+
+@implementation MyObject
+@end
+
+int test (id object)
+{
+ int i = 0;
+
+ @try
+ {
+ @throw object;
+ }
+ @catch (MyObject *o)
+ {
+ i += 1;
+ }
+ @catch (...)
+ {
+ i += 2;
+ }
+ @finally
+ {
+ i += 4;
+ }
+
+ return i;
+}
diff --git a/gcc/testsuite/obj-c++.dg/exceptions-2.mm b/gcc/testsuite/obj-c++.dg/exceptions-2.mm
new file mode 100644
index 00000000000..ce85b731325
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/exceptions-2.mm
@@ -0,0 +1,54 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-options "-fobjc-exceptions" } */
+
+/* FIXME: This does not test running the code, because Objective-C exceptions at the moment
+ do not execute correctly in Objective-C++. See PR objc++/23616. Once that is fixed,
+ this test should be changed to use 'dg-run' instead of just 'dg-compile'. */
+/* { dg-compile } */
+
+/* This test checks the syntax @catch (...) which catches any
+ exceptions. Check that code using it runs correctly. */
+
+#include "../objc-obj-c++-shared/Object1.h"
+#include <stdlib.h>
+
+@interface MyObject : Object
+@end
+
+@implementation MyObject
+@end
+
+int test (id object)
+{
+ int i = 0;
+
+ @try
+ {
+ @throw object;
+ }
+ @catch (MyObject *o)
+ {
+ i += 1;
+ }
+ @catch (...)
+ {
+ i += 2;
+ }
+ @finally
+ {
+ i += 4;
+ }
+
+ return i;
+}
+
+int main (void)
+{
+ if (test ([MyObject new]) != 5)
+ abort ();
+
+ if (test ([Object new]) != 6)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/obj-c++.dg/exceptions-3.mm b/gcc/testsuite/obj-c++.dg/exceptions-3.mm
new file mode 100644
index 00000000000..b1ba1852725
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/exceptions-3.mm
@@ -0,0 +1,114 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-options "-fobjc-exceptions" } */
+/* { dg-do compile } */
+
+/* Test that the compiler is checking the argument of @catch(), and
+ produce errors when invalid types are used. */
+
+#include <objc/objc.h>
+
+@interface MyObject
+{
+ Class isa;
+}
+@end
+
+@implementation MyObject
+@end
+
+@protocol MyProtocol;
+
+typedef MyObject MyObjectTypedef;
+typedef MyObject *MyObjectPtrTypedef;
+typedef int intTypedef;
+
+int test (id object)
+{
+ int dummy = 0;
+
+ @try { @throw object; }
+ @catch (int x) /* { dg-error "@catch parameter is not a known Objective-C class type" } */
+ {
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (intTypedef x) /* { dg-error "@catch parameter is not a known Objective-C class type" } */
+ {
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (int *x) /* { dg-error "@catch parameter is not a known Objective-C class type" } */
+ {
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (id x) /* Ok */
+ {
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (id <MyProtocol> x) /* { dg-error "@catch parameter can not be protocol-qualified" } */
+ {
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (MyObject *x) /* Ok */
+ {
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (MyObject <MyProtocol> *x) /* { dg-error "@catch parameter can not be protocol-qualified" } */
+ {
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (MyObject x) /* { dg-error "@catch parameter is not a known Objective-C class type" } */
+ { /* { dg-error "no matching function" "" { target *-*-* } 72 } */
+ dummy++; /* { dg-warning "MyObject" "" { target *-*-* } 13 } */
+ }
+
+ @try { @throw object; }
+ @catch (static MyObject *x) /* { dg-error "storage class" } */
+ {
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (MyObjectTypedef *x) /* Ok */
+ {
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (MyObjectTypedef <MyProtocol> *x) /* { dg-error "@catch parameter can not be protocol-qualified" } */
+ {
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (MyObjectPtrTypedef x) /* Ok */
+ {
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (Class x) /* { dg-error "@catch parameter is not a known Objective-C class type" } */
+ {
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (...) /* Ok */
+ {
+ dummy++;
+ }
+
+ return dummy;
+}
diff --git a/gcc/testsuite/obj-c++.dg/exceptions-4.mm b/gcc/testsuite/obj-c++.dg/exceptions-4.mm
new file mode 100644
index 00000000000..85debe444b6
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/exceptions-4.mm
@@ -0,0 +1,64 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-options "-fobjc-exceptions" } */
+/* { dg-do compile } */
+
+/* Test warnings when parsing syntax errors in @catch(). */
+
+#include <objc/objc.h>
+
+@interface MyObject
+{
+ Class isa;
+}
+@end
+
+@implementation MyObject
+@end
+
+@interface MyObject2
+{
+ Class isa;
+}
+@end
+
+@implementation MyObject2
+@end
+
+@protocol MyProtocol;
+
+int test (id object)
+{
+ int dummy = 0;
+
+ @try { @throw object; }
+ @catch
+ { /* { dg-error "expected" } */
+ dummy++; /* { dg-error "@catch parameter is not a known Objective-C class type" "" { target *-*-* } 35 } */
+ }
+ @catch () /* { dg-error "expected identifier before" } */
+ { /* { dg-error "@catch parameter is not a known Objective-C class type" "" { target *-*-* } 38 } */
+ dummy++;
+ }
+ @catch (i) /* { dg-error ".i. has not been declared" } */
+ { /* { dg-error "@catch parameter is not a known Objective-C class type" "" { target *-*-* } 42 } */
+ dummy++;
+ }
+ @catch (id <MyProtocol x) /* { dg-error "expected ... before .x." } */
+ { /* { dg-error "@catch parameter can not be protocol-qualified" "" { target *-*-* } 46 } */
+ dummy++;
+ }
+ @catch MyObject *x /* { dg-error "expected ... before .MyObject." } */
+ {
+ dummy++;
+ }
+ @catch MyObject2 *x) /* { dg-error "expected ... before .MyObject2." } */
+ {
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (MyObject *x)
+ @catch (MyObject2 *y) /* { dg-error "expected ... before .catch." } */
+
+ return dummy; /* { dg-error "expected ... before .return." } */
+}
diff --git a/gcc/testsuite/obj-c++.dg/exceptions-5.mm b/gcc/testsuite/obj-c++.dg/exceptions-5.mm
new file mode 100644
index 00000000000..f7404968844
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/exceptions-5.mm
@@ -0,0 +1,114 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-options "-fobjc-exceptions" } */
+/* { dg-do compile } */
+
+/* Test that you can use an unnamed argument with @catch. This test is the same
+ as exceptions-3.mm, but with no name for @catch arguments. */
+
+#include <objc/objc.h>
+
+@interface MyObject
+{
+ Class isa;
+}
+@end
+
+@implementation MyObject
+@end
+
+@protocol MyProtocol;
+
+typedef MyObject MyObjectTypedef;
+typedef MyObject *MyObjectPtrTypedef;
+typedef int intTypedef;
+
+int test (id object)
+{
+ int dummy = 0;
+
+ @try { @throw object; }
+ @catch (int) /* { dg-error "@catch parameter is not a known Objective-C class type" } */
+ {
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (intTypedef) /* { dg-error "@catch parameter is not a known Objective-C class type" } */
+ {
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (int *) /* { dg-error "@catch parameter is not a known Objective-C class type" } */
+ {
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (id) /* Ok */
+ {
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (id <MyProtocol>) /* { dg-error "@catch parameter can not be protocol-qualified" } */
+ {
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (MyObject *) /* Ok */
+ {
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (MyObject <MyProtocol> *) /* { dg-error "@catch parameter can not be protocol-qualified" } */
+ {
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (MyObject) /* { dg-error "@catch parameter is not a known Objective-C class type" } */
+ { /* { dg-error "no matching function" "" { target *-*-* } 72 } */
+ dummy++; /* { dg-warning "MyObject" "" { target *-*-* } 13 } */
+ }
+
+ @try { @throw object; }
+ @catch (static MyObject *) /* { dg-error "storage class" } */
+ {
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (MyObjectTypedef *) /* Ok */
+ {
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (MyObjectTypedef <MyProtocol> *) /* { dg-error "@catch parameter can not be protocol-qualified" } */
+ {
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (MyObjectPtrTypedef) /* Ok */
+ {
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (Class) /* { dg-error "@catch parameter is not a known Objective-C class type" } */
+ {
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (...) /* Ok */
+ {
+ dummy++;
+ }
+
+ return dummy;
+}
diff --git a/gcc/testsuite/obj-c++.dg/ivar-problem-1.mm b/gcc/testsuite/obj-c++.dg/ivar-problem-1.mm
new file mode 100644
index 00000000000..4ed5afaf4ef
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/ivar-problem-1.mm
@@ -0,0 +1,66 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+/* This test checks what happens if there are 16 instance variables.
+ In that case, the class was not created correctly. In this testcase,
+ we have two classes, one with 15 variables and one with 16. Older
+ GCCs would generate a bogus warning for the second class but not
+ for the first one. This only happened for ObjC, but it's good to
+ test ObjC++ as well. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+
+@interface MyRootClass1
+{
+ Class isa;
+ int v2;
+ int v3;
+ int v4;
+ int v5;
+ int v6;
+ int v7;
+ int v8;
+ int v9;
+ int v10;
+ int v11;
+ int v12;
+ int v13;
+ int v14;
+ int v15;
+}
+- (id) init;
+@end
+
+@implementation MyRootClass1
+- (id) init { return self; }
+@end
+
+
+@interface MyRootClass2
+{
+ Class isa;
+ int v2;
+ int v3;
+ int v4;
+ int v5;
+ int v6;
+ int v7;
+ int v8;
+ int v9;
+ int v10;
+ int v11;
+ int v12;
+ int v13;
+ int v14;
+ int v15;
+ /* Adding the 16th variable used to cause bogus warnings to be
+ generated. */
+ int v16;
+}
+- (id) init;
+@end
+
+@implementation MyRootClass2
+- (id) init { return self; } /* This should not generate a bogus warning. */
+@end
diff --git a/gcc/testsuite/obj-c++.dg/property/at-property-24.mm b/gcc/testsuite/obj-c++.dg/property/at-property-24.mm
new file mode 100644
index 00000000000..b4a7699f6e4
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/property/at-property-24.mm
@@ -0,0 +1,118 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* Test @optional @properties. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+@end
+
+/* Use a different getters/setters, so that the only way to compile
+ object.countX is to find the actual @property. */
+@protocol count
+@required
+/* @required + @synthesize. */
+@property (getter=number1, setter=setNumber1:) int count1;
+/* @required + manual setters/getters. */
+@property (getter=number2, setter=setNumber2:) int count2;
+
+@optional
+/* @optional + @synthesize. */
+@property (getter=number3, setter=setNumber3:) int count3;
+/* @optional + manual setters/getters. */
+@property (getter=number4, setter=setNumber4:) int count4;
+
+@optional
+/* @optional + readonly, with a setter added in the class itself. */
+@property (readonly, getter=number5) int count5;
+@end
+
+@interface MySubClass : MyRootClass <count>
+{
+ int count1;
+ int count2;
+ int count3;
+ int count4;
+ int count5;
+}
+- (void) setCount5: (int)value;
+@end
+
+@implementation MySubClass
+@synthesize count1;
+- (int) number2
+{
+ return count2;
+}
+- (void) setNumber2: (int)value
+{
+ count2 = value;
+}
+@synthesize count3;
+- (int) number4
+{
+ return count4;
+}
+- (void) setNumber4: (int)value
+{
+ count4 = value;
+}
+- (int) number5
+{
+ return count5;
+}
+- (void) setCount5: (int)value
+{
+ count5 = value;
+}
+@end
+
+int main (void)
+{
+ MySubClass *object = [[MySubClass alloc] init];
+
+ /* First, test that @required and @optional properties work as
+ expected if implemented either via @synthesize or manually. */
+ object.count1 = 44;
+ if (object.count1 != 44)
+ abort ();
+
+ object.count2 = 88;
+ if (object.count2 != 88)
+ abort ();
+
+ object.count3 = 77;
+ if (object.count3 != 77)
+ abort ();
+
+ object.count4 = 11;
+ if (object.count4 != 11)
+ abort ();
+
+ /* Now, test the complication: @optional @property which is
+ readonly, but which has a setter manually implemented.
+ Apparently it is possible to use the dotsyntax and the @optional
+ @property getter is used when reading, while the manual setter is
+ used when writing. */
+ object.count5 = 99;
+ if (object.count5 != 99)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/obj-c++.dg/property/at-property-25.mm b/gcc/testsuite/obj-c++.dg/property/at-property-25.mm
new file mode 100644
index 00000000000..422a29e552c
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/property/at-property-25.mm
@@ -0,0 +1,87 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+/* Test warnings and non-warnings with @optional @properties. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+@end
+
+@protocol count
+@optional
+@property int count1;
+@property (readonly) int count2;
+@end
+
+
+/* A class that implements all the properties. */
+@interface MySubClass1 : MyRootClass <count>
+{
+ int count1;
+ int count2;
+}
+@end
+
+@implementation MySubClass1
+@synthesize count1;
+@synthesize count2;
+@end
+
+
+/* A class that implements nothing; no warnings as the properties are
+ all optional. */
+@interface MySubClass2 : MyRootClass <count>
+@end
+
+@implementation MySubClass2
+@end
+
+
+@protocol count2
+@required
+@property int count1;
+@property (readonly) int count2;
+@end
+
+/* A class that implements all the properties. */
+@interface MySubClass3 : MyRootClass <count2>
+{
+ int count1;
+ int count2;
+}
+@end
+
+@implementation MySubClass3
+@synthesize count1;
+@synthesize count2;
+@end
+
+
+/* A class that implements nothing; warnings as the properties are
+ all required. */
+@interface MySubClass4 : MyRootClass <count2>
+@end
+
+@implementation MySubClass4
+@end
+
+/* { dg-warning "incomplete implementation of class" "" { target *-*-* } 81 } */
+/* { dg-warning "method definition for ..setCount1:. not found" "" { target *-*-* } 81 } */
+/* { dg-warning "method definition for ..count1. not found" "" { target *-*-* } 81 } */
+/* { dg-warning "method definition for ..count2. not found" "" { target *-*-* } 81 } */
+/* { dg-warning "class .MySubClass4. does not fully implement the .count2. protocol" "" { target *-*-* } 81 } */
diff --git a/gcc/testsuite/obj-c++.dg/protocol-qualifier-1.mm b/gcc/testsuite/obj-c++.dg/protocol-qualifier-1.mm
new file mode 100644
index 00000000000..c84bfbfa208
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/protocol-qualifier-1.mm
@@ -0,0 +1,33 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+/* Test that protocol qualifiers work in the same way with @class and @interface. */
+
+#include <objc/objc.h>
+
+@protocol MyProtocol
+- (void) method;
+@end
+
+
+/* This first snippet gives no warnings, which is correct as 'object'
+ implements <MyProtocol> and hence responds to 'method'. Note how
+ the details of the class 'MyClass' are never used. */
+@interface MyClass
+@end
+
+void test (MyClass <MyProtocol> *object)
+{
+ [object method];
+}
+
+
+/* This second snippet should behave identically. 'object' still implements
+ the same protocol and responds to 'method'. The details of MyClass or
+ MyClass2 are irrelevant. */
+@class MyClass2;
+
+void test2 (MyClass2 <MyProtocol> *object)
+{
+ [object method];
+}
diff --git a/gcc/testsuite/obj-c++.dg/protocol-qualifier-2.mm b/gcc/testsuite/obj-c++.dg/protocol-qualifier-2.mm
new file mode 100644
index 00000000000..fd25d8ff606
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/protocol-qualifier-2.mm
@@ -0,0 +1,31 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+/* Test that protocol qualifiers are maintained correctly when a
+ @class is replaced by its @interface. */
+
+#include <objc/objc.h>
+
+@protocol MyProtocol
+- (void) method;
+@end
+
+@class MyClass;
+
+static MyClass <MyProtocol> *object1;
+static MyClass *object2;
+
+/* Declarating the @interface now will need to update all the existing
+ ObjC types referring to MyClass with the new information. We need
+ to test that protocol information is not lost in the process. */
+@interface MyClass
+@end
+
+void test1 (void)
+{
+ [object1 method]; /* Ok */
+ [object2 method]; /* { dg-warning ".MyClass. may not respond to ..method." } */
+ /* { dg-warning "without a matching method" "" { target *-*-* } 27 } */
+ /* { dg-warning "will be assumed to return" "" { target *-*-* } 27 } */
+ /* { dg-warning "as arguments" "" { target *-*-* } 27 } */
+}
diff --git a/gcc/testsuite/objc.dg/exceptions-1.m b/gcc/testsuite/objc.dg/exceptions-1.m
new file mode 100644
index 00000000000..0f3b7e8ae14
--- /dev/null
+++ b/gcc/testsuite/objc.dg/exceptions-1.m
@@ -0,0 +1,42 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-options "-fobjc-exceptions" } */
+/* { dg-do compile } */
+
+/* This test checks the syntax @catch (...) which catches any
+ exceptions. At the moment, @catch (...) is identical to @catch (id
+ exception). */
+
+#include <objc/objc.h>
+
+@interface MyObject
+{
+ Class isa;
+}
+@end
+
+@implementation MyObject
+@end
+
+int test (id object)
+{
+ int i = 0;
+
+ @try
+ {
+ @throw object;
+ }
+ @catch (MyObject *o)
+ {
+ i += 1;
+ }
+ @catch (...)
+ {
+ i += 2;
+ }
+ @finally
+ {
+ i += 4;
+ }
+
+ return i;
+}
diff --git a/gcc/testsuite/objc.dg/exceptions-2.m b/gcc/testsuite/objc.dg/exceptions-2.m
new file mode 100644
index 00000000000..3e4227cb965
--- /dev/null
+++ b/gcc/testsuite/objc.dg/exceptions-2.m
@@ -0,0 +1,52 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do run } */
+/* { dg-options "-fobjc-exceptions" } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+/* { dg-additional-sources "../objc-obj-c++-shared/Object1.m" } */
+
+/* This test checks the syntax @catch (...) which catches any
+ exceptions. Check that code using it runs correctly. */
+
+#include "../objc-obj-c++-shared/Object1.h"
+#include <stdlib.h>
+
+@interface MyObject : Object
+@end
+
+@implementation MyObject
+@end
+
+int test (id object)
+{
+ int i = 0;
+
+ @try
+ {
+ @throw object;
+ }
+ @catch (MyObject *o)
+ {
+ i += 1;
+ }
+ @catch (...)
+ {
+ i += 2;
+ }
+ @finally
+ {
+ i += 4;
+ }
+
+ return i;
+}
+
+int main (void)
+{
+ if (test ([MyObject new]) != 5)
+ abort ();
+
+ if (test ([Object new]) != 6)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/exceptions-3.m b/gcc/testsuite/objc.dg/exceptions-3.m
new file mode 100644
index 00000000000..fe9dbfbfa06
--- /dev/null
+++ b/gcc/testsuite/objc.dg/exceptions-3.m
@@ -0,0 +1,114 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-options "-fobjc-exceptions" } */
+/* { dg-do compile } */
+
+/* Test that the compiler is checking the argument of @catch(), and
+ produce errors when invalid types are used. */
+
+#include <objc/objc.h>
+
+@interface MyObject
+{
+ Class isa;
+}
+@end
+
+@implementation MyObject
+@end
+
+@protocol MyProtocol;
+
+typedef MyObject MyObjectTypedef;
+typedef MyObject *MyObjectPtrTypedef;
+typedef int intTypedef;
+
+int test (id object)
+{
+ int dummy = 0;
+
+ @try { @throw object; }
+ @catch (int x) /* { dg-error "@catch parameter is not a known Objective-C class type" } */
+ {
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (intTypedef x) /* { dg-error "@catch parameter is not a known Objective-C class type" } */
+ {
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (int *x) /* { dg-error "@catch parameter is not a known Objective-C class type" } */
+ {
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (id x) /* Ok */
+ {
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (id <MyProtocol> x) /* { dg-error "@catch parameter can not be protocol-qualified" } */
+ {
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (MyObject *x) /* Ok */
+ {
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (MyObject <MyProtocol> *x) /* { dg-error "@catch parameter can not be protocol-qualified" } */
+ {
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (MyObject x) /* { dg-error "@catch parameter is not a known Objective-C class type" } */
+ { /* { dg-error "conversion to non-scalar type requested" "" { target *-*-* } 72 } */
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (static MyObject *x) /* { dg-error "storage class specified for" } */
+ {
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (MyObjectTypedef *x) /* Ok */
+ {
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (MyObjectTypedef <MyProtocol> *x) /* { dg-error "@catch parameter can not be protocol-qualified" } */
+ {
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (MyObjectPtrTypedef x) /* Ok */
+ {
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (Class x) /* { dg-error "@catch parameter is not a known Objective-C class type" } */
+ {
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (...) /* Ok */
+ {
+ dummy++;
+ }
+
+ return dummy;
+}
diff --git a/gcc/testsuite/objc.dg/exceptions-4.m b/gcc/testsuite/objc.dg/exceptions-4.m
new file mode 100644
index 00000000000..a8a26ecebb2
--- /dev/null
+++ b/gcc/testsuite/objc.dg/exceptions-4.m
@@ -0,0 +1,64 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-options "-fobjc-exceptions" } */
+/* { dg-do compile } */
+
+/* Test warnings when parsing syntax errors in @catch(). */
+
+#include <objc/objc.h>
+
+@interface MyObject
+{
+ Class isa;
+}
+@end
+
+@implementation MyObject
+@end
+
+@interface MyObject2
+{
+ Class isa;
+}
+@end
+
+@implementation MyObject2
+@end
+
+@protocol MyProtocol;
+
+int test (id object)
+{
+ int dummy = 0;
+
+ @try { @throw object; }
+ @catch
+ { /* { dg-error "expected ... before ... token" } */
+ dummy++;
+ }
+ @catch () /* { dg-error "expected declaration specifiers or ..... before ..." } */
+ {
+ dummy++;
+ }
+ @catch (i) /* { dg-error "expected declaration specifiers or ..... before .i." } */
+ {
+ dummy++;
+ }
+ @catch (id <MyProtocol x) /* { dg-error "expected ... before .x." } */
+ { /* { dg-error "@catch parameter can not be protocol-qualified" "" { target *-*-* } 46 } */
+ dummy++;
+ }
+ @catch MyObject *x /* { dg-error "expected ... before .MyObject." } */
+ {
+ dummy++;
+ }
+ @catch MyObject2 *x) /* { dg-error "expected ... before .MyObject2." } */
+ {
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (MyObject *x)
+ @catch (MyObject2 *y) /* { dg-error "expected ... before .catch." } */
+
+ return dummy;
+}
diff --git a/gcc/testsuite/objc.dg/exceptions-5.m b/gcc/testsuite/objc.dg/exceptions-5.m
new file mode 100644
index 00000000000..d89ad2967c0
--- /dev/null
+++ b/gcc/testsuite/objc.dg/exceptions-5.m
@@ -0,0 +1,114 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-options "-fobjc-exceptions" } */
+/* { dg-do compile } */
+
+/* Test that you can use an unnamed argument with @catch. This test is the same
+ as exceptions-3.m, but with no name for @catch arguments. */
+
+#include <objc/objc.h>
+
+@interface MyObject
+{
+ Class isa;
+}
+@end
+
+@implementation MyObject
+@end
+
+@protocol MyProtocol;
+
+typedef MyObject MyObjectTypedef;
+typedef MyObject *MyObjectPtrTypedef;
+typedef int intTypedef;
+
+int test (id object)
+{
+ int dummy = 0;
+
+ @try { @throw object; }
+ @catch (int) /* { dg-error "@catch parameter is not a known Objective-C class type" } */
+ {
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (intTypedef) /* { dg-error "@catch parameter is not a known Objective-C class type" } */
+ {
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (int *) /* { dg-error "@catch parameter is not a known Objective-C class type" } */
+ {
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (id) /* Ok */
+ {
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (id <MyProtocol>) /* { dg-error "@catch parameter can not be protocol-qualified" } */
+ {
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (MyObject *) /* Ok */
+ {
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (MyObject <MyProtocol> *) /* { dg-error "@catch parameter can not be protocol-qualified" } */
+ {
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (MyObject) /* { dg-error "@catch parameter is not a known Objective-C class type" } */
+ { /* { dg-error "conversion to non-scalar type requested" "" { target *-*-* } 72 } */
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (static MyObject *) /* { dg-error "storage class specified for" } */
+ {
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (MyObjectTypedef *) /* Ok */
+ {
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (MyObjectTypedef <MyProtocol> *) /* { dg-error "@catch parameter can not be protocol-qualified" } */
+ {
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (MyObjectPtrTypedef) /* Ok */
+ {
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (Class) /* { dg-error "@catch parameter is not a known Objective-C class type" } */
+ {
+ dummy++;
+ }
+
+ @try { @throw object; }
+ @catch (...) /* Ok */
+ {
+ dummy++;
+ }
+
+ return dummy;
+}
diff --git a/gcc/testsuite/objc.dg/ivar-problem-1.m b/gcc/testsuite/objc.dg/ivar-problem-1.m
new file mode 100644
index 00000000000..4a877680549
--- /dev/null
+++ b/gcc/testsuite/objc.dg/ivar-problem-1.m
@@ -0,0 +1,65 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+/* This test checks what happens if there are 16 instance variables.
+ In that case, the class was not created correctly. In this testcase,
+ we have two classes, one with 15 variables and one with 16. Older
+ GCCs would generate a bogus warning for the second class but not
+ for the first one. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+
+@interface MyRootClass1
+{
+ Class isa;
+ int v2;
+ int v3;
+ int v4;
+ int v5;
+ int v6;
+ int v7;
+ int v8;
+ int v9;
+ int v10;
+ int v11;
+ int v12;
+ int v13;
+ int v14;
+ int v15;
+}
+- (id) init;
+@end
+
+@implementation MyRootClass1
+- (id) init { return self; }
+@end
+
+
+@interface MyRootClass2
+{
+ Class isa;
+ int v2;
+ int v3;
+ int v4;
+ int v5;
+ int v6;
+ int v7;
+ int v8;
+ int v9;
+ int v10;
+ int v11;
+ int v12;
+ int v13;
+ int v14;
+ int v15;
+ /* Adding the 16th variable used to cause bogus warnings to be
+ generated. */
+ int v16;
+}
+- (id) init;
+@end
+
+@implementation MyRootClass2
+- (id) init { return self; } /* This should not generate a bogus warning. */
+@end
diff --git a/gcc/testsuite/objc.dg/property/at-property-24.m b/gcc/testsuite/objc.dg/property/at-property-24.m
new file mode 100644
index 00000000000..b4a7699f6e4
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-24.m
@@ -0,0 +1,118 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* Test @optional @properties. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+@end
+
+/* Use a different getters/setters, so that the only way to compile
+ object.countX is to find the actual @property. */
+@protocol count
+@required
+/* @required + @synthesize. */
+@property (getter=number1, setter=setNumber1:) int count1;
+/* @required + manual setters/getters. */
+@property (getter=number2, setter=setNumber2:) int count2;
+
+@optional
+/* @optional + @synthesize. */
+@property (getter=number3, setter=setNumber3:) int count3;
+/* @optional + manual setters/getters. */
+@property (getter=number4, setter=setNumber4:) int count4;
+
+@optional
+/* @optional + readonly, with a setter added in the class itself. */
+@property (readonly, getter=number5) int count5;
+@end
+
+@interface MySubClass : MyRootClass <count>
+{
+ int count1;
+ int count2;
+ int count3;
+ int count4;
+ int count5;
+}
+- (void) setCount5: (int)value;
+@end
+
+@implementation MySubClass
+@synthesize count1;
+- (int) number2
+{
+ return count2;
+}
+- (void) setNumber2: (int)value
+{
+ count2 = value;
+}
+@synthesize count3;
+- (int) number4
+{
+ return count4;
+}
+- (void) setNumber4: (int)value
+{
+ count4 = value;
+}
+- (int) number5
+{
+ return count5;
+}
+- (void) setCount5: (int)value
+{
+ count5 = value;
+}
+@end
+
+int main (void)
+{
+ MySubClass *object = [[MySubClass alloc] init];
+
+ /* First, test that @required and @optional properties work as
+ expected if implemented either via @synthesize or manually. */
+ object.count1 = 44;
+ if (object.count1 != 44)
+ abort ();
+
+ object.count2 = 88;
+ if (object.count2 != 88)
+ abort ();
+
+ object.count3 = 77;
+ if (object.count3 != 77)
+ abort ();
+
+ object.count4 = 11;
+ if (object.count4 != 11)
+ abort ();
+
+ /* Now, test the complication: @optional @property which is
+ readonly, but which has a setter manually implemented.
+ Apparently it is possible to use the dotsyntax and the @optional
+ @property getter is used when reading, while the manual setter is
+ used when writing. */
+ object.count5 = 99;
+ if (object.count5 != 99)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/property/at-property-25.m b/gcc/testsuite/objc.dg/property/at-property-25.m
new file mode 100644
index 00000000000..422a29e552c
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-25.m
@@ -0,0 +1,87 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+/* Test warnings and non-warnings with @optional @properties. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+@end
+
+@protocol count
+@optional
+@property int count1;
+@property (readonly) int count2;
+@end
+
+
+/* A class that implements all the properties. */
+@interface MySubClass1 : MyRootClass <count>
+{
+ int count1;
+ int count2;
+}
+@end
+
+@implementation MySubClass1
+@synthesize count1;
+@synthesize count2;
+@end
+
+
+/* A class that implements nothing; no warnings as the properties are
+ all optional. */
+@interface MySubClass2 : MyRootClass <count>
+@end
+
+@implementation MySubClass2
+@end
+
+
+@protocol count2
+@required
+@property int count1;
+@property (readonly) int count2;
+@end
+
+/* A class that implements all the properties. */
+@interface MySubClass3 : MyRootClass <count2>
+{
+ int count1;
+ int count2;
+}
+@end
+
+@implementation MySubClass3
+@synthesize count1;
+@synthesize count2;
+@end
+
+
+/* A class that implements nothing; warnings as the properties are
+ all required. */
+@interface MySubClass4 : MyRootClass <count2>
+@end
+
+@implementation MySubClass4
+@end
+
+/* { dg-warning "incomplete implementation of class" "" { target *-*-* } 81 } */
+/* { dg-warning "method definition for ..setCount1:. not found" "" { target *-*-* } 81 } */
+/* { dg-warning "method definition for ..count1. not found" "" { target *-*-* } 81 } */
+/* { dg-warning "method definition for ..count2. not found" "" { target *-*-* } 81 } */
+/* { dg-warning "class .MySubClass4. does not fully implement the .count2. protocol" "" { target *-*-* } 81 } */
diff --git a/gcc/testsuite/objc.dg/protocol-qualifier-1.m b/gcc/testsuite/objc.dg/protocol-qualifier-1.m
new file mode 100644
index 00000000000..c84bfbfa208
--- /dev/null
+++ b/gcc/testsuite/objc.dg/protocol-qualifier-1.m
@@ -0,0 +1,33 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+/* Test that protocol qualifiers work in the same way with @class and @interface. */
+
+#include <objc/objc.h>
+
+@protocol MyProtocol
+- (void) method;
+@end
+
+
+/* This first snippet gives no warnings, which is correct as 'object'
+ implements <MyProtocol> and hence responds to 'method'. Note how
+ the details of the class 'MyClass' are never used. */
+@interface MyClass
+@end
+
+void test (MyClass <MyProtocol> *object)
+{
+ [object method];
+}
+
+
+/* This second snippet should behave identically. 'object' still implements
+ the same protocol and responds to 'method'. The details of MyClass or
+ MyClass2 are irrelevant. */
+@class MyClass2;
+
+void test2 (MyClass2 <MyProtocol> *object)
+{
+ [object method];
+}
diff --git a/gcc/testsuite/objc.dg/protocol-qualifier-2.m b/gcc/testsuite/objc.dg/protocol-qualifier-2.m
new file mode 100644
index 00000000000..fd25d8ff606
--- /dev/null
+++ b/gcc/testsuite/objc.dg/protocol-qualifier-2.m
@@ -0,0 +1,31 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+/* Test that protocol qualifiers are maintained correctly when a
+ @class is replaced by its @interface. */
+
+#include <objc/objc.h>
+
+@protocol MyProtocol
+- (void) method;
+@end
+
+@class MyClass;
+
+static MyClass <MyProtocol> *object1;
+static MyClass *object2;
+
+/* Declarating the @interface now will need to update all the existing
+ ObjC types referring to MyClass with the new information. We need
+ to test that protocol information is not lost in the process. */
+@interface MyClass
+@end
+
+void test1 (void)
+{
+ [object1 method]; /* Ok */
+ [object2 method]; /* { dg-warning ".MyClass. may not respond to ..method." } */
+ /* { dg-warning "without a matching method" "" { target *-*-* } 27 } */
+ /* { dg-warning "will be assumed to return" "" { target *-*-* } 27 } */
+ /* { dg-warning "as arguments" "" { target *-*-* } 27 } */
+}