summaryrefslogtreecommitdiff
path: root/gcc/testsuite/objc.dg
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/testsuite/objc.dg')
-rw-r--r--gcc/testsuite/objc.dg/alias.m12
-rw-r--r--gcc/testsuite/objc.dg/anon-1.m14
-rw-r--r--gcc/testsuite/objc.dg/at-class-1.m11
-rw-r--r--gcc/testsuite/objc.dg/attributes/attributes.exp44
-rw-r--r--gcc/testsuite/objc.dg/attributes/categ-attribute-1.m31
-rw-r--r--gcc/testsuite/objc.dg/attributes/categ-attribute-2.m32
-rw-r--r--gcc/testsuite/objc.dg/attributes/class-attribute-1.m59
-rw-r--r--gcc/testsuite/objc.dg/attributes/class-attribute-2.m21
-rw-r--r--gcc/testsuite/objc.dg/attributes/class-attribute-3.m14
-rw-r--r--gcc/testsuite/objc.dg/attributes/invalid-attribute-1.m6
-rw-r--r--gcc/testsuite/objc.dg/attributes/method-attribute-1.m40
-rw-r--r--gcc/testsuite/objc.dg/attributes/method-attribute-2.m33
-rw-r--r--gcc/testsuite/objc.dg/attributes/method-attribute-3.m24
-rw-r--r--gcc/testsuite/objc.dg/attributes/method-deprecated-1.m33
-rw-r--r--gcc/testsuite/objc.dg/attributes/method-deprecated-2.m23
-rw-r--r--gcc/testsuite/objc.dg/attributes/method-deprecated-3.m21
-rw-r--r--gcc/testsuite/objc.dg/attributes/method-format-1.m43
-rw-r--r--gcc/testsuite/objc.dg/attributes/method-noreturn-1.m34
-rw-r--r--gcc/testsuite/objc.dg/attributes/method-sentinel-1.m35
-rw-r--r--gcc/testsuite/objc.dg/attributes/objc-exception-1.m32
-rw-r--r--gcc/testsuite/objc.dg/attributes/parameter-attribute-1.m45
-rw-r--r--gcc/testsuite/objc.dg/attributes/parameter-attribute-2.m25
-rw-r--r--gcc/testsuite/objc.dg/attributes/proto-attribute-1.m21
-rw-r--r--gcc/testsuite/objc.dg/attributes/proto-attribute-2.m31
-rw-r--r--gcc/testsuite/objc.dg/attributes/proto-attribute-3.m59
-rw-r--r--gcc/testsuite/objc.dg/attributes/proto-attribute-4.m31
-rw-r--r--gcc/testsuite/objc.dg/bad-receiver-type-2.m41
-rw-r--r--gcc/testsuite/objc.dg/bad-receiver-type.m15
-rw-r--r--gcc/testsuite/objc.dg/bitfield-1.m83
-rw-r--r--gcc/testsuite/objc.dg/bitfield-2.m56
-rw-r--r--gcc/testsuite/objc.dg/bitfield-3.m49
-rw-r--r--gcc/testsuite/objc.dg/bitfield-4.m28
-rw-r--r--gcc/testsuite/objc.dg/bitfield-5.m113
-rw-r--r--gcc/testsuite/objc.dg/break-in-ifstmt.m14
-rw-r--r--gcc/testsuite/objc.dg/call-super-1.m78
-rw-r--r--gcc/testsuite/objc.dg/call-super-2.m138
-rw-r--r--gcc/testsuite/objc.dg/call-super-3.m57
-rw-r--r--gcc/testsuite/objc.dg/category-1.m51
-rw-r--r--gcc/testsuite/objc.dg/class-1.m20
-rw-r--r--gcc/testsuite/objc.dg/class-2.m14
-rw-r--r--gcc/testsuite/objc.dg/class-extension-1.m30
-rw-r--r--gcc/testsuite/objc.dg/class-extension-2.m56
-rw-r--r--gcc/testsuite/objc.dg/class-extension-3.m26
-rw-r--r--gcc/testsuite/objc.dg/class-extension-4.m19
-rw-r--r--gcc/testsuite/objc.dg/class-protocol-1.m441
-rw-r--r--gcc/testsuite/objc.dg/comp-types-1.m87
-rw-r--r--gcc/testsuite/objc.dg/comp-types-10.m27
-rw-r--r--gcc/testsuite/objc.dg/comp-types-11.m14
-rw-r--r--gcc/testsuite/objc.dg/comp-types-12.m19
-rw-r--r--gcc/testsuite/objc.dg/comp-types-2.m37
-rw-r--r--gcc/testsuite/objc.dg/comp-types-3.m63
-rw-r--r--gcc/testsuite/objc.dg/comp-types-4.m73
-rw-r--r--gcc/testsuite/objc.dg/comp-types-5.m32
-rw-r--r--gcc/testsuite/objc.dg/comp-types-6.m38
-rw-r--r--gcc/testsuite/objc.dg/comp-types-7.m32
-rw-r--r--gcc/testsuite/objc.dg/comp-types-8.m24
-rw-r--r--gcc/testsuite/objc.dg/comp-types-9.m19
-rw-r--r--gcc/testsuite/objc.dg/conditional-1.m45
-rw-r--r--gcc/testsuite/objc.dg/defs.m70
-rw-r--r--gcc/testsuite/objc.dg/demangle-1.m59
-rw-r--r--gcc/testsuite/objc.dg/desig-init-1.m51
-rw-r--r--gcc/testsuite/objc.dg/desig-init-2.m7
-rw-r--r--gcc/testsuite/objc.dg/dg.exp42
-rw-r--r--gcc/testsuite/objc.dg/duplicate-class-1.m31
-rw-r--r--gcc/testsuite/objc.dg/dwarf-1.m6
-rw-r--r--gcc/testsuite/objc.dg/dwarf-2.m4
-rw-r--r--gcc/testsuite/objc.dg/encode-1.m23
-rw-r--r--gcc/testsuite/objc.dg/encode-10.m19
-rw-r--r--gcc/testsuite/objc.dg/encode-11.m43
-rw-r--r--gcc/testsuite/objc.dg/encode-2.m104
-rw-r--r--gcc/testsuite/objc.dg/encode-3.m113
-rw-r--r--gcc/testsuite/objc.dg/encode-4.m93
-rw-r--r--gcc/testsuite/objc.dg/encode-5.m76
-rw-r--r--gcc/testsuite/objc.dg/encode-6-next.m23
-rw-r--r--gcc/testsuite/objc.dg/encode-6.m23
-rw-r--r--gcc/testsuite/objc.dg/encode-7-next-64bit.m270
-rw-r--r--gcc/testsuite/objc.dg/encode-7-next.m269
-rw-r--r--gcc/testsuite/objc.dg/encode-7.m18
-rw-r--r--gcc/testsuite/objc.dg/encode-8.m31
-rw-r--r--gcc/testsuite/objc.dg/encode-9.m12
-rw-r--r--gcc/testsuite/objc.dg/enhanced-proto-1.m19
-rw-r--r--gcc/testsuite/objc.dg/enhanced-proto-2.m24
-rw-r--r--gcc/testsuite/objc.dg/error-1.m6
-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/exceptions-6.m29
-rw-r--r--gcc/testsuite/objc.dg/exceptions-7.m18
-rw-r--r--gcc/testsuite/objc.dg/extra-semi.m10
-rw-r--r--gcc/testsuite/objc.dg/fix-and-continue-1.m93
-rw-r--r--gcc/testsuite/objc.dg/fix-and-continue-2.m24
-rw-r--r--gcc/testsuite/objc.dg/fobjc-exceptions-1.m28
-rw-r--r--gcc/testsuite/objc.dg/fobjc-exceptions-2.m29
-rw-r--r--gcc/testsuite/objc.dg/fobjc-exceptions-3.m30
-rw-r--r--gcc/testsuite/objc.dg/fobjc-std-1.m76
-rw-r--r--gcc/testsuite/objc.dg/foreach-1.m83
-rw-r--r--gcc/testsuite/objc.dg/foreach-2.m288
-rw-r--r--gcc/testsuite/objc.dg/foreach-3.m118
-rw-r--r--gcc/testsuite/objc.dg/foreach-4.m268
-rw-r--r--gcc/testsuite/objc.dg/foreach-5.m266
-rw-r--r--gcc/testsuite/objc.dg/foreach-6.m61
-rw-r--r--gcc/testsuite/objc.dg/foreach-7.m58
-rw-r--r--gcc/testsuite/objc.dg/foreach-8.m51
-rw-r--r--gcc/testsuite/objc.dg/fsf-nsstring-format-1.m44
-rw-r--r--gcc/testsuite/objc.dg/fsf-package-0.m37
-rw-r--r--gcc/testsuite/objc.dg/fsyntax-only.m11
-rw-r--r--gcc/testsuite/objc.dg/func-ptr-1.m51
-rw-r--r--gcc/testsuite/objc.dg/func-ptr-2.m41
-rw-r--r--gcc/testsuite/objc.dg/fwd-proto-1.m29
-rw-r--r--gcc/testsuite/objc.dg/gnu-api-2-class.m488
-rw-r--r--gcc/testsuite/objc.dg/gnu-api-2-ivar.m83
-rw-r--r--gcc/testsuite/objc.dg/gnu-api-2-method.m230
-rw-r--r--gcc/testsuite/objc.dg/gnu-api-2-objc.m248
-rw-r--r--gcc/testsuite/objc.dg/gnu-api-2-objc_msg_lookup.m77
-rw-r--r--gcc/testsuite/objc.dg/gnu-api-2-object.m164
-rw-r--r--gcc/testsuite/objc.dg/gnu-api-2-property.m100
-rw-r--r--gcc/testsuite/objc.dg/gnu-api-2-protocol.m163
-rw-r--r--gcc/testsuite/objc.dg/gnu-api-2-resolve-method.m567
-rw-r--r--gcc/testsuite/objc.dg/gnu-api-2-sel.m209
-rw-r--r--gcc/testsuite/objc.dg/gnu-encoding/compat-common.h43
-rw-r--r--gcc/testsuite/objc.dg/gnu-encoding/generate-random.c265
-rw-r--r--gcc/testsuite/objc.dg/gnu-encoding/generate-random.h33
-rw-r--r--gcc/testsuite/objc.dg/gnu-encoding/generate-random_r.c385
-rw-r--r--gcc/testsuite/objc.dg/gnu-encoding/gnu-encoding.exp77
-rw-r--r--gcc/testsuite/objc.dg/gnu-encoding/struct-layout-1.h704
-rw-r--r--gcc/testsuite/objc.dg/gnu-encoding/struct-layout-1_test.h9
-rw-r--r--gcc/testsuite/objc.dg/gnu-encoding/struct-layout-encoding-1_generate.c1380
-rw-r--r--gcc/testsuite/objc.dg/gnu-encoding/vector-defs.h72
-rw-r--r--gcc/testsuite/objc.dg/gnu-runtime-1.m19
-rw-r--r--gcc/testsuite/objc.dg/gnu-runtime-2.m30
-rw-r--r--gcc/testsuite/objc.dg/gnu-runtime-3.m14
-rw-r--r--gcc/testsuite/objc.dg/headers.m31
-rw-r--r--gcc/testsuite/objc.dg/id-1.m7
-rw-r--r--gcc/testsuite/objc.dg/image-info.m43
-rw-r--r--gcc/testsuite/objc.dg/incomplete-type-1.m22
-rw-r--r--gcc/testsuite/objc.dg/invalid-method-1.m11
-rw-r--r--gcc/testsuite/objc.dg/invalid-method-2.m18
-rw-r--r--gcc/testsuite/objc.dg/invalid-type-1.m24
-rw-r--r--gcc/testsuite/objc.dg/isa-field-1.m63
-rw-r--r--gcc/testsuite/objc.dg/ivar-invalid-type-1.m19
-rw-r--r--gcc/testsuite/objc.dg/ivar-problem-1.m65
-rw-r--r--gcc/testsuite/objc.dg/keywords-1.m27
-rw-r--r--gcc/testsuite/objc.dg/keywords-2.m24
-rw-r--r--gcc/testsuite/objc.dg/keywords-3.m20
-rw-r--r--gcc/testsuite/objc.dg/layout-1.m15
-rw-r--r--gcc/testsuite/objc.dg/layout-2.m14
-rw-r--r--gcc/testsuite/objc.dg/libobjc-selector-1.m39
-rw-r--r--gcc/testsuite/objc.dg/local-decl-1.m25
-rw-r--r--gcc/testsuite/objc.dg/local-decl-2.m42
-rw-r--r--gcc/testsuite/objc.dg/lookup-1.m56
-rw-r--r--gcc/testsuite/objc.dg/lto/lto.exp84
-rw-r--r--gcc/testsuite/objc.dg/lto/trivial-1_0.m37
-rw-r--r--gcc/testsuite/objc.dg/member-1.m5
-rw-r--r--gcc/testsuite/objc.dg/method-1.m30
-rw-r--r--gcc/testsuite/objc.dg/method-10.m35
-rw-r--r--gcc/testsuite/objc.dg/method-11.m33
-rw-r--r--gcc/testsuite/objc.dg/method-12.m25
-rw-r--r--gcc/testsuite/objc.dg/method-13.m78
-rw-r--r--gcc/testsuite/objc.dg/method-14.m17
-rw-r--r--gcc/testsuite/objc.dg/method-15.m56
-rw-r--r--gcc/testsuite/objc.dg/method-16.m24
-rw-r--r--gcc/testsuite/objc.dg/method-17.m26
-rw-r--r--gcc/testsuite/objc.dg/method-18.m29
-rw-r--r--gcc/testsuite/objc.dg/method-19.m17
-rw-r--r--gcc/testsuite/objc.dg/method-2.m32
-rw-r--r--gcc/testsuite/objc.dg/method-20.m9
-rw-r--r--gcc/testsuite/objc.dg/method-20b.m45
-rw-r--r--gcc/testsuite/objc.dg/method-3.m48
-rw-r--r--gcc/testsuite/objc.dg/method-4.m26
-rw-r--r--gcc/testsuite/objc.dg/method-5.m20
-rw-r--r--gcc/testsuite/objc.dg/method-6.m32
-rw-r--r--gcc/testsuite/objc.dg/method-7.m29
-rw-r--r--gcc/testsuite/objc.dg/method-8.m14
-rw-r--r--gcc/testsuite/objc.dg/method-9.m45
-rw-r--r--gcc/testsuite/objc.dg/method-conflict-1.m26
-rw-r--r--gcc/testsuite/objc.dg/method-conflict-2.m34
-rw-r--r--gcc/testsuite/objc.dg/method-conflict-3.m63
-rw-r--r--gcc/testsuite/objc.dg/method-conflict-4.m47
-rw-r--r--gcc/testsuite/objc.dg/missing-proto-1.m6
-rw-r--r--gcc/testsuite/objc.dg/missing-proto-2.m5
-rw-r--r--gcc/testsuite/objc.dg/missing-proto-3.m26
-rw-r--r--gcc/testsuite/objc.dg/msg-in-protocol.m18
-rw-r--r--gcc/testsuite/objc.dg/naming-1.m19
-rw-r--r--gcc/testsuite/objc.dg/naming-2.m12
-rw-r--r--gcc/testsuite/objc.dg/naming-3.m17
-rw-r--r--gcc/testsuite/objc.dg/naming-4.m27
-rw-r--r--gcc/testsuite/objc.dg/naming-5.m42
-rw-r--r--gcc/testsuite/objc.dg/next-runtime-1.m20
-rw-r--r--gcc/testsuite/objc.dg/no-extra-load.m7
-rw-r--r--gcc/testsuite/objc.dg/objc-fast-4.m12
-rw-r--r--gcc/testsuite/objc.dg/objc-foreach-1.m41
-rw-r--r--gcc/testsuite/objc.dg/objc-foreach-2.m41
-rw-r--r--gcc/testsuite/objc.dg/objc-foreach-3.m42
-rw-r--r--gcc/testsuite/objc.dg/objc-foreach-4.m26
-rw-r--r--gcc/testsuite/objc.dg/objc-foreach-5.m39
-rw-r--r--gcc/testsuite/objc.dg/objc-gc-4.m64
-rw-r--r--gcc/testsuite/objc.dg/objc-nofilename-1.m22
-rw-r--r--gcc/testsuite/objc.dg/param-1.m20
-rw-r--r--gcc/testsuite/objc.dg/pch/interface-1.hs4
-rw-r--r--gcc/testsuite/objc.dg/pch/interface-1.m14
-rw-r--r--gcc/testsuite/objc.dg/pch/pch.exp64
-rw-r--r--gcc/testsuite/objc.dg/pr18255.m24
-rw-r--r--gcc/testsuite/objc.dg/pr23214.m38
-rw-r--r--gcc/testsuite/objc.dg/pr23709.m12
-rw-r--r--gcc/testsuite/objc.dg/pr24393.m10
-rw-r--r--gcc/testsuite/objc.dg/pr28049.m2
-rw-r--r--gcc/testsuite/objc.dg/pr28050.m2
-rw-r--r--gcc/testsuite/objc.dg/pr44509.m9
-rw-r--r--gcc/testsuite/objc.dg/pr45735.m4
-rw-r--r--gcc/testsuite/objc.dg/pr45878.m38
-rw-r--r--gcc/testsuite/objc.dg/pr48177.m35
-rw-r--r--gcc/testsuite/objc.dg/pragma-1.m7
-rw-r--r--gcc/testsuite/objc.dg/private-1.m59
-rw-r--r--gcc/testsuite/objc.dg/private-2.m54
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-1.m21
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-10.m100
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-11.m47
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-12.m47
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-13.m72
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-14.m20
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-15.m20
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-16.m55
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-17.m98
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-18.m47
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-19.m74
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-2.m13
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-20.m81
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-21.m23
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-22.m172
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-23.m17
-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/property/at-property-26.m85
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-27.m66
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-28.m29
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-29.m14
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-3.m15
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-4.m40
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-5.m34
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-6.m61
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-7.m58
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-8.m58
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-9.m53
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-deprecated-1.m37
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-deprecated-2.m25
-rw-r--r--gcc/testsuite/objc.dg/property/dotsyntax-1.m63
-rw-r--r--gcc/testsuite/objc.dg/property/dotsyntax-10.m86
-rw-r--r--gcc/testsuite/objc.dg/property/dotsyntax-11.m61
-rw-r--r--gcc/testsuite/objc.dg/property/dotsyntax-12.m105
-rw-r--r--gcc/testsuite/objc.dg/property/dotsyntax-13.m53
-rw-r--r--gcc/testsuite/objc.dg/property/dotsyntax-14.m77
-rw-r--r--gcc/testsuite/objc.dg/property/dotsyntax-15.m80
-rw-r--r--gcc/testsuite/objc.dg/property/dotsyntax-16.m91
-rw-r--r--gcc/testsuite/objc.dg/property/dotsyntax-17.m67
-rw-r--r--gcc/testsuite/objc.dg/property/dotsyntax-18.m90
-rw-r--r--gcc/testsuite/objc.dg/property/dotsyntax-19.m113
-rw-r--r--gcc/testsuite/objc.dg/property/dotsyntax-2.m72
-rw-r--r--gcc/testsuite/objc.dg/property/dotsyntax-20.m67
-rw-r--r--gcc/testsuite/objc.dg/property/dotsyntax-21.m113
-rw-r--r--gcc/testsuite/objc.dg/property/dotsyntax-22.m19
-rw-r--r--gcc/testsuite/objc.dg/property/dotsyntax-3.m64
-rw-r--r--gcc/testsuite/objc.dg/property/dotsyntax-4.m42
-rw-r--r--gcc/testsuite/objc.dg/property/dotsyntax-5.m78
-rw-r--r--gcc/testsuite/objc.dg/property/dotsyntax-6.m106
-rw-r--r--gcc/testsuite/objc.dg/property/dotsyntax-7.m48
-rw-r--r--gcc/testsuite/objc.dg/property/dotsyntax-8.m62
-rw-r--r--gcc/testsuite/objc.dg/property/dotsyntax-9.m77
-rw-r--r--gcc/testsuite/objc.dg/property/dotsyntax-deprecated-1.m41
-rw-r--r--gcc/testsuite/objc.dg/property/dynamic-1.m34
-rw-r--r--gcc/testsuite/objc.dg/property/dynamic-2.m45
-rw-r--r--gcc/testsuite/objc.dg/property/dynamic-3.m49
-rw-r--r--gcc/testsuite/objc.dg/property/dynamic-4.m45
-rw-r--r--gcc/testsuite/objc.dg/property/dynamic-5.m53
-rw-r--r--gcc/testsuite/objc.dg/property/dynamic-6.m26
-rw-r--r--gcc/testsuite/objc.dg/property/fsf-property-basic.m62
-rw-r--r--gcc/testsuite/objc.dg/property/fsf-property-method-access.m67
-rw-r--r--gcc/testsuite/objc.dg/property/fsf-property-named-ivar.m61
-rw-r--r--gcc/testsuite/objc.dg/property/property-1.m32
-rw-r--r--gcc/testsuite/objc.dg/property/property-encoding-1.m182
-rw-r--r--gcc/testsuite/objc.dg/property/property-neg-1.m13
-rw-r--r--gcc/testsuite/objc.dg/property/property-neg-2.m8
-rw-r--r--gcc/testsuite/objc.dg/property/property-neg-3.m14
-rw-r--r--gcc/testsuite/objc.dg/property/property-neg-4.m17
-rw-r--r--gcc/testsuite/objc.dg/property/property-neg-5.m5
-rw-r--r--gcc/testsuite/objc.dg/property/property-neg-6.m9
-rw-r--r--gcc/testsuite/objc.dg/property/property-neg-7.m20
-rw-r--r--gcc/testsuite/objc.dg/property/property.exp43
-rw-r--r--gcc/testsuite/objc.dg/property/synthesize-1.m53
-rw-r--r--gcc/testsuite/objc.dg/property/synthesize-10.m53
-rw-r--r--gcc/testsuite/objc.dg/property/synthesize-11.m31
-rw-r--r--gcc/testsuite/objc.dg/property/synthesize-2.m51
-rw-r--r--gcc/testsuite/objc.dg/property/synthesize-3.m66
-rw-r--r--gcc/testsuite/objc.dg/property/synthesize-4.m67
-rw-r--r--gcc/testsuite/objc.dg/property/synthesize-5.m18
-rw-r--r--gcc/testsuite/objc.dg/property/synthesize-6.m32
-rw-r--r--gcc/testsuite/objc.dg/property/synthesize-7.m86
-rw-r--r--gcc/testsuite/objc.dg/property/synthesize-8.m80
-rw-r--r--gcc/testsuite/objc.dg/property/synthesize-9.m80
-rw-r--r--gcc/testsuite/objc.dg/proto-hier-1.m58
-rw-r--r--gcc/testsuite/objc.dg/proto-hier-2.m49
-rw-r--r--gcc/testsuite/objc.dg/proto-init-mimatch-1.m35
-rw-r--r--gcc/testsuite/objc.dg/proto-lossage-1.m44
-rw-r--r--gcc/testsuite/objc.dg/proto-lossage-2.m20
-rw-r--r--gcc/testsuite/objc.dg/proto-lossage-3.m26
-rw-r--r--gcc/testsuite/objc.dg/proto-lossage-4.m54
-rw-r--r--gcc/testsuite/objc.dg/proto-lossage-5.m22
-rw-r--r--gcc/testsuite/objc.dg/proto-lossage-6.m18
-rw-r--r--gcc/testsuite/objc.dg/proto-lossage-7.m28
-rw-r--r--gcc/testsuite/objc.dg/proto-qual-1.m70
-rw-r--r--gcc/testsuite/objc.dg/protocol-forward-1.m26
-rw-r--r--gcc/testsuite/objc.dg/protocol-forward-2.m95
-rw-r--r--gcc/testsuite/objc.dg/protocol-inheritance-1.m54
-rw-r--r--gcc/testsuite/objc.dg/protocol-inheritance-2.m57
-rw-r--r--gcc/testsuite/objc.dg/protocol-optional-1.m48
-rw-r--r--gcc/testsuite/objc.dg/protocol-qualifier-1.m33
-rw-r--r--gcc/testsuite/objc.dg/protocol-qualifier-2.m31
-rw-r--r--gcc/testsuite/objc.dg/selector-1.m27
-rw-r--r--gcc/testsuite/objc.dg/selector-2.m16
-rw-r--r--gcc/testsuite/objc.dg/selector-3.m30
-rw-r--r--gcc/testsuite/objc.dg/selector-4.m30
-rw-r--r--gcc/testsuite/objc.dg/selector-warn-1.m16
-rw-r--r--gcc/testsuite/objc.dg/set-not-used-1.m36
-rw-r--r--gcc/testsuite/objc.dg/sizeof-1.m34
-rw-r--r--gcc/testsuite/objc.dg/special/load-category-1.h20
-rw-r--r--gcc/testsuite/objc.dg/special/load-category-1.m39
-rw-r--r--gcc/testsuite/objc.dg/special/load-category-1a.m21
-rw-r--r--gcc/testsuite/objc.dg/special/load-category-2.h19
-rw-r--r--gcc/testsuite/objc.dg/special/load-category-2.m105
-rw-r--r--gcc/testsuite/objc.dg/special/load-category-2a.m46
-rw-r--r--gcc/testsuite/objc.dg/special/load-category-3.h17
-rw-r--r--gcc/testsuite/objc.dg/special/load-category-3.m87
-rw-r--r--gcc/testsuite/objc.dg/special/load-category-3a.m65
-rw-r--r--gcc/testsuite/objc.dg/special/special.exp145
-rw-r--r--gcc/testsuite/objc.dg/special/unclaimed-category-1.h29
-rw-r--r--gcc/testsuite/objc.dg/special/unclaimed-category-1.m75
-rw-r--r--gcc/testsuite/objc.dg/special/unclaimed-category-1a.m29
-rw-r--r--gcc/testsuite/objc.dg/stabs-1.m18
-rw-r--r--gcc/testsuite/objc.dg/static-1.m33
-rw-r--r--gcc/testsuite/objc.dg/stret-1.m65
-rw-r--r--gcc/testsuite/objc.dg/stret-2.m49
-rw-r--r--gcc/testsuite/objc.dg/strings/const-cfstring-2.m27
-rw-r--r--gcc/testsuite/objc.dg/strings/const-cfstring-5.m26
-rw-r--r--gcc/testsuite/objc.dg/strings/const-str-1.m25
-rw-r--r--gcc/testsuite/objc.dg/strings/const-str-12.m16
-rw-r--r--gcc/testsuite/objc.dg/strings/const-str-12b.m28
-rw-r--r--gcc/testsuite/objc.dg/strings/const-str-2.m8
-rw-r--r--gcc/testsuite/objc.dg/strings/const-str-5.m28
-rw-r--r--gcc/testsuite/objc.dg/strings/const-str-6.m28
-rw-r--r--gcc/testsuite/objc.dg/strings/strings-1.m33
-rw-r--r--gcc/testsuite/objc.dg/strings/strings-2.m67
-rw-r--r--gcc/testsuite/objc.dg/strings/strings.exp46
-rw-r--r--gcc/testsuite/objc.dg/stubify-1.m35
-rw-r--r--gcc/testsuite/objc.dg/stubify-2.m33
-rw-r--r--gcc/testsuite/objc.dg/super-class-1.m5
-rw-r--r--gcc/testsuite/objc.dg/super-class-2.m44
-rw-r--r--gcc/testsuite/objc.dg/super-class-3.m46
-rw-r--r--gcc/testsuite/objc.dg/super-class-4.m34
-rw-r--r--gcc/testsuite/objc.dg/super-dealloc-1.m46
-rw-r--r--gcc/testsuite/objc.dg/super-dealloc-2.m46
-rw-r--r--gcc/testsuite/objc.dg/symtab-1.m27
-rw-r--r--gcc/testsuite/objc.dg/sync-1.m12
-rw-r--r--gcc/testsuite/objc.dg/sync-2.m35
-rw-r--r--gcc/testsuite/objc.dg/sync-3.m128
-rw-r--r--gcc/testsuite/objc.dg/threedotthree-abi-1.m69
-rw-r--r--gcc/testsuite/objc.dg/tls/diag-2.m26
-rw-r--r--gcc/testsuite/objc.dg/tls/diag-3.m11
-rw-r--r--gcc/testsuite/objc.dg/tls/diag-4.m10
-rw-r--r--gcc/testsuite/objc.dg/tls/diag-5.m4
-rw-r--r--gcc/testsuite/objc.dg/tls/init-1.m5
-rw-r--r--gcc/testsuite/objc.dg/tls/init-2.m14
-rw-r--r--gcc/testsuite/objc.dg/tls/tls.exp26
-rw-r--r--gcc/testsuite/objc.dg/too-many-args.m10
-rw-r--r--gcc/testsuite/objc.dg/torture/dg-torture.exp17
-rw-r--r--gcc/testsuite/objc.dg/torture/forward-1.m87
-rw-r--r--gcc/testsuite/objc.dg/torture/strings/const-cfstring-1.m62
-rw-r--r--gcc/testsuite/objc.dg/torture/strings/const-cfstring-3.m27
-rw-r--r--gcc/testsuite/objc.dg/torture/strings/const-cfstring-4.m21
-rw-r--r--gcc/testsuite/objc.dg/torture/strings/const-str-10.m35
-rw-r--r--gcc/testsuite/objc.dg/torture/strings/const-str-11.m35
-rw-r--r--gcc/testsuite/objc.dg/torture/strings/const-str-3.m54
-rw-r--r--gcc/testsuite/objc.dg/torture/strings/const-str-4.m32
-rw-r--r--gcc/testsuite/objc.dg/torture/strings/const-str-7.m42
-rw-r--r--gcc/testsuite/objc.dg/torture/strings/const-str-8.m43
-rw-r--r--gcc/testsuite/objc.dg/torture/strings/const-str-9.m27
-rw-r--r--gcc/testsuite/objc.dg/torture/strings/string1.m22
-rw-r--r--gcc/testsuite/objc.dg/torture/strings/string2.m23
-rw-r--r--gcc/testsuite/objc.dg/torture/strings/string3.m24
-rw-r--r--gcc/testsuite/objc.dg/torture/strings/string4.m22
-rw-r--r--gcc/testsuite/objc.dg/torture/strings/strings.exp34
-rw-r--r--gcc/testsuite/objc.dg/torture/tls/diag-1.m12
-rw-r--r--gcc/testsuite/objc.dg/torture/tls/thr-init-2.m43
-rw-r--r--gcc/testsuite/objc.dg/torture/tls/thr-init-3.m39
-rw-r--r--gcc/testsuite/objc.dg/torture/tls/thr-init.m26
-rw-r--r--gcc/testsuite/objc.dg/torture/tls/tls.exp17
-rw-r--r--gcc/testsuite/objc.dg/torture/tls/trivial.m3
-rw-r--r--gcc/testsuite/objc.dg/torture/trivial.m11
-rw-r--r--gcc/testsuite/objc.dg/try-catch-1.m41
-rw-r--r--gcc/testsuite/objc.dg/try-catch-10.m40
-rw-r--r--gcc/testsuite/objc.dg/try-catch-11.m51
-rw-r--r--gcc/testsuite/objc.dg/try-catch-12.m63
-rw-r--r--gcc/testsuite/objc.dg/try-catch-3.m19
-rw-r--r--gcc/testsuite/objc.dg/try-catch-4.m26
-rw-r--r--gcc/testsuite/objc.dg/try-catch-5.m27
-rw-r--r--gcc/testsuite/objc.dg/try-catch-6.m25
-rw-r--r--gcc/testsuite/objc.dg/try-catch-7.m27
-rw-r--r--gcc/testsuite/objc.dg/try-catch-9.m24
-rw-r--r--gcc/testsuite/objc.dg/two-types-1.m15
-rw-r--r--gcc/testsuite/objc.dg/type-size-1.m17
-rw-r--r--gcc/testsuite/objc.dg/type-size-2.m75
-rw-r--r--gcc/testsuite/objc.dg/type-size-3.m18
-rw-r--r--gcc/testsuite/objc.dg/type-size-4.m23
-rw-r--r--gcc/testsuite/objc.dg/type-size-5.m22
-rw-r--r--gcc/testsuite/objc.dg/type-stream-1.m17
-rw-r--r--gcc/testsuite/objc.dg/typedef-alias-1.m16
-rw-r--r--gcc/testsuite/objc.dg/undeclared-selector.m48
-rw-r--r--gcc/testsuite/objc.dg/va-meth-1.m73
-rw-r--r--gcc/testsuite/objc.dg/volatile-1.m18
-rw-r--r--gcc/testsuite/objc.dg/weak-1.m13
-rw-r--r--gcc/testsuite/objc.dg/zero-link-1.m31
-rw-r--r--gcc/testsuite/objc.dg/zero-link-2.m29
-rw-r--r--gcc/testsuite/objc.dg/zero-link-3.m28
423 files changed, 23076 insertions, 0 deletions
diff --git a/gcc/testsuite/objc.dg/alias.m b/gcc/testsuite/objc.dg/alias.m
new file mode 100644
index 000000000..a57d032eb
--- /dev/null
+++ b/gcc/testsuite/objc.dg/alias.m
@@ -0,0 +1,12 @@
+/* Test alias warnings. */
+/* { dg-do compile } */
+
+@compatibility_alias class1 class2; /* { dg-warning "annot find class" } */
+
+@interface class3;
+@end
+
+@interface class4;
+@end
+
+@compatibility_alias class4 class3; /* { dg-warning "lass" "already exists" } */
diff --git a/gcc/testsuite/objc.dg/anon-1.m b/gcc/testsuite/objc.dg/anon-1.m
new file mode 100644
index 000000000..5f10f7d60
--- /dev/null
+++ b/gcc/testsuite/objc.dg/anon-1.m
@@ -0,0 +1,14 @@
+/* Test for graceful handling of anonymous ivars. */
+/* { dg-do compile } */
+
+@interface Foo {
+ unsigned char : 1;
+ int e: 3;
+ signed: 2;
+ float f;
+}
+@end
+
+@implementation Foo
+@end
+
diff --git a/gcc/testsuite/objc.dg/at-class-1.m b/gcc/testsuite/objc.dg/at-class-1.m
new file mode 100644
index 000000000..63721aa99
--- /dev/null
+++ b/gcc/testsuite/objc.dg/at-class-1.m
@@ -0,0 +1,11 @@
+/* Test @class. */
+/* { dg-do compile } */
+
+@class Object; /* Ok */
+
+@class Object, ; /* { dg-error "expected identifier" } */
+@class Object, ; /* { dg-error "expected identifier" } */
+@class Object, AnotherObject, ; /* { dg-error "expected identifier" } */
+@class Object, AnotherObject, TestObject ; /* Ok */
+
+@class Object /* { dg-error "expected .;." } */
diff --git a/gcc/testsuite/objc.dg/attributes/attributes.exp b/gcc/testsuite/objc.dg/attributes/attributes.exp
new file mode 100644
index 000000000..cb11216c5
--- /dev/null
+++ b/gcc/testsuite/objc.dg/attributes/attributes.exp
@@ -0,0 +1,44 @@
+# Copyright (C) 2010 Free Software Foundation, Inc.
+#
+# This file is part of GCC.
+#
+# GCC 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, or (at your option)
+# any later version.
+#
+# GCC 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 GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+# Load support procs.
+
+load_lib objc-dg.exp
+
+# If a testcase doesn't have special options, use these.
+global DEFAULT_CFLAGS
+if ![info exists DEFAULT_CFLAGS] then {
+ set DEFAULT_CFLAGS ""
+}
+
+# Initialize `dg'.
+dg-init
+
+# Gather a list of all tests.
+set tests [lsort [glob -nocomplain $srcdir/$subdir/*.m]]
+
+# Main loop.
+dg-runtest $tests "-fgnu-runtime" $DEFAULT_CFLAGS
+
+# darwin targets can also run code with the NeXT runtime.
+if [istarget "*-*-darwin*" ] {
+ dg-runtest $tests "-fnext-runtime" $DEFAULT_CFLAGS
+}
+
+# All done.
+dg-finish
diff --git a/gcc/testsuite/objc.dg/attributes/categ-attribute-1.m b/gcc/testsuite/objc.dg/attributes/categ-attribute-1.m
new file mode 100644
index 000000000..e9fe9c986
--- /dev/null
+++ b/gcc/testsuite/objc.dg/attributes/categ-attribute-1.m
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+#include "../../objc-obj-c++-shared/Object1.h"
+
+@interface obj : Object {
+@public
+ int var;
+}
+- (int) mth;
+@end
+
+@implementation obj
+- (int) mth { return var; }
+@end
+
+__attribute ((deprecated))
+@interface obj (dep_categ)
+- (int) depmth;/* { dg-warning "category attributes are not available in this version" } */
+@end
+
+@implementation obj (dep_categ)
+- (int) depmth { return var + 1; }
+@end
+
+int foo (void)
+{
+ obj *p = [obj new];
+ int q = [p depmth];
+ return [p mth];
+}
diff --git a/gcc/testsuite/objc.dg/attributes/categ-attribute-2.m b/gcc/testsuite/objc.dg/attributes/categ-attribute-2.m
new file mode 100644
index 000000000..4a98de130
--- /dev/null
+++ b/gcc/testsuite/objc.dg/attributes/categ-attribute-2.m
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+#include "../../objc-obj-c++-shared/Object1.h"
+
+@interface obj : Object {
+@public
+ int var;
+}
+- (int) mth;
+@end
+
+@implementation obj
+- (int) mth { return var; }
+@end
+
+__attribute__ ((deprecated("no dep_categ")))
+@interface obj (dep_categ)
+- (int) depmth;/* { dg-warning "category attributes are not available in this version" } */
+@end
+
+__attribute__ ((deprecated))
+@implementation obj (dep_categ) /* { dg-warning "prefix attributes are ignored for implementations" } */
+- (int) depmth { return var + 1; }
+@end
+
+int foo (void)
+{
+ obj *p = [obj new];
+ int q = [p depmth];
+ return [p mth];
+}
diff --git a/gcc/testsuite/objc.dg/attributes/class-attribute-1.m b/gcc/testsuite/objc.dg/attributes/class-attribute-1.m
new file mode 100644
index 000000000..3444760bc
--- /dev/null
+++ b/gcc/testsuite/objc.dg/attributes/class-attribute-1.m
@@ -0,0 +1,59 @@
+/* { dg-do compile } */
+
+/* Test deprecate attribute with an @interface declaration. */
+
+#include <objc/objc.h>
+
+__attribute__ ((deprecated))
+@interface DeprecatedClass
+{
+ Class isa;
+}
++ (id) classObject;
++ (id) new;
+@end
+
+@implementation DeprecatedClass
++ (id) classObject { return self; }
++ (id) new { return nil; }
+@end
+
+@interface DeprecatedClass (Category)
+@end /* { dg-warning "is deprecated" } */
+
+@interface Subclass : DeprecatedClass
+@end /* { dg-warning "is deprecated" } */
+
+DeprecatedClass *object; /* { dg-warning "is deprecated" } */
+
+int function (DeprecatedClass *object) /* { dg-warning "is deprecated" } */
+{
+ /* Note how the following deprecation warning is generated by
+ "DeprecatedClass *", not by "[DeprecatedClass ...]. */
+ DeprecatedClass *x = [DeprecatedClass new]; /* { dg-warning "is deprecated" } */
+
+ if (x == object)
+ return 0;
+ else
+ return 1;
+}
+
+id function2 (void)
+{
+ return DeprecatedClass.classObject; /* { dg-warning "is deprecated" } */
+}
+
+@interface NormalClass
+{
+ Class isa;
+ DeprecatedClass *object; /* { dg-warning "is deprecated" } */
+}
+- (DeprecatedClass *)method; /* { dg-warning "is deprecated" } */
+@end
+
+@implementation NormalClass
+- (DeprecatedClass *)method /* { dg-warning "is deprecated" } */
+{
+ return nil;
+}
+@end
diff --git a/gcc/testsuite/objc.dg/attributes/class-attribute-2.m b/gcc/testsuite/objc.dg/attributes/class-attribute-2.m
new file mode 100644
index 000000000..2e1bacb3f
--- /dev/null
+++ b/gcc/testsuite/objc.dg/attributes/class-attribute-2.m
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+__attribute__ ((deprecated))
+@interface DeprecatedClass
+{
+ Class isa;
+}
++ (id) new;
+@end
+
+__attribute__ ((deprecated))
+@implementation DeprecatedClass /* { dg-warning "prefix attributes are ignored for implementations" } */
++ (id) new { return nil; }
+@end
+
+void function (void)
+{
+ DeprecatedClass *object = [DeprecatedClass new]; /* { dg-warning "is deprecated" } */
+}
diff --git a/gcc/testsuite/objc.dg/attributes/class-attribute-3.m b/gcc/testsuite/objc.dg/attributes/class-attribute-3.m
new file mode 100644
index 000000000..6cc5d4e26
--- /dev/null
+++ b/gcc/testsuite/objc.dg/attributes/class-attribute-3.m
@@ -0,0 +1,14 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
+/* { dg-do compile } */
+
+/* Test that you get a warning when an unknown class attribute is ignored. */
+
+#include <objc/objc.h>
+
+__attribute__ ((unknown_attribute))
+@interface MyClass
+{ /* { dg-warning "ignored" } */
+ Class isa;
+}
++ (id) new;
+@end
diff --git a/gcc/testsuite/objc.dg/attributes/invalid-attribute-1.m b/gcc/testsuite/objc.dg/attributes/invalid-attribute-1.m
new file mode 100644
index 000000000..ec17e9d71
--- /dev/null
+++ b/gcc/testsuite/objc.dg/attributes/invalid-attribute-1.m
@@ -0,0 +1,6 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, January 2011. */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+__attribute__ ((deprecated)) @class A; /* { dg-error "unexpected attribute before .class." } */
diff --git a/gcc/testsuite/objc.dg/attributes/method-attribute-1.m b/gcc/testsuite/objc.dg/attributes/method-attribute-1.m
new file mode 100644
index 000000000..ffe72e20f
--- /dev/null
+++ b/gcc/testsuite/objc.dg/attributes/method-attribute-1.m
@@ -0,0 +1,40 @@
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+#include "../../objc-obj-c++-shared/Object1.h"
+
+@interface obj : Object {
+@public
+ int var;
+}
+- (int) mth;
++ (id) dep_cls_mth __attribute__((deprecated)) ;
+- (int) dep_ins_mth __attribute__((deprecated)) ;
+- (int) dep_ins_mtharg: (int) i __attribute__((deprecated)) ;
+- (int) dep_ins_mtharg1: (int) i __attribute__((deprecated)) add: (int) j;/* { dg-error "expected ';' or '\{' after method attribute definition" } */
+- (int) nodef __attribute__((deprecated)) { return var-2; } ; /* { dg-error "expected ';' before '\{' token" } */
+__attribute__((deprecated))
+- (int) bad_pref_mth; /* { dg-warning "prefix attributes are ignored for methods" } */
+@end
+
+@implementation obj
+- (int) mth { return var; }
++ (id) dep_cls_mth { return self; }
+- (int) dep_ins_mth { return var ; }
+- (int) dep_ins_mtharg: (int) i { return var + i ; }
+- (int) dep_ins_mtharg1: (int) i add: (int) j { return var + i + j ; }
+- (int) bad_pref_mth { return var; };
+- (int) nodef { return var-2; } ;
+@end
+
+int foo (void)
+{
+ obj *p = [obj new];
+ id n = [obj dep_cls_mth]; /* { dg-warning "is deprecated" } */
+
+ [p dep_ins_mth]; /* { dg-warning "is deprecated" } */
+ [p dep_ins_mtharg:2]; /* { dg-warning "is deprecated" } */
+ [p dep_ins_mtharg1:3 add:3];
+
+ return [p mth];
+}
diff --git a/gcc/testsuite/objc.dg/attributes/method-attribute-2.m b/gcc/testsuite/objc.dg/attributes/method-attribute-2.m
new file mode 100644
index 000000000..4a56b3aa8
--- /dev/null
+++ b/gcc/testsuite/objc.dg/attributes/method-attribute-2.m
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+#include "../../objc-obj-c++-shared/Object1.h"
+
+@interface obj : Object {
+@public
+ int var;
+}
+- (int) depmth __attribute__((deprecated));
+- (int) depmtharg:(int) iarg __attribute__((deprecated));
+- (int) unusedarg:(int) __attribute__((unused)) uarg ;
+- (int) depunusedarg:(int) __attribute__((unused)) uarg __attribute__((deprecated)) ;
+@end
+
+@implementation obj
+- (int) depmth __attribute__((deprecated)) { return var; } /* { dg-warning "method attributes can not be specified in @implementation context" } */
+- (int) depmtharg:(int) iarg { return var + iarg ; }
+- (int) unusedarg:(int) __attribute__((unused)) uarg { return var; }
+- (int) depunusedarg:(int) __attribute__((unused)) uarg { return var; }
+@end
+
+int foo (void)
+{
+ obj *p = [obj new];
+
+ [p depmth]; /* { dg-warning "is deprecated" } */
+ [p depmtharg:1]; /* { dg-warning "is deprecated" } */
+ [p unusedarg:2]; /* { dg-bogus "is deprecated" } */
+ [p depunusedarg:3 ]; /* { dg-warning "is deprecated" } */
+
+ return [p depmtharg:0]; /* { dg-warning "is deprecated" } */
+}
diff --git a/gcc/testsuite/objc.dg/attributes/method-attribute-3.m b/gcc/testsuite/objc.dg/attributes/method-attribute-3.m
new file mode 100644
index 000000000..de607a3d9
--- /dev/null
+++ b/gcc/testsuite/objc.dg/attributes/method-attribute-3.m
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+
+#include "../../objc-obj-c++-shared/Object1.h"
+
+@interface obj : Object {
+@public
+ int var;
+}
+- (int) vargsn: (int) count, ... __attribute__((deprecated));
+@end
+
+@implementation obj
+- (int) vargsn: (int) count, ...
+{
+ return 0;
+}
+@end
+
+int foo (void)
+{
+ obj *p = [obj new];
+
+ return [p vargsn:0]; /* { dg-warning "'vargsn:' is deprecated .declared at " } */
+}
diff --git a/gcc/testsuite/objc.dg/attributes/method-deprecated-1.m b/gcc/testsuite/objc.dg/attributes/method-deprecated-1.m
new file mode 100644
index 000000000..8343856a5
--- /dev/null
+++ b/gcc/testsuite/objc.dg/attributes/method-deprecated-1.m
@@ -0,0 +1,33 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+@interface MyClass
+{
+ Class isa;
+}
++ (int) method;
+- (int) method;
++ (int) deprecatedClassMethod __attribute__((deprecated));
+- (int) deprecatedInstanceMethod __attribute__((deprecated));
+@end
+
+/* Test that deprecation warnings are produced, but not if the
+ receiver is of type 'id'. */
+void foo (void)
+{
+ Class c;
+ id object;
+ MyClass *another_object;
+
+ [c method];
+ [object method];
+ [c deprecatedClassMethod];
+ [object deprecatedInstanceMethod];
+
+ [object method];
+ [another_object method];
+ [MyClass deprecatedClassMethod]; /* { dg-warning "is deprecated" } */
+ [another_object deprecatedInstanceMethod]; /* { dg-warning "is deprecated" } */
+}
diff --git a/gcc/testsuite/objc.dg/attributes/method-deprecated-2.m b/gcc/testsuite/objc.dg/attributes/method-deprecated-2.m
new file mode 100644
index 000000000..1e5d87f3e
--- /dev/null
+++ b/gcc/testsuite/objc.dg/attributes/method-deprecated-2.m
@@ -0,0 +1,23 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+@interface MyClass
+{
+ Class isa;
+}
++ (int) deprecatedClassMethod: (id)firstObject, ... __attribute__((sentinel)) __attribute__((deprecated));
+- (int) deprecatedInstanceMethod: (id)firstobject, ... __attribute__((sentinel)) __attribute__((deprecated));
+@end
+
+/* Test that deprecation warnings are produced even if the method is
+ also marked with another attribute too (this is to test the
+ processing of multiple attributes). */
+void foo (void)
+{
+ MyClass *object = nil;
+
+ [MyClass deprecatedClassMethod: object, nil]; /* { dg-warning "is deprecated" } */
+ [object deprecatedInstanceMethod: object, nil]; /* { dg-warning "is deprecated" } */
+}
diff --git a/gcc/testsuite/objc.dg/attributes/method-deprecated-3.m b/gcc/testsuite/objc.dg/attributes/method-deprecated-3.m
new file mode 100644
index 000000000..5c715a20b
--- /dev/null
+++ b/gcc/testsuite/objc.dg/attributes/method-deprecated-3.m
@@ -0,0 +1,21 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+/* Test that __attribute__ ((__deprecated__)) works as well as __attribute__ ((deprecated)). */
+@interface MyClass
+{
+ Class isa;
+}
++ (int) deprecatedClassMethod: (id)firstObject, ... __attribute__((__deprecated__));
+- (int) deprecatedInstanceMethod: (id)firstobject, ... __attribute__((__deprecated__));
+@end
+
+void foo (void)
+{
+ MyClass *object = nil;
+
+ [MyClass deprecatedClassMethod: object, nil]; /* { dg-warning "is deprecated" } */
+ [object deprecatedInstanceMethod: object, nil]; /* { dg-warning "is deprecated" } */
+}
diff --git a/gcc/testsuite/objc.dg/attributes/method-format-1.m b/gcc/testsuite/objc.dg/attributes/method-format-1.m
new file mode 100644
index 000000000..11ce8eebb
--- /dev/null
+++ b/gcc/testsuite/objc.dg/attributes/method-format-1.m
@@ -0,0 +1,43 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */
+/* { dg-do compile } */
+/* { dg-options "-Wall" } */
+
+#include <objc/objc.h>
+#include <stdlib.h>
+
+@interface LogObject
+{
+ Class isa;
+}
++ (void) log: (int)level message: (const char *) my_format, ... __attribute__ ((format (printf, 2, 3)));
+- (void) log: (int)level message: (const char *) my_format, ... __attribute__ ((format (printf, 2, 3)));
+
++ (void) debug: (const char *) my_format, ... __attribute__ ((format (printf, 1, 2)));
+- (void) debug: (const char *) my_format, ... __attribute__ ((format (printf, 1, 2)));
+
+/* Just make sure a missing or invalid attribute won't crash the compiler. */
+- (void) log2: (int)level message: (const char *) my_format, ... __attribute__ ((format (printf, 2))); /* { dg-error "wrong" } */
++ (void) debug2: (const char *) my_format, ... __attribute__ ((format (printf))); /* { dg-error "wrong" } */
+- (void) debug2: (const char *) my_format, ... __attribute__ ((format (printf))); /* { dg-error "wrong" } */
++ (void) alert: (const char *) my_format __attribute__ ((format (printf, 1, 2))); /* { dg-error "args to be formatted is not ..." } */
+- (void) alert: (const char *) my_format __attribute__ ((format (printf, 1, 2))); /* { dg-error "args to be formatted is not ..." } */
+@end
+
+void test (LogObject *object)
+{
+ [object log: 2 message: "attribute only applies to variadic functions"];
+ [object log: 2 message: "attribute %s only applies to variadic functions", "'format'"];
+ [object log: 2 message: "attribute %s only applies to variadic functions"]; /* { dg-warning "expects a matching" } */
+
+ [object debug: "attribute only applies to variadic functions"];
+ [object debug: "attribute %s only applies to variadic functions", "'format'"];
+ [object debug: "attribute %s only applies to variadic functions"]; /* { dg-warning "expects a matching" } */
+
+ [LogObject log: 2 message: "attribute only applies to variadic functions"];
+ [LogObject log: 2 message: "attribute %s only applies to variadic functions", "'format'"];
+ [LogObject log: 2 message: "attribute %s only applies to variadic functions"]; /* { dg-warning "expects a matching" } */
+
+ [LogObject debug: "attribute only applies to variadic functions"];
+ [LogObject debug: "attribute %s only applies to variadic functions", "'format'"];
+ [LogObject debug: "attribute %s only applies to variadic functions"]; /* { dg-warning "expects a matching" } */
+}
diff --git a/gcc/testsuite/objc.dg/attributes/method-noreturn-1.m b/gcc/testsuite/objc.dg/attributes/method-noreturn-1.m
new file mode 100644
index 000000000..717d6e65e
--- /dev/null
+++ b/gcc/testsuite/objc.dg/attributes/method-noreturn-1.m
@@ -0,0 +1,34 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+#include <stdlib.h>
+
+@interface MyClass
+{
+ Class isa;
+}
++ (id) method1 __attribute__ ((noreturn));
+- (id) method2 __attribute__ ((noreturn));
++ (id) method3 __attribute__ ((noreturn));
+- (id) method4 __attribute__ ((noreturn));
+@end
+
+@implementation MyClass
++ (id) method1
+{
+ return self; /* { dg-warning "function declared .noreturn. has a .return. statement" } */
+} /* { dg-warning ".noreturn. function does return" "" { target *-*-* } 20 } */
+- (id) method2
+{
+ return self; /* { dg-warning "function declared .noreturn. has a .return. statement" } */
+} /* { dg-warning ".noreturn. function does return" "" { target *-*-* } 24 } */
++ (id) method3
+{
+ abort ();
+}
+- (id) method4
+{
+ abort ();
+}
+@end
diff --git a/gcc/testsuite/objc.dg/attributes/method-sentinel-1.m b/gcc/testsuite/objc.dg/attributes/method-sentinel-1.m
new file mode 100644
index 000000000..e2abb1e8a
--- /dev/null
+++ b/gcc/testsuite/objc.dg/attributes/method-sentinel-1.m
@@ -0,0 +1,35 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */
+/* { dg-do compile } */
+/* { dg-options "-Wall" } */
+
+#include <objc/objc.h>
+#include <stdlib.h>
+#include "../../objc-obj-c++-shared/objc-test-suite-types.h"
+
+@interface NSArray
+{
+ Class isa;
+}
++ (id) arrayWithObject: (id)object __attribute__ ((sentinel)); /* { dg-warning "attribute only applies to variadic functions" } */
++ (id) arrayWithObjects: (id)firstObject, ... __attribute__ ((sentinel));
+
+- (id) initWithObject: (id)object __attribute__ ((sentinel)); /* { dg-warning "attribute only applies to variadic functions" } */
+- (id) initWithObjects: (id)firstObject, ... __attribute__ ((sentinel));
+@end
+
+void test (id object)
+{
+ NSArray *array;
+
+ array = [NSArray arrayWithObject: object];
+ array = [NSArray arrayWithObjects: object, nil];
+ array = [NSArray arrayWithObjects: object, object, nil];
+ array = [NSArray arrayWithObjects: object]; /* { dg-warning "not enough variable arguments" } */
+ array = [NSArray arrayWithObjects: object, object]; /* { dg-warning "missing sentinel" } */
+
+ [array initWithObject: object];
+ [array initWithObjects: object, nil];
+ [array initWithObjects: object, object, nil];
+ [array initWithObjects: object]; /* { dg-warning "not enough variable arguments" } */
+ [array initWithObjects: object, object]; /* { dg-warning "missing sentinel" } */
+}
diff --git a/gcc/testsuite/objc.dg/attributes/objc-exception-1.m b/gcc/testsuite/objc.dg/attributes/objc-exception-1.m
new file mode 100644
index 000000000..e7f6f856f
--- /dev/null
+++ b/gcc/testsuite/objc.dg/attributes/objc-exception-1.m
@@ -0,0 +1,32 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, February 2011. */
+/* { dg-do compile } */
+
+/* Test that the 'objc_exception' attribute is accepted for
+ @interfaces, but not for anything else. */
+
+#include <objc/objc.h>
+
+/* Fine. */
+__attribute__ ((objc_exception))
+@interface MyClass
+{
+ Class isa;
+}
+@end
+
+/* Fine. */
+__attribute__ ((__objc_exception__))
+@interface MyClass2
+{
+ Class isa;
+}
+@end
+
+__attribute__ ((objc_exception))
+@protocol MyProtocol; /* { dg-warning "ignored" } */
+
+__attribute__ ((objc_exception))
+int myVariable; /* { dg-warning "ignored" } */
+
+__attribute__ ((objc_exception))
+int myFunction (int argument); /* { dg-warning "ignored" } */
diff --git a/gcc/testsuite/objc.dg/attributes/parameter-attribute-1.m b/gcc/testsuite/objc.dg/attributes/parameter-attribute-1.m
new file mode 100644
index 000000000..8263df66d
--- /dev/null
+++ b/gcc/testsuite/objc.dg/attributes/parameter-attribute-1.m
@@ -0,0 +1,45 @@
+/* Test __attribute__((unused)) for an Objective-C method parameter. */
+/* { dg-do compile } */
+/* { dg-options "-Wunused-parameter" } */
+
+#include <objc/objc.h>
+
+@interface MyRootClass
+{
+ Class isa;
+}
+- (id) method1: (id) argument1;
+- (id) method2: (id) __attribute__((unused)) argument1;
+- (id) method3: (id) __attribute__((unused)) argument1
+ andArgument: (id) argument2;
+- (id) method4: (id) __attribute__((unused)) argument1
+ andArgument: (id) __attribute__((unused)) argument2;
+- (id) method5: (id) argument1
+ andArgument: (id) __attribute__ ((unused)) argument2;
+@end
+
+@implementation MyRootClass
+- (id) method1: (id) argument1
+{ /* { dg-warning "unused parameter .argument1." } */
+ return nil;
+}
+- (id) method2: (id) __attribute__((unused)) argument1
+{
+ return nil;
+}
+- (id) method3: (id) __attribute__((unused)) argument1
+ andArgument: (id) argument2
+{ /* { dg-warning "unused parameter .argument2." } */
+ return nil;
+}
+- (id) method4: (id) __attribute__((unused)) argument1
+ andArgument: (id) __attribute__((unused)) argument2
+{
+ return nil;
+}
+- (id) method5: (id) argument1
+ andArgument: (id) __attribute__ ((unused)) argument2
+{ /* { dg-warning "unused parameter .argument1." } */
+ return nil;
+}
+@end
diff --git a/gcc/testsuite/objc.dg/attributes/parameter-attribute-2.m b/gcc/testsuite/objc.dg/attributes/parameter-attribute-2.m
new file mode 100644
index 000000000..99c5a308b
--- /dev/null
+++ b/gcc/testsuite/objc.dg/attributes/parameter-attribute-2.m
@@ -0,0 +1,25 @@
+/* Test that we get warnings for unrecognized attributes. */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+@interface MyRootClass
+{
+ Class isa;
+}
+/* TODO: Emit warnings in the @interface as well. Currently we only emit
+ them in @implementation. */
++ (id) method1: (id) __attribute__ ((xxxxx)) argument1;
++ (id) method2: (id) __attribute__ ((noinline)) argument1;
+@end
+
+@implementation MyRootClass
++ (id) method1: (id) __attribute__ ((xxxxx)) argument1
+{ /* { dg-warning ".xxxxx. attribute directive ignored" } */
+ return argument1;
+}
++ (id) method2: (id) __attribute__ ((noinline)) argument1
+{ /* { dg-warning ".noinline. attribute ignored" } */
+ return argument1;
+}
+@end
diff --git a/gcc/testsuite/objc.dg/attributes/proto-attribute-1.m b/gcc/testsuite/objc.dg/attributes/proto-attribute-1.m
new file mode 100644
index 000000000..a852a7a6c
--- /dev/null
+++ b/gcc/testsuite/objc.dg/attributes/proto-attribute-1.m
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+__attribute ((deprecated))
+@protocol dep_proto
+- (int) depprotomth;
+@end
+
+@interface obj <dep_proto> /* { dg-warning "is deprecated" } */
+{
+@public
+ int var;
+}
+- (int) mth;
+@end
+
+@implementation obj
+- (int) mth { return var; }
+- (int) depprotomth { return var + 1; }
+@end
diff --git a/gcc/testsuite/objc.dg/attributes/proto-attribute-2.m b/gcc/testsuite/objc.dg/attributes/proto-attribute-2.m
new file mode 100644
index 000000000..b23b81de2
--- /dev/null
+++ b/gcc/testsuite/objc.dg/attributes/proto-attribute-2.m
@@ -0,0 +1,31 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+/* Test deprecate attribute with a forward declarations of
+ @protocol. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+
+__attribute__ ((deprecated))
+@protocol DeprecatedProtocol1;
+
+@protocol NonDeprecatedProtocol1;
+
+void function1 (id <DeprecatedProtocol1> object); /* { dg-warning "is deprecated" } */
+void function2 (id <NonDeprecatedProtocol1> object);
+
+@class Class4;
+
+void function3 (Class4 <DeprecatedProtocol1> *object); /* { dg-warning "is deprecated" } */
+void function4 (Class4 <NonDeprecatedProtocol1> *object);
+void function5 (Class4 <NonDeprecatedProtocol1, DeprecatedProtocol1> *object); /* { dg-warning "is deprecated" } */
+
+int function6 (void)
+{
+ Protocol *p1 = @protocol (DeprecatedProtocol1); /* { dg-warning "is deprecated" } */
+ Protocol *p2 = @protocol (NonDeprecatedProtocol1);
+
+ return (p1 == p2);
+}
+
diff --git a/gcc/testsuite/objc.dg/attributes/proto-attribute-3.m b/gcc/testsuite/objc.dg/attributes/proto-attribute-3.m
new file mode 100644
index 000000000..2be286ecf
--- /dev/null
+++ b/gcc/testsuite/objc.dg/attributes/proto-attribute-3.m
@@ -0,0 +1,59 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+/* Test deprecate attribute with normal @protocol declarations. */
+
+
+#include <stdlib.h>
+#include <objc/objc.h>
+
+__attribute__ ((deprecated))
+@protocol DeprecatedProtocol1
+- (void) aMethod;
+@end
+
+@protocol NonDeprecatedProtocol1
+- (void) anotherMethod;
+@end
+
+@protocol Protocol2 <DeprecatedProtocol1> /* { dg-warning "is deprecated" } */
+- (void) someOtherMethod;
+@end
+
+@protocol Protocol3 <NonDeprecatedProtocol1>
+- (void) someOtherMethod2;
+@end
+
+@protocol Protocol4 <NonDeprecatedProtocol1, DeprecatedProtocol1> /* { dg-warning "is deprecated" } */
+- (void) someOtherMethod3;
+@end
+
+
+@interface Class1 <DeprecatedProtocol1> /* { dg-warning "is deprecated" } */
+@end
+
+@interface Class2 <NonDeprecatedProtocol1>
+@end
+
+@interface Class3 <NonDeprecatedProtocol1, DeprecatedProtocol1> /* { dg-warning "is deprecated" } */
+@end
+
+@interface Class2 (Category1) <DeprecatedProtocol1> /* { dg-warning "is deprecated" } */
+@end
+
+void function1 (id <DeprecatedProtocol1> object); /* { dg-warning "is deprecated" } */
+void function2 (id <NonDeprecatedProtocol1> object);
+
+@class Class4;
+
+void function3 (Class4 <DeprecatedProtocol1> *object); /* { dg-warning "is deprecated" } */
+void function4 (Class4 <NonDeprecatedProtocol1> *object);
+void function5 (Class4 <NonDeprecatedProtocol1, DeprecatedProtocol1> *object); /* { dg-warning "is deprecated" } */
+
+int function6 (void)
+{
+ Protocol *p1 = @protocol (DeprecatedProtocol1); /* { dg-warning "is deprecated" } */
+ Protocol *p2 = @protocol (NonDeprecatedProtocol1);
+
+ return (p1 == p2);
+}
diff --git a/gcc/testsuite/objc.dg/attributes/proto-attribute-4.m b/gcc/testsuite/objc.dg/attributes/proto-attribute-4.m
new file mode 100644
index 000000000..226fd68b3
--- /dev/null
+++ b/gcc/testsuite/objc.dg/attributes/proto-attribute-4.m
@@ -0,0 +1,31 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
+/* { dg-do compile } */
+
+/* Test that you get a warning when an unknown protocol attribute is ignored. */
+
+#include <objc/objc.h>
+
+__attribute__ ((unknown_attribute))
+@protocol MyProtocol
+- (id) new; /* { dg-warning "ignored" } */
+@end
+
+__attribute__ ((unknown_attribute))
+@protocol MyProtocol2; /* { dg-warning "ignored" } */
+
+/* Use the protocols to double-check that no more warnings are
+ generated. */
+
+@interface MyClass <MyProtocol>
+@end
+
+int test (id <MyProtocol2> x)
+{
+ if (@protocol (MyProtocol) == @protocol (MyProtocol2))
+ return 1;
+
+ if (x)
+ return 2;
+
+ return 3;
+}
diff --git a/gcc/testsuite/objc.dg/bad-receiver-type-2.m b/gcc/testsuite/objc.dg/bad-receiver-type-2.m
new file mode 100644
index 000000000..eca8400d5
--- /dev/null
+++ b/gcc/testsuite/objc.dg/bad-receiver-type-2.m
@@ -0,0 +1,41 @@
+/* { dg-do compile } */
+/* Contributed by Alexander Malmberg: PR18456 */
+
+@interface Foo
+-(void) foo;
+@end
+
+void *ip;
+
+void (*func1)(void);
+
+struct
+{
+ int a:2;
+} struct1,struct2[2];
+
+union
+{
+ int a:2;
+} union1,union2[2];
+
+Foo **f;
+
+int main(int argc,char **argv)
+{
+ [(struct {int a;} *)ip foo]; /* { dg-warning "invalid receiver type" } */
+ [func1 foo]; /* { dg-warning "invalid receiver type" } */
+ [struct1.a foo]; /* { dg-warning "invalid receiver type" } */
+ /* { dg-warning "cast to pointer from integer" "" { target *-*-* } 28 } */
+ [union1.a foo]; /* { dg-warning "invalid receiver type" } */
+ /* { dg-warning "cast to pointer from integer" "" { target *-*-* } 30 } */
+ [struct1 foo]; /* { dg-warning "invalid receiver type" } */
+ /* { dg-error "cannot convert" "" { target *-*-* } 32 } */
+ [union1 foo]; /* { dg-warning "invalid receiver type" } */
+ /* { dg-error "cannot convert" "" { target *-*-* } 34 } */
+ [struct2 foo]; /* { dg-warning "invalid receiver type" } */
+ /* { dg-error "cannot convert" "" { target *-*-* } 36 } */
+ [union2 foo]; /* { dg-warning "invalid receiver type" } */
+ /* { dg-error "cannot convert" "" { target *-*-* } 38 } */
+ [f foo]; /* { dg-warning "invalid receiver type" } */
+}
diff --git a/gcc/testsuite/objc.dg/bad-receiver-type.m b/gcc/testsuite/objc.dg/bad-receiver-type.m
new file mode 100644
index 000000000..8ab296257
--- /dev/null
+++ b/gcc/testsuite/objc.dg/bad-receiver-type.m
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+
+@interface A
+
+- (void)test;
+
+@end
+
+extern int foo();
+
+void baz()
+{
+ [foo test]; /* { dg-warning "invalid receiver type" } */
+ /* { dg-error "cannot convert to a pointer type" "" { target *-*-* } 13 } */
+}
diff --git a/gcc/testsuite/objc.dg/bitfield-1.m b/gcc/testsuite/objc.dg/bitfield-1.m
new file mode 100644
index 000000000..664a0e8d4
--- /dev/null
+++ b/gcc/testsuite/objc.dg/bitfield-1.m
@@ -0,0 +1,83 @@
+/* Check if bitfield ivars are inherited correctly (i.e., without
+ being "promoted" to ints). */
+/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+#include "../objc-obj-c++-shared/Object1.h"
+#include <objc/objc.h>
+
+extern void abort(void);
+
+#define CHECK_IF(expr) if(!(expr)) abort();
+
+@interface Base: Object
+{
+ int full;
+ int full2: 32;
+ int _refs: 8;
+ int field2: 3;
+ unsigned f3: 8;
+ short cc;
+ unsigned g: 16;
+ int r2: 8;
+ int r3: 8;
+ int r4: 2;
+ int r5: 8;
+ char c;
+}
+- (void)setValues;
+@end
+
+@interface Derived: Base
+{
+ char d;
+ int _field3: 6;
+}
+- (void)checkValues;
+@end
+
+@implementation Base
+-(void)setValues {
+ full = 1;
+ full2 = 2;
+ _refs = 3;
+ field2 = 1;
+ f3 = 6;
+ cc = 7;
+ g = 8;
+ r2 = 9;
+ r3 = 10;
+ r4 = 1;
+ r5 = 12;
+ c = 13;
+}
+@end
+
+@implementation Derived
+-(void)checkValues {
+ CHECK_IF(full == 1);
+ CHECK_IF(full2 == 2);
+ CHECK_IF(_refs == 3);
+ CHECK_IF(field2 == 1);
+ CHECK_IF(f3 == 6);
+ CHECK_IF(cc == 7);
+ CHECK_IF(g == 8);
+ CHECK_IF(r2 == 9);
+ CHECK_IF(r3 == 10);
+ CHECK_IF(r4 == 1);
+ CHECK_IF(r5 == 12);
+ CHECK_IF(c == 13);
+}
+@end
+
+int main(void) {
+ Derived *obj = [[Derived alloc] init];
+
+ [obj setValues];
+ [obj checkValues];
+
+ return 0;
+}
+
+#include "../objc-obj-c++-shared/Object1-implementation.h"
diff --git a/gcc/testsuite/objc.dg/bitfield-2.m b/gcc/testsuite/objc.dg/bitfield-2.m
new file mode 100644
index 000000000..7e8147a70
--- /dev/null
+++ b/gcc/testsuite/objc.dg/bitfield-2.m
@@ -0,0 +1,56 @@
+/* Check if bitfield ivars are correctly @encode'd when
+ the NeXT runtime is used. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-options "-fsigned-char" } */
+/* { dg-do run { target *-*-darwin* } } */
+/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */
+
+typedef struct objc_object { struct objc_class *class_pointer; } *id;
+
+extern void abort(void);
+extern int strcmp(const char *, const char *);
+
+#define CHECK_IF(expr) if(!(expr)) abort();
+
+@interface Base
+{
+ struct objc_class *isa;
+ int full;
+ int full2: 32;
+ int _refs: 8;
+ int field2: 3;
+ unsigned f3: 8;
+ short cc;
+ unsigned g: 16;
+ int r2: 8;
+ int r3: 8;
+ int r4: 2;
+ int r5: 8;
+ char c;
+}
+@end
+
+@interface Derived: Base
+{
+ char d;
+ int _field3: 6;
+}
+@end
+
+@implementation Base
+@end
+
+@implementation Derived
+@end
+
+int main(void) {
+ const char *s1r = "{Base=#ib32b8b3b8sb16b8b8b2b8c}";
+ const char *s1 = @encode(Base);
+ const char *s2r = "{Derived=#ib32b8b3b8sb16b8b8b2b8ccb6}";
+ const char *s2 = @encode(Derived);
+
+ CHECK_IF(!strcmp(s1r, s1));
+ CHECK_IF(!strcmp(s2r, s2));
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/bitfield-3.m b/gcc/testsuite/objc.dg/bitfield-3.m
new file mode 100644
index 000000000..5bea0fca9
--- /dev/null
+++ b/gcc/testsuite/objc.dg/bitfield-3.m
@@ -0,0 +1,49 @@
+/* Check if the @defs() construct preserves the correct
+ layout of bitfields. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-options "-Wpadded" } */
+/* { dg-do run } */
+
+#include "../objc-obj-c++-shared/Object1.h"
+
+extern void abort(void);
+extern int strcmp(const char *str1, const char *str2);
+#define CHECK_IF(expr) if(!(expr)) abort()
+
+enum Enum { one, two, three, four };
+
+@interface Base: Object {
+ unsigned a: 2;
+ int b: 3;
+ enum Enum c: 4;
+ unsigned d: 5;
+} /* { dg-warning "padding struct size to alignment boundary" } */
+@end
+
+@interface Derived: Base {
+ signed e: 5;
+ int f: 4;
+ enum Enum g: 3;
+} /* { dg-warning "padding struct size to alignment boundary" } */
+@end
+
+/* Note that the semicolon after @defs(...) is optional. */
+
+typedef struct { @defs(Base) } Base_t; /* { dg-warning "padding struct size to alignment boundary" } */
+typedef struct { @defs(Derived); } Derived_t; /* { dg-warning "padding struct size to alignment boundary" } */
+
+int main(void)
+{
+ CHECK_IF(sizeof(Base_t) == sizeof(Base));
+ CHECK_IF(sizeof(Derived_t) == sizeof(Derived));
+
+#ifdef __NEXT_RUNTIME__
+ CHECK_IF(!strcmp(@encode(Base), "{Base=#b2b3b4b5}"));
+ CHECK_IF(!strcmp(@encode(Derived), "{Derived=#b2b3b4b5b5b4b3}"));
+
+ CHECK_IF(!strcmp(@encode(Base_t), "{?=#b2b3b4b5}"));
+ CHECK_IF(!strcmp(@encode(Derived_t), "{?=#b2b3b4b5b5b4b3}"));
+#endif /* __NEXT_RUNTIME__ */
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/bitfield-4.m b/gcc/testsuite/objc.dg/bitfield-4.m
new file mode 100644
index 000000000..4883497e8
--- /dev/null
+++ b/gcc/testsuite/objc.dg/bitfield-4.m
@@ -0,0 +1,28 @@
+/* Make sure that bitfield types are printed correctly, and that ivar redeclaration
+ (@interface vs. @implementation) checks take the bitfield width into account. */
+/* Author: Ziemowit Laski <zlaski@apple.com> */
+/* { dg-do compile } */
+
+@interface Base {
+ int i;
+}
+@end
+
+@interface WithBitfields: Base {
+ void *isa;
+ unsigned a: 3;
+ signed b: 4;
+ int c: 5;
+}
+@end
+
+@implementation WithBitfields {
+ char *isa; /* { dg-error "conflicting instance variable type .char \\*isa." } */
+ /* { dg-error "previous declaration of .void \\*isa." "" { target *-*-* } 12 } */
+ unsigned a: 5; /* { dg-error "conflicting instance variable type .unsigned( int)? a: 5." } */
+ /* { dg-error "previous declaration of .unsigned( int)? a: 3." "" { target *-*-* } 13 } */
+ signed b: 4; /* This one is fine. */
+ int c: 3; /* { dg-error "conflicting instance variable type .int c: 3." } */
+ /* { dg-error "previous declaration of .int c: 5." "" { target *-*-* } 15 } */
+}
+@end
diff --git a/gcc/testsuite/objc.dg/bitfield-5.m b/gcc/testsuite/objc.dg/bitfield-5.m
new file mode 100644
index 000000000..1cc1cad9b
--- /dev/null
+++ b/gcc/testsuite/objc.dg/bitfield-5.m
@@ -0,0 +1,113 @@
+/* Check ObjC class layout follows the ABI (informally)
+ set in the past. ObjC structs must be laid out as if
+ all ivars, including those inherited from superclasses,
+ were defined at once (i.e., any padding introduced for
+ superclasses should be removed). */
+/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-options "-Wpadded" } */
+/* { dg-do run } */
+
+#include "../objc-obj-c++-shared/Object1.h"
+#include <objc/objc.h>
+#include <stdlib.h>
+
+#define CHECK_IF(expr) if(!(expr)) abort()
+
+enum Enum { zero, one, two, three, four };
+
+@interface Base: Object {
+@public
+ unsigned a: 2;
+ int b: 3;
+ enum Enum c: 4;
+ unsigned d: 5;
+} /* { dg-warning "padding struct size to alignment boundary" } */
+@end
+
+struct Base_0 {
+ Class isa;
+ unsigned a: 2;
+ int b: 3;
+ enum Enum c: 4;
+ unsigned d: 5;
+}; /* { dg-warning "padding struct size to alignment boundary" } */
+
+@interface Derived: Base {
+@public
+ signed e: 5;
+ unsigned f: 4;
+ enum Enum g: 3;
+} /* { dg-warning "padding struct size to alignment boundary" } */
+@end
+
+struct Derived_0 {
+ Class isa;
+ unsigned a: 2;
+ int b: 3;
+ enum Enum c: 4;
+ unsigned d: 5;
+ signed e: 5;
+ int f: 4;
+ enum Enum g: 3;
+}; /* { dg-warning "padding struct size to alignment boundary" } */
+
+@interface Leaf: Derived {
+@public
+ signed h: 2;
+} /* { dg-warning "padding struct size to alignment boundary" } */
+@end
+
+struct Leaf_0 {
+ Class isa;
+ unsigned a: 2;
+ int b: 3;
+ enum Enum c: 4;
+ unsigned d: 5;
+ signed e: 5;
+ unsigned f: 4;
+ enum Enum g: 3;
+ signed h: 2;
+}; /* { dg-warning "padding struct size to alignment boundary" } */
+
+/* Note that the semicolon after @defs(...) is optional. */
+
+typedef struct { @defs(Base) } Base_t; /* { dg-warning "padding struct size to alignment boundary" } */
+typedef struct { @defs(Derived); } Derived_t; /* { dg-warning "padding struct size to alignment boundary" } */
+typedef struct { @defs(Leaf); } Leaf_t; /* { dg-warning "padding struct size to alignment boundary" } */
+
+int main(void)
+{
+ struct Leaf_0 l_0;
+ Leaf *l = (Leaf *)&l_0;
+ Leaf_t *l_t = (Leaf_t *)&l_0;
+
+ CHECK_IF(sizeof(Base_t) == sizeof(Base));
+ CHECK_IF(sizeof(Derived_t) == sizeof(Derived));
+ CHECK_IF(sizeof(Leaf_t) == sizeof(Leaf));
+
+ CHECK_IF(sizeof(struct Base_0) == sizeof(Base));
+ CHECK_IF(sizeof(struct Derived_0) == sizeof(Derived));
+ CHECK_IF(sizeof(struct Leaf_0) == sizeof(Leaf));
+
+ l_0.isa = (Class)0;
+ l_0.a = 3;
+ l_0.b = 0;
+ l_0.c = three;
+ l_0.d = 31;
+ l_0.e = 0;
+ l_0.f = 15;
+ l_0.g = zero;
+ l_0.h = -2;
+
+ CHECK_IF(!l_t->isa);
+ CHECK_IF(l->a == 3 && l_t->a == 3);
+ CHECK_IF(!l->b && !l_t->b);
+ CHECK_IF(l->c == three && l_t->c == three);
+ CHECK_IF(l->d == 31 && l_t->d == 31);
+ CHECK_IF(!l->e && !l_t->e);
+ CHECK_IF(l->f == 15 && l_t->f == 15);
+ CHECK_IF(l->g == zero && l_t->g == zero);
+ CHECK_IF(l->h == -2 && l_t->h == -2);
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/break-in-ifstmt.m b/gcc/testsuite/objc.dg/break-in-ifstmt.m
new file mode 100644
index 000000000..896849472
--- /dev/null
+++ b/gcc/testsuite/objc.dg/break-in-ifstmt.m
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+
+@interface foo
+- (void) test;
+@end
+
+@implementation foo
+-(void) test {
+ if (1) {
+ break; /* { dg-error "break" } */
+ }
+}
+@end
+
diff --git a/gcc/testsuite/objc.dg/call-super-1.m b/gcc/testsuite/objc.dg/call-super-1.m
new file mode 100644
index 000000000..37b705ea1
--- /dev/null
+++ b/gcc/testsuite/objc.dg/call-super-1.m
@@ -0,0 +1,78 @@
+/* Check if objc_super stack variables are created correctly (and
+ not clobbered by other values). */
+/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-options "-std=c99" } */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+#include "../objc-obj-c++-shared/Object1.h"
+
+extern void abort(void);
+
+#define CHECK_IF(expr) if(!(expr)) abort();
+
+typedef struct _Point {
+ float x;
+ float y;
+} Point;
+
+Point MakePoint ( float x , float y ) {
+ Point p;
+ p.x = x;
+ p.y = y;
+ return p;
+}
+
+@interface Base: Object
+- ( void ) translateOriginToPoint : ( Point ) translation ;
+@end
+
+@interface Derived : Base
+- ( void ) scrollToPoint : ( Point ) newOrigin ;
+- ( void ) translateOriginToPoint : ( Point ) translation ;
+@end
+
+int blort;
+float result;
+
+@implementation Base
+- ( void ) translateOriginToPoint : ( Point ) translation {
+ result = translation.x + translation.y;
+}
+@end
+
+@implementation Derived
+- ( void ) scrollToPoint : ( Point ) newOrigin {
+ float transDeltaX =newOrigin.x, transDeltaY =newOrigin.y ;
+ Point w;
+ if ( ! blort ) {
+ w.x = transDeltaX ; w.y = transDeltaY ;
+ [ super translateOriginToPoint : w ] ;
+ return;
+ }
+ [ super translateOriginToPoint : MakePoint ( transDeltaX , transDeltaY ) ] ;
+ return;
+}
+- (void) translateOriginToPoint : ( Point ) translation {
+ /* This should never be called. */
+ CHECK_IF(0);
+}
+@end
+
+int main(void) {
+ Derived *v = [Derived new];
+ float r0 = 1.5 + 1.5;
+ blort = 1;
+ [v scrollToPoint: MakePoint(1.5, 1.5)];
+ CHECK_IF(result == r0);
+ blort = 0;
+ [v scrollToPoint: MakePoint(1.5, 1.5)];
+ CHECK_IF(result == r0);
+ blort = 1;
+ [v scrollToPoint: MakePoint(1.5, 1.5)];
+ CHECK_IF(result == r0);
+ [v free];
+ return 0;
+}
+
+#include "../objc-obj-c++-shared/Object1-implementation.h"
diff --git a/gcc/testsuite/objc.dg/call-super-2.m b/gcc/testsuite/objc.dg/call-super-2.m
new file mode 100644
index 000000000..190c407f7
--- /dev/null
+++ b/gcc/testsuite/objc.dg/call-super-2.m
@@ -0,0 +1,138 @@
+/* Check if casting 'self' or 'super' affects message lookup in the correct way. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-do compile } */
+
+#include "../objc-obj-c++-shared/Object1.h"
+#include "../objc-obj-c++-shared/next-mapping.h"
+#include <stddef.h>
+
+@protocol Func
++ (int) class_func0;
+- (int) instance_func0;
+@end
+
+@interface Derived: Object
++ (int) class_func1;
++ (int) class_func2;
++ (int) class_func3;
++ (int) class_func4;
++ (int) class_func5;
++ (int) class_func6;
++ (int) class_func7;
+- (int) instance_func1;
+- (int) instance_func2;
+- (int) instance_func3;
+- (int) instance_func4;
+- (int) instance_func5;
+- (int) instance_func6;
+- (int) instance_func7;
+@end
+
+@interface Derived (Categ)
++ (int) categ_class_func1;
++ (int) categ_class_func2;
+- (int) categ_instance_func1;
+- (int) categ_instance_func2;
+@end
+
+@implementation Derived
++ (int) class_func1
+{
+ int i = (size_t)[self class_func0]; /* { dg-warning ".Derived. may not respond to .\\+class_func0." } */
+ return i + (size_t)[super class_func0]; /* { dg-warning ".Object. may not respond to .\\+class_func0." } */
+}
++ (int) class_func2
+{
+ int i = [(id <Func>)self class_func0]; /* { dg-warning ".\\-class_func0. not found in protocol" } */
+ i += [(id <Func>)super class_func0]; /* { dg-warning ".\\-class_func0. not found in protocol" } */
+ i += [(Class <Func>)self class_func0];
+ return i + [(Class <Func>)super class_func0];
+}
++ (int) class_func3
+{
+ return [(Object <Func> *)super class_func0];
+}
++ (int) class_func4
+{
+ return [(Derived <Func> *)super class_func0];
+}
++ (int) class_func5
+{
+ int i = (size_t)[Derived class_func0]; /* { dg-warning ".Derived. may not respond to .\\+class_func0." } */
+ return i + (size_t)[Object class_func0]; /* { dg-warning ".Object. may not respond to .\\+class_func0." } */
+}
++ (int) class_func6
+{
+ return (size_t)[objc_get_class("Object") class_func1]; /* { dg-warning ".Object. may not respond to .\\+class_func1." } */
+}
++ (int) class_func7
+{
+ return [objc_get_class("Derived") class_func1];
+}
+- (int) instance_func1
+{
+ int i = (size_t)[self instance_func0]; /* { dg-warning ".Derived. may not respond to .\\-instance_func0." } */
+ return i + (size_t)[super instance_func0]; /* { dg-warning ".Object. may not respond to .\\-instance_func0." } */
+}
+- (int) instance_func2
+{
+ return [(id <Func>)super instance_func0];
+}
+- (int) instance_func3
+{
+ return [(Object <Func> *)super instance_func0];
+}
+- (int) instance_func4
+{
+ return [(Derived <Func> *)super instance_func0];
+}
+- (int) instance_func5
+{
+ int i = (size_t)[Derived instance_func1]; /* { dg-warning ".Derived. may not respond to .\\+instance_func1." } */
+ return i + (size_t)[Object instance_func1]; /* { dg-warning ".Object. may not respond to .\\+instance_func1." } */
+}
+- (int) instance_func6
+{
+ return (size_t)[objc_get_class("Object") class_func1]; /* { dg-warning ".Object. may not respond to .\\+class_func1." } */
+}
+- (int) instance_func7
+{
+ return [objc_get_class("Derived") class_func1];
+}
+@end
+
+@implementation Derived (Categ)
++ (int) categ_class_func1
+{
+ int i = (size_t)[self class_func0]; /* { dg-warning ".Derived. may not respond to .\\+class_func0." } */
+ i += [self class_func1];
+ i += [self categ_class_func2];
+ i += (size_t)[self categ_instance_func1]; /* { dg-warning ".Derived. may not respond to .\\+categ_instance_func1." } */
+ return i + (size_t)[super class_func0]; /* { dg-warning ".Object. may not respond to .\\+class_func0." } */
+}
++ (int) categ_class_func2
+{
+ int i = [(id <Func>)self class_func0]; /* { dg-warning ".\\-class_func0. not found in protocol" } */
+ i += [(id <Func>)super class_func0]; /* { dg-warning ".\\-class_func0. not found in protocol" } */
+ i += [(Class <Func>)self class_func0];
+ return i + [(Class <Func>)super class_func0];
+}
+- (int) categ_instance_func1
+{
+ int i = (size_t)[self instance_func0]; /* { dg-warning ".Derived. may not respond to .\\-instance_func0." } */
+ i += [(Derived <Func> *)self categ_instance_func2];
+ i += (size_t)[(Object <Func> *)self categ_instance_func2]; /* { dg-warning ".Object. may not respond to .\\-categ_instance_func2." } */
+ /* { dg-warning ".\\-categ_instance_func2. not found in protocol" "" { target *-*-* } 124 } */
+ i += (size_t)[(id <Func>)self categ_instance_func2]; /* { dg-warning ".\\-categ_instance_func2. not found in protocol" } */
+ i += [(id)self categ_instance_func2];
+ return i + (size_t)[super instance_func0]; /* { dg-warning ".Object. may not respond to .\\-instance_func0." } */
+}
+- (int) categ_instance_func2
+{
+ return [(id <Func>)super instance_func0];
+}
+@end
+
+/* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 0 } */
+/* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 0 } */
+/* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/objc.dg/call-super-3.m b/gcc/testsuite/objc.dg/call-super-3.m
new file mode 100644
index 000000000..0b950294b
--- /dev/null
+++ b/gcc/testsuite/objc.dg/call-super-3.m
@@ -0,0 +1,57 @@
+/* Check if sending messages to super does not interfere with sending messages
+ to classes. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-options "" } */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+#include "../objc-obj-c++-shared/Object1.h"
+
+extern void abort(void);
+#define CHECK_IF(expr) if(!(expr)) abort()
+
+@interface Base: Object
++ (int) class_func1;
+- (int) instance_func1;
+@end
+
+@interface Derived: Base
++ (int) class_func1;
+@end
+
+@interface Derived (Categ)
+- (int) instance_func1;
+@end
+
+@implementation Base
++ (int) class_func1 { return 234; }
+- (int) instance_func1 { return 345; }
+@end
+
+@implementation Derived
++ (int) class_func1 {
+ int i = [super class_func1];
+ i += [Base class_func1];
+ return i;
+}
+@end
+
+@implementation Derived (Categ)
+- (int) instance_func1 {
+ int i = [super instance_func1];
+ i += [Base class_func1]; /* { dg-bogus "invalid receiver type" } */
+ return i;
+}
+@end
+
+int main(void) {
+ Base *base = [[Base alloc] init]; /* { dg-bogus "invalid receiver type" } */
+ Derived *derived = [[Derived alloc] init];
+ CHECK_IF([Base class_func1] == 234); /* { dg-bogus "invalid receiver type" } */
+ CHECK_IF([Derived class_func1] == 234 + 234);
+ CHECK_IF([base instance_func1] == 345);
+ CHECK_IF([derived instance_func1] == 234 + 345);
+ return 0;
+}
+
+#include "../objc-obj-c++-shared/Object1-implementation.h"
diff --git a/gcc/testsuite/objc.dg/category-1.m b/gcc/testsuite/objc.dg/category-1.m
new file mode 100644
index 000000000..e195a46bf
--- /dev/null
+++ b/gcc/testsuite/objc.dg/category-1.m
@@ -0,0 +1,51 @@
+/* Test class methods inside categories. */
+/* Author: Ziemowit Laski <zlaski@apple.com>. */
+
+/* { dg-do run } */
+/* { dg-xfail-run-if "need OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+#include "../objc-obj-c++-shared/Object1.h"
+extern int strcmp(const char *s1, const char *s2);
+extern void abort(void);
+
+#ifdef __NEXT_RUNTIME__
+#define SUPERCLASS superclass
+#else
+#define SUPERCLASS superClass
+#endif
+
+#define CHECK_IF(expr) if(!(expr)) abort()
+
+@interface MyObject: Object
++ (Class)whatever1;
+@end
+
+@implementation MyObject
++ (Class)whatever1 { return [super SUPERCLASS]; }
+@end
+
+@interface MyObject (ThisWontCompile)
++(Class)whatever2;
+@end
+
+@implementation MyObject (ThisWontCompile)
++(Class)whatever2 { return [super SUPERCLASS]; }
+@end
+
+int main (int argc, const char * argv[])
+{
+ Class w1 = [MyObject whatever1];
+ Class w2 = [MyObject whatever2];
+
+#ifdef NEXT_OBJC_USE_NEW_INTERFACE
+ CHECK_IF(!strcmp( object_getClassName( w1 ), "Object"));
+ CHECK_IF(!strcmp( object_getClassName( w2 ), "Object"));
+#else
+ CHECK_IF(!strcmp(w1->name, "Object"));
+ CHECK_IF(!strcmp(w2->name, "Object"));
+#endif
+
+ return 0;
+}
+
+#include "../objc-obj-c++-shared/Object1-implementation.h"
diff --git a/gcc/testsuite/objc.dg/class-1.m b/gcc/testsuite/objc.dg/class-1.m
new file mode 100644
index 000000000..64304f590
--- /dev/null
+++ b/gcc/testsuite/objc.dg/class-1.m
@@ -0,0 +1,20 @@
+/* Redeclarations of class names. */
+/* { dg-do compile } */
+
+typedef int foo;
+
+@class foo; /* { dg-error "redeclared as different kind of symbol" } */
+/* { dg-error "previous declaration of" "" { target *-*-* } 4 } */
+
+typedef int bar;
+
+@interface bar
+@end /* { dg-error "redeclared as different kind of symbol" } */
+/* { dg-error "previous declaration of" "" { target *-*-* } 9 } */
+
+int glob;
+
+@implementation glob
+@end /* { dg-error "redeclared as different kind of symbol" } */
+/* { dg-error "previous declaration of" "" { target *-*-* } 15 } */
+/* { dg-warning "annot find interface declaration" "" { target *-*-* } 18 } */
diff --git a/gcc/testsuite/objc.dg/class-2.m b/gcc/testsuite/objc.dg/class-2.m
new file mode 100644
index 000000000..b98d117f5
--- /dev/null
+++ b/gcc/testsuite/objc.dg/class-2.m
@@ -0,0 +1,14 @@
+/* Test super classes. */
+/* { dg-do compile } */
+
+@interface supclass1
+@end
+
+@interface supclass2
+@end
+
+@interface class1 : supclass1
+@end
+
+@implementation class1 : supclass2 /* { dg-error "conflicting super class name" } */
+@end /* { dg-error "previous declaration" "" { target *-*-* } 13 } */
diff --git a/gcc/testsuite/objc.dg/class-extension-1.m b/gcc/testsuite/objc.dg/class-extension-1.m
new file mode 100644
index 000000000..eab59c413
--- /dev/null
+++ b/gcc/testsuite/objc.dg/class-extension-1.m
@@ -0,0 +1,30 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
+/* { dg-do compile } */
+
+/* This test tests the basic of class extensions. */
+
+#include <objc/objc.h>
+
+@interface MyObject
+{
+ Class isa;
+}
+- (int) test;
+@end
+
+@interface MyObject ()
+- (int) test2;
+- (int) test3;
+@end
+
+@implementation MyObject
+- (int) test
+{
+ return 20;
+}
+- (int) test2
+{
+ return 20;
+}
+@end /* { dg-warning "incomplete implementation of class .MyObject." } */
+ /* { dg-warning "method definition for .-test3. not found" "" { target *-*-* } 29 } */
diff --git a/gcc/testsuite/objc.dg/class-extension-2.m b/gcc/testsuite/objc.dg/class-extension-2.m
new file mode 100644
index 000000000..79b126f52
--- /dev/null
+++ b/gcc/testsuite/objc.dg/class-extension-2.m
@@ -0,0 +1,56 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
+/* { dg-do compile } */
+
+/* This test tests class extensions and protocols. */
+
+#include <objc/objc.h>
+
+/* First, a simple test where a plain class has a protocol attached to
+ it in a class extension. */
+@interface MyObject
+{
+ Class isa;
+}
+@end
+
+@protocol MyProtocol
+- (void) test;
+@end
+
+@interface MyObject () <MyProtocol>
+@end
+
+@implementation MyObject
+@end /* { dg-warning "incomplete implementation of class .MyObject." } */
+ /* { dg-warning "method definition for .-test. not found" "" { target *-*-* } 24 } */
+ /* { dg-warning "class .MyObject. does not fully implement the .MyProtocol. protocol" "" { target *-*-* } 24 } */
+
+
+
+/* Second, a more interesting test where protocols are added from the
+ main class and from two different class extensions. */
+@interface MyObject2 : MyObject <MyProtocol>
+@end
+
+@protocol MyProtocol2
+- (void) test2;
+@end
+
+@protocol MyProtocol3
+- (void) test3;
+@end
+
+@interface MyObject2 () <MyProtocol2>
+@end
+
+@interface MyObject2 () <MyProtocol3>
+@end
+
+@implementation MyObject2
+@end /* { dg-warning "incomplete implementation of class .MyObject2." } */
+ /* { dg-warning "method definition for .-test. not found" "" { target *-*-* } 50 } */
+ /* { dg-warning "class .MyObject2. does not fully implement the .MyProtocol. protocol" "" { target *-*-* } 50 } */
+ /* { dg-warning "method definition for .-test2. not found" "" { target *-*-* } 50 } */
+ /* { dg-warning "class .MyObject2. does not fully implement the .MyProtocol2. protocol" "" { target *-*-* } 50 } */
+ /* { dg-warning "method definition for .-test3. not found" "" { target *-*-* } 50 } */
+ /* { dg-warning "class .MyObject2. does not fully implement the .MyProtocol3. protocol" "" { target *-*-* } 50 } */
diff --git a/gcc/testsuite/objc.dg/class-extension-3.m b/gcc/testsuite/objc.dg/class-extension-3.m
new file mode 100644
index 000000000..69e570539
--- /dev/null
+++ b/gcc/testsuite/objc.dg/class-extension-3.m
@@ -0,0 +1,26 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
+/* { dg-do compile } */
+
+/* This test tests warnings on class extensions. */
+
+#include <objc/objc.h>
+
+@interface MyObject
+{
+ Class isa;
+ int count;
+}
+- (int) test; /* { dg-message "previous declaration" } */
+@property int count; /* { dg-message "originally specified here" } */
+@end
+
+@interface MyObject ()
+- (void) test; /* { dg-error "duplicate declaration of method .-test." } */
+@end
+
+@interface MyObject ()
+@end
+
+@interface MyObject ()
+@property int count; /* { dg-error "redeclaration of property .count." } */
+@end
diff --git a/gcc/testsuite/objc.dg/class-extension-4.m b/gcc/testsuite/objc.dg/class-extension-4.m
new file mode 100644
index 000000000..692a0fcbd
--- /dev/null
+++ b/gcc/testsuite/objc.dg/class-extension-4.m
@@ -0,0 +1,19 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
+/* { dg-do compile } */
+
+/* This test tests you can not declare a class extension after the class @implementation. */
+
+#include <objc/objc.h>
+
+@interface MyObject
+{
+ Class isa;
+}
+@end
+
+@implementation MyObject
+@end
+
+@interface MyObject ()
+- (void) test; /* { dg-error "class extension for class .MyObject. declared after its ..implementation." } */
+@end
diff --git a/gcc/testsuite/objc.dg/class-protocol-1.m b/gcc/testsuite/objc.dg/class-protocol-1.m
new file mode 100644
index 000000000..cf061cb8e
--- /dev/null
+++ b/gcc/testsuite/objc.dg/class-protocol-1.m
@@ -0,0 +1,441 @@
+/* Check Class <protocol> types */
+/* Author: David Ayers <d.ayers@inode.at> */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+#include <objc/objc-api.h>
+
+@protocol MyProto1
++(void)doItClass1;
+-(void)doItInstance1;
+@end
+
+@protocol MyProto2
++(void)doItClass2;
+-(void)doItInstance2;
+@end
+
+@interface MyClass1 <MyProto1>
+{
+ Class isa;
+}
+@end
+@implementation MyClass1
++(void)doItClass1{}
+-(void)doItInstance1{}
+@end
+
+@interface MyClass2 : MyClass1 <MyProto2>
+@end
+@implementation MyClass2
++(void)doItClass2{}
+-(void)doItInstance2{}
+@end
+
+@interface MyClass3
+{
+ Class isa;
+}
+@end
+@interface MyClass4 : MyClass3 <MyProto1>
+@end
+
+/*----------------------------------------*/
+
+Class cls = 0;
+Class <MyProto1> clsP1 = 0;
+Class <MyProto2> clsP2 = 0;
+
+void
+testSimple(void)
+{
+ [cls doItClass1];
+ [cls doItInstance1];
+ [cls doItClass2];
+ [cls doItInstance2];
+
+ [clsP1 doItClass1];
+ [clsP1 doItInstance1]; /* { dg-warning "instead of" } */
+ [clsP1 doItClass2]; /* { dg-warning "not found in protocol" } */
+ [clsP1 doItInstance2]; /* { dg-warning "not found in protocol" } */
+
+ [clsP2 doItClass1]; /* { dg-warning "not found in protocol" } */
+ [clsP2 doItInstance1]; /* { dg-warning "not found in protocol" } */
+ [clsP2 doItClass2];
+ [clsP2 doItInstance2]; /* { dg-warning "instead of" } */
+
+ [MyClass1 doItClass1];
+ [MyClass1 doItInstance1];
+ [MyClass1 doItClass2]; /* { dg-warning "may not respond to" } */
+ [MyClass1 doItInstance2]; /* { dg-warning "may not respond to" } */
+
+ [MyClass2 doItClass1];
+ [MyClass2 doItInstance1];
+ [MyClass2 doItClass2];
+ [MyClass2 doItInstance2]; /* { dg-warning "may not respond to" } */
+
+ [MyClass3 doItClass1]; /* { dg-warning "may not respond to" } */
+ [MyClass3 doItInstance1]; /* { dg-warning "may not respond to" } */
+
+ [MyClass4 doItClass1];
+ [MyClass4 doItInstance1]; /* { dg-warning "may not respond to" } */
+}
+
+/*----------------------------------------*/
+/* Protocols declared by categories */
+
+@protocol MyProto3
++(void)doItClass3;
+-(void)doItInstance3;
+@end
+@protocol MyProto4
++(void)doItClass4;
+-(void)doItInstance4;
+@end
+
+@interface MyClass1 (Category1) <MyProto3>
+@end
+@interface MyClass2 (Category2) <MyProto4>
+@end
+
+void
+testCategory(void)
+{
+ [cls doItClass3];
+ [cls doItInstance3];
+ [cls doItClass4];
+ [cls doItInstance4];
+
+ [MyClass1 doItClass3];
+ [MyClass1 doItInstance3];
+ [MyClass1 doItClass4]; /* { dg-warning "may not respond" } */
+ [MyClass1 doItInstance4]; /* { dg-warning "may not respond" } */
+
+ [MyClass2 doItClass3];
+ [MyClass2 doItInstance3];
+ [MyClass2 doItClass4];
+ [MyClass2 doItInstance4]; /* { dg-warning "may not respond" } */
+
+}
+
+/*----------------------------------------*/
+/* Inherited protocols declared by categories */
+
+@protocol MyProto5 <MyProto1>
++(void)doItClass5;
+-(void)doItInstance5;
+@end
+
+@protocol MyProto6 <MyProto2>
++(void)doItClass6;
+-(void)doItInstance6;
+@end
+
+@interface MyClass1 (Category3) <MyProto5>
+@end
+@interface MyClass2 (Category4) <MyProto6>
+@end
+
+Class <MyProto5> clsP5 = 0;
+Class <MyProto6> clsP6 = 0;
+
+void
+testCategoryInherited(void)
+{
+ [cls doItClass5];
+ [cls doItInstance5];
+ [cls doItClass6];
+ [cls doItInstance6];
+
+ [clsP5 doItClass1];
+ [clsP5 doItInstance1]; /* { dg-warning "instead of" } */
+ [clsP5 doItClass2]; /* { dg-warning "not found in protocol" } */
+ [clsP5 doItInstance2]; /* { dg-warning "not found in protocol" } */
+
+ [clsP6 doItClass1]; /* { dg-warning "not found in protocol" } */
+ [clsP6 doItInstance1]; /* { dg-warning "not found in protocol" } */
+ [clsP6 doItClass2];
+ [clsP6 doItInstance2]; /* { dg-warning "instead of" } */
+
+
+ [MyClass1 doItClass5];
+ [MyClass1 doItInstance5];
+ [MyClass1 doItClass6]; /* { dg-warning "may not respond" } */
+ [MyClass1 doItInstance6]; /* { dg-warning "may not respond" } */
+
+ [MyClass2 doItClass5];
+ [MyClass2 doItInstance5];
+ [MyClass2 doItClass6];
+ [MyClass2 doItInstance6]; /* { dg-warning "may not respond" } */
+
+}
+
+/*----------------------------------------*/
+/* Forward declared root protocols */
+
+@protocol FwProto;
+
+@interface MyClass1 (Forward) <FwProto> /* { dg-warning "definition of protocol .FwProto. not found" } */
+@end
+
+Class <FwProto> clsP7 = 0;
+
+void
+testForwardeDeclared1(void)
+{
+ [cls doItClass7]; /* { dg-warning "no .\\+doItClass7. method found" } */
+ [cls doItInstance7]; /* { dg-warning "no .\\+doItInstance7. method found" } */
+
+ [clsP7 doItClass7]; /* { dg-warning "not found in protocol" } */
+ /* { dg-warning "no .\\+doItClass7. method found" "" { target *-*-* } 189 } */
+ [clsP7 doItInstance7]; /* { dg-warning "not found in protocol" } */
+ /* { dg-warning "no .\\+doItInstance7. method found" "" { target *-*-* } 191 } */
+
+ [MyClass1 doItClass7]; /* { dg-warning "may not respond" } */
+ [MyClass1 doItInstance7]; /* { dg-warning "may not respond" } */
+
+ [MyClass2 doItClass7]; /* { dg-warning "may not respond" } */
+ [MyClass2 doItInstance7]; /* { dg-warning "may not respond" } */
+
+}
+
+@protocol FwProto
++(void)doItClass7;
+-(void)doItInstance7;
+@end
+
+void
+testForwardeDeclared2(void)
+{
+ [cls doItClass7];
+ [cls doItInstance7];
+
+ [clsP7 doItClass7];
+ [clsP7 doItInstance7]; /* { dg-warning "instead of" } */
+
+ [MyClass1 doItClass7];
+ [MyClass1 doItInstance7];
+
+ [MyClass2 doItClass7];
+ [MyClass2 doItInstance7];
+}
+
+/*----------------------------------------*/
+/* Inherited non root protocols */
+
+@protocol MyProto8
++(void)doItClass8;
+-(void)doItInstance8;
+@end
+
+@protocol MyProto9 <MyProto8>
++(void)doItClass9;
+-(void)doItInstance9;
+@end
+
+@interface MyClass1 (InheritedNonRoot) <MyProto9>
+@end
+
+Class <MyProto8> clsP8 = 0;
+Class <MyProto9> clsP9 = 0;
+
+void
+testInheritedNonRoot(void)
+{
+ [cls doItClass8];
+ [cls doItInstance8];
+ [cls doItClass9];
+ [cls doItInstance9];
+
+ [clsP8 doItClass8];
+ [clsP8 doItInstance8]; /* { dg-warning "instead of" } */
+ [clsP8 doItClass9]; /* { dg-warning "not found in protocol" } */
+ [clsP8 doItInstance9]; /* { dg-warning "not found in protocol" } */
+
+ [clsP9 doItClass8];
+ [clsP9 doItInstance8]; /* { dg-warning "instead of" } */
+ [clsP9 doItClass9];
+ [clsP9 doItInstance9]; /* { dg-warning "instead of" } */
+
+ [MyClass1 doItClass8];
+ [MyClass1 doItInstance8];
+ [MyClass1 doItClass9];
+ [MyClass1 doItInstance9];
+
+ [MyClass2 doItClass8];
+ [MyClass2 doItInstance8];
+ [MyClass2 doItClass9];
+ [MyClass2 doItInstance9];
+
+}
+
+/*----------------------------------------*/
+/* Prototype mismatch */
+
+@protocol MyOtherProto1
++(id)doItClass1;
+-(id)doItInstance1;
+@end
+@interface MyOtherClass1 <MyOtherProto1>
+@end
+
+Class <MyOtherProto1> oclsP1;
+
+void
+testPrototypeMismatch(void)
+{
+ id tmp1 = [oclsP1 doItClass1];
+ id tmp2 = [oclsP1 doItInstance1]; /* { dg-warning "instead of" } */
+
+ [clsP1 doItClass1];
+ [clsP1 doItInstance1]; /* { dg-warning "instead of" } */
+}
+
+id obj = nil;
+id <MyProto1> objP1 = nil;
+id <MyProto2> objP2 = nil;
+id <MyProto5> objP5 = nil;
+int num = 0;
+void *ptr = 0;
+
+MyClass1 *mc1 = nil;
+
+void
+testComptypes(void)
+{
+ { /* id <protocol>, id <protocol> */
+ objP1 == objP2; /* { dg-warning "lacks a cast" } */
+ objP2 == objP1; /* { dg-warning "lacks a cast" } */
+
+ objP1 == objP5;
+ objP5 == objP1;
+ }
+ { /* id <protocol>, SomeClass * */
+ mc1 == objP1;
+ objP1 == mc1;
+
+ mc1 == objP2; /* { dg-warning "lacks a cast" } */
+ objP2 == mc1; /* { dg-warning "lacks a cast" } */
+ }
+ { /* id <protocol>, id */
+ obj == objP1;
+ objP1 == obj;
+ }
+ { /* id <protocol>, Class */
+ cls == objP1; /* { dg-warning "lacks a cast" } */
+ objP1 == cls; /* { dg-warning "lacks a cast" } */
+ }
+ { /* id <protocol>, non-ObjC */
+ num == objP1; /* { dg-warning "between pointer" } */
+ objP1 == num; /* { dg-warning "between pointer" } */
+
+ ptr == objP1;
+ objP1 == ptr;
+ }
+ { /* Class <protocol>, Class <protocol> */
+ clsP1 == clsP2; /* { dg-warning "lacks a cast" } */
+ clsP2 == clsP1; /* { dg-warning "lacks a cast" } */
+
+ clsP1 == clsP5;
+ clsP5 == clsP1;
+ }
+ { /* Class <protocol>, SomeClass * */
+ mc1 == clsP1; /* { dg-warning "lacks a cast" } */
+ clsP1 == mc1; /* { dg-warning "lacks a cast" } */
+ }
+ { /* Class <protocol>, id */
+ obj == clsP1;
+ clsP1 == obj;
+ }
+ { /* Class <protocol>, Class */
+ cls == clsP1;
+ clsP1 == cls;
+ }
+ { /* Class <protocol>, non-ObjC */
+ num == clsP1; /* { dg-warning "between pointer" } */
+ clsP1 == num; /* { dg-warning "between pointer" } */
+
+ ptr == clsP1;
+ clsP1 == ptr;
+ }
+ { /* Class <protocol>, id <protocol> */
+ clsP1 == objP1; /* { dg-warning "lacks a cast" } */
+ objP1 == clsP1; /* { dg-warning "lacks a cast" } */
+ }
+
+ { /* id <protocol>, id <protocol> */
+ objP1 = objP2; /* { dg-warning "does not conform" } */
+ objP2 = objP1; /* { dg-warning "does not conform" } */
+
+ objP1 = objP5;
+ objP5 = objP1; /* { dg-warning "does not conform" } */
+ }
+ { /* id <protocol>, SomeClass * */
+ mc1 = objP1;
+ objP1 = mc1;
+
+ mc1 = objP2; /* { dg-warning "does not conform" } */
+ objP2 = mc1; /* { dg-warning "does not implement" } */
+ }
+ { /* id <protocol>, id */
+ obj = objP1;
+ objP1 = obj;
+ }
+ { /* id <protocol>, Class */
+ cls = objP1; /* { dg-warning "distinct Objective\\-C type" } */
+ objP1 = cls; /* { dg-warning "distinct Objective\\-C type" } */
+ }
+ { /* id <protocol>, non-ObjC */
+ num = objP1; /* { dg-warning "makes integer" } */
+ objP1 = num; /* { dg-warning "makes pointer" } */
+
+ ptr = objP1;
+ objP1 = ptr;
+ }
+ { /* Class <protocol>, Class <protocol> */
+ clsP1 = clsP2; /* { dg-warning "does not conform" } */
+ clsP2 = clsP1; /* { dg-warning "does not conform" } */
+
+ clsP1 = clsP5;
+ clsP5 = clsP1; /* { dg-warning "does not conform" } */
+ }
+ { /* Class <protocol>, SomeClass * */
+ /* These combinations should always elicit a warning. */
+ mc1 = clsP1; /* { dg-warning "distinct Objective\\-C type" } */
+ clsP1 = mc1; /* { dg-warning "distinct Objective\\-C type" } */
+
+ mc1 = clsP2; /* { dg-warning "distinct Objective\\-C type" } */
+ clsP2 = mc1; /* { dg-warning "distinct Objective\\-C type" } */
+ }
+ { /* Class <protocol>, id */
+ obj = clsP1;
+ clsP1 = obj;
+ }
+ { /* Class <protocol>, Class */
+ cls = clsP1;
+ clsP1 = cls;
+ }
+ { /* Class <protocol>, non-ObjC */
+ num = clsP1; /* { dg-warning "makes integer" } */
+ clsP1 = num; /* { dg-warning "makes pointer" } */
+
+ ptr = clsP1;
+ clsP1 = ptr;
+ }
+ { /* Class <protocol>, id <protocol> */
+ clsP1 = objP1; /* { dg-warning "distinct Objective\\-C type" } */
+ objP1 = clsP1; /* { dg-warning "distinct Objective\\-C type" } */
+ }
+}
+
+int main ()
+{
+ testSimple();
+ testCategory();
+ testCategoryInherited();
+ return(0);
+}
+
+/* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 0 } */
+/* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 0 } */
+/* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/objc.dg/comp-types-1.m b/gcc/testsuite/objc.dg/comp-types-1.m
new file mode 100644
index 000000000..5bf59a73c
--- /dev/null
+++ b/gcc/testsuite/objc.dg/comp-types-1.m
@@ -0,0 +1,87 @@
+/* Test various ObjC types assignments and comparisons. */
+/* Author: Nicola Pero <nicola@brainstorm.co.uk>. */
+/* { dg-do compile } */
+#include <objc/objc.h>
+
+@protocol MyProtocol
+- (void) foo;
+@end
+
+@interface MyClass
+@end
+
+@interface MyOtherClass <MyProtocol>
+- (void) foo;
+@end
+
+int main()
+{
+ id obj = nil;
+ id<MyProtocol> obj_p = nil;
+ MyClass *obj_c = nil;
+ MyOtherClass *obj_cp = nil;
+ Class obj_C = Nil;
+
+ /* Assigning to an 'id' variable should never
+ generate a warning. */
+ obj = obj_p; /* Ok */
+ obj = obj_c; /* Ok */
+ obj = obj_cp; /* Ok */
+ obj = obj_C; /* Ok */
+
+ /* Assigning to a 'MyClass *' variable should always generate a
+ warning, unless done from an 'id'. */
+ obj_c = obj; /* Ok */
+ obj_c = obj_p; /* { dg-warning "distinct Objective\\-C type" } */
+ obj_c = obj_cp; /* { dg-warning "distinct Objective\\-C type" } */
+ obj_c = obj_C; /* { dg-warning "distinct Objective\\-C type" } */
+
+ /* Assigning to an 'id<MyProtocol>' variable should generate a
+ warning if done from a 'MyClass *' (which doesn't implement
+ MyProtocol), but not from an 'id' or from a 'MyOtherClass *'
+ (which implements MyProtocol). */
+ obj_p = obj; /* Ok */
+ obj_p = obj_c; /* { dg-warning "does not implement" } */
+ obj_p = obj_cp; /* Ok */
+ obj_p = obj_C; /* { dg-warning "distinct Objective\\-C type" } */
+
+ /* Assigning to a 'MyOtherClass *' variable should always generate
+ a warning, unless done from an 'id' or an 'id<MyProtocol>' (since
+ MyOtherClass implements MyProtocol). */
+ obj_cp = obj; /* Ok */
+ obj_cp = obj_c; /* { dg-warning "distinct Objective\\-C type" } */
+ obj_cp = obj_p; /* Ok */
+ obj_cp = obj_C; /* { dg-warning "distinct Objective\\-C type" } */
+
+ /* Any comparison involving an 'id' must be without warnings. */
+ if (obj == obj_p) ; /* Ok */ /*Bogus warning here in 2.95.4*/
+ if (obj_p == obj) ; /* Ok */
+ if (obj == obj_c) ; /* Ok */
+ if (obj_c == obj) ; /* Ok */
+ if (obj == obj_cp) ; /* Ok */
+ if (obj_cp == obj) ; /* Ok */
+ if (obj == obj_C) ; /* Ok */
+ if (obj_C == obj) ; /* Ok */
+
+ /* Any comparison between 'MyClass *' and anything which is not an 'id'
+ must generate a warning. */
+ if (obj_c == obj_p) ; /* { dg-warning "lacks a cast" } */
+ if (obj_p == obj_c) ; /* { dg-warning "lacks a cast" } */
+ if (obj_c == obj_cp) ; /* { dg-warning "lacks a cast" } */
+ if (obj_cp == obj_c) ; /* { dg-warning "lacks a cast" } */
+ if (obj_c == obj_C) ; /* { dg-warning "lacks a cast" } */
+ if (obj_C == obj_c) ; /* { dg-warning "lacks a cast" } */
+
+ /* Any comparison between 'MyOtherClass *' (which implements
+ MyProtocol) and an 'id' implementing MyProtocol are Ok. */
+ if (obj_cp == obj_p) ; /* Ok */
+ if (obj_p == obj_cp) ; /* Ok */
+
+
+ if (obj_p == obj_C) ; /* { dg-warning "lacks a cast" } */
+ if (obj_C == obj_p) ; /* { dg-warning "lacks a cast" } */
+ if (obj_cp == obj_C) ; /* { dg-warning "lacks a cast" } */
+ if (obj_C == obj_cp) ; /* { dg-warning "lacks a cast" } */
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/comp-types-10.m b/gcc/testsuite/objc.dg/comp-types-10.m
new file mode 100644
index 000000000..3d8598399
--- /dev/null
+++ b/gcc/testsuite/objc.dg/comp-types-10.m
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+
+#include "../objc-obj-c++-shared/Object1.h"
+
+@protocol Foo
+- (id)meth1;
+- (id)meth2:(int)arg;
+@end
+
+@interface Derived1: Object
+@end
+
+@interface Derived2: Object
++ (Derived1 *)new;
+@end
+
+id<Foo> func(void) {
+ Object *o = [Object new];
+ return o; /* { dg-warning "class .Object. does not implement the .Foo. protocol" } */
+}
+
+@implementation Derived2
++ (Derived1 *)new {
+ Derived2 *o = [super new];
+ return o; /* { dg-warning "distinct Objective\\-C type in return" } */
+}
+@end
diff --git a/gcc/testsuite/objc.dg/comp-types-11.m b/gcc/testsuite/objc.dg/comp-types-11.m
new file mode 100644
index 000000000..959cc049a
--- /dev/null
+++ b/gcc/testsuite/objc.dg/comp-types-11.m
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+#include "../objc-obj-c++-shared/Object1.h"
+
+@interface Derived: Object
+@end
+
+extern Object* foo(void);
+static Derived *test(void)
+{
+ Derived *m = foo(); /* { dg-warning "initialization from distinct Objective\\-C type" } */
+
+ return m;
+}
+
diff --git a/gcc/testsuite/objc.dg/comp-types-12.m b/gcc/testsuite/objc.dg/comp-types-12.m
new file mode 100644
index 000000000..3a919d5d0
--- /dev/null
+++ b/gcc/testsuite/objc.dg/comp-types-12.m
@@ -0,0 +1,19 @@
+/* When assigning function pointers, allow for covariant return types
+ and contravariant argument types. */
+/* { dg-do compile } */
+#include <objc/Object.h>
+
+@class Derived;
+
+Object *ExternFunc (Object *filePath, Object *key);
+typedef id FuncSignature (Object *arg1, Derived *arg2);
+
+@interface Derived: Object
++ (void)registerFunc:(FuncSignature *)function;
+@end
+
+void foo(void)
+{
+ [Derived registerFunc: ExternFunc];
+}
+
diff --git a/gcc/testsuite/objc.dg/comp-types-2.m b/gcc/testsuite/objc.dg/comp-types-2.m
new file mode 100644
index 000000000..6e88df999
--- /dev/null
+++ b/gcc/testsuite/objc.dg/comp-types-2.m
@@ -0,0 +1,37 @@
+/* Test simple ObjC types casts. */
+/* Author: Nicola Pero <nicola@brainstorm.co.uk>. */
+/* { dg-do compile } */
+#include <objc/objc.h>
+
+@protocol MyProtocol
+- (void) foo;
+@end
+
+@interface MyClass
+@end
+
+int main()
+{
+ id obj = nil;
+ id<MyProtocol> obj_p = nil;
+ MyClass *obj_c = nil;
+ Class obj_C = Nil;
+
+ /* All these casts should generate no warnings. */
+
+ obj = (id)obj_p;
+ obj = (id)obj_c;
+ obj = (id)obj_C;
+ obj_c = (MyClass *)obj;
+ obj_c = (MyClass *)obj_p;
+ obj_c = (MyClass *)obj_C;
+ obj_p = (id<MyProtocol>)obj;
+ obj_p = (id<MyProtocol>)obj_c;
+ obj_p = (id<MyProtocol>)obj_C;
+ obj_C = (Class)obj;
+ obj_C = (Class)obj_p;
+ obj_C = (Class)obj_c;
+
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/comp-types-3.m b/gcc/testsuite/objc.dg/comp-types-3.m
new file mode 100644
index 000000000..51f418ef5
--- /dev/null
+++ b/gcc/testsuite/objc.dg/comp-types-3.m
@@ -0,0 +1,63 @@
+/* Test assignments and comparisons between protocols (obscure case). */
+/* Author: Nicola Pero <nicola@brainstorm.co.uk>. */
+/* { dg-do compile } */
+#include <objc/objc.h>
+
+@protocol MyProtocolA
+- (void) methodA;
+@end
+
+@protocol MyProtocolB
+- (void) methodB;
+@end
+
+@protocol MyProtocolAB <MyProtocolA, MyProtocolB>
+@end
+
+@protocol MyProtocolAC <MyProtocolA>
+- (void) methodC;
+@end
+
+int main()
+{
+ id<MyProtocolA> obj_a = nil;
+ id<MyProtocolB> obj_b = nil;
+ id<MyProtocolAB> obj_ab = nil;
+ id<MyProtocolAC> obj_ac = nil;
+
+ obj_a = obj_b; /* { dg-warning "does not conform" } */
+ obj_a = obj_ab; /* Ok */
+ obj_a = obj_ac; /* Ok */
+
+ obj_b = obj_a; /* { dg-warning "does not conform" } */
+ obj_b = obj_ab; /* Ok */
+ obj_b = obj_ac; /* { dg-warning "does not conform" } */
+
+ obj_ab = obj_a; /* { dg-warning "does not conform" } */
+ obj_ab = obj_b; /* { dg-warning "does not conform" } */
+ obj_ab = obj_ac; /* { dg-warning "does not conform" } */
+
+ obj_ac = obj_a; /* { dg-warning "does not conform" } */
+ obj_ac = obj_b; /* { dg-warning "does not conform" } */
+ obj_ac = obj_ab; /* { dg-warning "does not conform" } */
+
+ if (obj_a == obj_b) ; /* { dg-warning "lacks a cast" } */
+ if (obj_b == obj_a) ; /* { dg-warning "lacks a cast" } */
+
+ if (obj_a == obj_ab) ; /* Ok */
+ if (obj_ab == obj_a) ; /* Ok */ /* Spurious 2.95.4 warning here */
+
+ if (obj_a == obj_ac) ; /* Ok */
+ if (obj_ac == obj_a) ; /* Ok */ /* Spurious 2.95.4 warning here */
+
+ if (obj_b == obj_ab) ; /* Ok */
+ if (obj_ab == obj_b) ; /* Ok */ /* Spurious 2.95.4 warning here */
+
+ if (obj_b == obj_ac) ; /* { dg-warning "lacks a cast" } */
+ if (obj_ac == obj_b) ; /* { dg-warning "lacks a cast" } */
+
+ if (obj_ab == obj_ac) ; /* { dg-warning "lacks a cast" } */
+ if (obj_ac == obj_ab) ; /* { dg-warning "lacks a cast" } */
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/comp-types-4.m b/gcc/testsuite/objc.dg/comp-types-4.m
new file mode 100644
index 000000000..f15390a38
--- /dev/null
+++ b/gcc/testsuite/objc.dg/comp-types-4.m
@@ -0,0 +1,73 @@
+/* Test warnings for assignments and comparisons between ObjC and C types. */
+/* Author: Nicola Pero <nicola@brainstorm.co.uk>. */
+/* { dg-do compile } */
+#include <objc/objc.h>
+
+/* The NeXT runtime headers do not define NULL. */
+#ifndef NULL
+#define NULL ((void *)0)
+#endif
+
+@protocol MyProtocol
+- (void) method;
+@end
+
+@interface MyClass
+@end
+
+int main()
+{
+ id obj = nil;
+ id <MyProtocol> obj_p = nil;
+ MyClass *obj_c = nil;
+ Class obj_C = Nil;
+
+ int i = 0;
+ int *j = NULL;
+
+ /* These should all generate warnings. */
+
+ obj = i; /* { dg-warning "pointer from integer without a cast" } */
+ obj = j; /* { dg-warning "incompatible pointer type" } */
+
+ obj_p = i; /* { dg-warning "pointer from integer without a cast" } */
+ obj_p = j; /* { dg-warning "incompatible pointer type" } */
+
+ obj_c = i; /* { dg-warning "pointer from integer without a cast" } */
+ obj_c = j; /* { dg-warning "incompatible pointer type" } */
+
+ obj_C = i; /* { dg-warning "pointer from integer without a cast" } */
+ obj_C = j; /* { dg-warning "incompatible pointer type" } */
+
+ i = obj; /* { dg-warning "integer from pointer without a cast" } */
+ i = obj_p; /* { dg-warning "integer from pointer without a cast" } */
+ i = obj_c; /* { dg-warning "integer from pointer without a cast" } */
+ i = obj_C; /* { dg-warning "integer from pointer without a cast" } */
+
+ j = obj; /* { dg-warning "incompatible pointer type" } */
+ j = obj_p; /* { dg-warning "incompatible pointer type" } */
+ j = obj_c; /* { dg-warning "incompatible pointer type" } */
+ j = obj_C; /* { dg-warning "incompatible pointer type" } */
+
+ if (obj == i) ; /* { dg-warning "comparison between pointer and integer" } */
+ if (i == obj) ; /* { dg-warning "comparison between pointer and integer" } */
+ if (obj == j) ; /* { dg-warning "lacks a cast" } */
+ if (j == obj) ; /* { dg-warning "lacks a cast" } */
+
+ if (obj_c == i) ; /*{ dg-warning "comparison between pointer and integer" }*/
+ if (i == obj_c) ; /*{ dg-warning "comparison between pointer and integer" }*/
+ if (obj_c == j) ; /* { dg-warning "lacks a cast" } */
+ if (j == obj_c) ; /* { dg-warning "lacks a cast" } */
+
+ if (obj_p == i) ; /*{ dg-warning "comparison between pointer and integer" }*/
+ if (i == obj_p) ; /*{ dg-warning "comparison between pointer and integer" }*/
+ if (obj_p == j) ; /* { dg-warning "lacks a cast" } */
+ if (j == obj_p) ; /* { dg-warning "lacks a cast" } */
+
+ if (obj_C == i) ; /*{ dg-warning "comparison between pointer and integer" }*/
+ if (i == obj_C) ; /*{ dg-warning "comparison between pointer and integer" }*/
+ if (obj_C == j) ; /* { dg-warning "lacks a cast" } */
+ if (j == obj_C) ; /* { dg-warning "lacks a cast" } */
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/comp-types-5.m b/gcc/testsuite/objc.dg/comp-types-5.m
new file mode 100644
index 000000000..c112ecbe5
--- /dev/null
+++ b/gcc/testsuite/objc.dg/comp-types-5.m
@@ -0,0 +1,32 @@
+/* Test assignments and comparisons involving `one-off' protocols. */
+/* Author: Nicola Pero <nicola@brainstorm.co.uk>. */
+/* { dg-do compile } */
+#include <objc/objc.h>
+
+@protocol MyProtocol
+- (void) method;
+@end
+
+@interface MyClass
+@end
+
+int main()
+{
+ id obj = nil;
+ id <MyProtocol> obj_p = nil;
+ MyClass<MyProtocol> *obj_cp = nil;
+
+ obj_cp = obj; /* Ok */
+ obj = obj_cp; /* Ok */
+
+ obj_cp = obj_p; /* Ok */
+ obj_p = obj_cp; /* Ok */
+
+ if (obj_cp == obj) ; /* Ok */
+ if (obj == obj_cp) ; /* Ok */
+
+ if (obj_cp == obj_p) ; /* Ok */
+ if (obj_p == obj_cp) ; /* Ok */
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/comp-types-6.m b/gcc/testsuite/objc.dg/comp-types-6.m
new file mode 100644
index 000000000..e23558114
--- /dev/null
+++ b/gcc/testsuite/objc.dg/comp-types-6.m
@@ -0,0 +1,38 @@
+/* Test assignments and comparisons involving category protocols. */
+/* Author: Nicola Pero <nicola@brainstorm.co.uk>. */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+@protocol MyProtocol
+- (void) method;
+@end
+
+@interface MyClass
+@end
+
+@interface MyClass (Addition) <MyProtocol>
+- (void) method;
+@end
+
+@interface MyOtherClass : MyClass
+@end
+
+int main()
+{
+ id <MyProtocol> obj_p = nil;
+ MyClass *obj_cp = nil;
+ MyOtherClass *obj_cp2 = nil;
+
+ obj_cp = obj_p; /* { dg-warning "distinct Objective\\-C type" } */
+ obj_cp2 = obj_p; /* { dg-warning "distinct Objective\\-C type" } */
+ obj_p = obj_cp; /* Ok */
+ obj_p = obj_cp2; /* Ok */
+
+ if (obj_cp == obj_p) ; /* Ok */
+ if (obj_cp2 == obj_p) ; /* Ok */
+ if (obj_p == obj_cp) ; /* Ok */
+ if (obj_p == obj_cp2) ; /* Ok */
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/comp-types-7.m b/gcc/testsuite/objc.dg/comp-types-7.m
new file mode 100644
index 000000000..526934fbb
--- /dev/null
+++ b/gcc/testsuite/objc.dg/comp-types-7.m
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* We used to ICE because we removed the cast to List_linked*
+ in -[ListIndex_linked next]. */
+
+@interface List
+{
+@public
+ int firstLink;
+}
+@end
+
+@interface ListIndex_linked
+{
+@public
+ List *collection;
+ int link;
+}
+@end
+
+@interface List_linked: List
+@end
+
+@implementation List
+@end
+
+@implementation ListIndex_linked
+- next
+{
+ link = ((List_linked*)collection)->firstLink;
+}
+@end
+
diff --git a/gcc/testsuite/objc.dg/comp-types-8.m b/gcc/testsuite/objc.dg/comp-types-8.m
new file mode 100644
index 000000000..bb7b136fb
--- /dev/null
+++ b/gcc/testsuite/objc.dg/comp-types-8.m
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* Another gimplifier ICE... */
+
+#include "../objc-obj-c++-shared/Object1.h"
+
+@interface MyView: Object {
+ int _frame;
+}
+- (void)_finalize;
+@end
+
+@interface MyViewTemplate: MyView {
+ void *_className;
+}
+- (id)createRealObject;
+@end
+
+@implementation MyViewTemplate
+- (id)createRealObject {
+ id realObj;
+ *(MyView *)realObj = *(MyView *)self;
+ return realObj;
+}
+@end
diff --git a/gcc/testsuite/objc.dg/comp-types-9.m b/gcc/testsuite/objc.dg/comp-types-9.m
new file mode 100644
index 000000000..3abcde5be
--- /dev/null
+++ b/gcc/testsuite/objc.dg/comp-types-9.m
@@ -0,0 +1,19 @@
+/* Yet another mysterious gimplifier crasher. */
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+
+@class NSString;
+@protocol NSObject
+@end
+@interface NSObject <NSObject> {
+}
+@end
+void __setRetained(id *ivar, id value) {
+ *ivar = value;
+}
+static NSString *_logProcessPrefix = 0;
+@implementation NSObject (ScopeAdditions)
++ (void)setObjectLogProcessPrefix:(NSString *)processPrefix {
+ __setRetained(&_logProcessPrefix, processPrefix);
+}
+@end
diff --git a/gcc/testsuite/objc.dg/conditional-1.m b/gcc/testsuite/objc.dg/conditional-1.m
new file mode 100644
index 000000000..0aad62c55
--- /dev/null
+++ b/gcc/testsuite/objc.dg/conditional-1.m
@@ -0,0 +1,45 @@
+/* Testing conditional warnings (without headers). */
+/* Author: David Ayers */
+
+/* { dg-do compile } */
+
+#define nil ((id)0)
+@interface MyObject
+@end
+
+@protocol MyProtocol
+@end
+
+@interface MyProtoObject <MyProtocol>
+@end
+
+
+int
+main (int argc, char *argv[])
+{
+ id var_id = nil;
+ id <MyProtocol> var_id_p = nil;
+ MyObject *var_obj = nil;
+ MyProtoObject *var_obj_p = nil;
+
+ var_id = (var_id == var_obj) ? var_id : var_obj;
+ var_id = (var_id == var_obj) ? var_id : var_obj_p;
+
+ /* Ayers: Currently, the following test case passes for
+ technically the wrong reason (see below).
+ */
+ var_obj_p = (var_id == var_obj) ? var_obj_p : var_obj; /* { dg-warning "distinct Objective-C types" } */
+ var_obj_p = (var_id == var_obj) ? var_obj_p : var_id_p;
+
+ /* Ayers: The first of the following test cases
+ should probably warn for var_obj_p = var_obj,
+ yet that would require extensive changes to
+ build_conditional_expr to create a tree with
+ multiple types that the assignment would have
+ to evaluate both versions for correct diagnostics.
+ */
+ var_obj_p = (var_id == var_obj) ? var_id : var_obj;
+ var_obj_p = (var_id == var_obj) ? var_id : var_obj_p;
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/defs.m b/gcc/testsuite/objc.dg/defs.m
new file mode 100644
index 000000000..2ffde0035
--- /dev/null
+++ b/gcc/testsuite/objc.dg/defs.m
@@ -0,0 +1,70 @@
+/* Check if the @defs() construct preserves the correct
+ offsets of ivars. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-options "" } */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+#include "../objc-obj-c++-shared/Object1.h"
+//#include <objc/objc.h>
+
+extern void abort(void);
+
+#define CHECK_IF(expr) if(!(expr)) abort();
+
+@interface Base: Object {
+@public
+ int a;
+ float b;
+ char c;
+}
+@end
+
+@interface Derived: Base {
+@public
+ double d;
+ unsigned e;
+ id f;
+}
+- init;
+@end
+
+struct Derived_defs {
+ @defs(Derived);
+};
+
+@implementation Base
+@end
+@implementation Derived
+- init {
+ [super init];
+ a = 123;
+ b = 1.23;
+ c = 'c';
+ d = 123.456;
+ e = 456;
+ f = isa;
+ return self;
+}
+@end
+
+int main(void) {
+ Derived *derived = [[Derived alloc] init];
+ struct Derived_defs *derived_defs = (struct Derived_defs *)derived;
+
+ CHECK_IF(derived->a == derived_defs->a && derived_defs->a == 123);
+ CHECK_IF(derived->b == derived_defs->b && derived_defs->b == (float)1.23);
+ CHECK_IF(derived->c == derived_defs->c && derived_defs->c == 'c');
+ CHECK_IF(derived->d == derived_defs->d && derived_defs->d == (double)123.456);
+ CHECK_IF(derived->e == derived_defs->e && derived_defs->e == 456);
+ CHECK_IF(derived->f == derived_defs->f && derived_defs->f == derived_defs->isa);
+
+ /* Try out the "inline" notation as well. */
+ CHECK_IF(((struct { @defs(Derived); } *)derived)->a == 123);
+ CHECK_IF(((struct { @defs(Derived); } *)derived)->c == 'c');
+ CHECK_IF(((struct { @defs(Derived); } *)derived)->e == 456);
+
+ return 0;
+}
+
+#include "../objc-obj-c++-shared/Object1-implementation.h"
diff --git a/gcc/testsuite/objc.dg/demangle-1.m b/gcc/testsuite/objc.dg/demangle-1.m
new file mode 100644
index 000000000..42b79a9eb
--- /dev/null
+++ b/gcc/testsuite/objc.dg/demangle-1.m
@@ -0,0 +1,59 @@
+/* Test demangling an Objective-C method. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <objc/objc.h>
+
+@interface DemangleTest
+{
+ Class isa;
+}
++ (id) initialize;
++ (int) testFunction1;
++ (int) test_function2;
++ (int) __testFunction3: (int)unused andArgument: (char)unused2;
+@end
+
+@implementation DemangleTest
++ (id) initialize { return self; }
++ (int) testFunction1
+{
+ printf ("%s\n", __PRETTY_FUNCTION__);
+ return strcmp (__PRETTY_FUNCTION__, "+[DemangleTest testFunction1]");
+}
+/* Note that in general, due to how mangling is done, it's impossible
+ to get the demangling right for all functions containing '_' in the
+ name. But at least we should be able to get that right for single
+ argument ones that don't end with '_', such as the following
+ one. */
++ (int) test_function2
+{
+ printf ("%s\n", __PRETTY_FUNCTION__);
+ return strcmp (__PRETTY_FUNCTION__, "+[DemangleTest test_function2]");
+}
++ (int) __testFunction3: (int)unused andArgument: (char)unused2
+{
+ printf ("%s\n", __PRETTY_FUNCTION__);
+ return strcmp (__PRETTY_FUNCTION__, "+[DemangleTest __testFunction3:andArgument:]");
+}
+@end
+
+int main ()
+{
+ if ([DemangleTest testFunction1] != 0)
+ abort ();
+
+ if ([DemangleTest test_function2] != 0)
+ abort ();
+
+ if ([DemangleTest __testFunction3:0 andArgument: 'c'] != 0)
+ abort ();
+
+ return 0;
+}
+
+
diff --git a/gcc/testsuite/objc.dg/desig-init-1.m b/gcc/testsuite/objc.dg/desig-init-1.m
new file mode 100644
index 000000000..a07e72be1
--- /dev/null
+++ b/gcc/testsuite/objc.dg/desig-init-1.m
@@ -0,0 +1,51 @@
+/* Test Objective-C capability for handling GNU/C99 designated initializers, and distinguishing them
+ from message sends. Contributed by Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-options "-std=gnu99" } */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+
+#include "../objc-obj-c++-shared/Object1.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+@interface Cls : Object
++ (int) meth1;
++ (int) meth2;
++ (void) doTests;
+@end
+
+@implementation Cls
++ (int) meth1 { return 45; }
++ (int) meth2 { return 21; }
++ (void) doTests {
+ int arr[7] = {
+ 0,
+ [Cls meth1],
+ [2 + 1] = 3,
+ [2 * 2 ... 5] = (size_t)[0 meth4], /* { dg-warning "invalid receiver type" } */
+ /* { dg-warning "no .\\-meth4. method found" "" { target *-*-* } 26 } */
+ [2] [Cls meth2],
+ /* Since invalid receivers are treated as 'id' for purposes of message
+ lookup, we _should_ find a meth2 to call below. */
+ [6] = (int)[0 meth2] /* { dg-warning "invalid receiver type" } */
+ };
+
+ if (arr[0] != 0 || arr[1] != 45 || arr[2] != 21 || arr[3] != 3)
+ abort ();
+
+ printf ("%s\n", [super name]);
+ printf ("%d %d %d %d %d %d\n", arr[0], arr[1], arr[2], arr[3], arr[4], arr[5]);
+}
+@end
+
+int main(void) {
+ [Cls doTests];
+ return 0;
+}
+
+/* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 0 } */
+/* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 0 } */
+/* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 0 } */
+
+#include "../objc-obj-c++-shared/Object1-implementation.h"
diff --git a/gcc/testsuite/objc.dg/desig-init-2.m b/gcc/testsuite/objc.dg/desig-init-2.m
new file mode 100644
index 000000000..cf8e0c1c3
--- /dev/null
+++ b/gcc/testsuite/objc.dg/desig-init-2.m
@@ -0,0 +1,7 @@
+/* Test handling of C99 designator lists in Objective-C. Test array
+ designators after structure member designators. */
+/* Origin: Joseph Myers <joseph@codesourcery.com> */
+/* { dg-do compile } */
+/* { dg-options "-std=gnu99" } */
+
+struct s { int a[2]; } x = { .a[0] = 1 };
diff --git a/gcc/testsuite/objc.dg/dg.exp b/gcc/testsuite/objc.dg/dg.exp
new file mode 100644
index 000000000..350c4b833
--- /dev/null
+++ b/gcc/testsuite/objc.dg/dg.exp
@@ -0,0 +1,42 @@
+# GCC Objective-C testsuite that uses the `dg.exp' driver.
+# Copyright (C) 1997, 2001, 2007, 2010 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 GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+# Load support procs.
+load_lib objc-dg.exp
+
+# If a testcase doesn't have special options, use these.
+global DEFAULT_CFLAGS
+if ![info exists DEFAULT_CFLAGS] then {
+ set DEFAULT_CFLAGS ""
+}
+
+# Initialize `dg'.
+dg-init
+
+# Gather a list of all tests.
+set tests [lsort [glob -nocomplain $srcdir/$subdir/*.m]]
+
+# Main loop.
+dg-runtest $tests "-fgnu-runtime" $DEFAULT_CFLAGS
+
+# darwin targets can also run code with the NeXT runtime.
+if [istarget "*-*-darwin*" ] {
+ dg-runtest $tests "-fnext-runtime" $DEFAULT_CFLAGS
+}
+
+# All done.
+dg-finish
diff --git a/gcc/testsuite/objc.dg/duplicate-class-1.m b/gcc/testsuite/objc.dg/duplicate-class-1.m
new file mode 100644
index 000000000..f86159211
--- /dev/null
+++ b/gcc/testsuite/objc.dg/duplicate-class-1.m
@@ -0,0 +1,31 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+/* Test that a duplicated @implementation for the same class does not
+ crash the compiler. */
+
+@interface Test
+{
+ Class isa;
+}
+- (int) test;
+@end
+
+@implementation Test
+- (int) test
+{
+ return 4;
+}
+@end
+
+/* The most likely cause is that the programmer meant this to be a
+ category, so check what happens if we have some different methods
+ in there. */
+@implementation Test
+- (int) test2 /* { dg-error "reimplementation of class .Test." } */
+{
+ return [self test];
+}
+@end
+/* { dg-warning "incomplete implementation" "" { target *-*-* } 29 } */
+/* { dg-warning "not found" "" { target *-*-* } 29 } */
diff --git a/gcc/testsuite/objc.dg/dwarf-1.m b/gcc/testsuite/objc.dg/dwarf-1.m
new file mode 100644
index 000000000..c04b61350
--- /dev/null
+++ b/gcc/testsuite/objc.dg/dwarf-1.m
@@ -0,0 +1,6 @@
+/* { dg-options "-gdwarf-2 -dA" } */
+/* { dg-final { scan-assembler "\"id.0\".*DW_AT_name" } } */
+/* { dg-skip-if "No Dwarf" { { *-*-aix* alpha*-dec-osf* hppa*-*-hpux* } && { ! hppa*64*-*-* } } { "*" } { "" } } */
+@interface foo
+ id x;
+@end
diff --git a/gcc/testsuite/objc.dg/dwarf-2.m b/gcc/testsuite/objc.dg/dwarf-2.m
new file mode 100644
index 000000000..bedc520a6
--- /dev/null
+++ b/gcc/testsuite/objc.dg/dwarf-2.m
@@ -0,0 +1,4 @@
+/* { dg-options "-gdwarf-2 -dA -gno-strict-dwarf" } */
+/* { dg-final { scan-assembler "0x10\[^0-9a-f\].*DW_AT_language" } } */
+/* { dg-skip-if "No Dwarf" { { *-*-aix* alpha*-dec-osf* hppa*-*-hpux* } && { ! hppa*64*-*-* } } { "*" } { "" } } */
+int x;
diff --git a/gcc/testsuite/objc.dg/encode-1.m b/gcc/testsuite/objc.dg/encode-1.m
new file mode 100644
index 000000000..09cb6af19
--- /dev/null
+++ b/gcc/testsuite/objc.dg/encode-1.m
@@ -0,0 +1,23 @@
+/* Test if the Objective-C @encode machinery distinguishes between
+ 'BOOL *' (which should be encoded as a pointer to BOOL) and 'char *' (which
+ should be encoded as '*'). This is somewhat tricky wrt the NeXT runtime,
+ where we have 'typedef char BOOL'. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-do run } */
+#include <string.h>
+#include <stdlib.h>
+#include <objc/objc.h>
+
+int main(void) {
+ const char *BOOL_ptr = @encode(BOOL *);
+ const char *BOOL_ = @encode(BOOL);
+ const char *char_ptr = @encode(char *);
+
+ if(*BOOL_ptr != '^' || strcmp(BOOL_ptr + 1, BOOL_))
+ abort();
+
+ if(strcmp(char_ptr, "*"))
+ abort();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/encode-10.m b/gcc/testsuite/objc.dg/encode-10.m
new file mode 100644
index 000000000..bdfdb82b8
--- /dev/null
+++ b/gcc/testsuite/objc.dg/encode-10.m
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+
+typedef struct Vec {
+ double x, y;
+ int z;
+} xyz_t ;
+
+typedef struct {
+ float fscalar;
+ double dscalar;
+ xyz_t dv;
+ int iscalar;
+} anonymous;
+
+const char *enc = @encode(xyz_t);
+const char *enc2 = @encode(anonymous);
+
+/* { dg-final { scan-assembler "{Vec=ddi}" } } */
+/* { dg-final { scan-assembler "{?=fd{Vec=ddi}i}" } } */
diff --git a/gcc/testsuite/objc.dg/encode-11.m b/gcc/testsuite/objc.dg/encode-11.m
new file mode 100644
index 000000000..2e5fc84c8
--- /dev/null
+++ b/gcc/testsuite/objc.dg/encode-11.m
@@ -0,0 +1,43 @@
+/* { dg-do run } */
+
+extern void _exit(int);
+extern int strcmp(const char *, const char *);
+
+typedef struct Vec {
+ double xv[10], yv[5];
+ float fscal;
+ int z;
+} xyz_t ;
+
+typedef struct {
+ float fscalar;
+ double dscalar;
+ xyz_t dv;
+ int iscalar;
+ long ln;
+ long long lln;
+} anonymous;
+
+const char *enc = @encode(xyz_t);
+const char *enc2 = @encode(anonymous);
+
+#ifdef __LP64__
+#define L "q"
+#else
+#define L "l"
+#endif
+
+int main(void) {
+ const char *encode = @encode(long);
+
+ if (strcmp (encode, L))
+ _exit(-(__LINE__));
+
+ if (strcmp (enc, "{Vec=[10d][5d]fi}"))
+ _exit(-(__LINE__));
+
+ if (strcmp (enc2, "{?=fd{Vec=[10d][5d]fi}i" L "q}"))
+ _exit(-(__LINE__));
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/encode-2.m b/gcc/testsuite/objc.dg/encode-2.m
new file mode 100644
index 000000000..ea0ff6a7d
--- /dev/null
+++ b/gcc/testsuite/objc.dg/encode-2.m
@@ -0,0 +1,104 @@
+/* Test Objective-C method encodings. */
+
+/* The _encoded_ parameter offsets for Objective-C methods are
+ computed inductively as follows:
+ - The first paramter (self) has offset 0;
+ - The k-th parameter (k > 1) has offset equal to the
+ sum of:
+ - the offset of the k-1-st paramter
+ - the (void *)-promoted size of the k-1-st parameter.
+
+ Note that the encoded offsets need not correspond
+ to the actual placement of parameters (relative to 'self')
+ on the stack! Your target's ABI may have very different
+ opinions on the matter. */
+
+/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+#include "../objc-obj-c++-shared/Object1.h"
+#include "../objc-obj-c++-shared/next-mapping.h"
+
+#ifdef __NEXT_RUNTIME__
+#define METHOD Method
+#else
+#include <objc/objc-api.h>
+#define METHOD Method_t
+#define method_get_types(M) (M)->method_types
+#endif
+
+extern int sscanf(const char *str, const char *format, ...);
+extern void abort(void);
+#define CHECK_IF(expr) if(!(expr)) abort()
+
+@interface Foo: Object
+typedef struct { float x, y; } XXPoint;
+typedef struct { float width, height; } XXSize;
+typedef struct _XXRect { XXPoint origin; XXSize size; } XXRect;
+-(id)setRect:(XXRect)r withInt:(int)i;
+-(void) char:(signed char)c float:(float)f double:(double)d long:(long)l;
+@end
+
+XXRect my_rect;
+unsigned offs1, offs2, offs3, offs4, offs5, offs6, offs7;
+
+@implementation Foo
+-(id)setRect:(XXRect)r withInt:(int)i {
+ unsigned offs = sizeof(self);
+ CHECK_IF(offs == offs3);
+ offs += sizeof(_cmd);
+ CHECK_IF(offs == offs4);
+ offs += sizeof(r);
+ CHECK_IF(offs == offs5);
+ offs += sizeof(i);
+ CHECK_IF(offs == offs1);
+ return nil;
+}
+-(void) char:(signed char)c float:(float)f double:(double)d long:(long)l {
+ unsigned offs = sizeof(self);
+ CHECK_IF(offs == offs3);
+ offs += sizeof(_cmd);
+ CHECK_IF(offs == offs4);
+ offs += sizeof((int)c);
+ CHECK_IF(offs == offs5);
+ offs += sizeof(f);
+ CHECK_IF(offs == offs6);
+ offs += sizeof(d);
+ CHECK_IF(offs == offs7);
+ offs += sizeof(l);
+ CHECK_IF(offs == offs1);
+}
+@end
+
+
+int main(void) {
+ Foo *foo = [[Foo alloc] init];
+ Class fooClass = objc_get_class("Foo");
+ METHOD meth;
+ const char *string;
+
+ meth = class_get_instance_method(fooClass, @selector(setRect:withInt:));
+ offs2 = 9999;
+
+ sscanf(method_get_types(meth), "@%u@%u:%u{_XXRect={?=ff}{?=ff}}%ui%u", &offs1, &offs2, &offs3,
+ &offs4, &offs5);
+
+ CHECK_IF(!offs2);
+ [foo setRect:my_rect withInt:123];
+
+ meth = class_get_instance_method(fooClass, @selector(char:float:double:long:));
+ offs2 = 9999;
+ if (sizeof (long) == 8)
+ string = "v%u@%u:%uc%uf%ud%uq%u";
+ else
+ string = "v%u@%u:%uc%uf%ud%ul%u";
+ sscanf(method_get_types(meth), string, &offs1, &offs2, &offs3,
+ &offs4, &offs5, &offs6, &offs7);
+ CHECK_IF(!offs2);
+ [foo char:'c' float:2.3 double:3.5 long:2345L];
+
+ return 0;
+}
+
+#include "../objc-obj-c++-shared/Object1-implementation.h"
diff --git a/gcc/testsuite/objc.dg/encode-3.m b/gcc/testsuite/objc.dg/encode-3.m
new file mode 100644
index 000000000..c1327c1e6
--- /dev/null
+++ b/gcc/testsuite/objc.dg/encode-3.m
@@ -0,0 +1,113 @@
+/* Method encoding tests for stand-alone @protocol declarations. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifndef __NEXT_RUNTIME__
+# include <objc/objc-api.h>
+#endif
+#include "../objc-obj-c++-shared/objc-test-suite-types.h"
+#include "../objc-obj-c++-shared/next-mapping.h"
+#include <objc/Protocol.h>
+
+extern int sscanf(const char *str, const char *format, ...);
+extern void abort(void);
+#define CHECK_IF(expr) if(!(expr)) abort()
+
+enum Enum {
+ zero, one, two, three
+};
+typedef enum Enum Enum;
+typedef signed char ObjCBool; /* as used by the NeXT runtime */
+
+@protocol Proto
+union __XXAngle { unsigned int alpha, beta; };
+typedef struct { float x, y; union __XXAngle a; } XXPoint;
+typedef struct { double width, height; } XXSize;
+typedef struct _XXRect { XXPoint origin; XXSize size; struct _XXRect *next; } XXRect;
+- (void) char:(signed char)c float:(float)f double:(double)d unsigned:(unsigned)u short:(short)s long:(long)l;
+- (void *)setRect:(XXRect)r withBool:(ProtoBool)b withInt:(int)i;
++ (Enum *)getEnum:(XXPoint *)pt enum:(enum Enum)e bool:(ObjCBool)b;
++ (ProtoBool **)getBool:(ObjCBool **)b;
+@end
+
+Protocol *proto;
+struct objc_method_description *meth;
+#ifdef NEXT_OBJC_USE_NEW_INTERFACE
+struct objc_method_description meth_object;
+#endif
+unsigned totsize, offs0, offs1, offs2, offs3, offs4, offs5, offs6, offs7;
+
+static void scan_initial(const char *pattern) {
+ totsize = offs0 = offs1 = offs2 = offs3 = offs4 = offs5 = offs6 = offs7 = (unsigned)-1;
+ sscanf(meth->types, pattern, &totsize, &offs0, &offs1, &offs2, &offs3,
+ &offs4, &offs5, &offs6, &offs7);
+ CHECK_IF(!offs0 && offs1 == sizeof(id) && offs2 == offs1 + sizeof(SEL) && totsize >= offs2);
+}
+
+int main(void) {
+ const char *string;
+ proto = @protocol(Proto);
+#ifdef NEXT_OBJC_USE_NEW_INTERFACE
+ meth_object = protocol_getMethodDescription (proto,
+ @selector(char:float:double:unsigned:short:long:), YES, YES);
+ meth = &meth_object;
+#else
+ meth = [proto descriptionForInstanceMethod: @selector(char:float:double:unsigned:short:long:)];
+#endif
+ if (sizeof (long) == 8)
+ string = "v%u@%u:%uc%uf%ud%uI%us%uq%u";
+ else
+ string = "v%u@%u:%uc%uf%ud%uI%us%ul%u";
+ scan_initial(string);
+ CHECK_IF(offs3 == offs2 + sizeof(int) && offs4 == offs3 + sizeof(float));
+ CHECK_IF(offs5 == offs4 + sizeof(double) && offs6 == offs5 + sizeof(unsigned));
+ CHECK_IF(offs7 == offs6 + sizeof(int) && totsize == offs7 + sizeof(long));
+#ifdef NEXT_OBJC_USE_NEW_INTERFACE
+ meth_object = protocol_getMethodDescription (proto,
+ @selector(setRect:withBool:withInt:), YES, YES);
+ meth = &meth_object;
+#else
+ meth = [proto descriptionForInstanceMethod: @selector(setRect:withBool:withInt:)];
+#endif
+ scan_initial("^v%u@%u:%u{_XXRect={?=ff(__XXAngle=II)}{?=dd}^{_XXRect}}%uB%ui%u");
+ CHECK_IF(offs3 == offs2 + sizeof(XXRect) && offs4 == offs3 + sizeof(int));
+ CHECK_IF(totsize == offs4 + sizeof(int));
+#ifdef NEXT_OBJC_USE_NEW_INTERFACE
+ meth_object = protocol_getMethodDescription (proto,
+ @selector(getEnum:enum:bool:), YES, NO);
+ meth = &meth_object;
+#else
+ meth = [proto descriptionForClassMethod: @selector(getEnum:enum:bool:)];
+#endif
+
+ /* Here we have the complication that 'enum Enum' could be encoded
+ as 'i' on __NEXT_RUNTIME_, and (most likely) as 'I' on the GNU
+ runtime. So we get the @encode(enum Enum), then put it into the
+ string in place of the traditional 'i'.
+ */
+ /* scan_initial("^i%u@%u:%u^{?=ff(__XXAngle=II)}%ui%uc%u"); */
+ {
+ char pattern[1024];
+
+ sprintf (pattern, "^%s%%u@%%u:%%u^{?=ff(__XXAngle=II)}%%u%s%%uc%%u",
+ @encode(enum Enum), @encode(enum Enum));
+ scan_initial(pattern);
+ }
+
+ CHECK_IF(offs3 == offs2 + sizeof(XXPoint *) && offs4 == offs3 + sizeof(enum Enum));
+ CHECK_IF(totsize == offs4 + sizeof(int)); /* 'ObjCBool' is really 'char' */
+#ifdef NEXT_OBJC_USE_NEW_INTERFACE
+ meth_object = protocol_getMethodDescription (proto,
+ @selector(getBool:), YES, NO);
+ meth = &meth_object;
+#else
+ meth = [proto descriptionForClassMethod: @selector(getBool:)];
+#endif
+ scan_initial("^^B%u@%u:%u^*%u");
+ CHECK_IF(totsize == offs2 + sizeof(ObjCBool **));
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/encode-4.m b/gcc/testsuite/objc.dg/encode-4.m
new file mode 100644
index 000000000..d74c0ba1c
--- /dev/null
+++ b/gcc/testsuite/objc.dg/encode-4.m
@@ -0,0 +1,93 @@
+/* Encoding tests for ObjC class layouts. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-options "" } */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+#include "../objc-obj-c++-shared/Object1.h"
+#include "../objc-obj-c++-shared/next-mapping.h"
+#ifdef __NEXT_RUNTIME__
+#include <objc/objc-class.h>
+#else
+#include <objc/objc-api.h>
+#endif
+
+extern void abort(void);
+extern int strcmp(const char *s1, const char *s2);
+
+#define CHECK_IF(expr) if(!(expr)) abort()
+
+@class Int1, Int2;
+struct Nested;
+
+struct Innermost {
+ unsigned char a, b;
+ struct Nested *encl;
+};
+
+struct Nested {
+ float a, b;
+ Int1 *next;
+ struct Innermost innermost;
+};
+
+@interface Int1: Object {
+ signed char a, b;
+ Int2 *int2;
+ struct Nested nested;
+}
+@end
+
+@interface Int2: Int1 {
+ struct Innermost *innermost;
+ Int1 *base;
+}
+@end
+
+@implementation Int1
+@end
+
+@implementation Int2
+@end
+
+#ifdef NEXT_OBJC_USE_NEW_INTERFACE
+Ivar *ivar;
+#else
+struct objc_ivar *ivar;
+#endif
+
+static void check_ivar(const char *name, const char *type) {
+#ifdef NEXT_OBJC_USE_NEW_INTERFACE
+ CHECK_IF(!strcmp(ivar_getName(*ivar), name));
+ CHECK_IF(!strcmp(ivar_getTypeEncoding(*ivar), type));
+#else
+ CHECK_IF(!strcmp(ivar->ivar_name, name));
+ CHECK_IF(!strcmp(ivar->ivar_type, type));
+#endif
+ ivar++;
+}
+
+int main(void) {
+#ifdef NEXT_OBJC_USE_NEW_INTERFACE
+ ivar = class_copyIvarList ((Class)objc_get_class("Int1"), NULL);
+#else
+ ivar = ((Class)objc_get_class("Int1"))->ivars->ivar_list;
+#endif
+ check_ivar("a", "c");
+ check_ivar("b", "c");
+ check_ivar("int2", "@\"Int2\"");
+ check_ivar("nested",
+ "{Nested=\"a\"f\"b\"f\"next\"@\"Int1\"\"innermost\"{Innermost=\"a\"C\"b\"C\"encl\"^{Nested}}}");
+
+#ifdef NEXT_OBJC_USE_NEW_INTERFACE
+ ivar = class_copyIvarList ((Class)objc_get_class("Int2"), NULL);
+#else
+ ivar = ((Class)objc_get_class("Int2"))->ivars->ivar_list;
+#endif
+ check_ivar("innermost", "^{Innermost=CC^{Nested}}");
+ check_ivar("base", "@\"Int1\"");
+
+ return 0;
+}
+
+#include "../objc-obj-c++-shared/Object1-implementation.h"
diff --git a/gcc/testsuite/objc.dg/encode-5.m b/gcc/testsuite/objc.dg/encode-5.m
new file mode 100644
index 000000000..523c7ce02
--- /dev/null
+++ b/gcc/testsuite/objc.dg/encode-5.m
@@ -0,0 +1,76 @@
+/* Check if array arguments of ObjC methods are decayed to pointer types
+ in a proper fashion:
+ (1) The _encodings_ for the array arguments should remain to be '[4i]' and
+ such, since this has been the case since at least gcc 3.3.
+ (2) However, when building the static C functions out of ObjC method signatures,
+ we need to decay the arrays into pointers (as C does).
+ (3) If array size is not known (e.g., 'int a[]'), then the type shall be
+ encoded as a pointer. */
+
+/* Contributed by Alexander Malmberg <alexander@malmberg.org> */
+
+#include "../objc-obj-c++-shared/Object1.h"
+#include "../objc-obj-c++-shared/next-mapping.h"
+#include <stdlib.h>
+#include <stdio.h>
+#define CHECK_IF(expr) if(!(expr)) abort()
+
+#ifdef __NEXT_RUNTIME__
+#define METHOD Method
+#else
+#include <objc/objc-api.h>
+#define METHOD Method_t
+#define method_get_types(M) (M)->method_types
+#endif
+
+@interface Test : Object
+{ float j; }
+-(void) test2: (int [5])a with: (int [])b;
+-(id) test3: (Test **)b; /* { dg-message "previous declaration of .\\-\\(id\\)test3:\\(Test \\*\\*\\)b." } */
+@end
+
+@implementation Test
+-(void) test2: (int [5])a with: (int [])b
+{
+ a[3] = *b;
+}
+-(void) test3: (Test [3][4])b { /* { dg-warning "conflicting types for .\\-\\(void\\)test3:\\(Test \\\[3\\\]\\\[4\\\]\\)b." } */
+}
+@end
+
+int bb[6] = { 0, 1, 2, 3, 4, 5 };
+int *b = bb;
+Test *cc[4];
+Test **c = cc;
+
+int offs1, offs2, offs3, offs4, offs5, offs6;
+
+int main(int argc, char **argv)
+{
+ Class testClass = objc_get_class("Test");
+ METHOD meth;
+
+ cc[0] = [Test new];
+ CHECK_IF (bb[3] == 3);
+ [*c test2: b with: bb + 4];
+ CHECK_IF (bb[3] == 4);
+ bb[3] = 0;
+ [*c test2: bb with: bb + 5];
+ CHECK_IF (bb[3] == 5);
+
+ meth = class_get_instance_method(testClass, @selector(test2:with:));
+ offs1 = offs2 = offs3 = offs4 = offs5 = offs6 = -1;
+ sscanf(method_get_types(meth), "v%d@%d:%d[%di]%d^i%d", &offs1, &offs2, &offs3,
+ &offs4, &offs5, &offs6);
+ CHECK_IF (!offs2 && offs4 == 5 && offs3 > 0);
+ CHECK_IF (offs5 == 2 * offs3 && offs6 == 3 * offs3 && offs1 == 4 * offs3);
+
+ meth = class_get_instance_method(testClass, @selector(test3:));
+ offs1 = offs2 = offs3 = offs4 = offs5 = offs6 = -1;
+ sscanf(method_get_types(meth), "v%d@%d:%d[%d[%d{Test=#f}]]%d", &offs1, &offs2, &offs3,
+ &offs4, &offs5, &offs6);
+ CHECK_IF (!offs2 && offs4 == 3 && offs5 == 4 && offs3 > 0);
+ CHECK_IF (offs6 == 2 * offs3 && offs1 == 3 * offs3);
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/encode-6-next.m b/gcc/testsuite/objc.dg/encode-6-next.m
new file mode 100644
index 000000000..c3d922659
--- /dev/null
+++ b/gcc/testsuite/objc.dg/encode-6-next.m
@@ -0,0 +1,23 @@
+/* Test for graceful encoding of const-qualified fields and parameters. */
+/* Author: Ziemowit Laski <zlaski@apple.com> */
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */
+
+struct Cxx {
+ const struct Cxx *next;
+};
+
+@interface ObjC {
+ const struct Cxx *obj;
+}
+- (ObjC *)initWithCxx: (struct Cxx *const)c and: (const struct Cxx *)d;
+@end
+
+@implementation ObjC
+- (ObjC *)initWithCxx: (struct Cxx *const)c and: (const struct Cxx *)d {
+ obj = d;
+ return self;
+}
+@end
+
+/* { dg-final { scan-assembler "@\[0-9\]+@0:\[0-9\]+\\^{Cxx=\\^{Cxx}}\[0-9\]+r\\^{Cxx=\\^{Cxx}}" } } */
diff --git a/gcc/testsuite/objc.dg/encode-6.m b/gcc/testsuite/objc.dg/encode-6.m
new file mode 100644
index 000000000..291a41e96
--- /dev/null
+++ b/gcc/testsuite/objc.dg/encode-6.m
@@ -0,0 +1,23 @@
+/* Test for graceful encoding of const-qualified fields and parameters. */
+/* Author: Ziemowit Laski <zlaski@apple.com> */
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-fnext-runtime" } { "" } } */
+
+struct Cxx {
+ const struct Cxx *next;
+};
+
+@interface ObjC {
+ const struct Cxx *obj;
+}
+- (ObjC *)initWithCxx: (struct Cxx *const)c and: (const struct Cxx *)d;
+@end
+
+@implementation ObjC
+- (ObjC *)initWithCxx: (struct Cxx *const)c and: (const struct Cxx *)d {
+ obj = d;
+ return self;
+}
+@end
+
+/* { dg-final { scan-assembler "@\[0-9\]+@0:\[0-9\]+r\\^{Cxx=\\^r{Cxx}}\[0-9\]+\\^r{Cxx}" } } */
diff --git a/gcc/testsuite/objc.dg/encode-7-next-64bit.m b/gcc/testsuite/objc.dg/encode-7-next-64bit.m
new file mode 100644
index 000000000..60129f9d2
--- /dev/null
+++ b/gcc/testsuite/objc.dg/encode-7-next-64bit.m
@@ -0,0 +1,270 @@
+/* Additional testing for the NeXT runtime. Encoding in -m64 mode */
+
+/* { dg-do run { target *-*-darwin* } } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+#include <stdbool.h>
+#include <string.h>
+#include <stdlib.h>
+#include <objc/Object.h>
+#include "../objc-obj-c++-shared/next-mapping.h"
+
+#define CHECK_IF(E) if (!(E)) abort ()
+
+@class NSDictionary, NSFont, NSError, _NSATSTypesetterGuts, NSString, NSMenu, NSArray;
+
+typedef unsigned char UInt8;
+typedef const signed long OSStatus;
+typedef unsigned long CFIndex;
+typedef unsigned int UInt32;
+typedef UInt32 FourCharCode;
+typedef FourCharCode OSType;
+
+struct FSRef {
+ UInt8 hidden[80];
+};
+typedef struct FSRef FSRef;
+
+typedef struct _NSPoint {
+ float x;
+ float y;
+} NSPoint;
+
+typedef struct _NSSize {
+ float width;
+ float height;
+} NSSize;
+
+typedef struct _NSRect {
+ NSPoint origin;
+ NSSize size;
+} NSRect;
+
+typedef struct _NSRange {
+ unsigned int location;
+ unsigned int length;
+} NSRange;
+
+typedef const char *NXAtom;
+
+typedef struct {
+ NSDictionary *_attributes;
+ NSFont *_font;
+ CFIndex _characterLength;
+ CFIndex _nominalGlyphLocation;
+ const CFIndex *p;
+ float _defaultLineHeight;
+ float _defaultBaselineOffset;
+ float _horizExpansion;
+ float _baselineDelta;
+ NSRect _attachmentBBox;
+ long ll, *llp;
+ unsigned long ull, *ullp;
+ id a;
+ const id a1;
+ const struct objc_object *a2;
+ SEL b;
+ const SEL b1;
+ const struct objc_selector *b2;
+ const char *str1;
+ char *str2;
+ char *const str3;
+ const char *const str4;
+ struct {
+ unsigned int _isAttachmentRun:1;
+ unsigned int _hasPositionalStake:1;
+ unsigned int _isDefaultFace:1;
+ unsigned int _hasCombiningMarks:1;
+ unsigned int _isScreenFont:1;
+ unsigned int _reserved:27;
+ } _rFlags;
+} NSATSGlyphStorageRun;
+
+typedef struct __CFSet *CFMutableSetRef;
+typedef const struct __CTLine * CTLineRef;
+typedef const struct __NSAppleEventManagerSuspension* NSAppleEventManagerSuspensionID;
+
+struct ComponentInstanceRecord {
+ long data[1];
+};
+typedef struct ComponentInstanceRecord ComponentInstanceRecord;
+typedef ComponentInstanceRecord *ComponentInstance;
+
+typedef NSString *(*NSErrorUserInfoFormatterFunc)(id objToBeDisplayed, NSError *err, char modifier);
+typedef struct {
+ NSErrorUserInfoFormatterFunc formatterFunc;
+ NSString *userInfoKey;
+ unsigned int parameterMask;
+} NSErrorUserInfoFormatter;
+
+typedef Object MyObj;
+typedef Object *MyPtr;
+
+@interface Foo: Object {
+ NSATSGlyphStorageRun r;
+}
+- (NSError *)_errorWithOSStatus:(OSStatus)inOSStatus ref1:(const FSRef *)inRef1 ref2:(const struct FSRef *)inRef2
+ reading:(BOOL)inReadingNotWriting;
+- (const NSATSGlyphStorageRun *)_attributeRunForCharacterAtIndex:(const CFIndex)charIndex;
+- (const _NSATSTypesetterGuts *)_getATSTypesetterGuts:(const struct objc_selector *)sel;
+- (void)resumeWithSuspensionID:(NSAppleEventManagerSuspensionID)suspensionID and:(const CFIndex *)status;
+- (const id)anotherMeth:(const SEL)sel and:(const Foo *)foo and:(const struct objc_object *)obj;
+- (id)str1:(const char *)str1 str2:(char *)str2 str3:(char *const)str3 str4:(const char *const)str4;
+- (oneway void)foo1:(Foo *)foo1 foo2:(const Foo *)foo2 foo3:(Foo *const)foo3 foo4:(const Foo *const)foo4;
+- (in const char *)sel1:(const SEL)sel1 id1:(const id)id1;
+- (inout id)obj1:(const MyPtr)obj1 obj2:(Object *const)obj2 obj3:(MyObj *const)obj3;
++ (ComponentInstance)_defaultScriptingComponent;
+- (NSString *)_formatCocoaErrorString:(NSString *)formatString parameters:(const char *)parameters
+ applicableFormatters:(NSErrorUserInfoFormatter **)formatters count:(int)numFormatters;
+- (NSErrorUserInfoFormatter *)formatter_func:(id)obj run:(const NSATSGlyphStorageRun **)run;
+- (BOOL)_forgetWord:(bycopy in NSString *)word inDictionary:(bycopy in NSString *)language;
+- (void)_registerServicesMenu:(NSMenu *)servicesMenu withSendTypes:(const NXAtom *)sendTypes
+ andReturnTypes:(const NXAtom *)returnTypes addToList:(BOOL)addToList;
++ (CFMutableSetRef *)_proxySharePointer;
+- (NSRange)_checkGrammarInString:(in NSString *)stringToCheck language:(bycopy in NSString *)language details:(bycopy out NSArray **)details;
+- (bool)_resolvePositionalStakeGlyphsForLineFragment:(CTLineRef)line lineFragmentRect:(NSRect)lineFragmentRect
+ minPosition:(float)minPosition maxPosition:(float)maxPosition maxLineFragmentWidth:(float)maxLineFragmentWidth
+ breakHint:(CFIndex *)charIndex;
++ (BOOL)findVoiceByIdentifier:(NSString *)identifier returningCreator:(OSType *)returnedCreator returningID:(OSType *)returnedID;
+@end
+
+NSRange globalRange;
+
+@implementation Foo
+- (NSError *)_errorWithOSStatus:(OSStatus)inOSStatus ref1:(const FSRef *)inRef1 ref2:(const struct FSRef *)inRef2
+ reading:(BOOL)inReadingNotWriting {
+ return (NSError *)self;
+}
+- (const NSATSGlyphStorageRun *)_attributeRunForCharacterAtIndex:(CFIndex)charIndex {
+ return (const NSATSGlyphStorageRun *)self;
+}
+- (const _NSATSTypesetterGuts *)_getATSTypesetterGuts:(const struct objc_selector *)sel {
+ return (const _NSATSTypesetterGuts *)self;
+}
+- (void)resumeWithSuspensionID:(NSAppleEventManagerSuspensionID)suspensionID and:(const CFIndex *)status {
+}
+- (const id)anotherMeth:(const SEL)sel and:(const Foo *)foo and:(const struct objc_object *)obj {
+ return (const id)self;
+}
+- (id)str1:(const char *)str1 str2:(char *)str2 str3:(char *const)str3 str4:(const char *const)str4 {
+ return self;
+}
+- (oneway void)foo1:(Foo *)foo1 foo2:(const Foo *)foo2 foo3:(Foo *const)foo3 foo4:(const Foo *const)foo4 {
+}
+- (in const char *)sel1:(const SEL)sel1 id1:(const id)id1 {
+ return "Hello";
+}
+- (inout id)obj1:(const MyPtr)obj1 obj2:(Object *const)obj2 obj3:(MyObj *const)obj3 {
+ return self;
+}
++ (ComponentInstance)_defaultScriptingComponent {
+ return (ComponentInstance)0;
+}
+- (NSString *)_formatCocoaErrorString:(NSString *)formatString parameters:(const char *)parameters
+ applicableFormatters:(NSErrorUserInfoFormatter **)formatters count:(int)numFormatters {
+ return (NSString *)self;
+}
+- (NSErrorUserInfoFormatter *)formatter_func:(id)obj run:(const NSATSGlyphStorageRun **)run {
+ return (NSErrorUserInfoFormatter *)0;
+}
+- (BOOL)_forgetWord:(bycopy in NSString *)word inDictionary:(bycopy in NSString *)language {
+ return YES;
+}
+- (void)_registerServicesMenu:(NSMenu *)servicesMenu withSendTypes:(const NXAtom *)sendTypes
+ andReturnTypes:(const NXAtom *)returnTypes addToList:(BOOL)addToList {
+}
++ (CFMutableSetRef *)_proxySharePointer {
+ return (CFMutableSetRef *)0;
+}
+- (NSRange)_checkGrammarInString:(in NSString *)stringToCheck language:(bycopy in NSString *)language details:(bycopy out NSArray **)details {
+ return globalRange;
+}
+- (bool)_resolvePositionalStakeGlyphsForLineFragment:(CTLineRef)line lineFragmentRect:(NSRect)lineFragmentRect
+ minPosition:(float)minPosition maxPosition:(float)maxPosition maxLineFragmentWidth:(float)maxLineFragmentWidth
+ breakHint:(CFIndex *)charIndex {
+ return false;
+}
++ (BOOL)findVoiceByIdentifier:(NSString *)identifier returningCreator:(OSType *)returnedCreator returningID:(OSType *)returnedID {
+ return NO;
+}
+@end
+
+int main(void) {
+ Class fooClass = objc_getClass ("Foo");
+ Method meth;
+ Ivar *ivars;
+ unsigned int ivar_count;
+ Ivar ivar;
+
+ meth = class_getInstanceMethod (fooClass, @selector(_errorWithOSStatus:ref1:ref2:reading:));
+ CHECK_IF (!strcmp (method_getTypeEncoding(meth), "@44@0:8q16r^{FSRef=[80C]}24r^{FSRef=[80C]}32c40"));
+
+ meth = class_getInstanceMethod (fooClass, @selector(_attributeRunForCharacterAtIndex:));
+ CHECK_IF (!strcmp (method_getTypeEncoding (meth), "r^{?=@@QQ^Qffff{_NSRect={_NSPoint=ff}{_NSSize=ff}}q^qQ^Q@@@:::****{?=b1b1b1b1b1b27}}24@0:8Q16"));
+
+ meth = class_getInstanceMethod (fooClass, @selector(_getATSTypesetterGuts:));
+ CHECK_IF (!strcmp (method_getTypeEncoding (meth), "r@24@0:8r:16"));
+
+ meth = class_getInstanceMethod (fooClass, @selector(resumeWithSuspensionID:and:));
+ CHECK_IF (!strcmp (method_getTypeEncoding (meth), "v32@0:8^{__NSAppleEventManagerSuspension=}16r^Q24"));
+
+ meth = class_getInstanceMethod (fooClass, @selector(anotherMeth:and:and:));
+ CHECK_IF (!strcmp (method_getTypeEncoding (meth), "r@40@0:8r:16r@24r@32"));
+
+ meth = class_getInstanceMethod (fooClass, @selector(str1:str2:str3:str4:));
+ CHECK_IF (!strcmp (method_getTypeEncoding (meth), "@48@0:8r*16*24*32r*40"));
+
+ meth = class_getInstanceMethod (fooClass, @selector(foo1:foo2:foo3:foo4:));
+ CHECK_IF (!strcmp (method_getTypeEncoding (meth), "Vv48@0:8@16r@24@32r@40"));
+
+ meth = class_getInstanceMethod (fooClass, @selector(sel1:id1:));
+ CHECK_IF (!strcmp (method_getTypeEncoding (meth), "rn*32@0:8r:16r@24"));
+
+ meth = class_getInstanceMethod (fooClass, @selector(obj1:obj2:obj3:));
+ CHECK_IF (!strcmp (method_getTypeEncoding (meth), "N@40@0:8r@16@24^{Object=#}32"));
+
+ meth = class_getClassMethod (fooClass, @selector(_defaultScriptingComponent));
+ CHECK_IF (!strcmp (method_getTypeEncoding (meth), "^{ComponentInstanceRecord=[1q]}16@0:8"));
+
+ meth = class_getInstanceMethod (fooClass, @selector(_formatCocoaErrorString:parameters:applicableFormatters:count:));
+ CHECK_IF (!strcmp (method_getTypeEncoding (meth), "@44@0:8@16r*24^^{?}32i40"));
+
+ meth = class_getInstanceMethod (fooClass, @selector(formatter_func:run:));
+ CHECK_IF (!strcmp (method_getTypeEncoding (meth), "^{?=^?@I}32@0:8@16r^^{?}24"));
+
+ meth = class_getInstanceMethod (fooClass, @selector(_forgetWord:inDictionary:));
+ CHECK_IF (!strcmp (method_getTypeEncoding (meth), "c32@0:8nO@16nO@24"));
+
+ meth = class_getInstanceMethod (fooClass, @selector(_registerServicesMenu:withSendTypes:andReturnTypes:addToList:));
+ CHECK_IF (!strcmp (method_getTypeEncoding (meth), "v44@0:8@16r^*24r^*32c40"));
+
+ meth = class_getClassMethod (fooClass, @selector(_proxySharePointer));
+ CHECK_IF (!strcmp (method_getTypeEncoding (meth), "^^{__CFSet}16@0:8"));
+
+ meth = class_getInstanceMethod (fooClass, @selector(_checkGrammarInString:language:details:));
+ CHECK_IF (!strcmp (method_getTypeEncoding (meth), "{_NSRange=II}40@0:8n@16nO@24oO^@32"));
+
+ meth = class_getInstanceMethod (fooClass, @selector(_resolvePositionalStakeGlyphsForLineFragment:lineFragmentRect:minPosition:maxPosition:maxLineFragmentWidth:breakHint:));
+ CHECK_IF (!strcmp (method_getTypeEncoding (meth), "B60@0:8^{__CTLine=}16{_NSRect={_NSPoint=ff}{_NSSize=ff}}24f40f44f48^Q52"));
+
+ meth = class_getClassMethod (fooClass, @selector(findVoiceByIdentifier:returningCreator:returningID:));
+ CHECK_IF (!strcmp (method_getTypeEncoding (meth), "c40@0:8@16^I24^I32"));
+
+ ivars = class_copyIvarList (fooClass, &ivar_count);
+ CHECK_IF (ivar_count == 1);
+
+ ivar = ivars[0];
+ CHECK_IF (!strcmp (ivar_getName(ivar), "r"));
+ CHECK_IF (!strcmp (ivar_getTypeEncoding(ivar),
+ "{?=\"_attributes\"@\"NSDictionary\"\"_font\"@\"NSFont\"\"_characterLength\""
+ "Q\"_nominalGlyphLocation\"Q\"p\"^Q\"_defaultLineHeight\"f\"_defaultBaselineOffset\""
+ "f\"_horizExpansion\"f\"_baselineDelta\"f\"_attachmentBBox\"{_NSRect=\"origin\""
+ "{_NSPoint=\"x\"f\"y\"f}\"size\"{_NSSize=\"width\"f\"height\"f}}\"ll\"q\"llp\"^q\"ull\""
+ "Q\"ullp\"^Q\"a\"@\"a1\"@\"a2\"@\"b\":\"b1\":\"b2\":\"str1\"*\"str2\"*\"str3\"*\"str4\""
+ "*\"_rFlags\"{?=\"_isAttachmentRun\"b1\"_hasPositionalStake\"b1\"_isDefaultFace\""
+ "b1\"_hasCombiningMarks\"b1\"_isScreenFont\"b1\"_reserved\"b27}}"));
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/encode-7-next.m b/gcc/testsuite/objc.dg/encode-7-next.m
new file mode 100644
index 000000000..2768e115f
--- /dev/null
+++ b/gcc/testsuite/objc.dg/encode-7-next.m
@@ -0,0 +1,269 @@
+/* Additional testing for the NeXT runtime. */
+/* Author: Ziemowit Laski <zlaski@apple.com> */
+
+/* { dg-do run { target *-*-darwin* } } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-options "-Wno-deprecated-declarations" } */
+/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */
+
+#include "../objc-obj-c++-shared/Object1.h"
+#include "../objc-obj-c++-shared/next-mapping.h"
+#include <stdbool.h>
+#include <string.h>
+#include <stdlib.h>
+#define CHECK_IF(E) if (!(E)) abort ()
+
+@class NSDictionary, NSFont, NSError, _NSATSTypesetterGuts, NSString, NSMenu, NSArray;
+
+typedef unsigned char UInt8;
+typedef const signed long OSStatus;
+typedef unsigned long CFIndex;
+typedef unsigned int UInt32;
+typedef UInt32 FourCharCode;
+typedef FourCharCode OSType;
+
+struct FSRef {
+ UInt8 hidden[80];
+};
+typedef struct FSRef FSRef;
+
+typedef struct _NSPoint {
+ float x;
+ float y;
+} NSPoint;
+
+typedef struct _NSSize {
+ float width;
+ float height;
+} NSSize;
+
+typedef struct _NSRect {
+ NSPoint origin;
+ NSSize size;
+} NSRect;
+
+typedef struct _NSRange {
+ unsigned int location;
+ unsigned int length;
+} NSRange;
+
+typedef const char *NXAtom;
+
+typedef struct {
+ NSDictionary *_attributes;
+ NSFont *_font;
+ CFIndex _characterLength;
+ CFIndex _nominalGlyphLocation;
+ const CFIndex *p;
+ float _defaultLineHeight;
+ float _defaultBaselineOffset;
+ float _horizExpansion;
+ float _baselineDelta;
+ NSRect _attachmentBBox;
+ long ll, *llp;
+ unsigned long ull, *ullp;
+ id a;
+ const id a1;
+ const struct objc_object *a2;
+ SEL b;
+ const SEL b1;
+ const struct objc_selector *b2;
+ const char *str1;
+ char *str2;
+ char *const str3;
+ const char *const str4;
+ struct {
+ unsigned int _isAttachmentRun:1;
+ unsigned int _hasPositionalStake:1;
+ unsigned int _isDefaultFace:1;
+ unsigned int _hasCombiningMarks:1;
+ unsigned int _isScreenFont:1;
+ unsigned int _reserved:27;
+ } _rFlags;
+} NSATSGlyphStorageRun;
+
+typedef struct __CFSet *CFMutableSetRef;
+typedef const struct __CTLine * CTLineRef;
+typedef const struct __NSAppleEventManagerSuspension* NSAppleEventManagerSuspensionID;
+
+struct ComponentInstanceRecord {
+ long data[1];
+};
+typedef struct ComponentInstanceRecord ComponentInstanceRecord;
+typedef ComponentInstanceRecord *ComponentInstance;
+
+typedef NSString *(*NSErrorUserInfoFormatterFunc)(id objToBeDisplayed, NSError *err, char modifier);
+typedef struct {
+ NSErrorUserInfoFormatterFunc formatterFunc;
+ NSString *userInfoKey;
+ unsigned int parameterMask;
+} NSErrorUserInfoFormatter;
+
+typedef Object MyObj;
+typedef Object *MyPtr;
+
+@interface Foo: Object {
+ NSATSGlyphStorageRun r;
+}
+- (NSError *)_errorWithOSStatus:(OSStatus)inOSStatus ref1:(const FSRef *)inRef1 ref2:(const struct FSRef *)inRef2
+ reading:(BOOL)inReadingNotWriting;
+- (const NSATSGlyphStorageRun *)_attributeRunForCharacterAtIndex:(const CFIndex)charIndex;
+- (const _NSATSTypesetterGuts *)_getATSTypesetterGuts:(const struct objc_selector *)sel;
+- (void)resumeWithSuspensionID:(NSAppleEventManagerSuspensionID)suspensionID and:(const CFIndex *)status;
+- (const id)anotherMeth:(const SEL)sel and:(const Foo *)foo and:(const struct objc_object *)obj;
+- (id)str1:(const char *)str1 str2:(char *)str2 str3:(char *const)str3 str4:(const char *const)str4;
+- (oneway void)foo1:(Foo *)foo1 foo2:(const Foo *)foo2 foo3:(Foo *const)foo3 foo4:(const Foo *const)foo4;
+- (in const char *)sel1:(const SEL)sel1 id1:(const id)id1;
+- (inout id)obj1:(const MyPtr)obj1 obj2:(Object *const)obj2 obj3:(MyObj *const)obj3;
++ (ComponentInstance)_defaultScriptingComponent;
+- (NSString *)_formatCocoaErrorString:(NSString *)formatString parameters:(const char *)parameters
+ applicableFormatters:(NSErrorUserInfoFormatter **)formatters count:(int)numFormatters;
+- (NSErrorUserInfoFormatter *)formatter_func:(id)obj run:(const NSATSGlyphStorageRun **)run;
+- (BOOL)_forgetWord:(bycopy in NSString *)word inDictionary:(bycopy in NSString *)language;
+- (void)_registerServicesMenu:(NSMenu *)servicesMenu withSendTypes:(const NXAtom *)sendTypes
+ andReturnTypes:(const NXAtom *)returnTypes addToList:(BOOL)addToList;
++ (CFMutableSetRef *)_proxySharePointer;
+- (NSRange)_checkGrammarInString:(in NSString *)stringToCheck language:(bycopy in NSString *)language details:(bycopy out NSArray **)details;
+- (bool)_resolvePositionalStakeGlyphsForLineFragment:(CTLineRef)line lineFragmentRect:(NSRect)lineFragmentRect
+ minPosition:(float)minPosition maxPosition:(float)maxPosition maxLineFragmentWidth:(float)maxLineFragmentWidth
+ breakHint:(CFIndex *)charIndex;
++ (BOOL)findVoiceByIdentifier:(NSString *)identifier returningCreator:(OSType *)returnedCreator returningID:(OSType *)returnedID;
+@end
+
+NSRange globalRange;
+
+@implementation Foo
+- (NSError *)_errorWithOSStatus:(OSStatus)inOSStatus ref1:(const FSRef *)inRef1 ref2:(const struct FSRef *)inRef2
+ reading:(BOOL)inReadingNotWriting {
+ return (NSError *)self;
+}
+- (const NSATSGlyphStorageRun *)_attributeRunForCharacterAtIndex:(CFIndex)charIndex {
+ return (const NSATSGlyphStorageRun *)self;
+}
+- (const _NSATSTypesetterGuts *)_getATSTypesetterGuts:(const struct objc_selector *)sel {
+ return (const _NSATSTypesetterGuts *)self;
+}
+- (void)resumeWithSuspensionID:(NSAppleEventManagerSuspensionID)suspensionID and:(const CFIndex *)status {
+}
+- (const id)anotherMeth:(const SEL)sel and:(const Foo *)foo and:(const struct objc_object *)obj {
+ return (const id)self;
+}
+- (id)str1:(const char *)str1 str2:(char *)str2 str3:(char *const)str3 str4:(const char *const)str4 {
+ return self;
+}
+- (oneway void)foo1:(Foo *)foo1 foo2:(const Foo *)foo2 foo3:(Foo *const)foo3 foo4:(const Foo *const)foo4 {
+}
+- (in const char *)sel1:(const SEL)sel1 id1:(const id)id1 {
+ return "Hello";
+}
+- (inout id)obj1:(const MyPtr)obj1 obj2:(Object *const)obj2 obj3:(MyObj *const)obj3 {
+ return self;
+}
++ (ComponentInstance)_defaultScriptingComponent {
+ return (ComponentInstance)0;
+}
+- (NSString *)_formatCocoaErrorString:(NSString *)formatString parameters:(const char *)parameters
+ applicableFormatters:(NSErrorUserInfoFormatter **)formatters count:(int)numFormatters {
+ return (NSString *)self;
+}
+- (NSErrorUserInfoFormatter *)formatter_func:(id)obj run:(const NSATSGlyphStorageRun **)run {
+ return (NSErrorUserInfoFormatter *)0;
+}
+- (BOOL)_forgetWord:(bycopy in NSString *)word inDictionary:(bycopy in NSString *)language {
+ return YES;
+}
+- (void)_registerServicesMenu:(NSMenu *)servicesMenu withSendTypes:(const NXAtom *)sendTypes
+ andReturnTypes:(const NXAtom *)returnTypes addToList:(BOOL)addToList {
+}
++ (CFMutableSetRef *)_proxySharePointer {
+ return (CFMutableSetRef *)0;
+}
+- (NSRange)_checkGrammarInString:(in NSString *)stringToCheck language:(bycopy in NSString *)language details:(bycopy out NSArray **)details {
+ return globalRange;
+}
+- (bool)_resolvePositionalStakeGlyphsForLineFragment:(CTLineRef)line lineFragmentRect:(NSRect)lineFragmentRect
+ minPosition:(float)minPosition maxPosition:(float)maxPosition maxLineFragmentWidth:(float)maxLineFragmentWidth
+ breakHint:(CFIndex *)charIndex {
+ return false;
+}
++ (BOOL)findVoiceByIdentifier:(NSString *)identifier returningCreator:(OSType *)returnedCreator returningID:(OSType *)returnedID {
+ return NO;
+}
+@end
+
+int main(void) {
+ Class fooClass = objc_getClass ("Foo");
+ Method meth;
+ struct objc_ivar_list *ivars;
+ struct objc_ivar *ivar;
+
+ meth = class_getInstanceMethod (fooClass, @selector(_errorWithOSStatus:ref1:ref2:reading:));
+ CHECK_IF (!strcmp (meth->method_types, "@24@0:4l8r^{FSRef=[80C]}12r^{FSRef=[80C]}16c20"));
+
+ meth = class_getInstanceMethod (fooClass, @selector(_attributeRunForCharacterAtIndex:));
+ CHECK_IF (!strcmp (meth->method_types, "r^{?=@@II^Iffff{_NSRect={_NSPoint=ff}{_NSSize=ff}}l^lL^L@@@:::****{?=b1b1b1b1b1b27}}12@0:4L8"));
+
+ meth = class_getInstanceMethod (fooClass, @selector(_getATSTypesetterGuts:));
+ CHECK_IF (!strcmp (meth->method_types, "r@12@0:4r:8"));
+
+ meth = class_getInstanceMethod (fooClass, @selector(resumeWithSuspensionID:and:));
+ CHECK_IF (!strcmp (meth->method_types, "v16@0:4^{__NSAppleEventManagerSuspension=}8r^I12"));
+
+ meth = class_getInstanceMethod (fooClass, @selector(anotherMeth:and:and:));
+ CHECK_IF (!strcmp (meth->method_types, "r@20@0:4r:8r@12r@16"));
+
+ meth = class_getInstanceMethod (fooClass, @selector(str1:str2:str3:str4:));
+ CHECK_IF (!strcmp (meth->method_types, "@24@0:4r*8*12*16r*20"));
+
+ meth = class_getInstanceMethod (fooClass, @selector(foo1:foo2:foo3:foo4:));
+ CHECK_IF (!strcmp (meth->method_types, "Vv24@0:4@8r@12@16r@20"));
+
+ meth = class_getInstanceMethod (fooClass, @selector(sel1:id1:));
+ CHECK_IF (!strcmp (meth->method_types, "rn*16@0:4r:8r@12"));
+
+ meth = class_getInstanceMethod (fooClass, @selector(obj1:obj2:obj3:));
+ CHECK_IF (!strcmp (meth->method_types, "N@20@0:4r@8@12^{Object=#}16"));
+
+ meth = class_getClassMethod (fooClass, @selector(_defaultScriptingComponent));
+ CHECK_IF (!strcmp (meth->method_types, "^{ComponentInstanceRecord=[1l]}8@0:4"));
+
+ meth = class_getInstanceMethod (fooClass, @selector(_formatCocoaErrorString:parameters:applicableFormatters:count:));
+ CHECK_IF (!strcmp (meth->method_types, "@24@0:4@8r*12^^{?}16i20"));
+
+ meth = class_getInstanceMethod (fooClass, @selector(formatter_func:run:));
+ CHECK_IF (!strcmp (meth->method_types, "^{?=^?@I}16@0:4@8r^^{?}12"));
+
+ meth = class_getInstanceMethod (fooClass, @selector(_forgetWord:inDictionary:));
+ CHECK_IF (!strcmp (meth->method_types, "c16@0:4nO@8nO@12"));
+
+ meth = class_getInstanceMethod (fooClass, @selector(_registerServicesMenu:withSendTypes:andReturnTypes:addToList:));
+ CHECK_IF (!strcmp (meth->method_types, "v24@0:4@8r^*12r^*16c20"));
+
+ meth = class_getClassMethod (fooClass, @selector(_proxySharePointer));
+ CHECK_IF (!strcmp (meth->method_types, "^^{__CFSet}8@0:4"));
+
+ meth = class_getInstanceMethod (fooClass, @selector(_checkGrammarInString:language:details:));
+ CHECK_IF (!strcmp (meth->method_types, "{_NSRange=II}20@0:4n@8nO@12oO^@16"));
+
+ meth = class_getInstanceMethod (fooClass, @selector(_resolvePositionalStakeGlyphsForLineFragment:lineFragmentRect:minPosition:maxPosition:maxLineFragmentWidth:breakHint:));
+ CHECK_IF (!strcmp (meth->method_types, "B44@0:4^{__CTLine=}8{_NSRect={_NSPoint=ff}{_NSSize=ff}}12f28f32f36^I40"));
+
+ meth = class_getClassMethod (fooClass, @selector(findVoiceByIdentifier:returningCreator:returningID:));
+ CHECK_IF (!strcmp (meth->method_types, "c20@0:4@8^I12^I16"));
+
+ ivars = fooClass->ivars;
+ CHECK_IF (ivars->ivar_count == 1);
+
+ ivar = ivars->ivar_list;
+ CHECK_IF (!strcmp (ivar->ivar_name, "r"));
+ CHECK_IF (!strcmp (ivar->ivar_type,
+ "{?=\"_attributes\"@\"NSDictionary\"\"_font\"@\"NSFont\"\"_characterLength\""
+ "I\"_nominalGlyphLocation\"I\"p\"^I\"_defaultLineHeight\"f\"_defaultBaselineOffset\""
+ "f\"_horizExpansion\"f\"_baselineDelta\"f\"_attachmentBBox\"{_NSRect=\"origin\""
+ "{_NSPoint=\"x\"f\"y\"f}\"size\"{_NSSize=\"width\"f\"height\"f}}\"ll\"l\"llp\"^l\"ull\""
+ "L\"ullp\"^L\"a\"@\"a1\"@\"a2\"@\"b\":\"b1\":\"b2\":\"str1\"*\"str2\"*\"str3\"*\"str4\""
+ "*\"_rFlags\"{?=\"_isAttachmentRun\"b1\"_hasPositionalStake\"b1\"_isDefaultFace\""
+ "b1\"_hasCombiningMarks\"b1\"_isScreenFont\"b1\"_reserved\"b27}}"));
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/encode-7.m b/gcc/testsuite/objc.dg/encode-7.m
new file mode 100644
index 000000000..1fe0b2424
--- /dev/null
+++ b/gcc/testsuite/objc.dg/encode-7.m
@@ -0,0 +1,18 @@
+/* { dg-do run } */
+/* { dg-skip-if "" { *-*-* } { "-fnext-runtime" } { "" } } */
+
+#include <objc/encoding.h>
+#include <stdlib.h>
+
+struct f
+{
+ _Bool a;
+};
+
+
+int main(void)
+{
+ if (objc_sizeof_type (@encode (struct f)) != sizeof(struct f))
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/encode-8.m b/gcc/testsuite/objc.dg/encode-8.m
new file mode 100644
index 000000000..a992e3150
--- /dev/null
+++ b/gcc/testsuite/objc.dg/encode-8.m
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+/* { dg-skip-if "" { *-*-* } { "-fnext-runtime" } { "" } } */
+
+#include <objc/encoding.h>
+#include <stdlib.h>
+
+union f
+{
+ char i;
+ double f1;
+ short t;
+};
+
+union g
+{
+ int i;
+};
+
+
+int main(void)
+{
+ if (objc_sizeof_type (@encode (union f)) != sizeof(union f))
+ abort ();
+ if (objc_alignof_type (@encode (union f)) != __alignof__(union f))
+ abort ();
+ if (objc_sizeof_type (@encode (union g)) != sizeof(union g))
+ abort ();
+ if (objc_alignof_type (@encode (union g)) != __alignof__(union g))
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/encode-9.m b/gcc/testsuite/objc.dg/encode-9.m
new file mode 100644
index 000000000..1ff2a6b0e
--- /dev/null
+++ b/gcc/testsuite/objc.dg/encode-9.m
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+
+/* There was an ICE due to diving by zero in the objc front-end. */
+
+struct f
+{
+ int i;
+ struct{} g[4];
+ int tt;
+};
+
+char *e = @encode(struct f);
diff --git a/gcc/testsuite/objc.dg/enhanced-proto-1.m b/gcc/testsuite/objc.dg/enhanced-proto-1.m
new file mode 100644
index 000000000..fef4c97b5
--- /dev/null
+++ b/gcc/testsuite/objc.dg/enhanced-proto-1.m
@@ -0,0 +1,19 @@
+/* APPLE LOCAL file C* language */
+/* Test use of @optional/@required keywords in @protocol class. */
+/* { dg-do compile } */
+
+@protocol MyProto1
+@optional
+- (void) FOO;
+@optional
+- (void) FOO;
+@required
+- (void) REQ;
+@optional
+@end
+
+@protocol MyProto2 <MyProto1>
+- (void) FOO2;
+@optional
+- (void) FOO3;
+@end
diff --git a/gcc/testsuite/objc.dg/enhanced-proto-2.m b/gcc/testsuite/objc.dg/enhanced-proto-2.m
new file mode 100644
index 000000000..c196b5151
--- /dev/null
+++ b/gcc/testsuite/objc.dg/enhanced-proto-2.m
@@ -0,0 +1,24 @@
+/* Test use of @optional/@required keywords in @protocol class. */
+/* { dg-do compile } */
+
+@protocol MyProto1
+@optional
+- (void) FOO;
+@optional
+- (void) FOO;
+@optional
+- (void) REQ;
+@optional
+@end
+
+@interface MyProto2 <MyProto1>
+@required /* { dg-error ".@required. is allowed in @protocol context only" } */
+- (void) FOO2;
+@optional /* { dg-error ".@optional. is allowed in @protocol context only" } */
+- (void) FOO3;
+@end
+
+@implementation MyProto2
+- (void) FOO2{}
+- (void) FOO3{}
+@end
diff --git a/gcc/testsuite/objc.dg/error-1.m b/gcc/testsuite/objc.dg/error-1.m
new file mode 100644
index 000000000..86b9d7faa
--- /dev/null
+++ b/gcc/testsuite/objc.dg/error-1.m
@@ -0,0 +1,6 @@
+/* { dg-options "-w" } */
+/* { dg-do compile } */
+@implementation A
++B
++C {} /* { dg-error "expected '\{' before '\\\+' token" } */
+@end
diff --git a/gcc/testsuite/objc.dg/exceptions-1.m b/gcc/testsuite/objc.dg/exceptions-1.m
new file mode 100644
index 000000000..0f3b7e8ae
--- /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 000000000..3e4227cb9
--- /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 000000000..fe9dbfbfa
--- /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 000000000..fc07e4f42
--- /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 "unknown type name .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 000000000..d89ad2967
--- /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/exceptions-6.m b/gcc/testsuite/objc.dg/exceptions-6.m
new file mode 100644
index 000000000..58882fed8
--- /dev/null
+++ b/gcc/testsuite/objc.dg/exceptions-6.m
@@ -0,0 +1,29 @@
+/* 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 @throw. */
+
+#include <objc/objc.h>
+
+void test (id object)
+{
+ @throw object; /* Ok */
+ @throw; /* { dg-error ".@throw. .rethrow. used outside of a @catch block" } */
+ @throw (object); /* Ok. */
+ @throw (id)0
+} /* { dg-error "expected" } */
+
+void test2 (id object)
+{
+ @throw object); /* { dg-error "expected" } */
+ @throw (...); /* { dg-error "expected" } */
+ @throw (); /* { dg-error "expected" } */
+ @throw
+} /* { dg-error "expected" } */
+
+void test3 (id object1, id object2)
+{
+ /* This is apparently valid. */
+ @throw object1, object2; /* Ok. */
+}
diff --git a/gcc/testsuite/objc.dg/exceptions-7.m b/gcc/testsuite/objc.dg/exceptions-7.m
new file mode 100644
index 000000000..1f5adfc89
--- /dev/null
+++ b/gcc/testsuite/objc.dg/exceptions-7.m
@@ -0,0 +1,18 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
+/* { dg-options "-fobjc-exceptions" } */
+/* { dg-do compile } */
+
+/* Test warnings when the argument of @throw is invalid. */
+
+#include <objc/objc.h>
+
+void test (id object)
+{
+ struct x { int i; } invalid_1, *invalid_2;
+
+ @throw object; /* Ok */
+ @throw 1; /* { dg-error ".@throw. argument is not an object" } */
+ @throw "string"; /* { dg-error ".@throw. argument is not an object" } */
+ @throw invalid_1; /* { dg-error ".@throw. argument is not an object" } */
+ @throw invalid_2; /* { dg-error ".@throw. argument is not an object" } */
+}
diff --git a/gcc/testsuite/objc.dg/extra-semi.m b/gcc/testsuite/objc.dg/extra-semi.m
new file mode 100644
index 000000000..ad555962d
--- /dev/null
+++ b/gcc/testsuite/objc.dg/extra-semi.m
@@ -0,0 +1,10 @@
+/* Allow extra semicolons in between method declarations,
+ for old times' sake. */
+
+/* { dg-do compile } */
+
+@interface Foo
+ -(Foo *) expiration;
+ -(void) setExpiration:(Foo *) date;;
+ -(int) getVersion;
+@end
diff --git a/gcc/testsuite/objc.dg/fix-and-continue-1.m b/gcc/testsuite/objc.dg/fix-and-continue-1.m
new file mode 100644
index 000000000..1560beac4
--- /dev/null
+++ b/gcc/testsuite/objc.dg/fix-and-continue-1.m
@@ -0,0 +1,93 @@
+/* Fix and continue should not interfere with computation of
+ local (static) function addresses. */
+/* Author: Ziemowit Laski <zlaski@apple.com> */
+
+/* { dg-do run { target *-*-darwin* } } */
+/* { dg-options "-mfix-and-continue" } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+#include "../objc-obj-c++-shared/Object1.h"
+#include <stdlib.h>
+
+@class MyTarget, MySet;
+
+int global_value = 0;
+
+@interface MyTargetBuildContext : Object
+{
+ MyTarget * _target;
+ unsigned _cacheInvalDisableCount;
+ BOOL _cacheInvalidationNeeded;
+ unsigned short _isCreatingDependencies:1;
+ unsigned short _isCreatingHeadermap:1;
+ unsigned short _haveAddedIdleTimeInvoc:1;
+ BOOL _hasSetUpBuildSettings;
+}
+- (id)initWithTarget:(MyTarget *)target;
+- (MyTarget *)target;
+@end
+
+@interface MyTargetBuildContext (PrivateMethods)
++ (MySet *)_headerFileExtensions;
+@end
+
+@interface MyCountedSet: Object {
+@public
+ int cardinality;
+}
+- (id)init;
+- (id)sortedArrayUsingFunction:(int (*)(id, id, void *))comparator with:(int)value;
+@end
+
+@implementation MyCountedSet
+- (id)init {
+ cardinality = 5;
+ global_value = 17;
+ return self;
+}
+- (id)sortedArrayUsingFunction:(int (*)(id, id, void *))comparator with:(int)value {
+ if(value == comparator(self, self, self))
+ return self;
+ return nil;
+}
+@end
+
+@implementation MyTargetBuildContext : Object
+- (id)initWithTarget:(MyTarget *)target
+{
+ self = [super init];
+ return self;
+}
+- (MyTarget *)target
+{
+ return _target;
+}
+
+static int _MyCompareObjectsByDecreasingSetCount (id object1, id object2, MyCountedSet * countedSet)
+{
+ global_value = 5;
+ return countedSet->cardinality;
+}
++ (MySet *)_headerFileExtensions
+{
+ MySet * _headerFileExtensions = 0;
+ return _headerFileExtensions;
+}
+- (void)_recomputeHeadermap
+{
+ MyCountedSet *set = [MyCountedSet new];
+ int (*functionPointer)(id, id, void *) = (int (*)(id, id, void *))_MyCompareObjectsByDecreasingSetCount;
+ id result = [set sortedArrayUsingFunction:functionPointer with:5];
+}
+@end
+
+int main(void) {
+ MyTargetBuildContext *ctx = [MyTargetBuildContext new];
+ [ctx _recomputeHeadermap];
+ if (global_value != 5)
+ abort();
+
+ return 0;
+}
+
+#include "../objc-obj-c++-shared/Object1-implementation.h"
diff --git a/gcc/testsuite/objc.dg/fix-and-continue-2.m b/gcc/testsuite/objc.dg/fix-and-continue-2.m
new file mode 100644
index 000000000..fdfbcbd0c
--- /dev/null
+++ b/gcc/testsuite/objc.dg/fix-and-continue-2.m
@@ -0,0 +1,24 @@
+/* Static variables, even if local, require indirect access through a stub
+ if -mfix-and-continue is enabled. */
+
+/* Author: Ziemowit Laski <zlaski@apple.com> */
+
+/* { dg-do assemble { target *-*-darwin* } } */
+/* { dg-options "-mfix-and-continue" } */
+
+#include "../objc-obj-c++-shared/Object1.h"
+
+@interface Foo: Object
++ (Object *)indexableFileTypes;
+@end
+
+@implementation Foo
++ (Object *)indexableFileTypes
+{
+ static Object *fileTypes = 0;
+ if(!fileTypes) {
+ fileTypes = [Object new];
+ }
+ return fileTypes;
+}
+@end
diff --git a/gcc/testsuite/objc.dg/fobjc-exceptions-1.m b/gcc/testsuite/objc.dg/fobjc-exceptions-1.m
new file mode 100644
index 000000000..8cee4d849
--- /dev/null
+++ b/gcc/testsuite/objc.dg/fobjc-exceptions-1.m
@@ -0,0 +1,28 @@
+/* Test that Objective-C exceptions cause an error with -fobjc-exceptions. */
+/* { dg-do compile } */
+
+@class Object;
+
+int dummy (int number, Object *o)
+{
+ @try { /* { dg-error ".-fobjc-exceptions. is required to enable Objective-C exception syntax" } */
+ number++;
+ @throw o; /* Nothing, error has already been produced. */
+ }
+ @catch (id object)
+ {
+ number++;
+ @throw; /* Nothing, error has already been produced. */
+ }
+ @finally
+ {
+ number++;
+ }
+
+ @synchronized (o) /* Nothing, error has already been produced. */
+ {
+ number++;
+ }
+
+ return number;
+}
diff --git a/gcc/testsuite/objc.dg/fobjc-exceptions-2.m b/gcc/testsuite/objc.dg/fobjc-exceptions-2.m
new file mode 100644
index 000000000..32b3506ec
--- /dev/null
+++ b/gcc/testsuite/objc.dg/fobjc-exceptions-2.m
@@ -0,0 +1,29 @@
+/* Test that Objective-C exceptions cause an error with -fobjc-exceptions. */
+/* { dg-do compile } */
+
+@class Object;
+
+int dummy (int number, Object *o)
+{
+ @synchronized (o) /* { dg-error ".-fobjc-exceptions. is required to enable Objective-C exception syntax" } */
+ {
+ number++;
+ }
+
+ @try { /* Nothing, error has already been produced. */
+ number++;
+ @throw o; /* Nothing, error has already been produced. */
+ }
+ @catch (id object)
+ {
+ number++;
+ @throw; /* Nothing, error has already been produced. */
+ }
+ @finally
+ {
+ number++;
+ }
+
+
+ return number;
+}
diff --git a/gcc/testsuite/objc.dg/fobjc-exceptions-3.m b/gcc/testsuite/objc.dg/fobjc-exceptions-3.m
new file mode 100644
index 000000000..d3d6453df
--- /dev/null
+++ b/gcc/testsuite/objc.dg/fobjc-exceptions-3.m
@@ -0,0 +1,30 @@
+/* Test that Objective-C exceptions cause an error with -fobjc-exceptions. */
+/* { dg-do compile } */
+
+@class Object;
+
+int dummy (int number, Object *o)
+{
+ @throw o; /* { dg-error ".-fobjc-exceptions. is required to enable Objective-C exception syntax" } */
+
+ @try { /* Nothing, error has already been produced. */
+ number++;
+ @throw o; /* Nothing, error has already been produced. */
+ }
+ @catch (id object)
+ {
+ number++;
+ @throw; /* Nothing, error has already been produced. */
+ }
+ @finally
+ {
+ number++;
+ }
+
+ @synchronized (o) /* Nothing, error has already been produced. */
+ {
+ number++;
+ }
+
+ return number;
+}
diff --git a/gcc/testsuite/objc.dg/fobjc-std-1.m b/gcc/testsuite/objc.dg/fobjc-std-1.m
new file mode 100644
index 000000000..9a15b8af5
--- /dev/null
+++ b/gcc/testsuite/objc.dg/fobjc-std-1.m
@@ -0,0 +1,76 @@
+/* Test warnings when using -fobjc-std=objc1. */
+/* { dg-do compile } */
+/* { dg-options "-fobjc-std=objc1" } */
+
+#include <objc/objc.h>
+
+@interface MyRootClass
+{
+ Class isa;
+@package /* { dg-error "not available in Objective.C 1.0" } */
+ int a;
+ int b;
+}
++ (id) alloc __attribute__ ((deprecated)); /* { dg-error "not available in Objective.C 1.0" } */
++ (id) name;
+- (id) init;
+- (id) testMe: (id) __attribute__((unused)) argument; /* { dg-error "not available in Objective.C 1.0" } */
+@property (nonatomic) int a; /* { dg-error "not available in Objective.C 1.0" } */
+@property (nonatomic) int b; /* { dg-error "not available in Objective.C 1.0" } */
+@end
+
+@implementation MyRootClass
++ (id) alloc { return self; }
++ (id) name { return self; }
+- (id) init { return self; }
+- (id) testMe: (id) __attribute__((unused)) argument { return self; } /* { dg-error "not available in Objective.C 1.0" } */
+@synthesize a; /* { dg-error "not available in Objective.C 1.0" } */
+@dynamic b; /* { dg-error "not available in Objective.C 1.0" } */
+@end
+
+__attribute__ ((deprecated))
+@interface MyRootClass2
+{ /* { dg-error "class attributes are not available in Objective.C 1.0" } */
+ Class isa;
+}
+@end
+
+__attribute__ ((deprecated))
+@protocol MyProtocol
+- (id) test; /* { dg-error "protocol attributes are not available in Objective.C 1.0" } */
+@required /* { dg-error "not available in Objective.C 1.0" } */
+- (id) variable __attribute__ ((deprecated)); /* { dg-error "not available in Objective.C 1.0" } */
+@optional /* { dg-error "not available in Objective.C 1.0" } */
+@end
+
+@interface MyRootClass (NSFastEnumeration)
+- (unsigned long)countByEnumeratingWithState: (struct __objcFastEnumerationState *)state
+ objects:(id *)stackbuf
+ count:(unsigned int)len;
+@end
+
+@class NSArray;
+
+int array_length (NSArray *array)
+{
+ int i = 0;
+
+ for (id object in array) /* { dg-error "not available in Objective.C 1.0" } */
+ i++;
+
+ return i;
+}
+
+id test (void)
+{
+ return MyRootClass.name; /* { dg-error "not available in Objective.C 1.0" } */
+}
+
+@interface MyRootClass3
+{
+ Class isa;
+}
+@end
+
+@interface MyRootClass3 ()
+@end /* { dg-error "not available in Objective.C 1.0" } */
diff --git a/gcc/testsuite/objc.dg/foreach-1.m b/gcc/testsuite/objc.dg/foreach-1.m
new file mode 100644
index 000000000..bc9a21a09
--- /dev/null
+++ b/gcc/testsuite/objc.dg/foreach-1.m
@@ -0,0 +1,83 @@
+/* Test basic Objective-C foreach syntax. This tests iterations that
+ do nothing.
+*/
+/* { dg-do run } */
+/* { dg-skip-if "No NeXT fast enum. pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+/* { dg-additional-sources "../objc-obj-c++-shared/Object1.m" } */
+/* { dg-options "-Wall" } */
+
+#import "../objc-obj-c++-shared/Object1.h"
+
+extern void abort (void);
+/*
+struct __objcFastEnumerationState
+{
+ unsigned long state;
+ id *itemsPtr;
+ unsigned long *mutationsPtr;
+ unsigned long extra[5];
+};
+*/
+@interface Object (NSFastEnumeration)
+- (unsigned long)countByEnumeratingWithState: (struct __objcFastEnumerationState *)state
+ objects:(id *)stackbuf
+ count:(unsigned int)len;
+@end
+
+int main (void)
+{
+ int test_variable = 0;
+ int counter = 0;
+ id array = nil;
+ id object = nil;
+
+ /* Test that 'for (object in array)' is recognized and that nothing
+ happens if array is nil. */
+ for (object in array)
+ test_variable = 8;
+
+ if (test_variable == 8)
+ abort ();
+
+ if (object != nil)
+ abort ();
+
+ /* Test that if nothing is done, object is set to nil. */
+ object = [Object new];
+
+ for (object in array)
+ ;
+
+ if (object != nil)
+ abort ();
+
+ /* Test that you can reference 'object' inside the body. */
+ for (object in array)
+ object = nil;
+
+ if (object != nil)
+ abort ();
+
+ /* Test that 'for (id element in array) is recognized (and works). */
+ for (id element in array)
+ test_variable = 8;
+
+ if (test_variable == 8)
+ abort ();
+
+ /* Test that you can reference 'object' inside the body. */
+ for (id element in array)
+ element = nil;
+
+ /* Test that C for loops still work. */
+ test_variable = 0;
+
+ for (counter = 0; counter < 4; counter++)
+ test_variable++;
+
+ if (test_variable != 4)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/foreach-2.m b/gcc/testsuite/objc.dg/foreach-2.m
new file mode 100644
index 000000000..a319a4bc7
--- /dev/null
+++ b/gcc/testsuite/objc.dg/foreach-2.m
@@ -0,0 +1,288 @@
+/* Test basic Objective-C foreach syntax. This tests iterations, with
+ the basic syntax 'for (object in array) statements'
+*/
+/* { dg-do run } */
+/* { dg-skip-if "No NeXT fast enum. pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+/* { dg-options "-mno-constant-cfstrings" { target *-*-darwin* } } */
+/* { dg-additional-sources "../objc-obj-c++-shared/Object1.m ../objc-obj-c++-shared/nsconstantstring-class-impl.m" } */
+
+#include "../objc-obj-c++-shared/Object1.h"
+#include "../objc-obj-c++-shared/next-mapping.h"
+#ifndef __NEXT_RUNTIME__
+#include <objc/NXConstStr.h>
+#else
+#include "../objc-obj-c++-shared/nsconstantstring-class.h"
+#endif
+
+extern int printf (const char *, ...);
+#include <stdlib.h>
+
+/*
+struct __objcFastEnumerationState
+{
+ unsigned long state;
+ id *itemsPtr;
+ unsigned long *mutationsPtr;
+ unsigned long extra[5];
+};
+*/
+
+ /* A mini-array implementation that can be used to test fast
+ enumeration. You create the array with some objects; you can
+ mutate the array, and you can fast-enumerate it.
+ */
+@interface MyArray : Object
+{
+ unsigned int length;
+ id *objects;
+ unsigned long mutated;
+}
+- (id) initWithLength: (unsigned int)l objects: (id *)o;
+- (void) mutate;
+- (unsigned long)countByEnumeratingWithState: (struct __objcFastEnumerationState *)state
+ objects:(id *)stackbuf
+ count:(unsigned long)len;
+@end
+
+@implementation MyArray : Object
+- (id) initWithLength: (unsigned int)l
+ objects: (id *)o
+{
+ length = l;
+ objects = o;
+ mutated = 0;
+ return self;
+}
+- (void) mutate
+{
+ mutated = 1;
+}
+- (unsigned long)countByEnumeratingWithState: (struct __objcFastEnumerationState*)state
+ objects: (id*)stackbuf
+ count: (unsigned long)len
+{
+ unsigned long i, batch_size;
+
+ /* We keep how many objects we served in the state->state counter. So the next batch
+ will contain up to length - state->state objects. */
+ batch_size = length - state->state;
+
+ /* Make obvious adjustments. */
+ if (batch_size < 0)
+ batch_size = 0;
+
+ if (batch_size > len)
+ batch_size = len;
+
+ /* Copy the objects. */
+ for (i = 0; i < batch_size; i++)
+ stackbuf[i] = objects[i];
+
+ state->state += batch_size;
+ state->itemsPtr = stackbuf;
+ state->mutationsPtr = &mutated;
+
+ return batch_size;
+}
+@end
+
+int main (void)
+{
+ MyArray *array;
+ Object *object;
+ int test_variable, counter, i;
+ id *objects;
+
+ array = [[MyArray alloc] initWithLength: 0
+ objects: NULL];
+
+ /* Test that an empty array does nothing. */
+ for (object in array)
+ abort ();
+
+ if (object != nil)
+ abort ();
+
+ /* Test iterating over 1 object. */
+ objects = malloc (sizeof (id) * 1);
+ objects[0] = @"One Object";
+
+ array = [[MyArray alloc] initWithLength: 1
+ objects: objects];
+
+ for (object in array)
+ printf ("%p\n", object);
+
+ /* Test iterating over 20 objects. */
+ objects = malloc (sizeof (id) * 20);
+ for (i = 0; i < 20; i++)
+ objects[i] = @"object";
+
+ array = [[MyArray alloc] initWithLength: 20
+ objects: objects];
+
+ for (object in array)
+ printf ("%p\n", object);
+
+ /* Test iterating over 200 objects. */
+ objects = malloc (sizeof (id) * 200);
+ for (i = 0; i < 200; i++)
+ objects[i] = @"object";
+
+ array = [[MyArray alloc] initWithLength: 200
+ objects: objects];
+
+ counter = 0;
+ for (object in array)
+ {
+ if (object != nil)
+ counter++;
+ }
+
+ if (counter != 200)
+ abort ();
+
+ printf ("Counter was %d (should be 200)\n", counter);
+
+ /* Test iterating again over the same array. */
+ counter = 0;
+ for (object in array)
+ {
+ if (object != nil)
+ counter++;
+ }
+
+ if (counter != 200)
+ abort ();
+
+ printf ("Counter was %d (should be 200)\n", counter);
+
+ /* Test nested iterations. */
+ objects = malloc (sizeof (id) * 20);
+ for (i = 0; i < 20; i++)
+ objects[i] = @"object";
+
+ array = [[MyArray alloc] initWithLength: 20
+ objects: objects];
+ counter = 0;
+ for (object in array)
+ {
+ id another_object;
+ for (another_object in array)
+ if (another_object != nil)
+ counter++;
+ }
+
+ printf ("Counter was %d (should be 400)\n", counter);
+
+ if (counter != 400)
+ abort ();
+
+ /* Test 'continue'. */
+ objects = malloc (sizeof (id) * 20);
+ for (i = 0; i < 20; i++)
+ objects[i] = @"object";
+
+ array = [[MyArray alloc] initWithLength: 20
+ objects: objects];
+ counter = 0;
+ for (object in array)
+ {
+ if (counter == 15)
+ continue;
+
+ counter++;
+ }
+
+ printf ("Counter was %d (should be 15)\n", counter);
+
+ if (counter != 15)
+ abort ();
+
+ /* Test 'break'. */
+ objects = malloc (sizeof (id) * 20);
+ for (i = 0; i < 20; i++)
+ objects[i] = @"object";
+
+ array = [[MyArray alloc] initWithLength: 20
+ objects: objects];
+ counter = 0;
+ for (object in array)
+ {
+ counter++;
+
+ if (counter == 15)
+ break;
+ }
+
+ printf ("Counter was %d (should be 15)\n", counter);
+
+ if (counter != 15)
+ abort ();
+
+ /* Test 'break' and 'continue' in nested iterations. */
+ objects = malloc (sizeof (id) * 20);
+ for (i = 0; i < 20; i++)
+ objects[i] = @"object";
+
+ array = [[MyArray alloc] initWithLength: 20
+ objects: objects];
+ counter = 0;
+ for (object in array)
+ {
+ int local_counter = 0;
+ id another_object;
+
+ /* Each internal loop should increase counter by 24. */
+ for (another_object in array)
+ {
+ local_counter++;
+
+ if (local_counter == 10)
+ {
+ counter = counter + 20;
+ break;
+ }
+
+ if (local_counter >= 5)
+ continue;
+
+ counter++;
+ }
+
+ /* Exit after 4 iterations. */
+ if (counter == 96)
+ break;
+ }
+
+ printf ("Counter was %d (should be 96)\n", counter);
+
+ if (counter != 96)
+ abort ();
+
+ /* Test that if we 'break', the object is set to the last one, while
+ if we run out of objects, it is set to 'nil'. */
+ for (object in array)
+ ;
+
+ if (object != nil)
+ abort ();
+
+ for (object in array)
+ break;
+
+ if (object == nil)
+ abort ();
+
+ /* Test that C for loops still work. */
+ test_variable = 0;
+
+ for (counter = 0; counter < 4; counter++)
+ test_variable++;
+
+ if (test_variable != 4)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/foreach-3.m b/gcc/testsuite/objc.dg/foreach-3.m
new file mode 100644
index 000000000..ac08a4095
--- /dev/null
+++ b/gcc/testsuite/objc.dg/foreach-3.m
@@ -0,0 +1,118 @@
+/* Test basic Objective-C foreach syntax. This tests the mutation.
+*/
+/* { dg-do compile } */
+
+/* FIXME: This test should be run, and it succeeds if the program
+ aborts at the right time (when the mutation happens). It currently
+ works, but how do we tell the testsuite to test for it ?
+*/
+
+#import "../objc-obj-c++-shared/Object1.h"
+#import "../objc-obj-c++-shared/next-mapping.h"
+#ifndef __NEXT_RUNTIME__
+#include <objc/NXConstStr.h>
+#endif
+
+extern int printf (const char *, ...);
+#include <stdlib.h>
+
+/*
+struct __objcFastEnumerationState
+{
+ unsigned long state;
+ id *itemsPtr;
+ unsigned long *mutationsPtr;
+ unsigned long extra[5];
+};
+*/
+
+ /* A mini-array implementation that can be used to test fast
+ enumeration. You create the array with some objects; you can
+ mutate the array, and you can fast-enumerate it.
+ */
+@interface MyArray : Object
+{
+ unsigned int length;
+ id *objects;
+ unsigned long mutated;
+}
+- (id) initWithLength: (unsigned int)l objects: (id *)o;
+- (void) mutate;
+- (unsigned long)countByEnumeratingWithState: (struct __objcFastEnumerationState *)state
+ objects:(id *)stackbuf
+ count:(unsigned long)len;
+@end
+
+@implementation MyArray : Object
+- (id) initWithLength: (unsigned int)l
+ objects: (id *)o
+{
+ length = l;
+ objects = o;
+ mutated = 0;
+ return self;
+}
+- (void) mutate
+{
+ mutated = 1;
+}
+- (unsigned long)countByEnumeratingWithState: (struct __objcFastEnumerationState*)state
+ objects: (id*)stackbuf
+ count: (unsigned long)len
+{
+ unsigned long i, batch_size;
+
+ /* Change the mutationsPtr if 'mutate' is called. */
+ state->mutationsPtr = &mutated;
+
+ /* We keep how many objects we served in the state->state counter. So the next batch
+ will contain up to length - state->state objects. */
+ batch_size = length - state->state;
+
+ /* Make obvious adjustments. */
+ if (batch_size < 0)
+ batch_size = 0;
+
+ if (batch_size > len)
+ batch_size = len;
+
+ /* Copy the objects. */
+ for (i = 0; i < batch_size; i++)
+ stackbuf[i] = objects[i];
+
+ state->state += batch_size;
+ state->itemsPtr = stackbuf;
+
+ return batch_size;
+}
+@end
+
+int main (void)
+{
+ MyArray *array;
+ Object *object;
+ int counter, i;
+ id *objects;
+
+ /* Test iterating over 20 objects, mutating after 15. */
+ objects = malloc (sizeof (id) * 20);
+ for (i = 0; i < 20; i++)
+ objects[i] = @"object";
+
+ array = [[MyArray alloc] initWithLength: 20
+ objects: objects];
+
+ counter = 0;
+ for (object in array)
+ {
+ counter++;
+ printf ("%d\n", counter);
+ if (counter == 14)
+ {
+ printf ("Mutating (should abort at next iteration)\n");
+ [array mutate];
+ }
+ }
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/foreach-4.m b/gcc/testsuite/objc.dg/foreach-4.m
new file mode 100644
index 000000000..13b9b0bb9
--- /dev/null
+++ b/gcc/testsuite/objc.dg/foreach-4.m
@@ -0,0 +1,268 @@
+/* Test basic Objective-C foreach syntax. This tests iterations, with
+ the declaration syntax 'for (id object in array) statements'
+*/
+/* { dg-do run } */
+/* { dg-skip-if "No NeXT fast enum. pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+/* { dg-options "-mno-constant-cfstrings" { target *-*-darwin* } } */
+/* { dg-additional-sources "../objc-obj-c++-shared/Object1.m ../objc-obj-c++-shared/nsconstantstring-class-impl.m" } */
+
+#import "../objc-obj-c++-shared/Object1.h"
+#import "../objc-obj-c++-shared/next-mapping.h"
+#ifndef __NEXT_RUNTIME__
+#include <objc/NXConstStr.h>
+#else
+#include "../objc-obj-c++-shared/nsconstantstring-class.h"
+#endif
+
+extern int printf (const char *, ...);
+#include <stdlib.h>
+
+/*
+struct __objcFastEnumerationState
+{
+ unsigned long state;
+ id *itemsPtr;
+ unsigned long *mutationsPtr;
+ unsigned long extra[5];
+};
+*/
+
+ /* A mini-array implementation that can be used to test fast
+ enumeration. You create the array with some objects; you can
+ mutate the array, and you can fast-enumerate it.
+ */
+@interface MyArray : Object
+{
+ unsigned int length;
+ id *objects;
+ unsigned long mutated;
+}
+- (id) initWithLength: (unsigned int)l objects: (id *)o;
+- (void) mutate;
+- (unsigned long)countByEnumeratingWithState: (struct __objcFastEnumerationState *)state
+ objects:(id *)stackbuf
+ count:(unsigned long)len;
+@end
+
+@implementation MyArray : Object
+- (id) initWithLength: (unsigned int)l
+ objects: (id *)o
+{
+ length = l;
+ objects = o;
+ mutated = 0;
+ return self;
+}
+- (void) mutate
+{
+ mutated = 1;
+}
+- (unsigned long)countByEnumeratingWithState: (struct __objcFastEnumerationState*)state
+ objects: (id*)stackbuf
+ count: (unsigned long)len
+{
+ unsigned long i, batch_size;
+
+ /* We keep how many objects we served in the state->state counter. So the next batch
+ will contain up to length - state->state objects. */
+ batch_size = length - state->state;
+
+ /* Make obvious adjustments. */
+ if (batch_size < 0)
+ batch_size = 0;
+
+ if (batch_size > len)
+ batch_size = len;
+
+ /* Copy the objects. */
+ for (i = 0; i < batch_size; i++)
+ stackbuf[i] = objects[i];
+
+ state->state += batch_size;
+ state->itemsPtr = stackbuf;
+ state->mutationsPtr = &mutated;
+
+ return batch_size;
+}
+@end
+
+int main (void)
+{
+ MyArray *array;
+ int test_variable, counter, i;
+ id *objects;
+
+ array = [[MyArray alloc] initWithLength: 0
+ objects: NULL];
+
+ /* Test that an empty array does nothing. */
+ for (id object in array)
+ abort ();
+
+ /* Test iterating over 1 object. */
+ objects = malloc (sizeof (id) * 1);
+ objects[0] = @"One Object";
+
+ array = [[MyArray alloc] initWithLength: 1
+ objects: objects];
+
+ for (id object in array)
+ printf ("%p\n", object);
+
+ /* Test iterating over 20 objects. */
+ objects = malloc (sizeof (id) * 20);
+ for (i = 0; i < 20; i++)
+ objects[i] = @"object";
+
+ array = [[MyArray alloc] initWithLength: 20
+ objects: objects];
+
+ for (id object in array)
+ printf ("%p\n", object);
+
+ /* Test iterating over 200 objects. */
+ objects = malloc (sizeof (id) * 200);
+ for (i = 0; i < 200; i++)
+ objects[i] = @"object";
+
+ array = [[MyArray alloc] initWithLength: 200
+ objects: objects];
+
+ counter = 0;
+ for (id object in array)
+ {
+ if (object != nil)
+ counter++;
+ }
+
+ if (counter != 200)
+ abort ();
+
+ printf ("Counter was %d (should be 200)\n", counter);
+
+ /* Test iterating again over the same array. */
+ counter = 0;
+ for (id object in array)
+ {
+ if (object != nil)
+ counter++;
+ }
+
+ if (counter != 200)
+ abort ();
+
+ printf ("Counter was %d (should be 200)\n", counter);
+
+ /* Test nested iterations. */
+ objects = malloc (sizeof (id) * 20);
+ for (i = 0; i < 20; i++)
+ objects[i] = @"object";
+
+ array = [[MyArray alloc] initWithLength: 20
+ objects: objects];
+ counter = 0;
+ for (id object in array)
+ {
+ for (id another_object in array)
+ if (another_object != nil)
+ counter++;
+ }
+
+ printf ("Counter was %d (should be 400)\n", counter);
+
+ if (counter != 400)
+ abort ();
+
+ /* Test 'continue'. */
+ objects = malloc (sizeof (id) * 20);
+ for (i = 0; i < 20; i++)
+ objects[i] = @"object";
+
+ array = [[MyArray alloc] initWithLength: 20
+ objects: objects];
+ counter = 0;
+ for (id object in array)
+ {
+ if (counter == 15)
+ continue;
+
+ counter++;
+ }
+
+ printf ("Counter was %d (should be 15)\n", counter);
+
+ if (counter != 15)
+ abort ();
+
+ /* Test 'break'. */
+ objects = malloc (sizeof (id) * 20);
+ for (i = 0; i < 20; i++)
+ objects[i] = @"object";
+
+ array = [[MyArray alloc] initWithLength: 20
+ objects: objects];
+ counter = 0;
+ for (id object in array)
+ {
+ counter++;
+
+ if (counter == 15)
+ break;
+ }
+
+ printf ("Counter was %d (should be 15)\n", counter);
+
+ if (counter != 15)
+ abort ();
+
+ /* Test 'break' and 'continue' in nested iterations. */
+ objects = malloc (sizeof (id) * 20);
+ for (i = 0; i < 20; i++)
+ objects[i] = @"object";
+
+ array = [[MyArray alloc] initWithLength: 20
+ objects: objects];
+ counter = 0;
+ for (id object in array)
+ {
+ int local_counter = 0;
+
+ /* Each internal loop should increase counter by 24. */
+ for (id another_object in array)
+ {
+ local_counter++;
+
+ if (local_counter == 10)
+ {
+ counter = counter + 20;
+ break;
+ }
+
+ if (local_counter >= 5)
+ continue;
+
+ counter++;
+ }
+
+ /* Exit after 4 iterations. */
+ if (counter == 96)
+ break;
+ }
+
+ printf ("Counter was %d (should be 96)\n", counter);
+
+ if (counter != 96)
+ abort ();
+
+ /* Test that C for loops still work. */
+ test_variable = 0;
+
+ for (counter = 0; counter < 4; counter++)
+ test_variable++;
+
+ if (test_variable != 4)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/foreach-5.m b/gcc/testsuite/objc.dg/foreach-5.m
new file mode 100644
index 000000000..c715b2d82
--- /dev/null
+++ b/gcc/testsuite/objc.dg/foreach-5.m
@@ -0,0 +1,266 @@
+/* Test basic Objective-C foreach syntax. This tests that if you
+ define your own NSFastEnumeration struct, the compiler picks it up.
+*/
+/* { dg-do run } */
+/* { dg-skip-if "No NeXT fast enum. pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+/* { dg-options "-mno-constant-cfstrings" { target *-*-darwin* } } */
+/* { dg-additional-sources "../objc-obj-c++-shared/Object1.m ../objc-obj-c++-shared/nsconstantstring-class-impl.m" } */
+
+#import "../objc-obj-c++-shared/Object1.h"
+#import "../objc-obj-c++-shared/next-mapping.h"
+#ifndef __NEXT_RUNTIME__
+#include <objc/NXConstStr.h>
+#else
+#include "../objc-obj-c++-shared/nsconstantstring-class.h"
+#endif
+
+extern int printf (const char *, ...);
+#include <stdlib.h>
+
+typedef struct
+{
+ unsigned long state;
+ id *itemsPtr;
+ unsigned long *mutationsPtr;
+ unsigned long extra[5];
+} NSFastEnumerationState;
+
+/* A mini-array implementation that can be used to test fast
+ enumeration. You create the array with some objects; you can
+ mutate the array, and you can fast-enumerate it.
+*/
+@interface MyArray : Object
+{
+ unsigned int length;
+ id *objects;
+ unsigned long mutated;
+}
+- (id) initWithLength: (unsigned int)l objects: (id *)o;
+- (void) mutate;
+- (unsigned long)countByEnumeratingWithState: (NSFastEnumerationState *)state
+ objects:(id *)stackbuf
+ count:(unsigned long)len;
+@end
+
+@implementation MyArray : Object
+- (id) initWithLength: (unsigned int)l
+ objects: (id *)o
+{
+ length = l;
+ objects = o;
+ mutated = 0;
+ return self;
+}
+- (void) mutate
+{
+ mutated = 1;
+}
+- (unsigned long)countByEnumeratingWithState: (NSFastEnumerationState*)state
+ objects: (id*)stackbuf
+ count: (unsigned long)len
+{
+ unsigned long i, batch_size;
+
+ /* We keep how many objects we served in the state->state counter. So the next batch
+ will contain up to length - state->state objects. */
+ batch_size = length - state->state;
+
+ /* Make obvious adjustments. */
+ if (batch_size < 0)
+ batch_size = 0;
+
+ if (batch_size > len)
+ batch_size = len;
+
+ /* Copy the objects. */
+ for (i = 0; i < batch_size; i++)
+ stackbuf[i] = objects[i];
+
+ state->state += batch_size;
+ state->itemsPtr = stackbuf;
+ state->mutationsPtr = &mutated;
+
+ return batch_size;
+}
+@end
+
+int main (void)
+{
+ MyArray *array;
+ int test_variable, counter, i;
+ id *objects;
+
+ array = [[MyArray alloc] initWithLength: 0
+ objects: NULL];
+
+ /* Test that an empty array does nothing. */
+ for (id object in array)
+ abort ();
+
+ /* Test iterating over 1 object. */
+ objects = malloc (sizeof (id) * 1);
+ objects[0] = @"One Object";
+
+ array = [[MyArray alloc] initWithLength: 1
+ objects: objects];
+
+ for (id object in array)
+ printf ("%p\n", object);
+
+ /* Test iterating over 20 objects. */
+ objects = malloc (sizeof (id) * 20);
+ for (i = 0; i < 20; i++)
+ objects[i] = @"object";
+
+ array = [[MyArray alloc] initWithLength: 20
+ objects: objects];
+
+ for (id object in array)
+ printf ("%p\n", object);
+
+ /* Test iterating over 200 objects. */
+ objects = malloc (sizeof (id) * 200);
+ for (i = 0; i < 200; i++)
+ objects[i] = @"object";
+
+ array = [[MyArray alloc] initWithLength: 200
+ objects: objects];
+
+ counter = 0;
+ for (id object in array)
+ {
+ if (object != nil)
+ counter++;
+ }
+
+ if (counter != 200)
+ abort ();
+
+ printf ("Counter was %d (should be 200)\n", counter);
+
+ /* Test iterating again over the same array. */
+ counter = 0;
+ for (id object in array)
+ {
+ if (object != nil)
+ counter++;
+ }
+
+ if (counter != 200)
+ abort ();
+
+ printf ("Counter was %d (should be 200)\n", counter);
+
+ /* Test nested iterations. */
+ objects = malloc (sizeof (id) * 20);
+ for (i = 0; i < 20; i++)
+ objects[i] = @"object";
+
+ array = [[MyArray alloc] initWithLength: 20
+ objects: objects];
+ counter = 0;
+ for (id object in array)
+ {
+ for (id another_object in array)
+ if (another_object != nil)
+ counter++;
+ }
+
+ printf ("Counter was %d (should be 400)\n", counter);
+
+ if (counter != 400)
+ abort ();
+
+ /* Test 'continue'. */
+ objects = malloc (sizeof (id) * 20);
+ for (i = 0; i < 20; i++)
+ objects[i] = @"object";
+
+ array = [[MyArray alloc] initWithLength: 20
+ objects: objects];
+ counter = 0;
+ for (id object in array)
+ {
+ if (counter == 15)
+ continue;
+
+ counter++;
+ }
+
+ printf ("Counter was %d (should be 15)\n", counter);
+
+ if (counter != 15)
+ abort ();
+
+ /* Test 'break'. */
+ objects = malloc (sizeof (id) * 20);
+ for (i = 0; i < 20; i++)
+ objects[i] = @"object";
+
+ array = [[MyArray alloc] initWithLength: 20
+ objects: objects];
+ counter = 0;
+ for (id object in array)
+ {
+ counter++;
+
+ if (counter == 15)
+ break;
+ }
+
+ printf ("Counter was %d (should be 15)\n", counter);
+
+ if (counter != 15)
+ abort ();
+
+ /* Test 'break' and 'continue' in nested iterations. */
+ objects = malloc (sizeof (id) * 20);
+ for (i = 0; i < 20; i++)
+ objects[i] = @"object";
+
+ array = [[MyArray alloc] initWithLength: 20
+ objects: objects];
+ counter = 0;
+ for (id object in array)
+ {
+ int local_counter = 0;
+
+ /* Each internal loop should increase counter by 24. */
+ for (id another_object in array)
+ {
+ local_counter++;
+
+ if (local_counter == 10)
+ {
+ counter = counter + 20;
+ break;
+ }
+
+ if (local_counter >= 5)
+ continue;
+
+ counter++;
+ }
+
+ /* Exit after 4 iterations. */
+ if (counter == 96)
+ break;
+ }
+
+ printf ("Counter was %d (should be 96)\n", counter);
+
+ if (counter != 96)
+ abort ();
+
+ /* Test that C for loops still work. */
+ test_variable = 0;
+
+ for (counter = 0; counter < 4; counter++)
+ test_variable++;
+
+ if (test_variable != 4)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/foreach-6.m b/gcc/testsuite/objc.dg/foreach-6.m
new file mode 100644
index 000000000..96b145365
--- /dev/null
+++ b/gcc/testsuite/objc.dg/foreach-6.m
@@ -0,0 +1,61 @@
+/* Test basic Objective-C foreach syntax. This tests warnings and errors. */
+/* { dg-do compile } */
+
+#import "../objc-obj-c++-shared/Object1.h"
+#import "../objc-obj-c++-shared/next-mapping.h"
+
+/*
+struct __objcFastEnumerationState
+{
+ unsigned long state;
+ id *itemsPtr;
+ unsigned long *mutationsPtr;
+ unsigned long extra[5];
+};
+*/
+@interface Object (NSFastEnumeration)
+- (unsigned long)countByEnumeratingWithState: (struct __objcFastEnumerationState *)state
+ objects:(id *)stackbuf
+ count:(unsigned int)len;
+- (id) enumerator;
+- (Class) classEnumerator;
+@end
+
+int main (void)
+{
+ id array = nil;
+ id object = nil;
+ id *invalid = 0;
+
+ for (object in array) /* Ok */
+ ;
+
+ for (object in nil) /* Ok */
+ ;
+
+ for (object in) /* { dg-error "missing collection in fast enumeration" } */
+ ;
+
+ for (object = nil in array) /* { dg-error "invalid iterating variable in fast enumeration" } */
+ ;
+
+ for (object in [object enumerator]) /* Ok */
+ ;
+
+ for (object in [object classEnumerator]) /* Ok */
+ ;
+
+ for (12 in array) /* { dg-error "invalid iterating variable in fast enumeration" } */
+ ; /* { dg-error "iterating variable in fast enumeration is not an object" "" { target *-*-* } 48 } */
+
+ for (object in 12) /* { dg-error "collection in fast enumeration is not an object" } */
+ ;
+
+ for (object in invalid) /* { dg-error "collection in fast enumeration is not an object" } */
+ ;
+
+ for (invalid in [object enumerator]) /* { dg-error "iterating variable in fast enumeration is not an object" } */
+ ;
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/foreach-7.m b/gcc/testsuite/objc.dg/foreach-7.m
new file mode 100644
index 000000000..4629d61e1
--- /dev/null
+++ b/gcc/testsuite/objc.dg/foreach-7.m
@@ -0,0 +1,58 @@
+/* Test basic Objective-C foreach syntax. This tests warnings and errors. */
+/* { dg-do compile } */
+
+#import "../objc-obj-c++-shared/Object1.h"
+#import "../objc-obj-c++-shared/next-mapping.h"
+
+/*
+struct __objcFastEnumerationState
+{
+ unsigned long state;
+ id *itemsPtr;
+ unsigned long *mutationsPtr;
+ unsigned long extra[5];
+};
+*/
+@interface Object (NSFastEnumeration)
+- (unsigned long)countByEnumeratingWithState: (struct __objcFastEnumerationState *)state
+ objects:(id *)stackbuf
+ count:(unsigned int)len;
+- (id) enumerator;
+@end
+
+void function (void)
+{
+ return;
+}
+
+id object_function (void)
+{
+ return nil;
+}
+
+int main (void)
+{
+ id array = nil;
+ id object = nil;
+
+ for (typedef int my_typedef in array) /* { dg-error "declaration of non-variable" } */
+ ; /* { dg-error "iterating variable in fast enumeration is not an object" "" { target *-*-* } 38 } */
+
+ for (function () in nil) /* { dg-error "invalid iterating variable in fast enumeration" } */
+ ; /* { dg-error "iterating variable in fast enumeration is not an object" "" { target *-*-* } 41 } */
+
+ for (object_function () in nil) /* { dg-error "invalid iterating variable in fast enumeration" } */
+ ;
+
+ for ([object enumerator] in array) /* { dg-error "invalid iterating variable in fast enumeration" } */
+ ;
+
+ for (object = nil in array) /* { dg-error "invalid iterating variable in fast enumeration" } */
+ ;
+
+ for (id key, value in array) /* { dg-error "multiple iterating variables in fast enumeration" } */
+ ;
+
+ return 0;
+}
+
diff --git a/gcc/testsuite/objc.dg/foreach-8.m b/gcc/testsuite/objc.dg/foreach-8.m
new file mode 100644
index 000000000..9a68e9ffb
--- /dev/null
+++ b/gcc/testsuite/objc.dg/foreach-8.m
@@ -0,0 +1,51 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
+/* { dg-options "-Wall" } */
+/* { dg-do compile } */
+
+/* Test that fast enumeration loops where the iterating variable is declared
+ but not used do not generate warnings. */
+
+/*
+struct __objcFastEnumerationState
+{
+ unsigned long state;
+ id *itemsPtr;
+ unsigned long *mutationsPtr;
+ unsigned long extra[5];
+};
+*/
+@interface Object
+{
+ Class isa;
+}
+- (unsigned long)countByEnumeratingWithState: (struct __objcFastEnumerationState *)state
+ objects:(id *)stackbuf
+ count:(unsigned int)len;
+- (id) enumerator;
+- (Class) classEnumerator;
+@end
+
+unsigned int count_objects_in_collection (id collection)
+{
+ unsigned int count = 0;
+
+ /* The following line should generate no warnings even with
+ -Wall. */
+ for (id object in collection)
+ count++;
+
+ return count;
+}
+
+unsigned int count_objects_in_collection_2 (id collection)
+{
+ unsigned int count = 0;
+ id object;
+
+ /* The following line should generate no warnings even with
+ -Wall. */
+ for (object in collection)
+ count++;
+
+ return count;
+}
diff --git a/gcc/testsuite/objc.dg/fsf-nsstring-format-1.m b/gcc/testsuite/objc.dg/fsf-nsstring-format-1.m
new file mode 100644
index 000000000..0921bb33b
--- /dev/null
+++ b/gcc/testsuite/objc.dg/fsf-nsstring-format-1.m
@@ -0,0 +1,44 @@
+/* Check NSString format extensions. */
+/* { dg-do compile { target *-*-darwin* } } */
+/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */
+/* { dg-options "-Wall" } */
+
+extern int printf (const char *fmt, ...);
+
+#ifndef __CONSTANT_CFSTRINGS__
+#error requires CFString
+#endif
+
+typedef const struct __CFString * CFStringRef;
+@class NSString;
+
+int s1 (NSString *fmt, ...) __attribute__((format(NSString, 1, 2))) ; /* OK */
+/* A CFString can represent an NSString. */
+int s1a (CFStringRef fmt, ...) __attribute__((format(NSString, 1, 2))) ; /* OK */
+/* But... it is possible that a CFString format might imply functionality that
+ is not present in objective-c. */
+int s1b (NSString *fmt, ...) __attribute__((format(CFString, 1, 2))) ; /* { dg-error "format argument should be a .CFString. reference" } */
+
+int s2 (int a, NSString *fmt, ... ) __attribute__((format(__NSString__, 2, 3))) ; /* OK */
+
+int s2a (int a, NSString *fmt, ... ) __attribute__((format(NSString, 2, 2))) ; /* { dg-error "format string argument follows the args to be formatted" } */
+
+int s3 (const char *fmt, ... ) __attribute__((format(__NSString__, 1, 2))) ; /* { dg-error "format argument should be a .NSString. reference but a string was found" } */
+int s4 (NSString *fmt, ... ) __attribute__((format(printf, 1, 2))) ; /* { dg-error "found a .NSString. reference but the format argument should be a string" } */
+
+char *s5 (char dum, char *fmt1, ... ) __attribute__((format_arg(2))) ; /* OK */
+NSString *s6 (NSString *dum, NSString *fmt1, ... ) __attribute__((format_arg(2))) ; /* OK */
+
+char *s7 (int dum, void *fmt1, ... ) __attribute__((format_arg(2))) ; /* { dg-error "format string argument is not a string type" } */
+int s8 (NSString *dum, NSString *fmt1, ... ) __attribute__((format_arg(2))) ; /* { dg-error "function does not return string type" } */
+
+char *s9 (int dum, char *fmt1, ... ) __attribute__((format_arg(2))) ; /* OK */
+NSString *s10 (int dum, NSString *fmt1, ... ) __attribute__((format_arg(2))) ; /* OK */
+
+void foo (void)
+{
+ s1 (@"format not checked %d %s", 3, 4);
+ printf("this one is checked %d %s", 3, 4, 5); /* { dg-warning "format '%s' expects argument of type 'char .', but argument 3 has type 'int'" } */
+ /* { dg-warning "too many arguments for format" "" { target *-*-* } 41 } */
+ printf(s9 (1, "and so is this %d %d %s", 3, 4), 5, 6, 12); /* { dg-warning "format '%s' expects argument of type 'char .', but argument 4 has type 'int'" } */
+}
diff --git a/gcc/testsuite/objc.dg/fsf-package-0.m b/gcc/testsuite/objc.dg/fsf-package-0.m
new file mode 100644
index 000000000..d6b4db217
--- /dev/null
+++ b/gcc/testsuite/objc.dg/fsf-package-0.m
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+
+#import "../objc-obj-c++-shared/Object1.h"
+#include <objc/objc-api.h>
+
+@interface obj : Object
+{
+@public
+ int v1;
+@package /* { dg-warning ".@package. presently has the same effect as .@public." } */
+ int v2;
+@protected
+ int v3;
+@private
+ int v4;
+}
+- (int) value;
+- (void) setValue: (int)number;
+@end
+
+@implementation obj : Object
+
+- (int) value { return v1; }
+- (void) setValue: (int)number { v1 = number; }
+
+@end
+
+void foo (void)
+{
+ obj *a;
+
+ [a setValue:2];
+ a->v2 = 1;
+ a->v3 = [a value] - a->v2; /* { dg-warning ".v3. is @protected" } */
+ a->v4 = a->v3 - 1; /* { dg-warning ".v4. is @private" } */
+ /* { dg-warning ".v3. is @protected" "" { target *-*-* } 35 } */
+}
diff --git a/gcc/testsuite/objc.dg/fsyntax-only.m b/gcc/testsuite/objc.dg/fsyntax-only.m
new file mode 100644
index 000000000..54a879e22
--- /dev/null
+++ b/gcc/testsuite/objc.dg/fsyntax-only.m
@@ -0,0 +1,11 @@
+/* Test -fsyntax-only compiler option */
+/* { dg-do compile } */
+/* { dg-options "-fsyntax-only" } */
+
+@interface foo
+-(void) my_method:(int) i with:(int) j;
+@end
+
+@implementation foo
+-(void) my_method:(int) i with:(int) j { }
+@end
diff --git a/gcc/testsuite/objc.dg/func-ptr-1.m b/gcc/testsuite/objc.dg/func-ptr-1.m
new file mode 100644
index 000000000..4bdb344a3
--- /dev/null
+++ b/gcc/testsuite/objc.dg/func-ptr-1.m
@@ -0,0 +1,51 @@
+/* Test for handling of function pointer ivars */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+#include "../objc-obj-c++-shared/Object1.h"
+
+extern int strcmp(const char *, const char *);
+extern void abort(void);
+#define CHECK_IF(expr) if(!(expr)) abort()
+
+typedef float (*floatfunc)(float, float);
+
+@interface MyObject : Object
+{
+@public
+ int (*ivar)(int, int, int);
+ floatfunc ffunc;
+}
+- init;
+@end
+
+int foo(int a, int b, int c) {
+ return a + b + c;
+}
+
+float bar(float a, float b) {
+ return a * b;
+}
+
+@implementation MyObject
+- init {
+ [super init];
+ ivar = foo;
+ ffunc = bar;
+ return self;
+}
+@end
+
+int main ()
+{
+ MyObject *obj = [[MyObject alloc] init];
+ const char *enc = @encode(MyObject);
+
+ CHECK_IF(obj->ivar(4, 5, 6) == 15);
+ CHECK_IF(obj->ffunc(34.0, 45.0) == 34.0 * 45.0);
+ CHECK_IF(!strcmp(enc, "{MyObject=#^?^?}"));
+ return(0);
+}
+
+#include "../objc-obj-c++-shared/Object1-implementation.h"
+
diff --git a/gcc/testsuite/objc.dg/func-ptr-2.m b/gcc/testsuite/objc.dg/func-ptr-2.m
new file mode 100644
index 000000000..e68c71b70
--- /dev/null
+++ b/gcc/testsuite/objc.dg/func-ptr-2.m
@@ -0,0 +1,41 @@
+/* Check if method parameters that are functions are gracefully decayed
+ into pointers. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com> */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+#include <stdlib.h>
+/* provide an Object class for NeXT runtimes 10.5 and above */
+#include "../objc-obj-c++-shared/Object1.h"
+
+@interface Func: Object
++ (int) processNumber:(int)a and:(int)b usingFunction:(int(int,int))func;
+@end
+
+@implementation Func
++ (int) processNumber:(int)a and:(int)b usingFunction:(int(int,int))func {
+ return func (a, b);
+}
+@end
+
+static int my_computation(int a, int b) {
+ return a * 2 + b * 3;
+}
+
+static int processNumber(int a, int b, int func(int, int)) {
+ return func(a, b);
+}
+
+int main(void) {
+ int result = processNumber (6, 8, my_computation);
+ if (result != 36)
+ abort ();
+
+ result = [Func processNumber:8 and:6 usingFunction:my_computation];
+ if (result != 34)
+ abort ();
+
+ return 0;
+}
+
+#include "../objc-obj-c++-shared/Object1-implementation.h"
diff --git a/gcc/testsuite/objc.dg/fwd-proto-1.m b/gcc/testsuite/objc.dg/fwd-proto-1.m
new file mode 100644
index 000000000..3b21c513c
--- /dev/null
+++ b/gcc/testsuite/objc.dg/fwd-proto-1.m
@@ -0,0 +1,29 @@
+/* Test forward-decls for @protocols. */
+/* Author: Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-do compile } */
+
+/* One-line substitute for objc/objc.h */
+typedef struct objc_object { struct objc_class *class_pointer; } *id;
+
+@protocol Bar;
+@protocol Boo;
+
+@protocol Foo
+- (id <Bar>)someMethod;
+- (id <Baz>)anotherMethod; /* { dg-error "annot find protocol declaration" } */
+@end
+
+@protocol Bar <Boo>
+- (id <Foo>)someOtherMethod;
+- (id <Baz>)anotherMethod; /* { dg-error "annot find protocol declaration" } */
+- (id <Boo>)yetAnotherMethod;
+@end
+
+/* The following worthy test is stubbed out until we can get the
+ harness to match correctly on the "compilation terminated" message
+ when running on GNU/Linux. sts 2001-08-01 */
+#if 0
+@protocol Boo <Bar> /* { /*dg*/-error "has circular dependency" } */
+@end
+#endif
+
diff --git a/gcc/testsuite/objc.dg/gnu-api-2-class.m b/gcc/testsuite/objc.dg/gnu-api-2-class.m
new file mode 100644
index 000000000..f3469f6ed
--- /dev/null
+++ b/gcc/testsuite/objc.dg/gnu-api-2-class.m
@@ -0,0 +1,488 @@
+/* Test the Modern GNU Objective-C Runtime API.
+
+ This is test 'class', covering all functions starting with 'class'. */
+
+/* { dg-do run } */
+/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* To get the modern GNU Objective-C Runtime API, you include
+ objc/runtime.h. */
+#include <objc/runtime.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+@interface MyRootClass
+{ Class isa; }
++ alloc;
+- init;
++ initialize;
+@end
+
+@implementation MyRootClass
++ alloc { return class_createInstance (self, 0); }
+- init { return self; }
++ initialize { return self; }
+@end
+
+@protocol MyProtocol
+- (id) variable;
+@end
+
+@protocol MySecondProtocol
+- (id) setVariable: (id)value;
+@end
+
+@interface MySubClass : MyRootClass <MyProtocol>
+{ id variable_ivar; }
+- (void) setVariable: (id)value;
+- (id) variable;
+@end
+
+@implementation MySubClass
+- (void) setVariable: (id)value { variable_ivar = value; }
+- (id) variable { return variable_ivar; }
+@end
+
+@interface MyOtherSubClass : MySubClass
+@end
+
+@implementation MyOtherSubClass
+@end
+
+@interface DifferentClass : MyRootClass
+- (id) myClass;
+- (id) self;
+@end
+
+@implementation DifferentClass
+- (id) myClass { return object_getClass (self); }
+- (id) self { return self; }
+@end
+
+@interface MySubClass (MySelf)
+- (id) mySelf;
+@end
+
+/* Hack to calculate the log2 of a byte alignment. */
+unsigned char
+log_2_of (unsigned int x)
+{
+ unsigned char result = 0;
+
+ /* We count how many times we need to divide by 2 before we reach 1.
+ This algorithm is good enough for the small numbers (such as 8,
+ 16 or 64) that we have to deal with. */
+ while (x > 1)
+ {
+ x = x / 2;
+ result++;
+ }
+
+ return result;
+}
+
+int main(int argc, void **args)
+{
+ /* Functions are tested in alphabetical order. */
+
+ printf ("Testing class_addIvar ()...\n");
+ {
+ Class new_class = objc_allocateClassPair (objc_getClass ("MySubClass"), "MySubSubClass", 0);
+
+ if (new_class == Nil)
+ abort ();
+
+ if (! class_addIvar (new_class, "variable2_ivar", sizeof (id),
+ log_2_of (__alignof__ (id)), @encode (id)))
+ abort ();
+
+ if (! class_addIvar (new_class, "variable3_ivar", sizeof (unsigned char),
+ log_2_of (__alignof__ (unsigned char)), @encode (unsigned char)))
+ abort ();
+
+ if (! class_addIvar (new_class, "variable4_ivar", sizeof (unsigned long),
+ log_2_of (__alignof__ (unsigned long)), @encode (unsigned long)))
+ abort ();
+
+ objc_registerClassPair (new_class);
+
+ {
+ MySubClass *o = [[objc_getClass ("MySubSubClass") alloc] init];
+ Ivar variable2 = class_getInstanceVariable (objc_getClass ("MySubSubClass"), "variable2_ivar");
+ Ivar variable3 = class_getInstanceVariable (objc_getClass ("MySubSubClass"), "variable3_ivar");
+ Ivar variable4 = class_getInstanceVariable (objc_getClass ("MySubSubClass"), "variable4_ivar");
+
+ if (variable2 == NULL || variable3 == NULL || variable4 == NULL)
+ abort ();
+
+ if (strcmp (ivar_getName (variable2), "variable2_ivar") != 0)
+ abort ();
+
+ if (strcmp (ivar_getName (variable3), "variable3_ivar") != 0)
+ abort ();
+
+ if (strcmp (ivar_getName (variable4), "variable4_ivar") != 0)
+ abort ();
+
+ {
+ unsigned char *var3 = (unsigned char *)((char *)o + ivar_getOffset (variable3));
+ unsigned long *var4 = (unsigned long *)((char *)o + ivar_getOffset (variable4));
+
+ object_setIvar (o, variable2, new_class);
+ *var3 = 230;
+ *var4 = 89000L;
+
+ if (object_getIvar (o, variable2) != new_class)
+ abort ();
+
+ if (*var3 != 230)
+ abort ();
+
+ if (*var4 != 89000L)
+ abort ();
+ }
+ }
+ }
+
+ printf ("Testing class_addMethod ()...\n");
+ {
+ Class new_class = objc_allocateClassPair (objc_getClass ("MyRootClass"), "MySubClass2", 0);
+ Method method1 = class_getInstanceMethod (objc_getClass ("MySubClass"), @selector (setVariable:));
+ Method method2 = class_getInstanceMethod (objc_getClass ("MySubClass"), @selector (variable));
+
+ if (new_class == Nil)
+ abort ();
+
+ if (! class_addIvar (new_class, "variable_ivar", sizeof (id),
+ log_2_of (__alignof__ (id)), @encode (id)))
+ abort ();
+
+ if (! class_addMethod (new_class, @selector (setVariable:), method_getImplementation (method1),
+ method_getTypeEncoding (method1)))
+ abort ();
+
+ if (! class_addMethod (new_class, @selector (variable), method_getImplementation (method2),
+ method_getTypeEncoding (method2)))
+ abort ();
+
+ /* Test that if the method already exists in the class,
+ class_addMethod() returns NO. */
+ if (class_addMethod (new_class, @selector (variable), method_getImplementation (method2),
+ method_getTypeEncoding (method2)))
+ abort ();
+
+ objc_registerClassPair (new_class);
+
+ /* Now, MySubClass2 is basically the same as MySubClass! We'll
+ use the variable and setVariable: methods on it. */
+ {
+ MySubClass *o = (MySubClass *)[[objc_getClass ("MySubClass2") alloc] init];
+
+ [o setVariable: o];
+
+ if ([o variable] != o)
+ abort ();
+ }
+
+ /* Now, try that if you take an existing class and try to add an
+ already existing method, class_addMethod returns NO. This is
+ subtly different from before, when 'new_class' was still in
+ construction. Now it's a real class and the libobjc internals
+ differ between the two cases. */
+ if (class_addMethod (new_class, @selector (variable), method_getImplementation (method2),
+ method_getTypeEncoding (method2)))
+ abort ();
+ }
+
+ printf ("Testing class_addProtocol ()...\n");
+ {
+ if (!class_addProtocol (objc_getClass ("MySubClass"), @protocol (MySecondProtocol)))
+ abort ();
+
+ if (!class_conformsToProtocol (objc_getClass ("MySubClass"), @protocol (MyProtocol)))
+ abort ();
+
+ if (!class_conformsToProtocol (objc_getClass ("MySubClass"), @protocol (MySecondProtocol)))
+ abort ();
+ }
+
+ printf ("Testing class_conformsToProtocol ()...\n");
+ {
+ if (class_conformsToProtocol (objc_getClass ("MyRootClass"), @protocol (MyProtocol)))
+ abort ();
+
+ if (!class_conformsToProtocol (objc_getClass ("MySubClass"), @protocol (MyProtocol)))
+ abort ();
+
+ /* Test that class_conformsToProtocol checks the class, but not
+ superclasses. */
+ if (class_conformsToProtocol (objc_getClass ("MyOtherSubClass"), @protocol (MyProtocol)))
+ abort ();
+ }
+
+ printf ("Testing class_copyIvarList ()...\n");
+ {
+ unsigned int count;
+ Ivar * list = class_copyIvarList (objc_getClass ("MySubClass"), &count);
+
+ if (count != 1)
+ abort ();
+
+ if (strcmp (ivar_getName (list[0]), "variable_ivar") != 0)
+ abort ();
+
+ if (list[1] != NULL)
+ abort ();
+ }
+
+ printf ("Testing class_copyMethodList ()...\n");
+ {
+ unsigned int count;
+ Method * list = class_copyMethodList (objc_getClass ("MySubClass"), &count);
+
+ if (count != 2)
+ abort ();
+
+ if (! ((strcmp (sel_getName (method_getName (list[0])), "variable") == 0
+ && strcmp (sel_getName (method_getName (list[1])), "setVariable:") == 0)
+ || (strcmp (sel_getName (method_getName (list[0])), "setVariable:") == 0
+ && strcmp (sel_getName (method_getName (list[1])), "variable") == 0)))
+ abort ();
+
+ if (list[2] != NULL)
+ abort ();
+ }
+
+ /* TODO: Test new ABI (when available). */
+ printf ("Testing class_copyPropertyList ()...\n");
+ {
+ unsigned int count;
+ objc_property_t * list = class_copyPropertyList (objc_getClass ("MySubClass"), &count);
+
+ if (count != 0 || list != NULL)
+ abort ();
+ }
+
+ printf ("Testing class_copyProtocolList ()...\n");
+ {
+ unsigned int count;
+ Protocol ** list = class_copyProtocolList (objc_getClass ("MySubClass"), &count);
+
+ /* Remember that we added MySecondProtocol in the test above. */
+ if (count != 2)
+ abort ();
+
+ if (! ((strcmp (protocol_getName (list[0]), "MyProtocol") == 0
+ && strcmp (protocol_getName (list[1]), "MySecondProtocol") == 0)
+ || (strcmp (protocol_getName (list[0]), "MySecondProtocol") == 0
+ && strcmp (protocol_getName (list[1]), "MyProtocol") == 0)))
+ abort ();
+
+ if (list[2] != NULL)
+ abort ();
+ }
+
+ printf ("Testing class_createInstance ()...\n");
+ {
+ MySubClass *object = [[MySubClass alloc] init];
+
+ [object setVariable: object];
+ if ([object variable] != object)
+ abort ();
+ }
+
+ printf ("Testing class_getClassMethod ()...\n");
+ {
+ Method method = class_getClassMethod (objc_getClass ("MySubClass"),
+ @selector(alloc));
+
+ if (method == NULL)
+ abort ();
+
+ if (strcmp (sel_getName (method_getName (method)), "alloc") != 0)
+ abort ();
+
+ if (class_getClassMethod (objc_getClass ("MySubClass"),
+ @selector(variable)))
+ abort ();
+ }
+
+ printf ("Testing class_getClassVariable ()...\n");
+ {
+ if (class_getClassVariable (objc_getClass ("MySubClass"), "variable_ivar"))
+ abort ();
+ }
+
+ printf ("Testing class_getInstanceMethod ()...\n");
+ {
+ Method method = class_getInstanceMethod (objc_getClass ("MySubClass"),
+ @selector(variable));
+
+ if (method == NULL)
+ abort ();
+
+ if (strcmp (sel_getName (method_getName (method)), "variable") != 0)
+ abort ();
+
+ if (class_getInstanceMethod (objc_getClass ("MySubClass"),
+ @selector(alloc)))
+ abort ();
+ }
+
+ printf ("Testing class_getInstanceSize ()...\n");
+ {
+ if (class_getInstanceSize (objc_getClass ("MyRootClass")) != sizeof (struct objc_object))
+ abort ();
+ }
+
+ printf ("Testing class_getInstanceVariable ()...\n");
+ {
+ Ivar variable = class_getInstanceVariable (objc_getClass ("MySubClass"), "variable_ivar");
+
+ if (variable == NULL)
+ abort ();
+
+ if (strcmp (ivar_getName (variable), "variable_ivar") != 0)
+ abort ();
+
+ if (class_getInstanceVariable (objc_getClass ("MySubClass"), "variable_ivar_no"))
+ abort ();
+ }
+
+ printf ("Testing class_getIvarLayout ()...\n");
+ {
+ if (class_getIvarLayout (objc_getClass ("MyRootClass")) != NULL)
+ abort ();
+ }
+
+ printf ("Testing class_getMethodImplementation ()...\n");
+ {
+ MySubClass *object = [[MySubClass alloc] init];
+ IMP imp = class_getMethodImplementation (objc_getClass ("MySubClass"),
+ @selector(variable));
+
+ if (imp == NULL)
+ abort ();
+
+ [object setVariable: object];
+
+ if ((*imp)(object, @selector(variable)) != object)
+ abort ();
+ }
+
+ /* This function does not exist with the GNU runtime. */
+ /* printf ("Testing class_getMethodImplementation_stret ()...\n"); */
+
+ printf ("Testing class_getName ()...\n");
+ {
+ if (strcmp (class_getName (objc_getClass ("MyRootClass")),
+ "MyRootClass") != 0)
+ abort ();
+ }
+
+ /* TODO: Test new ABI (when available). */
+ printf ("Testing class_getProperty ()...\n");
+ {
+ if (class_getProperty (objc_getClass ("MyRootClass"), "property") != NULL)
+ abort ();
+ }
+
+ printf ("Testing class_getSuperclass ()...\n");
+ {
+ MySubClass *object = [[MySubClass alloc] init];
+ if (class_getSuperclass (object_getClass (object)) != objc_getClass ("MyRootClass"))
+ abort ();
+ }
+
+ printf ("Testing class_getVersion ()...\n");
+ {
+ if (class_getVersion (objc_getClass ("MySubClass")) != 0)
+ abort ();
+ }
+
+ printf ("Testing class_getWeakIvarLayout ()...\n");
+ {
+ if (class_getWeakIvarLayout (objc_getClass ("MyRootClass")) != NULL)
+ abort ();
+ }
+
+ printf ("Testing class_isMetaClass ()...\n");
+ {
+ MySubClass *object = [[MySubClass alloc] init];
+ if (class_isMetaClass (object_getClass (object))
+ || ! class_isMetaClass (object_getClass (object_getClass (object))))
+ abort ();
+ }
+
+ printf ("Testing class_replaceMethod ()...\n");
+ {
+ Method new_method = class_getInstanceMethod (objc_getClass ("DifferentClass"),
+ @selector (myClass));
+ Method old_method = class_getInstanceMethod (objc_getClass ("MySubClass"),
+ @selector (variable));
+ const char *new_types = method_getTypeEncoding (new_method);
+ IMP new_imp = method_getImplementation (new_method);
+ const char *old_types = method_getTypeEncoding (old_method);
+ IMP old_imp = class_replaceMethod (objc_getClass ("MySubClass"), @selector (variable),
+ method_getImplementation (new_method),
+ method_getTypeEncoding (new_method));
+ MySubClass *o = [[MySubClass alloc] init];
+
+ [o setVariable: o];
+
+ /* Try the new method implementation. */
+ if ([o variable] != objc_getClass ("MySubClass"))
+ abort ();
+
+ /* Put the original method back. */
+ class_replaceMethod (objc_getClass ("MySubClass"), @selector (variable),
+ old_imp, old_types);
+
+ /* Test it's back to what it was. */
+ if ([o variable] != o)
+ abort ();
+
+ {
+ DifferentClass *o = [[DifferentClass alloc] init];
+
+ /* Finally, try adding a new method. */
+ class_replaceMethod (objc_getClass ("DifferentClass"), @selector (mySelf),
+ new_imp, new_types);
+
+ if ([(MySubClass*)o mySelf] != objc_getClass ("DifferentClass"))
+ abort ();
+ }
+ }
+
+ printf ("Testing class_respondsToSelector ()...\n");
+ {
+ if (! class_respondsToSelector (objc_getClass ("MySubClass"), @selector(setVariable:)))
+ abort ();
+
+ if (class_respondsToSelector (objc_getClass ("MyRootClass"), @selector(setVariable:)))
+ abort ();
+ }
+
+ /* This is not really implemented with the GNU runtime. */
+ /* printf ("Testing class_setIvarLayout ()...\n"); */
+
+ printf ("Testing class_setVersion ()...\n");
+ {
+ class_setVersion (objc_getClass ("MySubClass"), 45);
+
+ if (class_getVersion (objc_getClass ("MySubClass")) != 45)
+ abort ();
+
+ class_setVersion (objc_getClass ("MySubClass"), 46);
+
+ if (class_getVersion (objc_getClass ("MySubClass")) != 46)
+ abort ();
+ }
+
+ /* This is not really implemented with the GNU runtime. */
+ /* printf ("Testing class_setWeakIvarLayout ()...\n"); */
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/gnu-api-2-ivar.m b/gcc/testsuite/objc.dg/gnu-api-2-ivar.m
new file mode 100644
index 000000000..19ac004e7
--- /dev/null
+++ b/gcc/testsuite/objc.dg/gnu-api-2-ivar.m
@@ -0,0 +1,83 @@
+/* Test the Modern GNU Objective-C Runtime API.
+
+ This is test 'ivar', covering all functions starting with 'ivar'. */
+
+/* { dg-do run } */
+/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* To get the modern GNU Objective-C Runtime API, you include
+ objc/runtime.h. */
+#include <objc/runtime.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+@interface MyRootClass
+{ Class isa; }
++ alloc;
+- init;
++ initialize;
+@end
+
+@implementation MyRootClass
++ alloc { return class_createInstance (self, 0); }
+- init { return self; }
++ initialize { return self; }
+@end
+
+@protocol MyProtocol
+- (id) variable;
+@end
+
+@protocol MySecondProtocol
+- (id) setVariable: (id)value;
+@end
+
+@interface MySubClass : MyRootClass <MyProtocol>
+{ id variable_ivar; }
+- (void) setVariable: (id)value;
+- (id) variable;
+@end
+
+@implementation MySubClass
+- (void) setVariable: (id)value { variable_ivar = value; }
+- (id) variable { return variable_ivar; }
+@end
+
+
+int main(int argc, void **args)
+{
+ /* Functions are tested in alphabetical order. */
+
+ printf ("Testing ivar_getName () ...\n");
+ {
+ Ivar ivar = class_getInstanceVariable (objc_getClass ("MySubClass"),
+ "variable_ivar");
+ if (strcmp (ivar_getName (ivar), "variable_ivar") != 0)
+ abort ();
+
+ ivar = class_getInstanceVariable (objc_getClass ("MySubClass"),
+ "variable");
+ if (ivar != 0)
+ abort ();
+ }
+
+ printf ("Testing ivar_getOffset () ...\n");
+ {
+ Ivar ivar = class_getInstanceVariable (objc_getClass ("MyRootClass"),
+ "isa");
+ if (ivar_getOffset (ivar) != 0)
+ abort ();
+ }
+
+ printf ("Testing ivar_getTypeEncoding () ...\n");
+ {
+ Ivar ivar = class_getInstanceVariable (objc_getClass ("MySubClass"),
+ "variable_ivar");
+ if (strcmp (ivar_getTypeEncoding (ivar), "@") != 0)
+ abort ();
+ }
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/gnu-api-2-method.m b/gcc/testsuite/objc.dg/gnu-api-2-method.m
new file mode 100644
index 000000000..fc447b69f
--- /dev/null
+++ b/gcc/testsuite/objc.dg/gnu-api-2-method.m
@@ -0,0 +1,230 @@
+/* Test the Modern GNU Objective-C Runtime API.
+
+ This is test 'method', covering all functions starting with 'method'. */
+
+/* { dg-do run } */
+/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* To get the modern GNU Objective-C Runtime API, you include
+ objc/runtime.h. */
+#include <objc/runtime.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+@interface MyRootClass
+{ Class isa; }
++ alloc;
+- init;
++ initialize;
+@end
+
+@implementation MyRootClass
++ alloc { return class_createInstance (self, 0); }
+- init { return self; }
++ initialize { return self; }
+@end
+
+@protocol MyProtocol
+- (id) variable;
+@end
+
+@protocol MySecondProtocol
+- (id) setVariable: (id)value;
+@end
+
+@interface MySubClass : MyRootClass <MyProtocol>
+{ id variable_ivar; }
+- (void) setVariable: (id)value;
+- (id) variable;
+- (id) constant;
+@end
+
+@implementation MySubClass
+- (void) setVariable: (id)value { variable_ivar = value; }
+- (id) variable { return variable_ivar; }
+- (id) constant { return nil; }
+@end
+
+
+int main(int argc, void **args)
+{
+ /* Functions are tested in alphabetical order. */
+
+ printf ("Testing method_copyArgumentType () ...\n");
+ {
+ Method method = class_getInstanceMethod (objc_getClass ("MySubClass"),
+ @selector (setVariable:));
+ char *type = method_copyArgumentType (method, 2);
+
+ if (type == NULL || type[0] != '@')
+ abort ();
+ }
+
+ printf ("Testing method_copyReturnType () ...\n");
+ {
+ Method method = class_getClassMethod (objc_getClass ("MyRootClass"),
+ @selector (alloc));
+ char *type = method_copyReturnType (method);
+
+ /* Check that it returns an object. */
+ if (type == NULL || type[0] != '@')
+ abort ();
+ }
+
+ printf ("Testing method_exchangeImplementations () ...\n");
+ {
+ Method method_a = class_getInstanceMethod (objc_getClass ("MySubClass"),
+ @selector (variable));
+ Method method_b = class_getInstanceMethod (objc_getClass ("MySubClass"),
+ @selector (constant));
+ MySubClass *object = [[MySubClass alloc] init];
+
+ /* Check that things work as expected before the swap. */
+ [object setVariable: object];
+
+ if ([object variable] != object || [object constant] != nil)
+ abort ();
+
+ /* Swap the methods. */
+ method_exchangeImplementations (method_a, method_b);
+
+ /* Check that behaviour has changed. */
+ if ([object variable] != nil || [object constant] != object)
+ abort ();
+
+ /* Swap the methods again. */
+ method_exchangeImplementations (method_a, method_b);
+
+ /* Check that behaviour is back to normal. */
+ if ([object variable] != object || [object constant] != nil)
+ abort ();
+ }
+
+ printf ("Testing method_getArgumentType () ...\n");
+ {
+ Method method = class_getInstanceMethod (objc_getClass ("MyRootClass"),
+ @selector (init));
+ char type[16];
+
+ method_getArgumentType (method, 1, type, 16);
+
+ /* Check the second argument (_cmd), which should be a SEL. */
+ if (type[0] != ':')
+ abort ();
+ }
+
+ printf ("Testing method_getDescription () ...\n");
+ {
+ Method method = class_getInstanceMethod (objc_getClass ("MySubClass"),
+ @selector (variable));
+ struct objc_method_description *description = method_getDescription (method);
+
+ if (strcmp (sel_getName (description->name), "variable") != 0)
+ abort ();
+
+ if (method_getDescription (NULL) != NULL)
+ abort ();
+ }
+
+ printf ("Testing method_getImplementation () ...\n");
+ {
+ typedef void (*set_variable_function) (id receiver, SEL _cmd, id variable);
+ Method method = class_getInstanceMethod (objc_getClass ("MySubClass"),
+ @selector (setVariable:));
+ set_variable_function imp;
+ MySubClass *object = [[MySubClass alloc] init];
+
+ imp = (set_variable_function)(method_getImplementation (method));
+
+ (*imp)(object, @selector (setVariable:), object);
+
+ if ([object variable] != object)
+ abort ();
+ }
+
+ printf ("Testing method_getName () ...\n");
+ {
+ Method method = class_getInstanceMethod (objc_getClass ("MySubClass"),
+ @selector (setVariable:));
+ if (strcmp (sel_getName (method_getName (method)), "setVariable:") != 0)
+ abort ();
+ }
+
+ printf ("Testing method_getNumberOfArguments () ...\n");
+ {
+ Method method = class_getInstanceMethod (objc_getClass ("MySubClass"),
+ @selector (setVariable:));
+ if (method_getNumberOfArguments (method) != 3)
+ abort ();
+
+ method = class_getInstanceMethod (objc_getClass ("MySubClass"),
+ @selector (variable));
+ if (method_getNumberOfArguments (method) != 2)
+ abort ();
+ }
+
+ printf ("Testing method_getTypeEncoding () ...\n");
+ {
+ Method method = class_getInstanceMethod (objc_getClass ("MySubClass"),
+ @selector (setVariable:));
+ const char *types = method_getTypeEncoding (method);
+
+ /* Check that method type string starts with 'v' (void) */
+ if (types == NULL || types[0] != 'v')
+ abort ();
+ }
+
+ printf ("Testing method_getReturnType () ...\n");
+ {
+ Method method = class_getInstanceMethod (objc_getClass ("MySubClass"),
+ @selector (setVariable:));
+ char type[16];
+
+ method_getReturnType (method, type, 16);
+
+ if (type[0] != 'v')
+ abort ();
+
+ method_getReturnType (NULL, type, 16);
+
+ if (type[0] != 0)
+ abort ();
+ }
+
+ printf ("Testing method_setImplementation () ...\n");
+ {
+ Method method_a = class_getInstanceMethod (objc_getClass ("MySubClass"),
+ @selector (variable));
+ Method method_b = class_getInstanceMethod (objc_getClass ("MySubClass"),
+ @selector (constant));
+ IMP original_imp_a = method_getImplementation (method_a);
+ IMP original_imp_b = method_getImplementation (method_b);
+ MySubClass *object = [[MySubClass alloc] init];
+
+ /* Check that things work as expected before the swap. */
+ [object setVariable: object];
+
+ if ([object variable] != object || [object constant] != nil)
+ abort ();
+
+ /* Have 'variable' use the same implementation as 'constant'. */
+ if (method_setImplementation (method_a, original_imp_b) != original_imp_a)
+ abort ();
+
+ /* Check that behaviour has changed. */
+ if ([object variable] != nil || [object constant] != nil)
+ abort ();
+
+ /* Put the original method back. */
+ if (method_setImplementation (method_a, original_imp_a) != original_imp_b)
+ abort ();
+
+ /* Check that behaviour is back to normal. */
+ if ([object variable] != object || [object constant] != nil)
+ abort ();
+ }
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/gnu-api-2-objc.m b/gcc/testsuite/objc.dg/gnu-api-2-objc.m
new file mode 100644
index 000000000..59344efaf
--- /dev/null
+++ b/gcc/testsuite/objc.dg/gnu-api-2-objc.m
@@ -0,0 +1,248 @@
+/* Test the Modern GNU Objective-C Runtime API.
+
+ This is test 'objc', covering all functions starting with 'objc'. */
+
+/* { dg-do run } */
+/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* To get the modern GNU Objective-C Runtime API, you include
+ objc/runtime.h. */
+#include <objc/runtime.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+@interface MyRootClass
+{ Class isa; }
++ alloc;
+- init;
++ initialize;
+@end
+
+@implementation MyRootClass
++ alloc { return class_createInstance (self, 0); }
+- init { return self; }
++ initialize { return self; }
+@end
+
+@protocol MyProtocol
+- (id) variable;
+@end
+
+@protocol MySecondProtocol
+- (id) setVariable: (id)value;
+@end
+
+@interface MySubClass : MyRootClass <MyProtocol>
+{ id variable_ivar; }
+- (void) setVariable: (id)value;
+- (id) variable;
+@end
+
+@implementation MySubClass
+- (void) setVariable: (id)value { variable_ivar = value; }
+- (id) variable { return variable_ivar; }
+@end
+
+
+int main(int argc, void **args)
+{
+ /* Functions are tested in alphabetical order. */
+
+ printf ("Testing objc_allocateClassPair ()...\n");
+ {
+ Class new_root_class = objc_allocateClassPair (Nil, "MyNewRootClass", 0);
+ Class new_class = objc_allocateClassPair (objc_getClass ("MyRootClass"), "MyNewSubClass", 0);
+
+ /* A new root class would obviously need at least an 'isa'
+ instance variable. We don't add it so we never actually
+ instantiate an instance of the class, which wouldn't work. */
+
+ objc_registerClassPair (new_root_class);
+ objc_registerClassPair (new_class);
+
+ if (strcmp (class_getName (new_class), "MyNewSubClass") != 0)
+ abort ();
+
+ if (class_getSuperclass (new_class) != objc_getClass ("MyRootClass"))
+ abort ();
+
+ if (strcmp (class_getName (new_root_class), "MyNewRootClass") != 0)
+ abort ();
+
+ if (class_getSuperclass (new_root_class) != Nil)
+ abort ();
+
+ {
+ MySubClass *o = [[objc_getClass ("MyNewSubClass") alloc] init];
+
+ if (object_getClass (o) != objc_getClass ("MyNewSubClass"))
+ abort ();
+ }
+ }
+
+ printf ("Testing objc_copyProtocolList ()...\n");
+ {
+ /* Make sure both our two protocols are known to the runtime. */
+ id my_protocol = @protocol (MyProtocol);
+ id my_second_protocol = @protocol (MySecondProtocol);
+ unsigned int count;
+ Protocol ** list = objc_copyProtocolList (&count);
+
+ if (count != 2)
+ abort ();
+
+ if (! ((strcmp (protocol_getName (list[0]), "MyProtocol") == 0
+ && strcmp (protocol_getName (list[1]), "MySecondProtocol") == 0)
+ || (strcmp (protocol_getName (list[0]), "MySecondProtocol") == 0
+ && strcmp (protocol_getName (list[1]), "MyProtocol") == 0)))
+ abort ();
+
+ if (list[2] != NULL)
+ abort ();
+ }
+
+ printf ("Testing objc_disposeClassPair ()...\n");
+ {
+ Method method = class_getInstanceMethod (objc_getClass ("MySubClass"), @selector (setVariable:));
+ Class new_class = objc_allocateClassPair (objc_getClass ("MyRootClass"), "MyNewSubClass2", 0);
+
+ if (new_class == Nil)
+ abort ();
+
+ /* Add a bit of everything to the class to exercise undoing all these changes. */
+
+ /* Instance variable. */
+ class_addIvar (new_class, "my_variable", sizeof (float), __alignof__ (float), @encode (float));
+
+ /* Instance method. */
+ class_addMethod (new_class, @selector (setVariable:), method_getImplementation (method),
+ method_getTypeEncoding (method));
+
+ /* Class method. */
+ class_addMethod (object_getClass (new_class), @selector (setVariable:), method_getImplementation (method),
+ method_getTypeEncoding (method));
+
+ /* Protocol. */
+ class_addProtocol (new_class, @protocol (MyProtocol));
+
+ objc_disposeClassPair (new_class);
+ }
+
+ /* This function currently does not exist with the GNU runtime. */
+ /* printf ("Testing objc_duplicateClass ()...\n"); */
+
+ /* TODO - Test it when implemented in the GNU Runtime */
+ /* printf ("Testing objc_getAssociatedObject ()...\n"); */
+
+ printf ("Testing objc_getClass ()...\n");
+ {
+ if (strcmp (class_getName (objc_getClass ("MySubClass")),
+ "MySubClass") != 0)
+ abort ();
+ }
+
+ printf ("Testing objc_getClassList ()...\n");
+ {
+ Class *list;
+ int i, count, other_count;
+ count = objc_getClassList (NULL, 0);
+
+ /* count most likely will be 5, (MyRootClass, MySubClass,
+ Protocol, Object, NXConstantString). */
+ if (count < 3)
+ abort ();
+
+ list = malloc (sizeof (Class) * count);
+ other_count = objc_getClassList (list, count);
+
+ if (other_count != count)
+ abort ();
+
+ /* Spot-check: search for class 'MyRootClass' in the list. */
+ for (i = 0; i < count; i++)
+ {
+ if (strcmp (class_getName (list[i]), "MyRootClass") == 0)
+ break;
+ }
+ if (i == count)
+ abort ();
+
+ /* Spot-check: search for class 'MySubClass' in the list. */
+ for (i = 0; i < count; i++)
+ {
+ if (strcmp (class_getName (list[i]), "MySubClass") == 0)
+ break;
+ }
+ if (i == count)
+ abort ();
+
+ /* Spot-check: search for class 'Protocol' in the list. */
+ for (i = 0; i < count; i++)
+ {
+ if (strcmp (class_getName (list[i]), "Protocol") == 0)
+ break;
+ }
+ if (i == count)
+ abort ();
+ }
+
+ /* This function does not exist with the GNU runtime. */
+ /* printf ("Testing objc_getFutureClass ()...\n"); */
+
+ printf ("Testing objc_getMetaClass ()...\n");
+ {
+ if (! class_isMetaClass (objc_getMetaClass ("MyRootClass")))
+ abort ();
+ }
+
+ printf ("Testing objc_getProtocol ()...\n");
+ {
+ if (! protocol_isEqual (objc_getProtocol ("MyProtocol"), @protocol (MyProtocol)))
+ abort ();
+ }
+
+ printf ("Testing objc_getRequiredClass ()...\n");
+ {
+ if (strcmp (class_getName (objc_getRequiredClass ("MyRootClass")),
+ "MyRootClass") != 0)
+ abort ();
+ }
+
+ printf ("Testing objc_lookUpClass ()...\n");
+ {
+ if (strcmp (class_getName (objc_lookUpClass ("MyRootClass")),
+ "MyRootClass") != 0)
+ abort ();
+ }
+
+ /* This function does not exist with the GNU runtime. */
+ /* printf ("Testing objc_setFutureClass ()...\n"); */
+
+ printf ("Testing objc_registerClassPair ()...\n");
+ {
+ Class new_class = objc_allocateClassPair (objc_getClass ("MySubClass"), "MySubSubClass", 0);
+
+ class_addProtocol (new_class, @protocol (MySecondProtocol));
+
+ objc_registerClassPair (new_class);
+
+ if (strcmp (class_getName (new_class), "MySubSubClass") != 0)
+ abort ();
+
+ if (class_getSuperclass (new_class) != objc_getClass ("MySubClass"))
+ abort ();
+
+ if (! class_conformsToProtocol (new_class, @protocol (MySecondProtocol)))
+ abort ();
+ }
+
+ /* TODO - Test it when implemented in the GNU Runtime */
+ /* printf ("Testing objc_removeAssociatedObjects ()...\n"); */
+
+ /* TODO - Test it when implemented in the GNU Runtime */
+ /* printf ("Testing objc_setAssociatedObject ()...\n"); */
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/gnu-api-2-objc_msg_lookup.m b/gcc/testsuite/objc.dg/gnu-api-2-objc_msg_lookup.m
new file mode 100644
index 000000000..5751f3fd2
--- /dev/null
+++ b/gcc/testsuite/objc.dg/gnu-api-2-objc_msg_lookup.m
@@ -0,0 +1,77 @@
+/* Test the Modern GNU Objective-C Runtime API.
+
+ This is test 'objc_msg_lookup', covering objc_msg_lookup(),
+ objc_msg_lookup_super() and struct objc_super. */
+
+/* { dg-do run } */
+/* { dg-skip-if "" { *-*-* } { "-fnext-runtime" } { "" } } */
+
+/* To get the modern GNU Objective-C Runtime API, you include
+ objc/runtime.h. */
+#include <objc/runtime.h>
+
+/* For objc_msg_lookup(), objc_msg_lookup_super() and struct
+ objc_super. */
+#include <objc/message.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+@interface MyRootClass
+{ Class isa; }
++ alloc;
+- init;
+- (int) test;
+@end
+
+@implementation MyRootClass
++ alloc { return class_createInstance (self, 0); }
+- init { return self; }
+- (int) test { return 20; }
+@end
+
+@interface MySubClass : MyRootClass
+- (int) test;
+@end
+
+@implementation MySubClass
+- (int) test { return 11; }
+@end
+
+int main (int argc, void **args)
+{
+ /* Functions are tested in alphabetical order. */
+
+ printf ("Testing objc_msg_lookup ()...\n");
+ {
+ MySubClass *object = [[MySubClass alloc] init];
+ int (* test_IMP) (id receiver, SEL selector);
+
+ test_IMP = (int (*)(id, SEL))objc_msg_lookup (object, @selector (test));
+
+ if (test_IMP (object, @selector (test)) != 11)
+ abort ();
+ }
+
+ printf ("Testing objc_msg_lookup_super ()...\n");
+ {
+ MySubClass *object = [[MySubClass alloc] init];
+ struct objc_super super = { 0, 0 };
+ int (* test_IMP) (id receiver, SEL selector);
+
+ /* Get the implementation of -test for the superclass of object -
+ as if we were calling [super test] inside a method
+ implementation of object. */
+ super.self = object;
+ super.super_class = class_getSuperclass (object_getClass (object));
+ test_IMP = (int (*)(id, SEL))objc_msg_lookup_super (&super, @selector (test));
+
+ /* Invoke it. The method in MyRootClass, not the one in
+ MySubClass, should be invoked. */
+ if (test_IMP (object, @selector (test)) != 20)
+ abort ();
+ }
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/gnu-api-2-object.m b/gcc/testsuite/objc.dg/gnu-api-2-object.m
new file mode 100644
index 000000000..3d4d444fe
--- /dev/null
+++ b/gcc/testsuite/objc.dg/gnu-api-2-object.m
@@ -0,0 +1,164 @@
+/* Test the Modern GNU Objective-C Runtime API.
+
+ This is test 'object', covering all functions starting with 'object'. */
+
+/* { dg-do run } */
+/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* To get the modern GNU Objective-C Runtime API, you include
+ objc/runtime.h. */
+#include <objc/runtime.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+@interface MyRootClass
+{ Class isa; }
++ alloc;
+- init;
++ initialize;
+@end
+
+@implementation MyRootClass
++ alloc { return class_createInstance (self, 0); }
+- init { return self; }
++ initialize { return self; }
+@end
+
+@protocol MyProtocol
+- (id) variable;
+@end
+
+@protocol MySecondProtocol
+- (id) setVariable: (id)value;
+@end
+
+@interface MySubClass : MyRootClass <MyProtocol>
+{ id variable_ivar; }
+- (void) setVariable: (id)value;
+- (id) variable;
+@end
+
+@implementation MySubClass
+- (void) setVariable: (id)value { variable_ivar = value; }
+- (id) variable { return variable_ivar; }
+@end
+
+@interface MySubSubClass : MySubClass
+- (id) test;
+@end
+
+@implementation MySubSubClass
+- (id) test { return self; }
+@end
+
+
+
+int main(int argc, void **args)
+{
+ /* Functions are tested in alphabetical order. */
+
+ printf ("Testing object_copy () ...\n");
+ {
+ MySubClass *object_a = [[MySubClass alloc] init];
+ MySubClass *object_b = object_copy (object_a, 0);
+
+ [object_b setVariable: object_a];
+ if ([object_b variable] != object_a)
+ abort ();
+ }
+
+ printf ("Testing object_dispose () ...\n");
+ {
+ MySubClass *object = [[MySubClass alloc] init];
+
+ object_dispose (object);
+ }
+
+ printf ("Testing object_getClass () ...\n");
+ {
+ MyRootClass *o = [[MySubClass alloc] init];
+
+ if (object_getClass (o) != objc_getClass ("MySubClass"))
+ abort ();
+ }
+
+ printf ("Testing object_getClassName () ...\n");
+ {
+ MyRootClass *o = [[MyRootClass alloc] init];
+
+ if (strcmp (object_getClassName (o), "MyRootClass") != 0)
+ abort ();
+ }
+
+ printf ("Testing object_getIndexedIvars () ...\n");
+ {
+ if (object_getIndexedIvars ([[MyRootClass alloc] init]) == NULL)
+ abort ();
+ }
+
+ printf ("Testing object_getInstanceVariable () ...\n");
+ {
+ MySubClass *o = [[MySubClass alloc] init];
+ id value;
+
+ [o setVariable: o];
+
+ if (object_getInstanceVariable (o, "variable_ivar", (void **)&value) == NULL)
+ abort ();
+
+ if (value != o)
+ abort ();
+ }
+
+ printf ("Testing object_getIvar () ...\n");
+ {
+ MySubClass *o = [[MySubClass alloc] init];
+ Ivar ivar = class_getInstanceVariable (objc_getClass ("MySubClass"), "variable_ivar");
+
+ [o setVariable: o];
+
+ if (object_getIvar (o, ivar) != o)
+ abort ();
+ }
+
+ printf ("Testing object_setClass () ...\n");
+ {
+ MySubClass *o = [[MySubClass alloc] init];
+
+ object_setClass (o, objc_getClass ("MySubSubClass"));
+
+ if ([(MySubSubClass *)o test] != o)
+ abort ();
+ }
+
+ printf ("Testing object_setInstanceVariable () ...\n");
+ {
+ MySubClass *o = [[MySubClass alloc] init];
+
+ [o setVariable: nil];
+
+ if (object_setInstanceVariable (o, "variable_ivar", (void *)o) == NULL)
+ abort ();
+
+ if ([o variable] != o)
+ abort ();
+ }
+
+ printf ("Testing object_setIvar () ...\n");
+ {
+ MySubClass *o = [[MySubClass alloc] init];
+ MySubClass *value = [[MySubClass alloc] init];
+ Ivar ivar = class_getInstanceVariable (objc_getClass ("MySubClass"), "variable_ivar");
+
+ [o setVariable: o];
+
+ object_setIvar (o, ivar, value);
+
+ if ([o variable] != value)
+ abort ();
+ }
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/gnu-api-2-property.m b/gcc/testsuite/objc.dg/gnu-api-2-property.m
new file mode 100644
index 000000000..12c0d8b98
--- /dev/null
+++ b/gcc/testsuite/objc.dg/gnu-api-2-property.m
@@ -0,0 +1,100 @@
+/* Test the Modern GNU Objective-C Runtime API.
+
+ This is test 'property', covering all functions starting with 'property'. */
+
+/* { dg-do run } */
+/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */
+
+/* To get the modern GNU Objective-C Runtime API, you include
+ objc/runtime.h. */
+#include <objc/runtime.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+@interface MyRootClass
+{ Class isa; }
++ alloc;
+- init;
++ initialize;
+@end
+
+@implementation MyRootClass
++ alloc { return class_createInstance (self, 0); }
+- init { return self; }
++ initialize { return self; }
+@end
+
+@interface MySubClass : MyRootClass
+{
+ id propertyA;
+ id propertyB;
+}
+@property (assign, getter=getP, setter=setP:) id propertyA;
+@property (assign, nonatomic) id propertyB;
+@end
+
+@implementation MySubClass
+@synthesize propertyA;
+@synthesize propertyB;
+@end
+
+
+int main(int argc, void **args)
+{
+ /* Functions are tested in alphabetical order. */
+
+ printf ("Testing property_getAttributes () ...\n");
+ {
+ /* The Apple/NeXT runtime seems to crash on the following. */
+#ifdef __GNU_LIBOBJC__
+ if (property_getAttributes (NULL) != NULL)
+ abort ();
+#endif
+
+ /* The GNU runtime doesn't support looking up properties at
+ runtime yet. */
+#ifdef __OBJC2__
+ {
+ objc_property_t property;
+
+ property = class_getProperty (objc_getClass ("MySubClass"), "propertyA");
+ if (strcmp (property_getAttributes (property),
+ "T@,GgetP,SsetP:,VpropertyA") != 0)
+ abort ();
+
+ property = class_getProperty (objc_getClass ("MySubClass"), "propertyB");
+ if (strcmp (property_getAttributes (property),
+ "T@,N,VpropertyB") != 0)
+ abort ();
+ }
+#endif
+ }
+
+ printf ("Testing property_getName () ...\n");
+ {
+ /* The Apple/NeXT runtime seems to crash on the following. */
+#ifdef __GNU_LIBOBJC__
+ if (property_getName (NULL) != NULL)
+ abort ();
+#endif
+
+ /* The GNU runtime doesn't support looking up properties at
+ runtime yet. */
+#ifdef __OBJC2__
+ {
+ objc_property_t property;
+
+ property = class_getProperty (objc_getClass ("MySubClass"), "propertyA");
+ if (strcmp (property_getName (property), "propertyA") != 0)
+ abort ();
+
+ property = class_getProperty (objc_getClass ("MySubClass"), "propertyB");
+ if (strcmp (property_getName (property), "propertyB") != 0)
+ abort ();
+ }
+#endif
+ }
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/gnu-api-2-protocol.m b/gcc/testsuite/objc.dg/gnu-api-2-protocol.m
new file mode 100644
index 000000000..a34d74ce9
--- /dev/null
+++ b/gcc/testsuite/objc.dg/gnu-api-2-protocol.m
@@ -0,0 +1,163 @@
+/* Test the Modern GNU Objective-C Runtime API.
+
+ This is test 'protocol', covering all functions starting with 'protocol'. */
+
+/* { dg-do run } */
+/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* To get the modern GNU Objective-C Runtime API, you include
+ objc/runtime.h. */
+#include <objc/runtime.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+@interface MyRootClass
+{ Class isa; }
++ alloc;
+- init;
++ initialize;
+@end
+
+@implementation MyRootClass
++ alloc { return class_createInstance (self, 0); }
+- init { return self; }
++ initialize { return self; }
+@end
+
+@protocol MyProtocol
+- (id) variable;
+@end
+
+@protocol MySecondProtocol
+- (id) setVariable: (id)value;
+@end
+
+@protocol MyThirdProtocol <MySecondProtocol>
+- (id) setAnotherVariable: (id)value;
+@end
+
+@interface MySubClass : MyRootClass <MyProtocol>
+{ id variable_ivar; }
+- (void) setVariable: (id)value;
+- (id) variable;
+@end
+
+@implementation MySubClass
+- (void) setVariable: (id)value { variable_ivar = value; }
+- (id) variable { return variable_ivar; }
+@end
+
+
+int main(int argc, void **args)
+{
+ /* Functions are tested in alphabetical order. */
+
+ printf ("Testing protocol_conformsToProtocol ()...\n");
+ {
+ if (!protocol_conformsToProtocol (@protocol (MyProtocol),
+ @protocol (MyProtocol)))
+ abort ();
+
+ if (!protocol_conformsToProtocol (@protocol (MyThirdProtocol),
+ @protocol (MySecondProtocol)))
+ abort ();
+
+ if (protocol_conformsToProtocol (@protocol (MyProtocol),
+ @protocol (MySecondProtocol)))
+ abort ();
+ }
+
+ printf ("Testing protocol_copyMethodDescriptionList ()...\n");
+ {
+ unsigned int count;
+ struct objc_method_description *list;
+
+ list = protocol_copyMethodDescriptionList (@protocol (MyThirdProtocol),
+ YES, YES, &count);
+
+ if (count != 1)
+ abort ();
+
+ if (strcmp (sel_getName (list[0].name), "setAnotherVariable:") != 0)
+ abort ();
+
+ if (list[1].name != NULL && list[1].types != NULL)
+ abort ();
+ }
+
+ /* TODO: Test new ABI (when available). */
+ printf ("Testing protocol_copyPropertyList ()...\n");
+ {
+ unsigned int count;
+ objc_property_t *list;
+
+ list = protocol_copyPropertyList (@protocol (MyProtocol), &count);
+
+ if (count != 0 || list != NULL)
+ abort ();
+ }
+
+ printf ("Testing protocol_copyProtocolList ()...\n");
+ {
+ unsigned int count;
+ Protocol **list;
+
+ list = protocol_copyProtocolList (@protocol (MyThirdProtocol), &count);
+
+ if (count != 1)
+ abort ();
+
+ if (strcmp (protocol_getName (list[0]), "MySecondProtocol") != 0)
+ abort ();
+
+ if (list[1] != NULL)
+ abort ();
+ }
+
+ printf ("Testing protocol_getMethodDescription ()...\n");
+ {
+ struct objc_method_description description;
+
+ description = protocol_getMethodDescription (@protocol (MySecondProtocol),
+ @selector (setVariable:),
+ YES, YES);
+ if (description.name == NULL && description.types == NULL)
+ abort ();
+
+ if (strcmp (sel_getName (description.name), "setVariable:") != 0)
+ abort ();
+ }
+
+ printf ("Testing protocol_getName ()...\n");
+ {
+ if (strcmp (protocol_getName (@protocol (MyProtocol)), "MyProtocol") != 0)
+ abort ();
+ }
+
+ /* TODO: Test new ABI (when available). */
+ printf ("Testing protocol_getProperty ()...\n");
+ {
+ objc_property_t property;
+
+ property = protocol_getProperty (objc_getProtocol ("MyProtocol"), "someProperty",
+ YES, YES);
+
+ if (property != NULL)
+ abort ();
+ }
+
+ printf ("Testing protocol_isEqual ()...\n");
+ {
+ if (!protocol_isEqual (@protocol (MyProtocol),
+ @protocol (MyProtocol)))
+ abort ();
+
+ if (!protocol_isEqual (@protocol (MyProtocol),
+ objc_getProtocol ("MyProtocol")))
+ abort ();
+ }
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/gnu-api-2-resolve-method.m b/gcc/testsuite/objc.dg/gnu-api-2-resolve-method.m
new file mode 100644
index 000000000..a38770990
--- /dev/null
+++ b/gcc/testsuite/objc.dg/gnu-api-2-resolve-method.m
@@ -0,0 +1,567 @@
+/* Test the Modern GNU Objective-C Runtime API.
+
+ This is test 'resolve-method', covering +resolveClassMethod: and
+ +resolveInstanceMethod:. */
+
+/* { dg-do run } */
+/* { dg-skip-if "" { *-*-* } { "-fnext-runtime" } { "" } } */
+
+/* To get the modern GNU Objective-C Runtime API, you include
+ objc/runtime.h. */
+#include <objc/runtime.h>
+
+/* For __objc_msg_forward2. */
+#include <objc/message.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+@interface MyRootClass
+{ Class isa; }
++ alloc;
+- init;
+@end
+
+@implementation MyRootClass
++ alloc { return class_createInstance (self, 0); }
+- init { return self; }
+@end
+
+
+/* A number of tests will try invoking methods that don't exist. We
+ want to record the fact, but not abort the program, so we supply
+ our own fowarding implementation which will invoke the following
+ function for any method that is not found. */
+
+/* Keep track of how many times a non-existing method was executed. */
+static int nonExistingMethodCount = 0;
+
+/* Inspired by nil_method in libobjc. */
+id nonExisting_method (id receiver __attribute__ ((__unused__)),
+ SEL sel __attribute__ ((__unused__)))
+{
+ nonExistingMethodCount++;
+ return nil;
+}
+
+/* Keep track of how many times the forwarding lookup was invoked. */
+static int forwardingCount = 0;
+
+/* We install this forwarding hook to cause all failed method lookups
+ to call our 'nonExisting_method' function. */
+IMP forward_everything_to_non_existing_method (id receiver __attribute__ ((__unused__)),
+ SEL sel __attribute__ ((__unused__)))
+{
+ forwardingCount++;
+ return (IMP)nonExisting_method;
+}
+
+
+/* 'CountClass' is used to test that +resolveClassMethod: and
+ +resolveInstanceMethod: are called when expected. They do nothing
+ other than recording that they are called. */
+@interface CountClass : MyRootClass
++ (BOOL) resolveClassMethod: (SEL)selector;
++ (BOOL) resolveInstanceMethod: (SEL)selector;
++ (void) existingClassMethod;
+- (void) existingInstanceMethod;
+@end
+
+/* Count how many times the methods are called for class
+ 'CountClass'. */
+static int resolveClassMethodCount = 0;
+static int resolveInstanceMethodCount = 0;
+
+@implementation CountClass : MyRootClass
++ (BOOL) resolveClassMethod: (SEL)selector
+{
+ resolveClassMethodCount++;
+ return NO;
+}
++ (BOOL) resolveInstanceMethod: (SEL)selector
+{
+ resolveInstanceMethodCount++;
+ return NO;
+}
++ (void) existingClassMethod
+{
+ return;
+}
+- (void) existingInstanceMethod
+{
+ return;
+}
+@end
+
+@protocol NonExistingStuff
++ (void) nonExistingClassMethod;
+- (void) nonExistingInstanceMethod;
+@end
+
+/* Declare a category with some non existing methods, but don't
+ actually implement them. */
+@interface CountClass (NonExistingStuff) <NonExistingStuff>
+@end
+
+
+/* 'SelfExtendingClass' is used to test that +resolveClassMethod: and
+ +resolveInstanceMethod: can extend the class. Any time they are
+ called, they install the requested method, mapping it to the same
+ implementation as 'countHits'. */
+@interface SelfExtendingClass : MyRootClass
++ (int) countHits;
++ (BOOL) resolveClassMethod: (SEL)selector;
++ (BOOL) resolveInstanceMethod: (SEL)selector;
+@end
+
+/* How many times the countHits method (or a clone) was called. */
+static int hitCount = 0;
+
+@implementation SelfExtendingClass : MyRootClass
++ (int) countHits
+{
+ hitCount++;
+ return hitCount;
+}
++ (BOOL) resolveClassMethod: (SEL)selector
+{
+ /* Duplicate the 'countHits' method into the new method. */
+ Method method = class_getClassMethod (self, @selector (countHits));
+ class_addMethod (object_getClass (self), selector,
+ method_getImplementation (method),
+ method_getTypeEncoding (method));
+ resolveClassMethodCount++;
+ return YES;
+}
++ (BOOL) resolveInstanceMethod: (SEL)selector
+{
+ /* Duplicate the 'countHits' method into the new method. */
+ Method method = class_getClassMethod (self, @selector (countHits));
+ class_addMethod (self, selector,
+ method_getImplementation (method),
+ method_getTypeEncoding (method));
+ resolveInstanceMethodCount++;
+ return YES;
+
+}
+@end
+
+@protocol NonExistingStuff2
++ (int) nonExistingCountHitsMethod;
+- (int) nonExistingCountHitsMethod;
+
++ (int) nonExistingCountHitsMethod2;
+- (int) nonExistingCountHitsMethod2;
+
++ (int) nonExistingCountHitsMethod3;
+- (int) nonExistingCountHitsMethod3;
+@end
+
+/* Declare a category with some non existing methods, but don't
+ actually implement them. */
+@interface SelfExtendingClass (NonExistingStuff) <NonExistingStuff2>
+@end
+
+
+int main (int argc, void **args)
+{
+ /* Functions are tested in alphabetical order. */
+
+ /* Install our test forwarding hook. */
+ __objc_msg_forward2 = forward_everything_to_non_existing_method;
+
+ printf ("Testing [+resolveClassMethod:]...\n");
+ {
+ Method m;
+ IMP i;
+
+ /** CountClass tests. **/
+
+ /* Call an existing method. No +resolveClassMethod and no
+ forwarding should be triggered. */
+ [CountClass existingClassMethod];
+
+ if (resolveClassMethodCount != 0)
+ abort ();
+
+ if (forwardingCount != 0)
+ abort ();
+
+ if (nonExistingMethodCount != 0)
+ abort ();
+
+ /* Call a non-existing method. Both +resolveClassMethod and the
+ forwarding should be triggered. */
+ [CountClass nonExistingClassMethod];
+
+ if (resolveClassMethodCount != 1)
+ abort ();
+
+ if (forwardingCount != 1)
+ abort ();
+
+ if (nonExistingMethodCount != 1)
+ abort ();
+
+ /* Now try the same tests with class_getClassMethod(), which
+ should trigger the resolve methods too, but not the
+ forwarding. */
+ m = class_getClassMethod (objc_getClass ("CountClass"),
+ @selector (existingClassMethod));
+ if (resolveClassMethodCount != 1)
+ abort ();
+
+ if (forwardingCount != 1)
+ abort ();
+
+ if (nonExistingMethodCount != 1)
+ abort ();
+
+ m = class_getClassMethod (objc_getClass ("CountClass"),
+ @selector (nonExistingClassMethod));
+ if (resolveClassMethodCount != 2)
+ abort ();
+
+ if (forwardingCount != 1)
+ abort ();
+
+ if (nonExistingMethodCount != 1)
+ abort ();
+
+ /* Now try the same tests with class_getMethodImplementation(),
+ which should trigger the resolve methods and the forwarding
+ (but not execute the forwarding, obviously). */
+ i = class_getMethodImplementation (object_getClass (objc_getClass ("CountClass")),
+ @selector (existingClassMethod));
+ if (resolveClassMethodCount != 2)
+ abort ();
+
+ if (forwardingCount != 1)
+ abort ();
+
+ if (nonExistingMethodCount != 1)
+ abort ();
+
+ i = class_getMethodImplementation (object_getClass (objc_getClass ("CountClass")),
+ @selector (nonExistingClassMethod));
+ if (resolveClassMethodCount != 3)
+ abort ();
+
+ if (forwardingCount != 2)
+ abort ();
+
+ if (nonExistingMethodCount != 1)
+ abort ();
+
+
+ /* Reset the counters for the next test. */
+ resolveClassMethodCount = 0;
+ forwardingCount = 0;
+ nonExistingMethodCount = 0;
+
+
+ /** SelfExtendingClass tests. **/
+
+ /* Try the direct countHits method first. No resolving or
+ forwarding should be triggered. */
+ if ([SelfExtendingClass countHits] != 1)
+ abort ();
+
+ if (resolveClassMethodCount != 0)
+ abort ();
+
+ if (forwardingCount != 0)
+ abort ();
+
+ if (nonExistingMethodCount != 0)
+ abort ();
+
+ /* Now, try calling a non-existing count method; it should be
+ installed and invoked. */
+ if ([SelfExtendingClass nonExistingCountHitsMethod] != 2)
+ abort ();
+
+ if (resolveClassMethodCount != 1)
+ abort ();
+
+ if (forwardingCount != 0)
+ abort ();
+
+ if (nonExistingMethodCount != 0)
+ abort ();
+
+ /* Try it again. The method has now been installed, so it should
+ be used and work, but with no additional resolving
+ involved. */
+ if ([SelfExtendingClass nonExistingCountHitsMethod] != 3)
+ abort ();
+
+ if (resolveClassMethodCount != 1)
+ abort ();
+
+ if (forwardingCount != 0)
+ abort ();
+
+ if (nonExistingMethodCount != 0)
+ abort ();
+
+
+ /* Now try the same tests with class_getClassMethod(). */
+ m = class_getClassMethod (objc_getClass ("SelfExtendingClass"),
+ @selector (nonExistingCountHitsMethod2));
+ if (resolveClassMethodCount != 2)
+ abort ();
+
+ if (forwardingCount != 0)
+ abort ();
+
+ if (nonExistingMethodCount != 0)
+ abort ();
+
+ /* Try it again. The method has now been installed, so it should
+ be used and work, but with no additional resolving
+ involved. */
+ if ([SelfExtendingClass nonExistingCountHitsMethod2] != 4)
+ abort ();
+
+ if (resolveClassMethodCount != 2)
+ abort ();
+
+ if (forwardingCount != 0)
+ abort ();
+
+ if (nonExistingMethodCount != 0)
+ abort ();
+
+
+ /* Now try the same tests with class_getMethodImplementation(). */
+ i = class_getMethodImplementation (object_getClass (objc_getClass ("SelfExtendingClass")),
+ @selector (nonExistingCountHitsMethod3));
+ if (resolveClassMethodCount != 3)
+ abort ();
+
+ if (forwardingCount != 0)
+ abort ();
+
+ if (nonExistingMethodCount != 0)
+ abort ();
+
+ /* Try it again. The method has now been installed, so it should
+ be used and work, but with no additional resolving
+ involved. */
+ if ([SelfExtendingClass nonExistingCountHitsMethod3] != 5)
+ abort ();
+
+ if (resolveClassMethodCount != 3)
+ abort ();
+
+ if (forwardingCount != 0)
+ abort ();
+
+ if (nonExistingMethodCount != 0)
+ abort ();
+ }
+
+ /* Reset the counters for the next test. */
+ nonExistingMethodCount = 0;
+ forwardingCount = 0;
+ hitCount = 0;
+
+ printf ("Testing [+resolveInstanceMethod:]...\n");
+ {
+ Method m;
+ IMP i;
+ CountClass *object = [[CountClass alloc] init];
+ SelfExtendingClass *object2 = [[SelfExtendingClass alloc] init];
+
+ /** CountClass tests. **/
+
+ /* Call an existing method. No +resolveInstanceMethod and no
+ forwarding should be triggered. */
+ [object existingInstanceMethod];
+
+ if (resolveInstanceMethodCount != 0)
+ abort ();
+
+ if (forwardingCount != 0)
+ abort ();
+
+ if (nonExistingMethodCount != 0)
+ abort ();
+
+ /* Call a non-existing method. Both +resolveInstanceMethod and the
+ forwarding should be triggered. */
+ [object nonExistingInstanceMethod];
+
+ if (resolveInstanceMethodCount != 1)
+ abort ();
+
+ if (forwardingCount != 1)
+ abort ();
+
+ if (nonExistingMethodCount != 1)
+ abort ();
+
+ /* Now try the same tests with class_getInstanceMethod(), which
+ should trigger the resolve methods too, but not the
+ forwarding. */
+ m = class_getInstanceMethod (objc_getClass ("CountClass"),
+ @selector (existingInstanceMethod));
+
+ if (resolveInstanceMethodCount != 1)
+ abort ();
+
+ if (forwardingCount != 1)
+ abort ();
+
+ if (nonExistingMethodCount != 1)
+ abort ();
+
+ m = class_getInstanceMethod (objc_getClass ("CountClass"),
+ @selector (nonExistingInstanceMethod));
+
+ if (resolveInstanceMethodCount != 2)
+ abort ();
+
+ if (forwardingCount != 1)
+ abort ();
+
+ if (nonExistingMethodCount != 1)
+ abort ();
+
+ /* Now try the same tests with class_getMethodImplementation(),
+ which should trigger the resolve methods and the
+ forwarding. */
+ i = class_getMethodImplementation (objc_getClass ("CountClass"),
+ @selector (existingInstanceMethod));
+ if (resolveInstanceMethodCount != 2)
+ abort ();
+
+ if (forwardingCount != 1)
+ abort ();
+
+ if (nonExistingMethodCount != 1)
+ abort ();
+
+ i = class_getMethodImplementation (objc_getClass ("CountClass"),
+ @selector (nonExistingInstanceMethod));
+ if (resolveInstanceMethodCount != 3)
+ abort ();
+
+ if (forwardingCount != 2)
+ abort ();
+
+ if (nonExistingMethodCount != 1)
+ abort ();
+
+ /* Reset the counters for the next test. */
+ resolveInstanceMethodCount = 0;
+ forwardingCount = 0;
+ nonExistingMethodCount = 0;
+
+
+ /** SelfExtendingClass tests. **/
+
+ /* Try the direct countHits method first. No resolving or
+ forwarding should be triggered. */
+ if ([SelfExtendingClass countHits] != 1)
+ abort ();
+
+ if (resolveInstanceMethodCount != 0)
+ abort ();
+
+ if (forwardingCount != 0)
+ abort ();
+
+ if (nonExistingMethodCount != 0)
+ abort ();
+
+ /* Now, try calling a non-existing count method; it should be
+ installed and invoked. */
+ if ([object2 nonExistingCountHitsMethod] != 2)
+ abort ();
+
+ if (resolveInstanceMethodCount != 1)
+ abort ();
+
+ if (forwardingCount != 0)
+ abort ();
+
+ if (nonExistingMethodCount != 0)
+ abort ();
+
+ /* Try it again. The method has now been installed, so it should
+ be used and work, but with no additional resolving
+ involved. */
+ if ([object2 nonExistingCountHitsMethod] != 3)
+ abort ();
+
+ if (resolveInstanceMethodCount != 1)
+ abort ();
+
+ if (forwardingCount != 0)
+ abort ();
+
+ if (nonExistingMethodCount != 0)
+ abort ();
+
+ /* Now try the same tests with class_getInstanceMethod(). */
+ m = class_getInstanceMethod (objc_getClass ("SelfExtendingClass"),
+ @selector (nonExistingCountHitsMethod2));
+ if (resolveInstanceMethodCount != 2)
+ abort ();
+
+ if (forwardingCount != 0)
+ abort ();
+
+ if (nonExistingMethodCount != 0)
+ abort ();
+
+ /* Try it again. The method has now been installed, so it should
+ be used and work, but with no additional resolving
+ involved. */
+ if ([object2 nonExistingCountHitsMethod2] != 4)
+ abort ();
+
+ if (resolveInstanceMethodCount != 2)
+ abort ();
+
+ if (forwardingCount != 0)
+ abort ();
+
+ if (nonExistingMethodCount != 0)
+ abort ();
+
+
+ /* Now try the same tests with class_getMethodImplementation(). */
+ i = class_getMethodImplementation (objc_getClass ("SelfExtendingClass"),
+ @selector (nonExistingCountHitsMethod3));
+ if (resolveInstanceMethodCount != 3)
+ abort ();
+
+ if (forwardingCount != 0)
+ abort ();
+
+ if (nonExistingMethodCount != 0)
+ abort ();
+
+ /* Try it again. The method has now been installed, so it should
+ be used and work, but with no additional resolving
+ involved. */
+ if ([object2 nonExistingCountHitsMethod3] != 5)
+ abort ();
+
+ if (resolveInstanceMethodCount != 3)
+ abort ();
+
+ if (forwardingCount != 0)
+ abort ();
+
+ if (nonExistingMethodCount != 0)
+ abort ();
+ }
+
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/gnu-api-2-sel.m b/gcc/testsuite/objc.dg/gnu-api-2-sel.m
new file mode 100644
index 000000000..b71fdfab4
--- /dev/null
+++ b/gcc/testsuite/objc.dg/gnu-api-2-sel.m
@@ -0,0 +1,209 @@
+/* Test the Modern GNU Objective-C Runtime API.
+
+ This is test 'sel', covering all functions starting with 'sel'. */
+
+/* { dg-do run } */
+/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */
+
+/* To get the modern GNU Objective-C Runtime API, you include
+ objc/runtime.h. */
+#include <objc/runtime.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+@interface MyRootClass
+{ Class isa; }
++ alloc;
+- init;
++ initialize;
+@end
+
+@implementation MyRootClass
++ alloc { return class_createInstance (self, 0); }
+- init { return self; }
++ initialize { return self; }
+@end
+
+@protocol MyProtocol
+- (id) variable;
+@end
+
+@protocol MySecondProtocol
+- (id) setVariable: (id)value;
+@end
+
+@interface MySubClass : MyRootClass <MyProtocol>
+{ id variable_ivar; }
+- (void) setVariable: (id)value;
+- (id) variable;
+- (void) method;
+@end
+
+@implementation MySubClass
+- (void) setVariable: (id)value { variable_ivar = value; }
+- (id) variable { return variable_ivar; }
+- (void) method { return; }
+@end
+
+@interface ClassA : MyRootClass
+- (id) conflictingSelectorMethod;
+@end
+
+@implementation ClassA
+- (id) conflictingSelectorMethod { return nil; }
+@end
+
+@interface ClassB : MyRootClass
+- (void) conflictingSelectorMethod;
+@end
+
+@implementation ClassB
+- (void) conflictingSelectorMethod { return; }
+@end
+
+int main(int argc, void **args)
+{
+ /* Functions are tested in alphabetical order. */
+
+#ifdef __GNU_LIBOBJC__
+ printf ("Testing sel_copyTypedSelectorList ()...\n");
+ {
+ unsigned int count;
+ SEL * list = sel_copyTypedSelectorList ("method", &count);
+
+ /* There should only be two, since 'method' is referenced twice,
+ once with types and once without (in this very test). */
+ if (count != 2)
+ abort ();
+
+ /* Check that both selectors are not-NULL, and have the correct
+ name. We use @selector() here, which wouldn't really be
+ needed, just to register a second, untyped selector with name
+ 'method'. */
+ if (strcmp (sel_getName (list[0]), sel_getName (@selector (method))) != 0)
+ abort ();
+
+ if (strcmp (sel_getName (list[1]), sel_getName (@selector (method))) != 0)
+ abort ();
+
+ if (list[2] != NULL)
+ abort ();
+ }
+#endif
+
+ printf ("Testing sel_getName () ...\n");
+ {
+ if (strcmp (sel_getName (@selector (variable)), "variable") != 0)
+ abort ();
+
+ if (strcmp (sel_getName (NULL), "<null selector>") != 0)
+ abort ();
+ }
+
+#ifdef __GNU_LIBOBJC__
+ printf ("Testing sel_getTypeEncoding () ...\n");
+ {
+ /* Get a selector from a real class, so it has interesting
+ types. */
+ Method method = class_getInstanceMethod (objc_getClass ("MySubClass"),
+ @selector (variable));
+
+ if (strcmp (sel_getTypeEncoding (method_getName (method)),
+ method_getTypeEncoding (method)) != 0)
+ abort ();
+
+ if (sel_getTypeEncoding (NULL) != NULL)
+ abort ();
+ }
+#endif
+
+#ifdef __GNU_LIBOBJC__
+ printf ("Testing sel_getTypedSelector () ...\n");
+ {
+ /* First try with a selector where we know that a typed one has
+ been registered. */
+ SEL selector = sel_getTypedSelector ("variable");
+
+ if (selector == NULL)
+ abort ();
+
+ if (sel_getTypeEncoding (selector) == NULL)
+ abort ();
+
+ /* Now try a selector which was never registered. */
+ selector = sel_getTypedSelector ("not_registered");
+
+ if (selector != NULL)
+ abort ();
+
+ /* Now try registering a selector with no types. The following
+ line is just a way to have an unused '@selector()' expression
+ without the compiler complaining. */
+ if (@selector (registered_with_no_types) == NULL)
+ abort ();
+
+ /* Try getting it. Nothing should be returned because it is
+ untyped. */
+ selector = sel_getTypedSelector ("registered_with_no_types");
+
+ if (selector != NULL)
+ abort ();
+
+ /* Now try a selector with multiple, conflicting types. NULL
+ should be returned. */
+ selector = sel_getTypedSelector ("conflictingSelectorMethod");
+
+ if (selector != NULL)
+ abort ();
+ }
+#endif
+
+ printf ("Testing sel_getUid () ...\n");
+ {
+ if (strcmp (sel_getName (sel_getUid ("myMethod")), "myMethod") != 0)
+ abort ();
+
+ if (sel_getUid (NULL) != NULL)
+ abort ();
+ }
+
+ printf ("Testing sel_isEqual () ...\n");
+ {
+ if (! sel_isEqual (@selector (setVariable:), @selector (setVariable:)))
+ abort ();
+ }
+
+ printf ("Testing sel_registerName () ...\n");
+ {
+ if (strcmp (sel_getName (sel_registerName ("myMethod")), "myMethod") != 0)
+ abort ();
+
+ if (sel_registerName (NULL) != NULL)
+ abort ();
+ }
+
+#ifdef __GNU_LIBOBJC__
+ printf ("Testing set_registerTypedName () ...\n");
+ {
+ const char *types = method_getTypeEncoding (class_getInstanceMethod
+ (objc_getClass ("MySubClass"),
+ @selector (variable)));
+ SEL selector = sel_registerTypedName ("aMethod", types);
+
+ if (strcmp (sel_getName (selector), "aMethod") != 0)
+ abort ();
+
+ if (strcmp (sel_getTypeEncoding (selector), types) != 0)
+ abort ();
+
+ if (sel_registerTypedName (NULL, NULL) != NULL)
+ abort ();
+
+ if (sel_registerTypedName (NULL, types) != NULL)
+ abort ();
+ }
+#endif
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/gnu-encoding/compat-common.h b/gcc/testsuite/objc.dg/gnu-encoding/compat-common.h
new file mode 100644
index 000000000..635e7446d
--- /dev/null
+++ b/gcc/testsuite/objc.dg/gnu-encoding/compat-common.h
@@ -0,0 +1,43 @@
+/* Several of the binary compatibility tests use these macros to
+ allow debugging the test or tracking down a failure by getting an
+ indication of whether each individual check passed or failed.
+ When DBG is defined, each check is shown by a dot (pass) or 'F'
+ (fail) rather than aborting as soon as a failure is detected. */
+
+#ifdef DBG
+#include <stdio.h>
+#define DEBUG_INIT setbuf (stdout, NULL);
+#define DEBUG_FPUTS(x) fputs (x, stdout)
+#define DEBUG_DOT putc ('.', stdout)
+#define DEBUG_NL putc ('\n', stdout)
+#define DEBUG_FAIL putc ('F', stdout); fails++
+#define DEBUG_CHECK { DEBUG_FAIL; } else { DEBUG_DOT; }
+#define DEBUG_FINI if (fails) DEBUG_FPUTS ("failed\n"); \
+ else DEBUG_FPUTS ("passed\n");
+#else
+#define DEBUG_INIT
+#define DEBUG_FPUTS(x)
+#define DEBUG_DOT
+#define DEBUG_NL
+#define DEBUG_FAIL abort ()
+#define DEBUG_CHECK abort ();
+#define DEBUG_FINI
+#endif
+
+#ifdef __GNUC__
+#define CINT(x, y) (x + y * __extension__ 1i)
+#define CDBL(x, y) (x + y * __extension__ 1i)
+#else
+#ifdef __SUNPRO_C
+/* ??? Complex support without <complex.h>. */
+#else
+#include <complex.h>
+#endif
+#ifndef SKIP_COMPLEX_INT
+#define CINT(x, y) ((_Complex int) (x + y * _Complex_I))
+#endif
+#define CDBL(x, y) (x + y * _Complex_I)
+#endif
+
+extern void abort (void);
+extern int fails;
diff --git a/gcc/testsuite/objc.dg/gnu-encoding/generate-random.c b/gcc/testsuite/objc.dg/gnu-encoding/generate-random.c
new file mode 100644
index 000000000..c4b06db67
--- /dev/null
+++ b/gcc/testsuite/objc.dg/gnu-encoding/generate-random.c
@@ -0,0 +1,265 @@
+/* Copyright (C) 1995, 2004 Free Software Foundation
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA. */
+
+/*
+ * This is derived from the Berkeley source:
+ * @(#)random.c 5.5 (Berkeley) 7/6/88
+ * It was reworked for the GNU C Library by Roland McGrath.
+ * Rewritten to use reentrant functions by Ulrich Drepper, 1995.
+ */
+
+/*
+ Copyright (C) 1983 Regents of the University of California.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 4. Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.*/
+
+#include <limits.h>
+#include <stdlib.h>
+#include "generate-random.h"
+
+
+/* An improved random number generation package. In addition to the standard
+ rand()/srand() like interface, this package also has a special state info
+ interface. The initstate() routine is called with a seed, an array of
+ bytes, and a count of how many bytes are being passed in; this array is
+ then initialized to contain information for random number generation with
+ that much state information. Good sizes for the amount of state
+ information are 32, 64, 128, and 256 bytes. The state can be switched by
+ calling the setstate() function with the same array as was initialized
+ with initstate(). By default, the package runs with 128 bytes of state
+ information and generates far better random numbers than a linear
+ congruential generator. If the amount of state information is less than
+ 32 bytes, a simple linear congruential R.N.G. is used. Internally, the
+ state information is treated as an array of longs; the zeroth element of
+ the array is the type of R.N.G. being used (small integer); the remainder
+ of the array is the state information for the R.N.G. Thus, 32 bytes of
+ state information will give 7 longs worth of state information, which will
+ allow a degree seven polynomial. (Note: The zeroth word of state
+ information also has some other information stored in it; see setstate
+ for details). The random number generation technique is a linear feedback
+ shift register approach, employing trinomials (since there are fewer terms
+ to sum up that way). In this approach, the least significant bit of all
+ the numbers in the state table will act as a linear feedback shift register,
+ and will have period 2^deg - 1 (where deg is the degree of the polynomial
+ being used, assuming that the polynomial is irreducible and primitive).
+ The higher order bits will have longer periods, since their values are
+ also influenced by pseudo-random carries out of the lower bits. The
+ total period of the generator is approximately deg*(2**deg - 1); thus
+ doubling the amount of state information has a vast influence on the
+ period of the generator. Note: The deg*(2**deg - 1) is an approximation
+ only good for large deg, when the period of the shift register is the
+ dominant factor. With deg equal to seven, the period is actually much
+ longer than the 7*(2**7 - 1) predicted by this formula. */
+
+
+
+/* For each of the currently supported random number generators, we have a
+ break value on the amount of state information (you need at least this many
+ bytes of state info to support this random number generator), a degree for
+ the polynomial (actually a trinomial) that the R.N.G. is based on, and
+ separation between the two lower order coefficients of the trinomial. */
+
+/* Linear congruential. */
+#define TYPE_0 0
+#define BREAK_0 8
+#define DEG_0 0
+#define SEP_0 0
+
+/* x**7 + x**3 + 1. */
+#define TYPE_1 1
+#define BREAK_1 32
+#define DEG_1 7
+#define SEP_1 3
+
+/* x**15 + x + 1. */
+#define TYPE_2 2
+#define BREAK_2 64
+#define DEG_2 15
+#define SEP_2 1
+
+/* x**31 + x**3 + 1. */
+#define TYPE_3 3
+#define BREAK_3 128
+#define DEG_3 31
+#define SEP_3 3
+
+/* x**63 + x + 1. */
+#define TYPE_4 4
+#define BREAK_4 256
+#define DEG_4 63
+#define SEP_4 1
+
+
+/* Array versions of the above information to make code run faster.
+ Relies on fact that TYPE_i == i. */
+
+#define MAX_TYPES 5 /* Max number of types above. */
+
+
+/* Initially, everything is set up as if from:
+ initstate(1, randtbl, 128);
+ Note that this initialization takes advantage of the fact that srandom
+ advances the front and rear pointers 10*rand_deg times, and hence the
+ rear pointer which starts at 0 will also end up at zero; thus the zeroth
+ element of the state information, which contains info about the current
+ position of the rear pointer is just
+ (MAX_TYPES * (rptr - state)) + TYPE_3 == TYPE_3. */
+
+static int randtbl[DEG_3 + 1] =
+ {
+ TYPE_3,
+
+ -1726662223, 379960547, 1735697613, 1040273694, 1313901226,
+ 1627687941, -179304937, -2073333483, 1780058412, -1989503057,
+ -615974602, 344556628, 939512070, -1249116260, 1507946756,
+ -812545463, 154635395, 1388815473, -1926676823, 525320961,
+ -1009028674, 968117788, -123449607, 1284210865, 435012392,
+ -2017506339, -911064859, -370259173, 1132637927, 1398500161,
+ -205601318,
+ };
+
+
+static struct generate_random_data unsafe_state =
+ {
+/* FPTR and RPTR are two pointers into the state info, a front and a rear
+ pointer. These two pointers are always rand_sep places aparts, as they
+ cycle through the state information. (Yes, this does mean we could get
+ away with just one pointer, but the code for random is more efficient
+ this way). The pointers are left positioned as they would be from the call:
+ initstate(1, randtbl, 128);
+ (The position of the rear pointer, rptr, is really 0 (as explained above
+ in the initialization of randtbl) because the state table pointer is set
+ to point to randtbl[1] (as explained below).) */
+
+ &randtbl[SEP_3 + 1], /* fptr */
+ &randtbl[1], /* rptr */
+
+/* The following things are the pointer to the state information table,
+ the type of the current generator, the degree of the current polynomial
+ being used, and the separation between the two pointers.
+ Note that for efficiency of random, we remember the first location of
+ the state information, not the zeroth. Hence it is valid to access
+ state[-1], which is used to store the type of the R.N.G.
+ Also, we remember the last location, since this is more efficient than
+ indexing every time to find the address of the last element to see if
+ the front and rear pointers have wrapped. */
+
+ &randtbl[1], /* state */
+
+ TYPE_3, /* rand_type */
+ DEG_3, /* rand_deg */
+ SEP_3, /* rand_sep */
+
+ &randtbl[sizeof (randtbl) / sizeof (randtbl[0])] /* end_ptr */
+};
+
+/* Initialize the random number generator based on the given seed. If the
+ type is the trivial no-state-information type, just remember the seed.
+ Otherwise, initializes state[] based on the given "seed" via a linear
+ congruential generator. Then, the pointers are set to known locations
+ that are exactly rand_sep places apart. Lastly, it cycles the state
+ information a given number of times to get rid of any initial dependencies
+ introduced by the L.C.R.N.G. Note that the initialization of randtbl[]
+ for default usage relies on values produced by this routine. */
+void
+generate_srandom (unsigned int x)
+{
+ (void) generate_srandom_r (x, &unsafe_state);
+}
+
+/* Initialize the state information in the given array of N bytes for
+ future random number generation. Based on the number of bytes we
+ are given, and the break values for the different R.N.G.'s, we choose
+ the best (largest) one we can and set things up for it. srandom is
+ then called to initialize the state information. Note that on return
+ from srandom, we set state[-1] to be the type multiplexed with the current
+ value of the rear pointer; this is so successive calls to initstate won't
+ lose this information and will be able to restart with setstate.
+ Note: The first thing we do is save the current state, if any, just like
+ setstate so that it doesn't matter when initstate is called.
+ Returns a pointer to the old state. */
+char *
+generate_initstate (unsigned int seed, char *arg_state, size_t n)
+{
+ int *ostate;
+
+ ostate = &unsafe_state.state[-1];
+ generate_initstate_r (seed, arg_state, n, &unsafe_state);
+ return (char *) ostate;
+}
+
+/* Restore the state from the given state array.
+ Note: It is important that we also remember the locations of the pointers
+ in the current state information, and restore the locations of the pointers
+ from the old state information. This is done by multiplexing the pointer
+ location into the zeroth word of the state information. Note that due
+ to the order in which things are done, it is OK to call setstate with the
+ same state as the current state
+ Returns a pointer to the old state information. */
+char *
+generate_setstate (char *arg_state)
+{
+ int *ostate;
+
+ ostate = &unsafe_state.state[-1];
+ if (generate_setstate_r (arg_state, &unsafe_state) < 0)
+ ostate = NULL;
+ return (char *) ostate;
+}
+
+/* If we are using the trivial TYPE_0 R.N.G., just do the old linear
+ congruential bit. Otherwise, we do our fancy trinomial stuff, which is the
+ same in all the other cases due to all the global variables that have been
+ set up. The basic operation is to add the number at the rear pointer into
+ the one at the front pointer. Then both pointers are advanced to the next
+ location cyclically in the table. The value returned is the sum generated,
+ reduced to 31 bits by throwing away the "least random" low bit.
+ Note: The code takes advantage of the fact that both the front and
+ rear pointers can't wrap on the same call by not testing the rear
+ pointer if the front one has wrapped. Returns a 31-bit random number. */
+
+long int
+generate_random (void)
+{
+ int retval;
+ (void) generate_random_r (&unsafe_state, &retval);
+ return retval;
+}
diff --git a/gcc/testsuite/objc.dg/gnu-encoding/generate-random.h b/gcc/testsuite/objc.dg/gnu-encoding/generate-random.h
new file mode 100644
index 000000000..e14f526bb
--- /dev/null
+++ b/gcc/testsuite/objc.dg/gnu-encoding/generate-random.h
@@ -0,0 +1,33 @@
+/* Copyright (C) 2004 Free Software Foundation
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA. */
+
+struct generate_random_data
+ {
+ int *fptr, *rptr, *state;
+ int rand_type, rand_deg, rand_sep;
+ int *end_ptr;
+ };
+
+extern void generate_srandom (unsigned int);
+extern char *generate_initstate (unsigned int, char *, size_t);
+extern char *generate_setstate (char *);
+extern long int generate_random (void);
+extern int generate_random_r (struct generate_random_data *, int *);
+extern int generate_srandom_r (unsigned int, struct generate_random_data *);
+extern int generate_initstate_r (unsigned int, char *, size_t,
+ struct generate_random_data *);
+extern int generate_setstate_r (char *, struct generate_random_data *);
diff --git a/gcc/testsuite/objc.dg/gnu-encoding/generate-random_r.c b/gcc/testsuite/objc.dg/gnu-encoding/generate-random_r.c
new file mode 100644
index 000000000..6e83f3596
--- /dev/null
+++ b/gcc/testsuite/objc.dg/gnu-encoding/generate-random_r.c
@@ -0,0 +1,385 @@
+/*
+ Copyright (C) 1995, 2004 Free Software Foundation
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA. */
+
+/*
+ Copyright (C) 1983 Regents of the University of California.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 4. Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.*/
+
+/*
+ * This is derived from the Berkeley source:
+ * @(#)random.c 5.5 (Berkeley) 7/6/88
+ * It was reworked for the GNU C Library by Roland McGrath.
+ * Rewritten to be reentrant by Ulrich Drepper, 1995
+ */
+
+#include <limits.h>
+#include <stdlib.h>
+#include "generate-random.h"
+
+
+/* An improved random number generation package. In addition to the standard
+ rand()/srand() like interface, this package also has a special state info
+ interface. The initstate() routine is called with a seed, an array of
+ bytes, and a count of how many bytes are being passed in; this array is
+ then initialized to contain information for random number generation with
+ that much state information. Good sizes for the amount of state
+ information are 32, 64, 128, and 256 bytes. The state can be switched by
+ calling the setstate() function with the same array as was initialized
+ with initstate(). By default, the package runs with 128 bytes of state
+ information and generates far better random numbers than a linear
+ congruential generator. If the amount of state information is less than
+ 32 bytes, a simple linear congruential R.N.G. is used. Internally, the
+ state information is treated as an array of longs; the zeroth element of
+ the array is the type of R.N.G. being used (small integer); the remainder
+ of the array is the state information for the R.N.G. Thus, 32 bytes of
+ state information will give 7 longs worth of state information, which will
+ allow a degree seven polynomial. (Note: The zeroth word of state
+ information also has some other information stored in it; see setstate
+ for details). The random number generation technique is a linear feedback
+ shift register approach, employing trinomials (since there are fewer terms
+ to sum up that way). In this approach, the least significant bit of all
+ the numbers in the state table will act as a linear feedback shift register,
+ and will have period 2^deg - 1 (where deg is the degree of the polynomial
+ being used, assuming that the polynomial is irreducible and primitive).
+ The higher order bits will have longer periods, since their values are
+ also influenced by pseudo-random carries out of the lower bits. The
+ total period of the generator is approximately deg*(2**deg - 1); thus
+ doubling the amount of state information has a vast influence on the
+ period of the generator. Note: The deg*(2**deg - 1) is an approximation
+ only good for large deg, when the period of the shift register is the
+ dominant factor. With deg equal to seven, the period is actually much
+ longer than the 7*(2**7 - 1) predicted by this formula. */
+
+
+
+/* For each of the currently supported random number generators, we have a
+ break value on the amount of state information (you need at least this many
+ bytes of state info to support this random number generator), a degree for
+ the polynomial (actually a trinomial) that the R.N.G. is based on, and
+ separation between the two lower order coefficients of the trinomial. */
+
+/* Linear congruential. */
+#define TYPE_0 0
+#define BREAK_0 8
+#define DEG_0 0
+#define SEP_0 0
+
+/* x**7 + x**3 + 1. */
+#define TYPE_1 1
+#define BREAK_1 32
+#define DEG_1 7
+#define SEP_1 3
+
+/* x**15 + x + 1. */
+#define TYPE_2 2
+#define BREAK_2 64
+#define DEG_2 15
+#define SEP_2 1
+
+/* x**31 + x**3 + 1. */
+#define TYPE_3 3
+#define BREAK_3 128
+#define DEG_3 31
+#define SEP_3 3
+
+/* x**63 + x + 1. */
+#define TYPE_4 4
+#define BREAK_4 256
+#define DEG_4 63
+#define SEP_4 1
+
+
+/* Array versions of the above information to make code run faster.
+ Relies on fact that TYPE_i == i. */
+
+#define MAX_TYPES 5 /* Max number of types above. */
+
+struct random_poly_info
+{
+ int seps[MAX_TYPES];
+ int degrees[MAX_TYPES];
+};
+
+static const struct random_poly_info random_poly_info =
+{
+ { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 },
+ { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 }
+};
+
+
+
+
+/* Initialize the random number generator based on the given seed. If the
+ type is the trivial no-state-information type, just remember the seed.
+ Otherwise, initializes state[] based on the given "seed" via a linear
+ congruential generator. Then, the pointers are set to known locations
+ that are exactly rand_sep places apart. Lastly, it cycles the state
+ information a given number of times to get rid of any initial dependencies
+ introduced by the L.C.R.N.G. Note that the initialization of randtbl[]
+ for default usage relies on values produced by this routine. */
+int
+generate_srandom_r (unsigned int seed, struct generate_random_data *buf)
+{
+ int type;
+ int *state;
+ long int i;
+ long int word;
+ int *dst;
+ int kc;
+
+ if (buf == NULL)
+ goto fail;
+ type = buf->rand_type;
+ if ((unsigned int) type >= MAX_TYPES)
+ goto fail;
+
+ state = buf->state;
+ /* We must make sure the seed is not 0. Take arbitrarily 1 in this case. */
+ if (seed == 0)
+ seed = 1;
+ state[0] = seed;
+ if (type == TYPE_0)
+ goto done;
+
+ dst = state;
+ word = seed;
+ kc = buf->rand_deg;
+ for (i = 1; i < kc; ++i)
+ {
+ /* This does:
+ state[i] = (16807 * state[i - 1]) % 2147483647;
+ but avoids overflowing 31 bits. */
+ long int hi = word / 127773;
+ long int lo = word % 127773;
+ word = 16807 * lo - 2836 * hi;
+ if (word < 0)
+ word += 2147483647;
+ *++dst = word;
+ }
+
+ buf->fptr = &state[buf->rand_sep];
+ buf->rptr = &state[0];
+ kc *= 10;
+ while (--kc >= 0)
+ {
+ int discard;
+ (void) generate_random_r (buf, &discard);
+ }
+
+ done:
+ return 0;
+
+ fail:
+ return -1;
+}
+
+/* Initialize the state information in the given array of N bytes for
+ future random number generation. Based on the number of bytes we
+ are given, and the break values for the different R.N.G.'s, we choose
+ the best (largest) one we can and set things up for it. srandom is
+ then called to initialize the state information. Note that on return
+ from srandom, we set state[-1] to be the type multiplexed with the current
+ value of the rear pointer; this is so successive calls to initstate won't
+ lose this information and will be able to restart with setstate.
+ Note: The first thing we do is save the current state, if any, just like
+ setstate so that it doesn't matter when initstate is called.
+ Returns a pointer to the old state. */
+int
+generate_initstate_r (unsigned int seed, char *arg_state, size_t n,
+ struct generate_random_data *buf)
+{
+ int type;
+ int degree;
+ int separation;
+ int *state;
+
+ if (buf == NULL)
+ goto fail;
+
+ if (n >= BREAK_3)
+ type = n < BREAK_4 ? TYPE_3 : TYPE_4;
+ else if (n < BREAK_1)
+ {
+ if (n < BREAK_0)
+ {
+ goto fail;
+ }
+ type = TYPE_0;
+ }
+ else
+ type = n < BREAK_2 ? TYPE_1 : TYPE_2;
+
+ degree = random_poly_info.degrees[type];
+ separation = random_poly_info.seps[type];
+
+ buf->rand_type = type;
+ buf->rand_sep = separation;
+ buf->rand_deg = degree;
+ state = &((int *) arg_state)[1]; /* First location. */
+ /* Must set END_PTR before srandom. */
+ buf->end_ptr = &state[degree];
+
+ buf->state = state;
+
+ generate_srandom_r (seed, buf);
+
+ state[-1] = TYPE_0;
+ if (type != TYPE_0)
+ state[-1] = (buf->rptr - state) * MAX_TYPES + type;
+
+ return 0;
+
+ fail:
+ return -1;
+}
+
+/* Restore the state from the given state array.
+ Note: It is important that we also remember the locations of the pointers
+ in the current state information, and restore the locations of the pointers
+ from the old state information. This is done by multiplexing the pointer
+ location into the zeroth word of the state information. Note that due
+ to the order in which things are done, it is OK to call setstate with the
+ same state as the current state
+ Returns a pointer to the old state information. */
+int
+generate_setstate_r (char *arg_state, struct generate_random_data *buf)
+{
+ int *new_state = 1 + (int *) arg_state;
+ int type;
+ int old_type;
+ int *old_state;
+ int degree;
+ int separation;
+
+ if (arg_state == NULL || buf == NULL)
+ goto fail;
+
+ old_type = buf->rand_type;
+ old_state = buf->state;
+ if (old_type == TYPE_0)
+ old_state[-1] = TYPE_0;
+ else
+ old_state[-1] = (MAX_TYPES * (buf->rptr - old_state)) + old_type;
+
+ type = new_state[-1] % MAX_TYPES;
+ if (type < TYPE_0 || type > TYPE_4)
+ goto fail;
+
+ buf->rand_deg = degree = random_poly_info.degrees[type];
+ buf->rand_sep = separation = random_poly_info.seps[type];
+ buf->rand_type = type;
+
+ if (type != TYPE_0)
+ {
+ int rear = new_state[-1] / MAX_TYPES;
+ buf->rptr = &new_state[rear];
+ buf->fptr = &new_state[(rear + separation) % degree];
+ }
+ buf->state = new_state;
+ /* Set end_ptr too. */
+ buf->end_ptr = &new_state[degree];
+
+ return 0;
+
+ fail:
+ return -1;
+}
+
+/* If we are using the trivial TYPE_0 R.N.G., just do the old linear
+ congruential bit. Otherwise, we do our fancy trinomial stuff, which is the
+ same in all the other cases due to all the global variables that have been
+ set up. The basic operation is to add the number at the rear pointer into
+ the one at the front pointer. Then both pointers are advanced to the next
+ location cyclically in the table. The value returned is the sum generated,
+ reduced to 31 bits by throwing away the "least random" low bit.
+ Note: The code takes advantage of the fact that both the front and
+ rear pointers can't wrap on the same call by not testing the rear
+ pointer if the front one has wrapped. Returns a 31-bit random number. */
+
+int
+generate_random_r (struct generate_random_data *buf, int *result)
+{
+ int *state;
+
+ if (buf == NULL || result == NULL)
+ goto fail;
+
+ state = buf->state;
+
+ if (buf->rand_type == TYPE_0)
+ {
+ int val = state[0];
+ val = ((state[0] * 1103515245) + 12345) & 0x7fffffff;
+ state[0] = val;
+ *result = val;
+ }
+ else
+ {
+ int *fptr = buf->fptr;
+ int *rptr = buf->rptr;
+ int *end_ptr = buf->end_ptr;
+ int val;
+
+ val = *fptr += *rptr;
+ /* Chucking least random bit. */
+ *result = (val >> 1) & 0x7fffffff;
+ ++fptr;
+ if (fptr >= end_ptr)
+ {
+ fptr = state;
+ ++rptr;
+ }
+ else
+ {
+ ++rptr;
+ if (rptr >= end_ptr)
+ rptr = state;
+ }
+ buf->fptr = fptr;
+ buf->rptr = rptr;
+ }
+ return 0;
+
+ fail:
+ return -1;
+}
diff --git a/gcc/testsuite/objc.dg/gnu-encoding/gnu-encoding.exp b/gcc/testsuite/objc.dg/gnu-encoding/gnu-encoding.exp
new file mode 100644
index 000000000..b137b751a
--- /dev/null
+++ b/gcc/testsuite/objc.dg/gnu-encoding/gnu-encoding.exp
@@ -0,0 +1,77 @@
+# GCC Objective-C testsuite that uses the `dg.exp' driver.
+# Copyright (C) 1997, 2001, 2007, 2008 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 GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+# Load support procs.
+load_lib objc-dg.exp
+load_lib target-libpath.exp
+
+# If a testcase doesn't have special options, use these.
+global DEFAULT_CFLAGS
+if ![info exists DEFAULT_CFLAGS] then {
+ set DEFAULT_CFLAGS "-fgnu-runtime"
+}
+
+# Initialize `dg'.
+dg-init
+
+#
+# gnu-encoding tests
+#
+set tstobjdir "$tmpdir/objc.dg-struct-layout-encoding-1"
+set generator "$tmpdir/objc.dg-struct-layout-encoding-1_generate"
+
+set generator_src "$srcdir/$subdir/struct-layout-encoding-1_generate.c"
+set generator_src "$generator_src $srcdir/$subdir/generate-random.c"
+set generator_src "$generator_src $srcdir/$subdir/generate-random_r.c"
+set generator_cmd "-o $generator $generator_src"
+# Temporarily switch to the environment of the host compiler.
+restore_ld_library_path_env_vars
+set status [remote_exec build "$HOSTCC $HOSTCFLAGS $generator_cmd"]
+set status [lindex $status 0]
+set_ld_library_path_env_vars
+if { $status == 0 } then {
+ file delete -force $tstobjdir
+ file mkdir $tstobjdir
+ set generator_args "-s $srcdir/$subdir -d $tstobjdir"
+# set generator_args "$generator_args -n 15000"
+ set status [remote_exec host "$generator $generator_args"]
+ set status [lindex $status 0]
+ if { $status == 0 } then {
+ foreach src [lsort [find $tstobjdir *_main.m]] {
+ # If we're only testing specific files and this isn't one
+ # of them, skip it.
+ if ![runtest_file_p $runtests $src] then {
+ continue
+ }
+
+ dg-runtest $src "" $DEFAULT_CFLAGS
+ }
+ } else {
+ warning "Could not execute objc.dg/gnu-encoding/struct-layout-encoding-1 generator"
+ }
+} else {
+ warning "Could not compile objc.dg/gnu-encoding/struct-layout-encoding-1 generator"
+}
+
+
+
+
+
+
+# All done.
+dg-finish
+
diff --git a/gcc/testsuite/objc.dg/gnu-encoding/struct-layout-1.h b/gcc/testsuite/objc.dg/gnu-encoding/struct-layout-1.h
new file mode 100644
index 000000000..e165e203a
--- /dev/null
+++ b/gcc/testsuite/objc.dg/gnu-encoding/struct-layout-1.h
@@ -0,0 +1,704 @@
+#include <limits.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "compat-common.h"
+
+#ifndef SKIP_ATTRIBUTE
+# include "vector-defs.h"
+#else
+typedef int qi;
+typedef int hi;
+typedef int si;
+typedef int di;
+typedef float sf;
+typedef float df;
+typedef int v8qi;
+typedef int v16qi;
+typedef int v2hi;
+typedef int v4hi;
+typedef int v8hi;
+typedef int v2si;
+typedef int v4si;
+typedef int v1di;
+typedef int v2di;
+typedef int v2sf;
+typedef int v4sf;
+typedef int v16sf;
+typedef int v2df;
+typedef int u8qi;
+typedef int u16qi;
+typedef int u2hi;
+typedef int u4hi;
+typedef int u8hi;
+typedef int u2si;
+typedef int u4si;
+typedef int u1di;
+typedef int u2di;
+typedef int u2sf;
+typedef int u4sf;
+typedef int u16sf;
+typedef int u2df;
+#endif
+#if (defined __i386__ || defined __x86_64__) && !defined SKIP_ATTRIBUTE
+# ifdef __MMX__
+# include <mmintrin.h>
+# else
+typedef int __m64;
+# endif
+# ifdef __SSE__
+# include <xmmintrin.h>
+# else
+typedef int __m128;
+# endif
+#else
+typedef int __m64;
+typedef int __m128;
+#endif
+
+#define FLDS_MAX 32
+extern struct Info
+{
+ int nfields, nbitfields;
+ void *sp, *a0p, *a3p;
+ void *flds[FLDS_MAX];
+ size_t sz, sizes[FLDS_MAX];
+ size_t als, ala0, ala3, aligns[FLDS_MAX];
+} info;
+
+extern int intarray[256];
+extern int fn0 (void), fn1 (void), fn2 (void), fn3 (void), fn4 (void);
+extern int fn5 (void), fn6 (void), fn7 (void), fn8 (void), fn9 (void);
+
+#ifdef DBG
+#define FAIL(n, m) printf ("fail %d.%d\n", n, m), ++fails
+#else
+#define FAIL(n, m) ++fails
+#endif
+
+#ifdef SKIP_ATTRIBUTE
+# define __attribute__(x)
+#endif
+#define atal __attribute__((aligned))
+#define atpa __attribute__((packed))
+#define atalpa __attribute__((aligned, packed))
+#define atpaal __attribute__((packed, aligned))
+#define atal1 __attribute__((aligned (1)))
+#define atal2 __attribute__((aligned (2)))
+#define atal4 __attribute__((aligned (4)))
+#define atal8 __attribute__((aligned (8)))
+#define atal16 __attribute__((aligned (16)))
+#define atal1pa __attribute__((aligned (1), packed))
+#define atal2pa __attribute__((aligned (2), packed))
+#define atal4pa __attribute__((aligned (4), packed))
+#define atal8pa __attribute__((aligned (8), packed))
+#define atal16pa __attribute__((aligned (16), packed))
+#define atpaal1 __attribute__((packed, aligned (1)))
+#define atpaal2 __attribute__((packed, aligned (2)))
+#define atpaal4 __attribute__((packed, aligned (4)))
+#define atpaal8 __attribute__((packed, aligned (8)))
+#define atpaal16 __attribute__((packed, aligned (16)))
+
+#if UCHAR_MAX == 255 && USHORT_MAX == 65535 && UINT_MAX == 4294967295U \
+ && ULLONG_MAX == 18446744073709551615ULL
+/* For ILP32 and LP64 targets, assume float is at least 32-bit
+ and double plus long double at least 64-bit. */
+# define atalx1 atal1
+# define atalx2 atal2
+# define atalx4 atal4
+# define atalx8 atal8
+# define atalx16 atal16
+# define atalx1pa atal1pa
+# define atalx2pa atal2pa
+# define atalx4pa atal4pa
+# define atalx8pa atal8pa
+# define atalx16pa atal16pa
+# define atpaalx1 atpaal1
+# define atpaalx2 atpaal2
+# define atpaalx4 atpaal4
+# define atpaalx8 atpaal8
+# define atpaalx16 atpaal16
+# if ULONG_MAX > 4294967295UL
+# define ataly8 atal8
+# define ataly8pa atal8pa
+# define atpaaly8 atpaal8
+# define ataly16 atal16
+# define ataly16pa atal16pa
+# define atpaaly16 atpaal16
+# else
+# define ataly8
+# define ataly8pa
+# define atpaaly8
+# define ataly16
+# define ataly16pa
+# define atpaaly16
+# endif
+#else
+# define atalx1
+# define atalx2
+# define atalx4
+# define atalx8
+# define atalx16
+# define atalx1pa
+# define atalx2pa
+# define atalx4pa
+# define atalx8pa
+# define atalx16pa
+# define atpaalx1
+# define atpaalx2
+# define atpaalx4
+# define atpaalx8
+# define atpaalx16
+# define ataly8
+# define ataly8pa
+# define atpaaly8
+# define ataly16
+# define ataly16pa
+# define atpaaly16
+#endif
+
+#define atQI __attribute__((mode (QI)))
+#define atHI __attribute__((mode (HI)))
+#define atSI __attribute__((mode (SI)))
+#define atDI __attribute__((mode (DI)))
+
+enum E0 { e0_0 };
+enum E1 { e1_0, e1_1 };
+enum E2 { e2_m3 = -3, e2_m2, e2_m1, e2_0, e2_1, e2_2, e2_3 };
+enum E3 { e3_m127 = -127, e3_m126, e3_m125, e3_0 = 0, e3_125 = 125, e3_126, e3_127 };
+enum E4 { e4_0, e4_1, e4_2, e4_3, e4_253 = 253, e4_254, e4_255 };
+enum E5 { e5_m32767 = -32767, e5_m32766, e5_m32765, e5_0 = 0, e5_32765 = 32765, e5_32766, e5_32767 };
+enum E6 { e6_0, e6_1, e6_2, e6_3, e6_65533 = 65533, e6_65534, e6_65535 };
+enum E7 { e7_m2147483647 = -2147483647, e7_m2147483646, e7_m2147483645,
+ e7_0, e7_2147483645 = 2147483645, e7_2147483646, e7_2147483647 };
+enum E8 { e8_0, e8_1, e8_2, e8_3, e8_4294967293 = 4294967293U, e8_4294967294, e8_4294967295 };
+enum E9 { e9_m1099511627775 = -1099511627775LL, e9_m1099511627774, e9_m1099511627773,
+ e9_0, e9_1099511627773 = 1099511627773LL, e9_1099511627774, e9_1099511627775 };
+
+typedef char Tchar;
+typedef signed char Tschar;
+typedef unsigned char Tuchar;
+typedef short int Tshort;
+typedef unsigned short int Tushort;
+typedef int Tint;
+typedef unsigned int Tuint;
+typedef long int Tlong;
+typedef unsigned long int Tulong;
+typedef long long int Tllong;
+typedef unsigned long long int Tullong;
+#ifndef SKIP_COMPLEX_INT
+typedef _Complex char Tcchar;
+typedef _Complex signed char Tcschar;
+typedef _Complex unsigned char Tcuchar;
+typedef _Complex short int Tcshort;
+typedef _Complex unsigned short int Tcushort;
+typedef _Complex int Tcint;
+typedef _Complex unsigned int Tcuint;
+typedef _Complex long int Tclong;
+typedef _Complex unsigned long int Tculong;
+typedef _Complex long long int Tcllong;
+typedef _Complex unsigned long long int Tcullong;
+#endif
+typedef float Tfloat;
+typedef double Tdouble;
+typedef long double Tldouble;
+typedef _Complex float Tcfloat;
+typedef _Complex double Tcdouble;
+typedef _Complex long double Tcldouble;
+typedef bool Tbool;
+typedef enum E0 TE0;
+typedef enum E1 TE1;
+typedef enum E2 TE2;
+typedef enum E3 TE3;
+typedef enum E4 TE4;
+typedef enum E5 TE5;
+typedef enum E6 TE6;
+typedef enum E7 TE7;
+typedef enum E8 TE8;
+typedef enum E9 TE9;
+typedef void *Tptr;
+typedef char *Tcptr;
+typedef int *Tiptr;
+typedef char Talchar atal;
+typedef signed char Talschar atal;
+typedef unsigned char Taluchar atal;
+typedef short int Talshort atal;
+typedef unsigned short int Talushort atal;
+typedef int Talint atal;
+typedef unsigned int Taluint atal;
+typedef long int Tallong atal;
+typedef unsigned long int Talulong atal;
+typedef long long int Talllong atal;
+typedef unsigned long long int Talullong atal;
+#ifndef SKIP_COMPLEX_INT
+typedef _Complex char Talcchar atal;
+typedef _Complex signed char Talcschar atal;
+typedef _Complex unsigned char Talcuchar atal;
+typedef _Complex short int Talcshort atal;
+typedef _Complex unsigned short int Talcushort atal;
+typedef _Complex int Talcint atal;
+typedef _Complex unsigned int Talcuint atal;
+typedef _Complex long int Talclong atal;
+typedef _Complex unsigned long int Talculong atal;
+typedef _Complex long long int Talcllong atal;
+typedef _Complex unsigned long long int Talcullong atal;
+#endif
+typedef float Talfloat atal;
+typedef double Taldouble atal;
+typedef long double Talldouble atal;
+typedef _Complex float Talcfloat atal;
+typedef _Complex double Talcdouble atal;
+typedef _Complex long double Talcldouble atal;
+typedef bool Talbool atal;
+typedef enum E0 TalE0 atal;
+typedef enum E1 TalE1 atal;
+typedef enum E2 TalE2 atal;
+typedef enum E3 TalE3 atal;
+typedef enum E4 TalE4 atal;
+typedef enum E5 TalE5 atal;
+typedef enum E6 TalE6 atal;
+typedef enum E7 TalE7 atal;
+typedef enum E8 TalE8 atal;
+typedef enum E9 TalE9 atal;
+typedef void *Talptr atal;
+typedef char *Talcptr atal;
+typedef int *Taliptr atal;
+typedef char Tal1char atal1;
+typedef signed char Tal1schar atal1;
+typedef unsigned char Tal1uchar atal1;
+typedef short int Tal1short atal1;
+typedef unsigned short int Tal1ushort atal1;
+typedef int Tal1int atal1;
+typedef unsigned int Tal1uint atal1;
+typedef long int Tal1long atal1;
+typedef unsigned long int Tal1ulong atal1;
+typedef long long int Tal1llong atal1;
+typedef unsigned long long int Tal1ullong atal1;
+#ifndef SKIP_COMPLEX_INT
+typedef _Complex char Tal1cchar atal1;
+typedef _Complex signed char Tal1cschar atal1;
+typedef _Complex unsigned char Tal1cuchar atal1;
+typedef _Complex short int Tal1cshort atal1;
+typedef _Complex unsigned short int Tal1cushort atal1;
+typedef _Complex int Tal1cint atal1;
+typedef _Complex unsigned int Tal1cuint atal1;
+typedef _Complex long int Tal1clong atal1;
+typedef _Complex unsigned long int Tal1culong atal1;
+typedef _Complex long long int Tal1cllong atal1;
+typedef _Complex unsigned long long int Tal1cullong atal1;
+#endif
+typedef float Tal1float atal1;
+typedef double Tal1double atal1;
+typedef long double Tal1ldouble atal1;
+typedef _Complex float Tal1cfloat atal1;
+typedef _Complex double Tal1cdouble atal1;
+typedef _Complex long double Tal1cldouble atal1;
+typedef bool Tal1bool atal1;
+typedef enum E0 Tal1E0 atal1;
+typedef enum E1 Tal1E1 atal1;
+typedef enum E2 Tal1E2 atal1;
+typedef enum E3 Tal1E3 atal1;
+typedef enum E4 Tal1E4 atal1;
+typedef enum E5 Tal1E5 atal1;
+typedef enum E6 Tal1E6 atal1;
+typedef enum E7 Tal1E7 atal1;
+typedef enum E8 Tal1E8 atal1;
+typedef enum E9 Tal1E9 atal1;
+typedef void *Tal1ptr atal1;
+typedef char *Tal1cptr atal1;
+typedef int *Tal1iptr atal1;
+typedef char Tal2char atal2;
+typedef signed char Tal2schar atal2;
+typedef unsigned char Tal2uchar atal2;
+typedef short int Tal2short atal2;
+typedef unsigned short int Tal2ushort atal2;
+typedef int Tal2int atal2;
+typedef unsigned int Tal2uint atal2;
+typedef long int Tal2long atal2;
+typedef unsigned long int Tal2ulong atal2;
+typedef long long int Tal2llong atal2;
+typedef unsigned long long int Tal2ullong atal2;
+#ifndef SKIP_COMPLEX_INT
+typedef _Complex char Tal2cchar atal2;
+typedef _Complex signed char Tal2cschar atal2;
+typedef _Complex unsigned char Tal2cuchar atal2;
+typedef _Complex short int Tal2cshort atal2;
+typedef _Complex unsigned short int Tal2cushort atal2;
+typedef _Complex int Tal2cint atal2;
+typedef _Complex unsigned int Tal2cuint atal2;
+typedef _Complex long int Tal2clong atal2;
+typedef _Complex unsigned long int Tal2culong atal2;
+typedef _Complex long long int Tal2cllong atal2;
+typedef _Complex unsigned long long int Tal2cullong atal2;
+#endif
+typedef float Tal2float atal2;
+typedef double Tal2double atal2;
+typedef long double Tal2ldouble atal2;
+typedef _Complex float Tal2cfloat atal2;
+typedef _Complex double Tal2cdouble atal2;
+typedef _Complex long double Tal2cldouble atal2;
+typedef bool Tal2bool atal2;
+typedef enum E0 Tal2E0 atal2;
+typedef enum E1 Tal2E1 atal2;
+typedef enum E2 Tal2E2 atal2;
+typedef enum E3 Tal2E3 atal2;
+typedef enum E4 Tal2E4 atal2;
+typedef enum E5 Tal2E5 atal2;
+typedef enum E6 Tal2E6 atal2;
+typedef enum E7 Tal2E7 atal2;
+typedef enum E8 Tal2E8 atal2;
+typedef enum E9 Tal2E9 atal2;
+typedef void *Tal2ptr atal2;
+typedef char *Tal2cptr atal2;
+typedef int *Tal2iptr atal2;
+typedef char Tal4char atal4;
+typedef signed char Tal4schar atal4;
+typedef unsigned char Tal4uchar atal4;
+typedef short int Tal4short atal4;
+typedef unsigned short int Tal4ushort atal4;
+typedef int Tal4int atal4;
+typedef unsigned int Tal4uint atal4;
+typedef long int Tal4long atal4;
+typedef unsigned long int Tal4ulong atal4;
+typedef long long int Tal4llong atal4;
+typedef unsigned long long int Tal4ullong atal4;
+#ifndef SKIP_COMPLEX_INT
+typedef _Complex char Tal4cchar atal4;
+typedef _Complex signed char Tal4cschar atal4;
+typedef _Complex unsigned char Tal4cuchar atal4;
+typedef _Complex short int Tal4cshort atal4;
+typedef _Complex unsigned short int Tal4cushort atal4;
+typedef _Complex int Tal4cint atal4;
+typedef _Complex unsigned int Tal4cuint atal4;
+typedef _Complex long int Tal4clong atal4;
+typedef _Complex unsigned long int Tal4culong atal4;
+typedef _Complex long long int Tal4cllong atal4;
+typedef _Complex unsigned long long int Tal4cullong atal4;
+#endif
+typedef float Tal4float atal4;
+typedef double Tal4double atal4;
+typedef long double Tal4ldouble atal4;
+typedef _Complex float Tal4cfloat atal4;
+typedef _Complex double Tal4cdouble atal4;
+typedef _Complex long double Tal4cldouble atal4;
+typedef bool Tal4bool atal4;
+typedef enum E0 Tal4E0 atal4;
+typedef enum E1 Tal4E1 atal4;
+typedef enum E2 Tal4E2 atal4;
+typedef enum E3 Tal4E3 atal4;
+typedef enum E4 Tal4E4 atal4;
+typedef enum E5 Tal4E5 atal4;
+typedef enum E6 Tal4E6 atal4;
+typedef enum E7 Tal4E7 atal4;
+typedef enum E8 Tal4E8 atal4;
+typedef enum E9 Tal4E9 atal4;
+typedef void *Tal4ptr atal4;
+typedef char *Tal4cptr atal4;
+typedef int *Tal4iptr atal4;
+typedef char Tal8char atal8;
+typedef signed char Tal8schar atal8;
+typedef unsigned char Tal8uchar atal8;
+typedef short int Tal8short atal8;
+typedef unsigned short int Tal8ushort atal8;
+typedef int Tal8int atal8;
+typedef unsigned int Tal8uint atal8;
+typedef long int Tal8long atal8;
+typedef unsigned long int Tal8ulong atal8;
+typedef long long int Tal8llong atal8;
+typedef unsigned long long int Tal8ullong atal8;
+#ifndef SKIP_COMPLEX_INT
+typedef _Complex char Tal8cchar atal8;
+typedef _Complex signed char Tal8cschar atal8;
+typedef _Complex unsigned char Tal8cuchar atal8;
+typedef _Complex short int Tal8cshort atal8;
+typedef _Complex unsigned short int Tal8cushort atal8;
+typedef _Complex int Tal8cint atal8;
+typedef _Complex unsigned int Tal8cuint atal8;
+typedef _Complex long int Tal8clong atal8;
+typedef _Complex unsigned long int Tal8culong atal8;
+typedef _Complex long long int Tal8cllong atal8;
+typedef _Complex unsigned long long int Tal8cullong atal8;
+#endif
+typedef float Tal8float atal8;
+typedef double Tal8double atal8;
+typedef long double Tal8ldouble atal8;
+typedef _Complex float Tal8cfloat atal8;
+typedef _Complex double Tal8cdouble atal8;
+typedef _Complex long double Tal8cldouble atal8;
+typedef bool Tal8bool atal8;
+typedef enum E0 Tal8E0 atal8;
+typedef enum E1 Tal8E1 atal8;
+typedef enum E2 Tal8E2 atal8;
+typedef enum E3 Tal8E3 atal8;
+typedef enum E4 Tal8E4 atal8;
+typedef enum E5 Tal8E5 atal8;
+typedef enum E6 Tal8E6 atal8;
+typedef enum E7 Tal8E7 atal8;
+typedef enum E8 Tal8E8 atal8;
+typedef enum E9 Tal8E9 atal8;
+typedef void *Tal8ptr atal8;
+typedef char *Tal8cptr atal8;
+typedef int *Tal8iptr atal8;
+typedef char Tal16char atal16;
+typedef signed char Tal16schar atal16;
+typedef unsigned char Tal16uchar atal16;
+typedef short int Tal16short atal16;
+typedef unsigned short int Tal16ushort atal16;
+typedef int Tal16int atal16;
+typedef unsigned int Tal16uint atal16;
+typedef long int Tal16long atal16;
+typedef unsigned long int Tal16ulong atal16;
+typedef long long int Tal16llong atal16;
+typedef unsigned long long int Tal16ullong atal16;
+#ifndef SKIP_COMPLEX_INT
+typedef _Complex char Tal16cchar atal16;
+typedef _Complex signed char Tal16cschar atal16;
+typedef _Complex unsigned char Tal16cuchar atal16;
+typedef _Complex short int Tal16cshort atal16;
+typedef _Complex unsigned short int Tal16cushort atal16;
+typedef _Complex int Tal16cint atal16;
+typedef _Complex unsigned int Tal16cuint atal16;
+typedef _Complex long int Tal16clong atal16;
+typedef _Complex unsigned long int Tal16culong atal16;
+typedef _Complex long long int Tal16cllong atal16;
+typedef _Complex unsigned long long int Tal16cullong atal16;
+#endif
+typedef float Tal16float atal16;
+typedef double Tal16double atal16;
+typedef long double Tal16ldouble atal16;
+typedef _Complex float Tal16cfloat atal16;
+typedef _Complex double Tal16cdouble atal16;
+typedef _Complex long double Tal16cldouble atal16;
+typedef bool Tal16bool atal16;
+typedef enum E0 Tal16E0 atal16;
+typedef enum E1 Tal16E1 atal16;
+typedef enum E2 Tal16E2 atal16;
+typedef enum E3 Tal16E3 atal16;
+typedef enum E4 Tal16E4 atal16;
+typedef enum E5 Tal16E5 atal16;
+typedef enum E6 Tal16E6 atal16;
+typedef enum E7 Tal16E7 atal16;
+typedef enum E8 Tal16E8 atal16;
+typedef enum E9 Tal16E9 atal16;
+typedef void *Tal16ptr atal16;
+typedef char *Tal16cptr atal16;
+typedef int *Tal16iptr atal16;
+typedef char Talx1char atalx1;
+typedef signed char Talx1schar atalx1;
+typedef unsigned char Talx1uchar atalx1;
+typedef short int Talx1short atalx1;
+typedef unsigned short int Talx1ushort atalx1;
+typedef int Talx1int atalx1;
+typedef unsigned int Talx1uint atalx1;
+typedef long int Talx1long atalx1;
+typedef unsigned long int Talx1ulong atalx1;
+typedef long long int Talx1llong atalx1;
+typedef unsigned long long int Talx1ullong atalx1;
+#ifndef SKIP_COMPLEX_INT
+typedef _Complex char Talx1cchar atalx1;
+typedef _Complex signed char Talx1cschar atalx1;
+typedef _Complex unsigned char Talx1cuchar atalx1;
+typedef _Complex short int Talx1cshort atalx1;
+typedef _Complex unsigned short int Talx1cushort atalx1;
+typedef _Complex int Talx1cint atalx1;
+typedef _Complex unsigned int Talx1cuint atalx1;
+typedef _Complex long int Talx1clong atalx1;
+typedef _Complex unsigned long int Talx1culong atalx1;
+typedef _Complex long long int Talx1cllong atalx1;
+typedef _Complex unsigned long long int Talx1cullong atalx1;
+#endif
+typedef float Talx1float atalx1;
+typedef double Talx1double atalx1;
+typedef long double Talx1ldouble atalx1;
+typedef _Complex float Talx1cfloat atalx1;
+typedef _Complex double Talx1cdouble atalx1;
+typedef _Complex long double Talx1cldouble atalx1;
+typedef bool Talx1bool atalx1;
+typedef enum E0 Talx1E0 atalx1;
+typedef enum E1 Talx1E1 atalx1;
+typedef enum E2 Talx1E2 atalx1;
+typedef enum E3 Talx1E3 atalx1;
+typedef enum E4 Talx1E4 atalx1;
+typedef enum E5 Talx1E5 atalx1;
+typedef enum E6 Talx1E6 atalx1;
+typedef enum E7 Talx1E7 atalx1;
+typedef enum E8 Talx1E8 atalx1;
+typedef enum E9 Talx1E9 atalx1;
+typedef void *Talx1ptr atalx1;
+typedef char *Talx1cptr atalx1;
+typedef int *Talx1iptr atalx1;
+typedef short int Talx2short atalx2;
+typedef unsigned short int Talx2ushort atalx2;
+typedef int Talx2int atalx2;
+typedef unsigned int Talx2uint atalx2;
+typedef long int Talx2long atalx2;
+typedef unsigned long int Talx2ulong atalx2;
+typedef long long int Talx2llong atalx2;
+typedef unsigned long long int Talx2ullong atalx2;
+#ifndef SKIP_COMPLEX_INT
+typedef _Complex char Talx2cchar atalx2;
+typedef _Complex signed char Talx2cschar atalx2;
+typedef _Complex unsigned char Talx2cuchar atalx2;
+typedef _Complex short int Talx2cshort atalx2;
+typedef _Complex unsigned short int Talx2cushort atalx2;
+typedef _Complex int Talx2cint atalx2;
+typedef _Complex unsigned int Talx2cuint atalx2;
+typedef _Complex long int Talx2clong atalx2;
+typedef _Complex unsigned long int Talx2culong atalx2;
+typedef _Complex long long int Talx2cllong atalx2;
+typedef _Complex unsigned long long int Talx2cullong atalx2;
+#endif
+typedef float Talx2float atalx2;
+typedef double Talx2double atalx2;
+typedef long double Talx2ldouble atalx2;
+typedef _Complex float Talx2cfloat atalx2;
+typedef _Complex double Talx2cdouble atalx2;
+typedef _Complex long double Talx2cldouble atalx2;
+typedef enum E0 Talx2E0 atalx2;
+typedef enum E1 Talx2E1 atalx2;
+typedef enum E2 Talx2E2 atalx2;
+typedef enum E3 Talx2E3 atalx2;
+typedef enum E4 Talx2E4 atalx2;
+typedef enum E5 Talx2E5 atalx2;
+typedef enum E6 Talx2E6 atalx2;
+typedef enum E7 Talx2E7 atalx2;
+typedef enum E8 Talx2E8 atalx2;
+typedef enum E9 Talx2E9 atalx2;
+typedef void *Talx2ptr atalx2;
+typedef char *Talx2cptr atalx2;
+typedef int *Talx2iptr atalx2;
+typedef int Talx4int atalx4;
+typedef unsigned int Talx4uint atalx4;
+typedef long int Talx4long atalx4;
+typedef unsigned long int Talx4ulong atalx4;
+typedef long long int Talx4llong atalx4;
+typedef unsigned long long int Talx4ullong atalx4;
+#ifndef SKIP_COMPLEX_INT
+typedef _Complex short int Talx4cshort atalx4;
+typedef _Complex unsigned short int Talx4cushort atalx4;
+typedef _Complex int Talx4cint atalx4;
+typedef _Complex unsigned int Talx4cuint atalx4;
+typedef _Complex long int Talx4clong atalx4;
+typedef _Complex unsigned long int Talx4culong atalx4;
+typedef _Complex long long int Talx4cllong atalx4;
+typedef _Complex unsigned long long int Talx4cullong atalx4;
+#endif
+typedef float Talx4float atalx4;
+typedef double Talx4double atalx4;
+typedef long double Talx4ldouble atalx4;
+typedef _Complex float Talx4cfloat atalx4;
+typedef _Complex double Talx4cdouble atalx4;
+typedef _Complex long double Talx4cldouble atalx4;
+typedef enum E0 Talx4E0 atalx4;
+typedef enum E1 Talx4E1 atalx4;
+typedef enum E2 Talx4E2 atalx4;
+typedef enum E3 Talx4E3 atalx4;
+typedef enum E4 Talx4E4 atalx4;
+typedef enum E5 Talx4E5 atalx4;
+typedef enum E6 Talx4E6 atalx4;
+typedef enum E7 Talx4E7 atalx4;
+typedef enum E8 Talx4E8 atalx4;
+typedef enum E9 Talx4E9 atalx4;
+typedef void *Talx4ptr atalx4;
+typedef char *Talx4cptr atalx4;
+typedef int *Talx4iptr atalx4;
+typedef long int Taly8long ataly8;
+typedef unsigned long int Taly8ulong ataly8;
+typedef long long int Talx8llong atalx8;
+typedef unsigned long long int Talx8ullong atalx8;
+#ifndef SKIP_COMPLEX_INT
+typedef _Complex int Talx8cint atalx8;
+typedef _Complex unsigned int Talx8cuint atalx8;
+typedef _Complex long int Talx8clong atalx8;
+typedef _Complex unsigned long int Talx8culong atalx8;
+typedef _Complex long long int Talx8cllong atalx8;
+typedef _Complex unsigned long long int Talx8cullong atalx8;
+#endif
+typedef double Talx8double atalx8;
+typedef long double Talx8ldouble atalx8;
+typedef _Complex float Talx8cfloat atalx8;
+typedef _Complex double Talx8cdouble atalx8;
+typedef _Complex long double Talx8cldouble atalx8;
+typedef void *Taly8ptr ataly8;
+typedef char *Taly8cptr ataly8;
+typedef int *Taly8iptr ataly8;
+#ifndef SKIP_COMPLEX_INT
+typedef _Complex long int Taly16clong ataly16;
+typedef _Complex unsigned long int Taly16culong ataly16;
+typedef _Complex long long int Talx16cllong atalx16;
+typedef _Complex unsigned long long int Talx16cullong atalx16;
+#endif
+typedef _Complex double Talx16cdouble atalx16;
+typedef _Complex long double Talx16cldouble atalx16;
+typedef int (*Tfnptr) (void);
+
+/* Bitfield macros. In C, it is invalid to use numbers larger
+ than type's bitsize, but we don't know the size when generating
+ the testcases. */
+#define BN8(n) ((((n) - 1) & 7) + 1)
+#define BN16(n) ((((n) - 1) & 15) + 1)
+#define BN32(n) ((((n) - 1) & 31) + 1)
+#define BN64(n) ((((n) - 1) & 63) + 1)
+#define BCN(n) BN8 (n)
+#if USHRT_MAX == 255
+# define BSN(n) BN8 (n)
+#elif USHRT_MAX == 65535
+# define BSN(n) BN16 (n)
+#elif USHRT_MAX == 4294967295U
+# define BSN(n) BN32 (n)
+#elif USHRT_MAX == 18446744073709551615ULL
+# define BSN(n) BN64 (n)
+#endif
+#if UINT_MAX == 255
+# define BIN(n) BN8 (n)
+#elif UINT_MAX == 65535
+# define BIN(n) BN16 (n)
+#elif UINT_MAX == 4294967295U
+# define BIN(n) BN32 (n)
+#elif UINT_MAX == 18446744073709551615ULL
+# define BIN(n) BN64 (n)
+#endif
+#if ULONG_MAX == 255
+# define BLN(n) BN8 (n)
+#elif ULONG_MAX == 65535
+# define BLN(n) BN16 (n)
+#elif ULONG_MAX == 4294967295U
+# define BLN(n) BN32 (n)
+#elif ULONG_MAX == 18446744073709551615ULL
+# define BLN(n) BN64 (n)
+#endif
+#if ULONG_MAX == 255
+# define BLN(n) BN8 (n)
+#elif ULONG_MAX == 65535
+# define BLN(n) BN16 (n)
+#elif ULONG_MAX == 4294967295U
+# define BLN(n) BN32 (n)
+#elif ULONG_MAX == 18446744073709551615ULL
+# define BLN(n) BN64 (n)
+#endif
+#if !defined ULLONG_MAX && defined __LONG_LONG_MAX__
+# define ULLONG_MAX (__LONG_LONG_MAX__ * 2ULL + 1ULL)
+#endif
+#if ULLONG_MAX == 255
+# define BQN(n) BN8 (n)
+#elif ULLONG_MAX == 65535
+# define BQN(n) BN16 (n)
+#elif ULLONG_MAX == 4294967295U
+# define BQN(n) BN32 (n)
+#elif ULLONG_MAX == 18446744073709551615ULL
+# define BQN(n) BN64 (n)
+#endif
+
+#define T(n, fields, ops) TX(n, struct, , fields, ({ ops });)
+#define U(n, fields, ops) TX(n, union, , fields, ({ ops });)
+#ifdef SKIP_COMPLEX_INT
+#define TXCI(n, type, attrs, fields, ops)
+#define TCI(n, fields, ops)
+#define UCI(n, fields, ops)
+#else
+#define TXCI(n, type, attrs, fields, ops) TX(n, type, attrs, fields, ({ ops });)
+#define TCI(n, fields, ops) TX(n, struct, , fields, ({ ops });)
+#define UCI(n, fields, ops) TX(n, union, , fields, ({ ops });)
+#endif
diff --git a/gcc/testsuite/objc.dg/gnu-encoding/struct-layout-1_test.h b/gcc/testsuite/objc.dg/gnu-encoding/struct-layout-1_test.h
new file mode 100644
index 000000000..3463bb912
--- /dev/null
+++ b/gcc/testsuite/objc.dg/gnu-encoding/struct-layout-1_test.h
@@ -0,0 +1,9 @@
+#include "struct-layout-1.h"
+
+#define TX(n, type, attrs, fields, ops) \
+type S##n { fields } attrs; \
+void test##n (void) \
+{ \
+ if (objc_sizeof_type (@encoding (type S##n)) != sizeof(type S##n)) \
+ fails ++; \
+}
diff --git a/gcc/testsuite/objc.dg/gnu-encoding/struct-layout-encoding-1_generate.c b/gcc/testsuite/objc.dg/gnu-encoding/struct-layout-encoding-1_generate.c
new file mode 100644
index 000000000..7494131c1
--- /dev/null
+++ b/gcc/testsuite/objc.dg/gnu-encoding/struct-layout-encoding-1_generate.c
@@ -0,0 +1,1380 @@
+/* Structure layout test generator.
+ Copyright (C) 2004, 2005, 2007, 2010, 2011 Free Software Foundation, Inc.
+ Contributed by Jakub Jelinek <jakub@redhat.com>.
+
+This file is part of GCC.
+
+GCC 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, or (at your option) any later
+version.
+
+GCC 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 GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+/* Compile with gcc -o struct-layout-1_generate{,.c} generate_random{,_r}.c */
+
+/* N.B. -- This program cannot use libiberty as that will not work
+ when testing an installed compiler. */
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stddef.h>
+/* We use our own pseudo-random number generator, so that it gives the same
+ values on all hosts. */
+#include "generate-random.h"
+
+#if LLONG_MAX != 9223372036854775807LL && __LONG_LONG_MAX__ != 9223372036854775807LL
+# error Need 64-bit long long
+#endif
+
+typedef unsigned int hashval_t;
+
+enum TYPE
+{
+ TYPE_INT,
+ TYPE_UINT,
+ TYPE_CINT,
+ TYPE_CUINT,
+ TYPE_FLOAT,
+ TYPE_CFLOAT,
+ TYPE_SENUM,
+ TYPE_UENUM,
+ TYPE_PTR,
+ TYPE_FNPTR,
+ TYPE_OTHER
+};
+
+struct types
+{
+ const char *name;
+ enum TYPE type;
+ unsigned long long int maxval;
+ char bitfld;
+};
+
+struct types base_types[] = {
+/* As we don't know whether char will be signed or not, just limit ourselves
+ to unsigned values less than maximum signed char value. */
+{ "char", TYPE_UINT, 127, 'C' },
+{ "signed char", TYPE_INT, 127, 'C' },
+{ "unsigned char", TYPE_UINT, 255, 'C' },
+{ "short int", TYPE_INT, 32767, 'S' },
+{ "unsigned short int", TYPE_UINT, 65535, 'S' },
+{ "int", TYPE_INT, 2147483647, 'I' },
+{ "unsigned int", TYPE_UINT, 4294967295U, 'I' },
+{ "long int", TYPE_INT, 9223372036854775807LL, 'L' },
+{ "unsigned long int", TYPE_UINT, 18446744073709551615ULL, 'L' },
+{ "long long int", TYPE_INT, 9223372036854775807LL, 'Q' },
+{ "unsigned long long int", TYPE_UINT, 18446744073709551615ULL, 'Q' },
+{ "bool", TYPE_UINT, 1, 'B' },
+{ "void *", TYPE_PTR, 0, 0 },
+{ "char *", TYPE_PTR, 0, 0 },
+{ "int *", TYPE_PTR, 0, 0 },
+{ "float", TYPE_FLOAT, 0, 0 },
+{ "double", TYPE_FLOAT, 0, 0 },
+/*{ "long double", TYPE_FLOAT, 0, 0 },*/
+/* Disabled as double and long double
+ are encoded thee same, currently */
+#define NTYPES1 16
+#if 0
+/* enums are disabled for now as it seems like their encoding is broken, we should
+ just encode them using their underlaying type but we don't. */
+{ "enum E0", TYPE_UENUM, 0, ' ' },
+{ "enum E1", TYPE_UENUM, 1, ' ' },
+{ "enum E2", TYPE_SENUM, 3, ' ' },
+{ "enum E3", TYPE_SENUM, 127, ' ' },
+{ "enum E4", TYPE_UENUM, 255, ' ' },
+{ "enum E5", TYPE_SENUM, 32767, ' ' },
+{ "enum E6", TYPE_UENUM, 65535, ' ' },
+{ "enum E7", TYPE_SENUM, 2147483647, ' ' },
+{ "enum E8", TYPE_UENUM, 4294967295U, ' ' },
+{ "enum E9", TYPE_SENUM, 1099511627775LL, ' ' },
+#endif
+#define NTYPES2 (sizeof (base_types) / sizeof (base_types[0]))
+};
+struct types complex_types[] = {
+{ "_Complex char", TYPE_CUINT, 127, 0 },
+{ "_Complex signed char", TYPE_CINT, 127, 0 },
+{ "_Complex unsigned char", TYPE_CUINT, 255, 0 },
+{ "_Complex short int", TYPE_CINT, 32767, 0 },
+{ "_Complex unsigned short int", TYPE_CUINT, 65535, 0 },
+{ "_Complex int", TYPE_CINT, 2147483647, 0 },
+{ "_Complex unsigned int", TYPE_CUINT, 4294967295U, 0 },
+{ "_Complex long int", TYPE_CINT, 9223372036854775807LL, 0 },
+{ "_Complex unsigned long int", TYPE_CUINT, 18446744073709551615ULL, 0 },
+{ "_Complex long long int", TYPE_CINT, 9223372036854775807LL, 0 },
+{ "_Complex unsigned long long int", TYPE_CUINT, 18446744073709551615ULL, 0 },
+{ "_Complex float", TYPE_CFLOAT, 0, 0 },
+{ "_Complex double", TYPE_CFLOAT, 0, 0 },
+/*{ "_Complex long double", TYPE_CFLOAT, 0, 0 }, */
+/* Disable until long doubles are encoded correctly. */
+#define NCTYPES2 (sizeof (complex_types) / sizeof (complex_types[0]))
+};
+struct types vector_types[] = {
+/* vector-defs.h typedefs */
+{ "v8qi", TYPE_OTHER, 0, 0 },
+{ "v16qi", TYPE_OTHER, 0, 0 },
+{ "v2hi", TYPE_OTHER, 0, 0 },
+{ "v4hi", TYPE_OTHER, 0, 0 },
+{ "v8hi", TYPE_OTHER, 0, 0 },
+{ "v2si", TYPE_OTHER, 0, 0 },
+{ "v4si", TYPE_OTHER, 0, 0 },
+{ "v1di", TYPE_OTHER, 0, 0 },
+{ "v2di", TYPE_OTHER, 0, 0 },
+{ "v2sf", TYPE_OTHER, 0, 0 },
+{ "v4sf", TYPE_OTHER, 0, 0 },
+{ "v16sf", TYPE_OTHER, 0, 0 },
+{ "v2df", TYPE_OTHER, 0, 0 },
+{ "u8qi", TYPE_OTHER, 0, 0 },
+{ "u16qi", TYPE_OTHER, 0, 0 },
+{ "u2hi", TYPE_OTHER, 0, 0 },
+{ "u4hi", TYPE_OTHER, 0, 0 },
+{ "u8hi", TYPE_OTHER, 0, 0 },
+{ "u2si", TYPE_OTHER, 0, 0 },
+{ "u4si", TYPE_OTHER, 0, 0 },
+{ "u1di", TYPE_OTHER, 0, 0 },
+{ "u2di", TYPE_OTHER, 0, 0 },
+{ "u2sf", TYPE_OTHER, 0, 0 },
+{ "u4sf", TYPE_OTHER, 0, 0 },
+{ "u16sf", TYPE_OTHER, 0, 0 },
+{ "u2df", TYPE_OTHER, 0, 0 },
+{ "__m64", TYPE_OTHER, 0, 0 },
+{ "__m128", TYPE_OTHER, 0, 0 }
+#define NVTYPES2 (sizeof (vector_types) / sizeof (vector_types[0]))
+};
+
+struct types bitfld_types[NTYPES2];
+int n_bitfld_types;
+
+enum ETYPE
+{
+ ETYPE_TYPE,
+ ETYPE_ARRAY,
+ ETYPE_BITFLD,
+ ETYPE_STRUCT,
+ ETYPE_UNION,
+ ETYPE_STRUCT_ARRAY,
+ ETYPE_UNION_ARRAY
+};
+
+struct entry
+{
+#ifdef __GNUC__
+ enum ETYPE etype : 8;
+#else
+ unsigned char etype;
+#endif
+ unsigned short len;
+ unsigned char arr_len;
+ struct types *type;
+ const char *attrib;
+ /* Used to chain together entries in the hash table. */
+ struct entry *next;
+};
+
+/* A prime number giving the number of slots in the hash table. */
+#define HASH_SIZE 32749
+static struct entry *hash_table[HASH_SIZE];
+
+static int idx, limidx, output_one;
+static const char *destdir;
+static const char *srcdir;
+FILE *outfile;
+
+void
+switchfiles (int fields)
+{
+ static int filecnt;
+ static char *destbuf, *destptr;
+ ++filecnt;
+ if (outfile)
+ fclose (outfile);
+ if (output_one)
+ {
+ outfile = stdout;
+ return;
+ }
+ if (destbuf == NULL)
+ {
+ size_t len = strlen (destdir);
+ destbuf = malloc (len + 20);
+ if (!destbuf)
+ abort ();
+ memcpy (destbuf, destdir, len);
+ if (!len || destbuf[len - 1] != '/')
+ destbuf[len++] = '/';
+ destptr = destbuf + len;
+ }
+ sprintf (destptr, "t%03d_main.m", filecnt);
+ outfile = fopen (destbuf, "w");
+ if (outfile == NULL)
+ {
+ fail:
+ fputs ("failed to create test files\n", stderr);
+ exit (1);
+ }
+ /* FIXME: these tests should not be xfailed on aix but they are because
+ libobjc uses GCC's headers for trying to find the struct layout but it
+ gets it wrong. */
+ if (filecnt == 2
+ || filecnt == 3
+ || filecnt == 4
+ || filecnt == 6
+ || filecnt == 7
+ || filecnt == 8
+ || filecnt == 11
+ || filecnt == 12
+ || filecnt == 15
+ || filecnt == 22)
+ {
+ fprintf (outfile, "\
+/* { dg-do run { xfail { powerpc*-*-aix* } } } */\n\
+/* { dg-options \"-w -I%s -fgnu-runtime\" } */\n", srcdir);
+ }
+ /* FIXME: these should not be xfailed but they are because
+ of bugs in libobjc and the objc front-end. 25 is because
+ vectors are not encoded. The rest are because or zero sized
+ arrays are encoded as pointers. See PR objc/25361. */
+ else if (filecnt == 25 || (filecnt >= 27 && filecnt <= 29))
+ {
+ fprintf (outfile, "\
+/* { dg-do run { xfail { { i?86-*-* x86_64-*-* } || { powerpc*-apple-darwin* && ilp32 } } } } */\n\
+/* { dg-options \"-w -I%s -fgnu-runtime\" } */\n", srcdir);
+ }
+ else if (filecnt >= 30)
+ {
+ fprintf (outfile, "\
+/* { dg-do run { xfail { i?86-*-* x86_64-*-* } } } */\n\
+/* { dg-options \"-w -I%s -fgnu-runtime\" } */\n", srcdir);
+ }
+ else
+ {
+ fprintf (outfile, "\
+/* { dg-do run } */\n\
+/* { dg-options \"-w -I%s -fgnu-runtime\" } */\n", srcdir);
+ }
+ fprintf(outfile, "#include <objc/encoding.h> \n\
+#include \"struct-layout-1.h\"\n\
+\n\
+int fails; \n\
+#define TX(n, type, attrs, fields, ops) \\\n\
+type S##n { fields } attrs; \\\n\
+void test##n (void) \\\n\
+{ \\\n\
+ char *encoding = @encode (type S##n); \\\n\
+ if (objc_sizeof_type (encoding) != sizeof(type S##n)) \\\n\
+ { \\\n\
+ fails ++; \\\n\
+ printf(#type \" { \" #fields \"} size is %%u, but is calulated as %%u\\n\", \\\n\
+ sizeof(type S##n), objc_sizeof_type (encoding)); \\\n\
+ } \\\n\
+ if (objc_alignof_type (encoding) != __alignof__ (type S##n)) \\\n\
+ { \\\n\
+ fails ++; \\\n\
+ printf(#type \" { \" #fields \"} align is %%u, but is calulated as %%u\\n\", \\\n\
+ __alignof__ (type S##n), objc_alignof_type (encoding)); \\\n\
+ } \\\n\
+}\n\
+#include \"t%03d_test.h\"\n\
+#undef TX\n\
+\n\
+int main (void)\n\
+{\n\
+#define TX(n, type, attrs, fields, ops) test##n ();\n\
+#include \"t%03d_test.h\"\n\
+#undef TX\n\
+ if (fails)\n\
+ {\n\
+ fflush (stdout);\n\
+ abort ();\n\
+ }\n\
+ exit (0);\n\
+}\n", filecnt, filecnt);
+ fclose (outfile);
+ sprintf (destptr, "t%03d_test.h", filecnt);
+ outfile = fopen (destbuf, "w");
+ if (outfile == NULL)
+ goto fail;
+ if (fields <= 2)
+ limidx = idx + 300;
+ else if (fields <= 4)
+ limidx = idx + 200;
+ else if (fields <= 6)
+ limidx = idx + 100;
+ else
+ limidx = idx + 50;
+}
+
+unsigned long long int
+getrandll (void)
+{
+ unsigned long long int ret;
+ ret = generate_random () & 0xffffff;
+ ret |= (generate_random () & 0xffffffLL) << 24;
+ ret |= ((unsigned long long int) generate_random ()) << 48;
+ return ret;
+}
+
+int
+subfield (struct entry *e, char *letter)
+{
+ int i, type;
+ char buf[20];
+ const char *p;
+ switch (e[0].etype)
+ {
+ case ETYPE_STRUCT:
+ case ETYPE_UNION:
+ case ETYPE_STRUCT_ARRAY:
+ case ETYPE_UNION_ARRAY:
+ type = e[0].attrib ? 1 + (generate_random () & 3) : 0;
+ if (e[0].etype == ETYPE_STRUCT || e[0].etype == ETYPE_STRUCT_ARRAY)
+ p = "struct";
+ else
+ p = "union";
+ if (e[0].etype == ETYPE_STRUCT_ARRAY || e[0].etype == ETYPE_UNION_ARRAY)
+ {
+ if (e[0].arr_len == 255)
+ snprintf (buf, 20, "%c[]", *letter);
+ else
+ snprintf (buf, 20, "%c[%d]", *letter, e[0].arr_len);
+ }
+ else
+ {
+ buf[0] = *letter;
+ buf[1] = '\0';
+ }
+ ++*letter;
+ switch (type)
+ {
+ case 0:
+ case 3:
+ case 4:
+ fprintf (outfile, "%s{", p);
+ break;
+ case 1:
+ fprintf (outfile, "%s %s{", e[0].attrib, p);
+ break;
+ case 2:
+ fprintf (outfile, "%s %s{", p, e[0].attrib);
+ break;
+ }
+
+ for (i = 1; i <= e[0].len; )
+ i += subfield (e + i, letter);
+
+ switch (type)
+ {
+ case 0:
+ case 1:
+ case 2:
+ fprintf (outfile, "}%s;", buf);
+ break;
+ case 3:
+ fprintf (outfile, "}%s %s;", e[0].attrib, buf);
+ break;
+ case 4:
+ fprintf (outfile, "}%s %s;", buf, e[0].attrib);
+ break;
+ }
+ return 1 + e[0].len;
+ case ETYPE_TYPE:
+ case ETYPE_ARRAY:
+ if (e[0].etype == ETYPE_ARRAY)
+ {
+ if (e[0].arr_len == 255)
+ snprintf (buf, 20, "%c[]", *letter);
+ else
+ snprintf (buf, 20, "%c[%d]", *letter, e[0].arr_len);
+ }
+ else
+ {
+ buf[0] = *letter;
+ buf[1] = '\0';
+ }
+ ++*letter;
+ if (e[0].attrib)
+ switch (generate_random () % 3)
+ {
+ case 0:
+ fprintf (outfile, "%s %s %s;", e[0].attrib, e[0].type->name, buf);
+ break;
+ case 1:
+ fprintf (outfile, "%s %s %s;", e[0].type->name, e[0].attrib, buf);
+ break;
+ case 2:
+ fprintf (outfile, "%s %s %s;", e[0].type->name, buf, e[0].attrib);
+ break;
+ }
+ else
+ fprintf (outfile, "%s %s;", e[0].type->name, buf);
+ return 1;
+ case ETYPE_BITFLD:
+ if (e[0].len == 0)
+ {
+ if (e[0].attrib)
+ switch (generate_random () % 3)
+ {
+ case 0:
+ fprintf (outfile, "%s %s:0;", e[0].attrib, e[0].type->name);
+ break;
+ case 1:
+ fprintf (outfile, "%s %s:0;", e[0].type->name, e[0].attrib);
+ break;
+ case 2:
+ fprintf (outfile, "%s:0 %s;", e[0].type->name, e[0].attrib);
+ break;
+ }
+ else
+ fprintf (outfile, "%s:0;", e[0].type->name);
+ ++*letter;
+ return 1;
+ }
+ switch (e[0].type->bitfld)
+ {
+ case 'C':
+ case 'S':
+ case 'I':
+ case 'L':
+ case 'Q':
+ snprintf (buf, 20, "B%cN(%d)", e[0].type->bitfld, e[0].len);
+ break;
+ case 'B':
+ case ' ':
+ snprintf (buf, 20, "%d", e[0].len);
+ break;
+ default:
+ abort ();
+ }
+ if (e[0].attrib)
+ switch (generate_random () % 3)
+ {
+ case 0:
+ fprintf (outfile, "%s %s %c:%s;", e[0].attrib, e[0].type->name,
+ *letter, buf);
+ break;
+ case 1:
+ fprintf (outfile, "%s %s %c:%s;", e[0].type->name, e[0].attrib,
+ *letter, buf);
+ break;
+ case 2:
+ fprintf (outfile, "%s %c:%s %s;", e[0].type->name, *letter,
+ buf, e[0].attrib);
+ break;
+ }
+ else
+ fprintf (outfile, "%s %c:%s;", e[0].type->name, *letter, buf);
+ ++*letter;
+ return 1;
+ default:
+ abort ();
+ }
+}
+
+char namebuf[1024];
+
+void
+output_FNB (char mode, struct entry *e)
+{
+ unsigned long long int l1, l2, m;
+ int signs = 0;
+ const char *p, *q;
+
+ if (e->type->type == TYPE_OTHER)
+ {
+ if (mode == 'B')
+ abort ();
+ fprintf (outfile, "N(%d,%s)", idx, namebuf);
+ return;
+ }
+ fprintf (outfile, "%c(%d,%s,", mode, idx, namebuf);
+ l1 = getrandll ();
+ l2 = getrandll ();
+ switch (e->type->type)
+ {
+ case TYPE_INT:
+ signs = generate_random () & 3;
+ m = e->type->maxval;
+ if (mode == 'B')
+ m &= e->len > 1 ? (1ULL << (e->len - 1)) - 1 : 1;
+ l1 &= m;
+ l2 &= m;
+ fprintf (outfile, "%s%llu%s,%s%llu%s",
+ (signs & 1) ? "-" : "", l1, l1 > 2147483647 ? "LL" : "",
+ (signs & 2) ? "-" : "", l2, l2 > 2147483647 ? "LL" : "");
+ break;
+ case TYPE_UINT:
+ m = e->type->maxval;
+ if (mode == 'B')
+ m &= (1ULL << e->len) - 1;
+ l1 &= m;
+ l2 &= m;
+ fprintf (outfile, "%lluU%s,%lluU%s", l1, l1 > 4294967295U ? "LL" : "",
+ l2, l2 > 4294967295U ? "LL" : "");
+ break;
+ case TYPE_FLOAT:
+ l1 &= 0xffffff;
+ l2 &= 0xffffff;
+ signs = generate_random () & 3;
+ fprintf (outfile, "%s%f,%s%f", (signs & 1) ? "-" : "",
+ ((double) l1) / 64, (signs & 2) ? "-" : "", ((double) l2) / 64);
+ break;
+ case TYPE_CINT:
+ signs = generate_random () & 3;
+ l1 &= e->type->maxval;
+ l2 &= e->type->maxval;
+ fprintf (outfile, "CINT(%s%llu%s,%s%llu%s),",
+ (signs & 1) ? "-" : "", l1, l1 > 2147483647 ? "LL" : "",
+ (signs & 2) ? "-" : "", l2, l2 > 2147483647 ? "LL" : "");
+ signs = generate_random () & 3;
+ l1 = getrandll ();
+ l2 = getrandll ();
+ l1 &= e->type->maxval;
+ l2 &= e->type->maxval;
+ fprintf (outfile, "CINT(%s%llu%s,%s%llu%s)",
+ (signs & 1) ? "-" : "", l1, l1 > 2147483647 ? "LL" : "",
+ (signs & 2) ? "-" : "", l2, l2 > 2147483647 ? "LL" : "");
+ break;
+ case TYPE_CUINT:
+ l1 &= e->type->maxval;
+ l2 &= e->type->maxval;
+ fprintf (outfile, "CINT(%lluU%s,%lluU%s),",
+ l1, l1 > 4294967295U ? "LL" : "",
+ l2, l2 > 4294967295U ? "LL" : "");
+ l1 = getrandll ();
+ l2 = getrandll ();
+ l1 &= e->type->maxval;
+ l2 &= e->type->maxval;
+ fprintf (outfile, "CINT(%lluU%s,%lluU%s)",
+ l1, l1 > 4294967295U ? "LL" : "",
+ l2, l2 > 4294967295U ? "LL" : "");
+ break;
+ case TYPE_CFLOAT:
+ l1 &= 0xffffff;
+ l2 &= 0xffffff;
+ signs = generate_random () & 3;
+ fprintf (outfile, "CDBL(%s%f,%s%f),",
+ (signs & 1) ? "-" : "", ((double) l1) / 64,
+ (signs & 2) ? "-" : "", ((double) l2) / 64);
+ l1 = getrandll ();
+ l2 = getrandll ();
+ l1 &= 0xffffff;
+ l2 &= 0xffffff;
+ signs = generate_random () & 3;
+ fprintf (outfile, "CDBL(%s%f,%s%f)",
+ (signs & 1) ? "-" : "", ((double) l1) / 64,
+ (signs & 2) ? "-" : "", ((double) l2) / 64);
+ break;
+ case TYPE_UENUM:
+ if (e->type->maxval == 0)
+ fputs ("e0_0,e0_0", outfile);
+ else if (e->type->maxval == 1)
+ fprintf (outfile, "e1_%lld,e1_%lld", l1 & 1, l2 & 1);
+ else
+ {
+ p = strchr (e->type->name, '\0');
+ while (--p >= e->type->name && *p >= '0' && *p <= '9');
+ p++;
+ l1 %= 7;
+ l2 %= 7;
+ if (l1 > 3)
+ l1 += e->type->maxval - 6;
+ if (l2 > 3)
+ l2 += e->type->maxval - 6;
+ fprintf (outfile, "e%s_%lld,e%s_%lld", p, l1, p, l2);
+ }
+ break;
+ case TYPE_SENUM:
+ p = strchr (e->type->name, '\0');
+ while (--p >= e->type->name && *p >= '0' && *p <= '9');
+ p++;
+ l1 %= 7;
+ l2 %= 7;
+ fprintf (outfile, "e%s_%s%lld,e%s_%s%lld",
+ p, l1 < 3 ? "m" : "",
+ l1 == 3 ? 0LL : e->type->maxval - (l1 & 3),
+ p, l2 < 3 ? "m" : "",
+ l2 == 3 ? 0LL : e->type->maxval - (l2 & 3));
+ break;
+ case TYPE_PTR:
+ l1 %= 256;
+ l2 %= 256;
+ fprintf (outfile, "(%s)&intarray[%lld],(%s)&intarray[%lld]",
+ e->type->name, l1, e->type->name, l2);
+ break;
+ case TYPE_FNPTR:
+ l1 %= 10;
+ l2 %= 10;
+ fprintf (outfile, "fn%lld,fn%lld", l1, l2);
+ break;
+ default:
+ abort ();
+ }
+ fputs (")", outfile);
+}
+
+int
+subvalues (struct entry *e, char *p, char *letter)
+{
+ int i, j;
+ char *q;
+ if (p >= namebuf + sizeof (namebuf) - 32)
+ abort ();
+ p[0] = *letter;
+ p[1] = '\0';
+ q = p + 1;
+ switch (e[0].etype)
+ {
+ case ETYPE_STRUCT_ARRAY:
+ case ETYPE_UNION_ARRAY:
+ if (e[0].arr_len == 0 || e[0].arr_len == 255)
+ {
+ *letter += 1 + e[0].len;
+ return 1 + e[0].len;
+ }
+ i = generate_random () % e[0].arr_len;
+ snprintf (p, sizeof (namebuf) - (p - namebuf) - 1,
+ "%c[%d]", *letter, i);
+ q = strchr (p, '\0');
+ /* FALLTHROUGH */
+ case ETYPE_STRUCT:
+ case ETYPE_UNION:
+ *q++ = '.';
+ ++*letter;
+ for (i = 1; i <= e[0].len; )
+ {
+ i += subvalues (e + i, q, letter);
+ if (e[0].etype == ETYPE_UNION || e[0].etype == ETYPE_UNION_ARRAY)
+ {
+ *letter += e[0].len - i + 1;
+ break;
+ }
+ }
+ return 1 + e[0].len;
+ case ETYPE_TYPE:
+ ++*letter;
+ output_FNB ('F', e);
+ return 1;
+ case ETYPE_ARRAY:
+ if (e[0].arr_len == 0 || e[0].arr_len == 255)
+ {
+ ++*letter;
+ return 1;
+ }
+ i = generate_random () % e[0].arr_len;
+ snprintf (p, sizeof (namebuf) - (p - namebuf),
+ "%c[%d]", *letter, i);
+ output_FNB ('F', e);
+ if ((generate_random () & 7) == 0)
+ {
+ j = generate_random () % e[0].arr_len;
+ if (i != j)
+ {
+ snprintf (p, sizeof (namebuf) - (p - namebuf),
+ "%c[%d]", *letter, j);
+ output_FNB ('F', e);
+ }
+ }
+ ++*letter;
+ return 1;
+ case ETYPE_BITFLD:
+ ++*letter;
+ if (e[0].len != 0)
+ output_FNB ('B', e);
+ return 1;
+ }
+}
+
+/* DERIVED FROM:
+--------------------------------------------------------------------
+lookup2.c, by Bob Jenkins, December 1996, Public Domain.
+hash(), hash2(), hash3, and mix() are externally useful functions.
+Routines to test the hash are included if SELF_TEST is defined.
+You can use this free for any purpose. It has no warranty.
+--------------------------------------------------------------------
+*/
+
+/*
+--------------------------------------------------------------------
+mix -- mix 3 32-bit values reversibly.
+For every delta with one or two bit set, and the deltas of all three
+ high bits or all three low bits, whether the original value of a,b,c
+ is almost all zero or is uniformly distributed,
+* If mix() is run forward or backward, at least 32 bits in a,b,c
+ have at least 1/4 probability of changing.
+* If mix() is run forward, every bit of c will change between 1/3 and
+ 2/3 of the time. (Well, 22/100 and 78/100 for some 2-bit deltas.)
+mix() was built out of 36 single-cycle latency instructions in a
+ structure that could supported 2x parallelism, like so:
+ a -= b;
+ a -= c; x = (c>>13);
+ b -= c; a ^= x;
+ b -= a; x = (a<<8);
+ c -= a; b ^= x;
+ c -= b; x = (b>>13);
+ ...
+ Unfortunately, superscalar Pentiums and Sparcs can't take advantage
+ of that parallelism. They've also turned some of those single-cycle
+ latency instructions into multi-cycle latency instructions. Still,
+ this is the fastest good hash I could find. There were about 2^^68
+ to choose from. I only looked at a billion or so.
+--------------------------------------------------------------------
+*/
+/* same, but slower, works on systems that might have 8 byte hashval_t's */
+#define mix(a,b,c) \
+{ \
+ a -= b; a -= c; a ^= (c>>13); \
+ b -= c; b -= a; b ^= (a<< 8); \
+ c -= a; c -= b; c ^= ((b&0xffffffff)>>13); \
+ a -= b; a -= c; a ^= ((c&0xffffffff)>>12); \
+ b -= c; b -= a; b = (b ^ (a<<16)) & 0xffffffff; \
+ c -= a; c -= b; c = (c ^ (b>> 5)) & 0xffffffff; \
+ a -= b; a -= c; a = (a ^ (c>> 3)) & 0xffffffff; \
+ b -= c; b -= a; b = (b ^ (a<<10)) & 0xffffffff; \
+ c -= a; c -= b; c = (c ^ (b>>15)) & 0xffffffff; \
+}
+
+/*
+--------------------------------------------------------------------
+hash() -- hash a variable-length key into a 32-bit value
+ k : the key (the unaligned variable-length array of bytes)
+ len : the length of the key, counting by bytes
+ level : can be any 4-byte value
+Returns a 32-bit value. Every bit of the key affects every bit of
+the return value. Every 1-bit and 2-bit delta achieves avalanche.
+About 36+6len instructions.
+
+The best hash table sizes are powers of 2. There is no need to do
+mod a prime (mod is sooo slow!). If you need less than 32 bits,
+use a bitmask. For example, if you need only 10 bits, do
+ h = (h & hashmask(10));
+In which case, the hash table should have hashsize(10) elements.
+
+If you are hashing n strings (ub1 **)k, do it like this:
+ for (i=0, h=0; i<n; ++i) h = hash( k[i], len[i], h);
+
+By Bob Jenkins, 1996. bob_jenkins@burtleburtle.net. You may use this
+code any way you wish, private, educational, or commercial. It's free.
+
+See http://burtleburtle.net/bob/hash/evahash.html
+Use for hash table lookup, or anything where one collision in 2^32 is
+acceptable. Do NOT use for cryptographic purposes.
+--------------------------------------------------------------------
+*/
+
+static hashval_t
+iterative_hash (const void *k_in /* the key */,
+ register size_t length /* the length of the key */,
+ register hashval_t initval /* the previous hash, or
+ an arbitrary value */)
+{
+ register const unsigned char *k = (const unsigned char *)k_in;
+ register hashval_t a,b,c,len;
+
+ /* Set up the internal state */
+ len = length;
+ a = b = 0x9e3779b9; /* the golden ratio; an arbitrary value */
+ c = initval; /* the previous hash value */
+
+ /*---------------------------------------- handle most of the key */
+ while (len >= 12)
+ {
+ a += (k[0] +((hashval_t)k[1]<<8) +((hashval_t)k[2]<<16) +((hashval_t)k[3]<<24));
+ b += (k[4] +((hashval_t)k[5]<<8) +((hashval_t)k[6]<<16) +((hashval_t)k[7]<<24));
+ c += (k[8] +((hashval_t)k[9]<<8) +((hashval_t)k[10]<<16)+((hashval_t)k[11]<<24));
+ mix(a,b,c);
+ k += 12; len -= 12;
+ }
+
+ /*------------------------------------- handle the last 11 bytes */
+ c += length;
+ switch(len) /* all the case statements fall through */
+ {
+ case 11: c+=((hashval_t)k[10]<<24);
+ case 10: c+=((hashval_t)k[9]<<16);
+ case 9 : c+=((hashval_t)k[8]<<8);
+ /* the first byte of c is reserved for the length */
+ case 8 : b+=((hashval_t)k[7]<<24);
+ case 7 : b+=((hashval_t)k[6]<<16);
+ case 6 : b+=((hashval_t)k[5]<<8);
+ case 5 : b+=k[4];
+ case 4 : a+=((hashval_t)k[3]<<24);
+ case 3 : a+=((hashval_t)k[2]<<16);
+ case 2 : a+=((hashval_t)k[1]<<8);
+ case 1 : a+=k[0];
+ /* case 0: nothing left to add */
+ }
+ mix(a,b,c);
+ /*-------------------------------------------- report the result */
+ return c;
+}
+
+hashval_t
+e_hash (const void *a)
+{
+ const struct entry *e = a;
+ hashval_t ret = 0;
+ int i;
+
+ if (e[0].etype != ETYPE_STRUCT && e[0].etype != ETYPE_UNION)
+ abort ();
+ for (i = 0; i <= e[0].len; ++i)
+ {
+ int attriblen;
+ ret = iterative_hash (&e[i], offsetof (struct entry, attrib), ret);
+ attriblen = e[i].attrib ? strlen (e[i].attrib) : -1;
+ ret = iterative_hash (&attriblen, sizeof (int), ret);
+ if (e[i].attrib)
+ ret = iterative_hash (e[i].attrib, attriblen, ret);
+ }
+ return ret;
+}
+
+int
+e_eq (const void *a, const void *b)
+{
+ const struct entry *ea = a, *eb = b;
+ int i;
+ if (ea[0].etype != ETYPE_STRUCT && ea[0].etype != ETYPE_UNION)
+ abort ();
+ if (ea[0].len != eb[0].len)
+ return 0;
+ for (i = 0; i <= ea[0].len; ++i)
+ {
+ if (ea[i].etype != eb[i].etype
+ || ea[i].len != eb[i].len
+ || ea[i].arr_len != eb[i].arr_len
+ || ea[i].type != eb[i].type)
+ return 0;
+ if ((ea[i].attrib == NULL) ^ (eb[i].attrib == NULL))
+ return 0;
+ if (ea[i].attrib && strcmp (ea[i].attrib, eb[i].attrib) != 0)
+ return 0;
+ }
+ return 1;
+}
+
+static int
+e_exists (const struct entry *e)
+{
+ struct entry *h;
+ hashval_t hval;
+
+ hval = e_hash (e);
+ for (h = hash_table[hval % HASH_SIZE]; h; h = h->next)
+ if (e_eq (e, h))
+ return 1;
+ return 0;
+}
+
+static void
+e_insert (struct entry *e)
+{
+ hashval_t hval;
+
+ hval = e_hash (e);
+ e->next = hash_table[hval % HASH_SIZE];
+ hash_table[hval % HASH_SIZE] = e;
+}
+
+void
+output (struct entry *e)
+{
+ int i;
+ char c;
+ struct entry *n;
+ const char *skip_cint = "";
+
+ if (e[0].etype != ETYPE_STRUCT && e[0].etype != ETYPE_UNION)
+ abort ();
+
+ if (e_exists (e))
+ return;
+
+ n = (struct entry *) malloc ((e[0].len + 1) * sizeof (struct entry));
+ memcpy (n, e, (e[0].len + 1) * sizeof (struct entry));
+ e_insert (n);
+
+ if (idx == limidx)
+ switchfiles (e[0].len);
+
+ for (i = 1; i <= e[0].len; ++i)
+ if ((e[i].etype == ETYPE_TYPE || e[i].etype == ETYPE_ARRAY)
+ && (e[i].type->type == TYPE_CINT || e[i].type->type == TYPE_CUINT))
+ break;
+ if (i <= e[0].len)
+ skip_cint = "CI";
+ if (e[0].attrib)
+ fprintf (outfile, (generate_random () & 1)
+ ? "TX%s(%d,%s %s,," : "TX%s(%d,%s,%s,", skip_cint,
+ idx, e[0].etype == ETYPE_STRUCT ? "struct" : "union",
+ e[0].attrib);
+ else if (e[0].etype == ETYPE_STRUCT)
+ fprintf (outfile, "T%s(%d,", skip_cint, idx);
+ else
+ fprintf (outfile, "U%s(%d,", skip_cint, idx);
+ c = 'a';
+ for (i = 1; i <= e[0].len; )
+ i += subfield (e + i, &c);
+ fputs (",", outfile);
+ c = 'a';
+ for (i = 1; i <= e[0].len; )
+ {
+ i += subvalues (e + i, namebuf, &c);
+ if (e[0].etype == ETYPE_UNION)
+ break;
+ }
+ fputs (")\n", outfile);
+ if (output_one && idx == limidx)
+ exit (0);
+ ++idx;
+}
+
+enum FEATURE
+{
+ FEATURE_VECTOR = 1,
+ FEATURE_COMPLEX = 2,
+ FEATURE_ZEROARRAY = 8,
+ FEATURE_ZEROBITFLD = 16,
+ ALL_FEATURES = FEATURE_COMPLEX | FEATURE_VECTOR | FEATURE_ZEROARRAY
+ | FEATURE_ZEROBITFLD
+};
+
+void
+singles (enum FEATURE features)
+{
+ struct entry e[2];
+ int i;
+ memset (e, 0, sizeof (e));
+ e[0].etype = ETYPE_STRUCT;
+ output (e);
+ e[0].etype = ETYPE_UNION;
+ output (e);
+ e[0].len = 1;
+ e[0].attrib = NULL;
+ for (i = 0; i < NTYPES2; ++i)
+ {
+ e[0].etype = ETYPE_STRUCT;
+ e[1].etype = ETYPE_TYPE;
+ e[1].type = &base_types[i];
+ output (e);
+ e[0].etype = ETYPE_UNION;
+ output (e);
+ }
+ if (features & FEATURE_COMPLEX)
+ for (i = 0; i < NCTYPES2; ++i)
+ {
+ e[0].etype = ETYPE_STRUCT;
+ e[1].etype = ETYPE_TYPE;
+ e[1].type = &complex_types[i];
+ output (e);
+ e[0].etype = ETYPE_UNION;
+ output (e);
+ }
+ if (features & FEATURE_VECTOR)
+ for (i = 0; i < NVTYPES2; ++i)
+ {
+ e[0].etype = ETYPE_STRUCT;
+ e[1].etype = ETYPE_TYPE;
+ e[1].type = &vector_types[i];
+ output (e);
+ e[0].etype = ETYPE_UNION;
+ output (e);
+ }
+}
+
+void
+choose_type (enum FEATURE features, struct entry *e, int r, int in_array)
+{
+ int i;
+
+ i = NTYPES2 - NTYPES1;
+ if (features & FEATURE_COMPLEX)
+ i += NCTYPES2;
+ if (features & FEATURE_VECTOR)
+ i += NVTYPES2;
+ r >>= 2;
+ r %= i;
+ if (r < NTYPES2 - NTYPES1)
+ e->type = &base_types[r + NTYPES1];
+ r -= NTYPES2 - NTYPES1;
+ if (e->type == NULL && (features & FEATURE_COMPLEX))
+ {
+ if (r < NCTYPES2)
+ e->type = &complex_types[r];
+ r -= NCTYPES2;
+ }
+ if (e->type == NULL && (features & FEATURE_VECTOR))
+ {
+ if (r < NVTYPES2)
+ e->type = &vector_types[r];
+ r -= NVTYPES2;
+ }
+ if (e->type == NULL)
+ abort ();
+}
+
+/* This is from gcc.c-torture/execute/builtin-bitops-1.c. */
+static int
+my_ffsll (unsigned long long x)
+{
+ int i;
+ if (x == 0)
+ return 0;
+ /* We've tested LLONG_MAX for 64 bits so this should be safe. */
+ for (i = 0; i < 64; i++)
+ if (x & (1ULL << i))
+ break;
+ return i + 1;
+}
+
+void
+generate_fields (enum FEATURE features, struct entry *e, struct entry *parent,
+ int len)
+{
+ int r, i, j, ret = 1, n, incr, sametype;
+
+ for (n = 0; n < len; n += incr)
+ {
+ r = generate_random ();
+ /* 50% ETYPE_TYPE base_types NTYPES1
+ 12.5% ETYPE_TYPE other
+ 12.5% ETYPE_ARRAY
+ 12.5% ETYPE_BITFLD
+ 12.5% ETYPE_STRUCT|ETYPE_UNION|ETYPE_STRUCT_ARRAY|ETYPE_UNION_ARRAY */
+ i = (r & 7);
+ r >>= 3;
+ incr = 1;
+ switch (i)
+ {
+ case 6: /* BITfields disabled for now as _Bool bitfields are broken. */
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ e[n].etype = ETYPE_TYPE;
+ e[n].type = &base_types[r % NTYPES1];
+ break;
+ case 4:
+ e[n].etype = ETYPE_TYPE;
+ choose_type (features, &e[n], r, 0);
+ break;
+ case 5:
+ e[n].etype = ETYPE_ARRAY;
+ i = r & 1;
+ r >>= 1;
+ if (i)
+ e[n].type = &base_types[r % NTYPES1];
+ else
+ choose_type (features, &e[n], r, 1);
+ r = generate_random ();
+ if ((features & FEATURE_ZEROARRAY) && (r & 3) == 0)
+ {
+ e[n].arr_len = 0;
+ if (n == len - 1 && (r & 4)
+ && (parent->etype == ETYPE_STRUCT
+ || parent->etype == ETYPE_STRUCT_ARRAY))
+ {
+ int k;
+ for (k = 0; k < n; ++k)
+ if (e[k].etype != ETYPE_BITFLD || e[k].len)
+ {
+ e[n].arr_len = 255;
+ break;
+ }
+ }
+ }
+ else if ((r & 3) != 3)
+ e[n].arr_len = (r >> 2) & 7;
+ else
+ e[n].arr_len = (r >> 2) & 31;
+ break;
+#if 0
+ case 6:
+ sametype = 1;
+ switch (r & 7)
+ {
+ case 0:
+ case 1:
+ case 2:
+ break;
+ case 3:
+ case 4:
+ case 5:
+ incr = 1 + (r >> 3) % (len - n);
+ break;
+ case 6:
+ case 7:
+ sametype = 0;
+ incr = 1 + (r >> 3) % (len - n);
+ break;
+ }
+ for (j = n; j < n + incr; ++j)
+ {
+ int mi, ma;
+
+ e[j].etype = ETYPE_BITFLD;
+ if (j == n || !sametype)
+ {
+ r = generate_random ();
+ r >>= 2;
+ e[j].type
+ = &bitfld_types[r % n_bitfld_types];
+ }
+ else
+ e[j].type = e[n].type;
+ r = generate_random ();
+ mi = 0;
+ ma = 0;
+ switch (e[j].type->bitfld)
+ {
+ case 'C': ma = 8; break;
+ case 'S': ma = 16; break;
+ case 'I': ma = 32; break;
+ case 'L':
+ case 'Q': ma = 64; break;
+ case 'B': ma = 1; break;
+ case ' ':
+ if (e[j].type->type == TYPE_UENUM)
+ mi = my_ffsll (e[j].type->maxval + 1) - 1;
+ else if (e[j].type->type == TYPE_SENUM)
+ mi = my_ffsll (e[j].type->maxval + 1);
+ else
+ abort ();
+ if (!mi)
+ mi = 1;
+ if (mi <= 32)
+ ma = 32;
+ else
+ ma = 64;
+ break;
+ default:
+ abort ();
+ }
+ e[j].len = ma + 1;
+ if (sametype && (r & 3) == 0 && ma > 1)
+ {
+ int sum = 0, k;
+ for (k = n; k < j; ++k)
+ sum += e[k].len;
+ sum %= ma;
+ e[j].len = sum ? ma - sum : ma;
+ }
+ r >>= 2;
+ if (! (features & FEATURE_ZEROBITFLD) && mi == 0)
+ mi = 1;
+ if (e[j].len < mi || e[j].len > ma)
+ e[j].len = mi + (r % (ma + 1 - mi));
+ r >>= 6;
+ if ((features & FEATURE_ZEROBITFLD) && (r & 3) == 0
+ && mi == 0)
+ e[j].len = 0;
+ }
+ break;
+#endif
+ case 7:
+ switch (r & 7)
+ {
+ case 0:
+ case 1:
+ case 2:
+ e[n].etype = ETYPE_STRUCT;
+ break;
+ case 3:
+ case 4:
+ e[n].etype = ETYPE_UNION;
+ break;
+ case 5:
+ case 6:
+ e[n].etype = ETYPE_STRUCT_ARRAY;
+ break;
+ case 7:
+ e[n].etype = ETYPE_UNION_ARRAY;
+ break;
+ }
+ r >>= 3;
+ e[n].len = r % (len - n);
+ incr = 1 + e[n].len;
+ generate_fields (features, &e[n + 1], &e[n], e[n].len);
+ if (e[n].etype == ETYPE_STRUCT_ARRAY
+ || e[n].etype == ETYPE_UNION_ARRAY)
+ {
+ r = generate_random ();
+ if ((features & FEATURE_ZEROARRAY) && (r & 3) == 0)
+ {
+ e[n].arr_len = 0;
+ if (n + incr == len && (r & 4)
+ && (parent->etype == ETYPE_STRUCT
+ || parent->etype == ETYPE_STRUCT_ARRAY))
+ {
+ int k;
+ for (k = 0; k < n; ++k)
+ if (e[k].etype != ETYPE_BITFLD || e[k].len)
+ {
+ e[n].arr_len = 255;
+ break;
+ }
+ }
+ }
+ else if ((r & 3) != 3)
+ e[n].arr_len = (r >> 2) & 7;
+ else
+ e[n].arr_len = (r >> 2) & 31;
+ }
+ break;
+ }
+ }
+}
+
+void
+generate_random_tests (enum FEATURE features, int len)
+{
+ struct entry e[len + 1];
+ int i, r;
+ if (len > 'z' - 'a' + 1)
+ abort ();
+ memset (e, 0, sizeof (e));
+ r = generate_random ();
+ if ((r & 7) == 0)
+ e[0].etype = ETYPE_UNION;
+ else
+ e[0].etype = ETYPE_STRUCT;
+ r >>= 3;
+ e[0].len = len;
+ generate_fields (features, &e[1], &e[0], len);
+ output (e);
+}
+
+struct { const char *name; enum FEATURE f; }
+features[] = {
+{ "normal", 0 },
+{ "complex", FEATURE_COMPLEX },
+{ "vector", FEATURE_VECTOR },
+{ "[0] :0", FEATURE_ZEROARRAY | FEATURE_ZEROBITFLD },
+{ "complex vector [0]",
+ FEATURE_COMPLEX | FEATURE_VECTOR | FEATURE_ZEROARRAY }
+};
+
+int
+main (int argc, char **argv)
+{
+ int i, j, count, c, n = 3000;
+ char *optarg;
+
+ if (sizeof (int) != 4 || sizeof (long long) != 8)
+ return 1;
+
+ i = 1;
+ while (i < argc)
+ {
+ c = '\0';
+ if (argv[i][0] == '-' && argv[i][2] == '\0')
+ c = argv[i][1];
+ optarg = argv[i + 1];
+ if (!optarg)
+ goto usage;
+ switch (c)
+ {
+ case 'n':
+ n = atoi (optarg);
+ break;
+ case 'd':
+ destdir = optarg;
+ break;
+ case 's':
+ srcdir = optarg;
+ break;
+ case 'i':
+ output_one = 1;
+ limidx = atoi (optarg);
+ break;
+ default:
+ fprintf (stderr, "unrecognized option %s\n", argv[i]);
+ goto usage;
+ }
+ i += 2;
+ }
+
+ if (output_one)
+ {
+ outfile = fopen ("/dev/null", "w");
+ if (outfile == NULL)
+ {
+ fputs ("could not open /dev/null", stderr);
+ return 1;
+ }
+ n = limidx + 1;
+ }
+
+ if (destdir == NULL && !output_one)
+ {
+ usage:
+ fprintf (stderr, "Usage:\n\
+%s [-s srcdir -d destdir] [-n count] [-i idx]\n\
+Either -s srcdir -d destdir or -i idx must be used\n", argv[0]);
+ return 1;
+ }
+
+ if (srcdir == NULL && !output_one)
+ goto usage;
+
+ for (i = 0; i < NTYPES2; ++i)
+ if (base_types[i].bitfld)
+ bitfld_types[n_bitfld_types++] = base_types[i];
+ for (i = 0; i < sizeof (features) / sizeof (features[0]); ++i)
+ {
+ int startidx = idx;
+ if (! output_one)
+ limidx = idx;
+ if (!i)
+ count = 200;
+ else
+ count = 20;
+ for (j = 1; j <= 9; ++j)
+ while (idx < startidx + j * count)
+ generate_random_tests (features[i].f, j);
+ while (idx < startidx + count * 10)
+ generate_random_tests (features[i].f, 10 + (generate_random () % 16));
+ }
+ for (i = 0; n > 3000 && i < sizeof (features) / sizeof (features[0]); ++i)
+ {
+ int startidx;
+ startidx = idx;
+ if (! output_one)
+ limidx = idx;
+ singles (features[i].f);
+ if (!i)
+ {
+ count = 1000;
+ while (idx < startidx + 1000)
+ generate_random_tests (features[i].f, 1);
+ }
+ else
+ {
+ startidx = idx;
+ count = 100;
+ while (idx < startidx + 100)
+ generate_random_tests (features[i].f, 1);
+ }
+ startidx = idx;
+ for (j = 2; j <= 9; ++j)
+ while (idx < startidx + (j - 1) * count)
+ generate_random_tests (features[i].f, j);
+ while (idx < startidx + count * 9)
+ generate_random_tests (features[i].f, 10 + (generate_random () % 16));
+ }
+ if (! output_one)
+ limidx = idx;
+ while (idx < n)
+ generate_random_tests (ALL_FEATURES, 1 + (generate_random () % 25));
+ fclose (outfile);
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/gnu-encoding/vector-defs.h b/gcc/testsuite/objc.dg/gnu-encoding/vector-defs.h
new file mode 100644
index 000000000..57140f115
--- /dev/null
+++ b/gcc/testsuite/objc.dg/gnu-encoding/vector-defs.h
@@ -0,0 +1,72 @@
+/* This includes all of the vector modes that are recognized by
+ c_common_type_for_mode. */
+
+typedef int __attribute__((mode(QI))) qi;
+typedef int __attribute__((mode(HI))) hi;
+typedef int __attribute__((mode(SI))) si;
+typedef int __attribute__((mode(DI))) di;
+typedef float __attribute__((mode(SF))) sf;
+typedef float __attribute__((mode(DF))) df;
+
+#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 5)
+
+typedef qi __attribute__((vector_size (8))) v8qi;
+typedef qi __attribute__((vector_size (16))) v16qi;
+
+typedef hi __attribute__((vector_size (4))) v2hi;
+typedef hi __attribute__((vector_size (8))) v4hi;
+typedef hi __attribute__((vector_size (16))) v8hi;
+
+typedef si __attribute__((vector_size (8))) v2si;
+typedef si __attribute__((vector_size (16))) v4si;
+
+typedef di __attribute__((vector_size (8))) v1di;
+typedef di __attribute__((vector_size (16))) v2di;
+
+typedef sf __attribute__((vector_size (8))) v2sf;
+typedef sf __attribute__((vector_size (16))) v4sf;
+typedef sf __attribute__((vector_size (64))) v16sf;
+
+typedef df __attribute__((vector_size (16))) v2df;
+
+#else
+
+typedef int __attribute__((mode(V8QI))) v8qi;
+typedef int __attribute__((mode(V16QI))) v16qi;
+
+typedef int __attribute__((mode(V2HI))) v2hi;
+typedef int __attribute__((mode(V4HI))) v4hi;
+typedef int __attribute__((mode(V8HI))) v8hi;
+
+typedef int __attribute__((mode(V2SI))) v2si;
+typedef int __attribute__((mode(V4SI))) v4si;
+
+typedef int __attribute__((mode(V1DI))) v1di;
+typedef int __attribute__((mode(V2DI))) v2di;
+
+typedef float __attribute__((mode(V2SF))) v2sf;
+typedef float __attribute__((mode(V4SF))) v4sf;
+typedef float __attribute__((mode(V16SF))) v16sf;
+
+typedef float __attribute__((mode(V2DF))) v2df;
+
+#endif
+
+typedef union U8QI { v8qi v; qi a[8]; } u8qi;
+typedef union U16QI { v16qi v; qi a[16]; } u16qi;
+
+typedef union U2HI { v2hi v; hi a[2]; } u2hi;
+typedef union U4HI { v4hi v; hi a[4]; } u4hi;
+typedef union U8HI { v8hi v; hi a[8]; } u8hi;
+
+typedef union U2SI { v2si v; si a[2]; } u2si;
+typedef union U4SI { v4si v; si a[4]; } u4si;
+
+typedef union U1DI { v1di v; di a[1]; } u1di;
+typedef union U2DI { v2di v; di a[2]; } u2di;
+
+typedef union U2SF { v2sf v; sf a[2]; } u2sf;
+typedef union U4SF { v4sf v; sf a[4]; } u4sf;
+typedef union U16SF { v16sf v; sf a[16]; } u16sf;
+
+typedef union U2DF { v2df v; df a[2]; } u2df;
diff --git a/gcc/testsuite/objc.dg/gnu-runtime-1.m b/gcc/testsuite/objc.dg/gnu-runtime-1.m
new file mode 100644
index 000000000..c7e3bcc3a
--- /dev/null
+++ b/gcc/testsuite/objc.dg/gnu-runtime-1.m
@@ -0,0 +1,19 @@
+/* Test that compiling for the GNU runtime works (regardless of
+ the system runtime used). */
+/* Author: Ziemowit Laski <zlaski@apple.com> */
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-fnext-runtime" } { "" } } */
+
+#include <objc/Object.h>
+
+@interface FooBar: Object
+- (void)boo;
+@end
+
+int main ()
+{
+ id fooBarInst = [[FooBar alloc] init];
+ [fooBarInst boo];
+ return 0;
+}
+
diff --git a/gcc/testsuite/objc.dg/gnu-runtime-2.m b/gcc/testsuite/objc.dg/gnu-runtime-2.m
new file mode 100644
index 000000000..9903d2972
--- /dev/null
+++ b/gcc/testsuite/objc.dg/gnu-runtime-2.m
@@ -0,0 +1,30 @@
+/* Sanity check for GNU-runtime version of constant strings,
+ regardless of runtime used on target system. */
+
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-fnext-runtime" } { "" } } */
+
+#include <objc/Object.h>
+#include <string.h>
+#include <stdlib.h>
+
+@interface NXConstantString: Object
+{
+ char *c_string;
+ unsigned int len;
+}
+-(const char *) cString;
+-(unsigned int) length;
+@end
+
+@implementation NXConstantString
+-(const char *) cString { return c_string; }
+-(unsigned int) length { return len; }
+@end
+
+int main(int argc, void **args)
+{
+ if (strcmp ([@"this is a string" cString], "this is a string"))
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/gnu-runtime-3.m b/gcc/testsuite/objc.dg/gnu-runtime-3.m
new file mode 100644
index 000000000..e0c8cc416
--- /dev/null
+++ b/gcc/testsuite/objc.dg/gnu-runtime-3.m
@@ -0,0 +1,14 @@
+/* Sanity check for GNU-runtime regardless of runtime used on target system. */
+
+/* { dg-do run } */
+/* { dg-skip-if "" { *-*-* } { "-fnext-runtime" } { "" } } */
+
+#include <objc/Object.h>
+#include <string.h>
+#include <stdlib.h>
+
+int main(int argc, void **args)
+{
+ [Object new];
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/headers.m b/gcc/testsuite/objc.dg/headers.m
new file mode 100644
index 000000000..4c61e1e55
--- /dev/null
+++ b/gcc/testsuite/objc.dg/headers.m
@@ -0,0 +1,31 @@
+// Test for obscure conflicts with the system headers (inspired by similar
+// test in libstdc++-v3). Author: Loren J. Rittle <ljrittle@acm.org>.
+// { dg-options "-Wall -Wpointer-arith -Wcast-qual -Wstrict-prototypes -Wshadow" }
+// { dg-do compile }
+
+#ifdef __NEXT_RUNTIME__
+#include <Foundation/NSString.h>
+#else
+#include <objc/NXConstStr.h>
+#endif
+#include <objc/Object.h>
+#include <objc/Protocol.h>
+#ifdef __NEXT_RUNTIME__
+#include <objc/objc-runtime.h>
+#else
+#include <objc/encoding.h>
+#include <objc/hash.h>
+#endif
+
+#include <objc/objc-api.h>
+#ifndef __NEXT_RUNTIME__
+#include <objc/objc-list.h>
+#endif
+
+#include <objc/objc.h>
+
+#ifndef __NEXT_RUNTIME__
+#include <objc/sarray.h>
+#include <objc/thr.h>
+#include <objc/typedstream.h>
+#endif
diff --git a/gcc/testsuite/objc.dg/id-1.m b/gcc/testsuite/objc.dg/id-1.m
new file mode 100644
index 000000000..2bfcc63f9
--- /dev/null
+++ b/gcc/testsuite/objc.dg/id-1.m
@@ -0,0 +1,7 @@
+/* Test attempt to redefine 'id' in an incompatible fashion. */
+/* { dg-do compile } */
+
+typedef int id; /* { dg-error "conflicting types for .id." } */
+/* { dg-message "previous declaration of .id. was here" "" { target *-*-* } 0 } */
+
+id b;
diff --git a/gcc/testsuite/objc.dg/image-info.m b/gcc/testsuite/objc.dg/image-info.m
new file mode 100644
index 000000000..194d3664f
--- /dev/null
+++ b/gcc/testsuite/objc.dg/image-info.m
@@ -0,0 +1,43 @@
+/* Check if the '-freplace-objc-classes' option causes the
+ __OBJC,__image_info section to be emitted. This is only
+ usable on MacOS X 10.3 and later. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
+
+/* { dg-do compile { target { *-*-darwin* } } } */
+/* { dg-skip-if "NeXT-only" { *-*-* } { "-fgnu-runtime" } { "" } } */
+/* { dg-options "-freplace-objc-classes" } */
+
+#include <objc/objc.h>
+#include <objc/Object.h>
+
+extern void abort(void);
+#define CHECK_IF(expr) if(!(expr)) abort();
+
+@interface Object (TEST_SUITE_C1)
+- init;
+@end
+@implementation Object (TEST_SUITE_C1)
+- init {return self;}
+@end
+
+@interface Base: Object {
+@public
+ int a;
+ float b;
+ char c;
+}
+- init;
+@end
+
+@implementation Base
+- init {
+ [super init];
+ a = 123;
+ b = 1.23;
+ c = 'c';
+ return self;
+}
+@end
+
+/* { dg-final { scan-assembler "\t.section __OBJC, __image_info.*\n\t.align.*\nL_OBJC_ImageInfo.*:\n\t.long\t0\n\t.long\t1" { target { *-*-darwin* && { ! lp64 } } } } } */
+/* { dg-final { scan-assembler "\t.section __DATA, __objc_imageinfo.*\n\t.align.*\nL_OBJC_ImageInfo.*:\n\t.long\t0\n\t.long\t17" { target { *-*-darwin* && { lp64 } } } } } */
diff --git a/gcc/testsuite/objc.dg/incomplete-type-1.m b/gcc/testsuite/objc.dg/incomplete-type-1.m
new file mode 100644
index 000000000..f1e875f9a
--- /dev/null
+++ b/gcc/testsuite/objc.dg/incomplete-type-1.m
@@ -0,0 +1,22 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+enum type1;
+struct type2;
+
+@interface MyObject
+- (void) method1: (enum type1)argument;
+- (void) method2: (struct type2)argument;
+@end
+
+@implementation MyObject
+- (void) method1: (enum type1)argument { /* { dg-error "does not have a known size" } */
+ return;
+}
+- (void) method2: (struct type2)argument { /* { dg-error "does not have a known size" } */
+ return;
+}
+@end
+
diff --git a/gcc/testsuite/objc.dg/invalid-method-1.m b/gcc/testsuite/objc.dg/invalid-method-1.m
new file mode 100644
index 000000000..78eae2c58
--- /dev/null
+++ b/gcc/testsuite/objc.dg/invalid-method-1.m
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* Test that we keep compiling if a method definition is found outside
+ of an @implementation context.
+*/
+
++ (void)C { } /* { dg-error "method definition not in @implementation context" } */
+
+/* We have another error here to test that the compiler is still going and
+ finding errors in the rest of the code.
+*/
+@compatibility_alias class1 class2; /* { dg-warning "annot find class" } */
diff --git a/gcc/testsuite/objc.dg/invalid-method-2.m b/gcc/testsuite/objc.dg/invalid-method-2.m
new file mode 100644
index 000000000..cb18de957
--- /dev/null
+++ b/gcc/testsuite/objc.dg/invalid-method-2.m
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+
+/* Test that using an invalid type in a method declaration produces a
+ friendly error without a compiler crash. */
+
+@interface MyClass
+@end
+
+@implementation MyClass
+- (x) method /* { dg-error "unknown type name" } */
+{
+ return 0;
+}
+- (id) method2: (x)argument /* { dg-error "unknown type name" } */
+{
+ return 0;
+}
+@end
diff --git a/gcc/testsuite/objc.dg/invalid-type-1.m b/gcc/testsuite/objc.dg/invalid-type-1.m
new file mode 100644
index 000000000..b8609f8c8
--- /dev/null
+++ b/gcc/testsuite/objc.dg/invalid-type-1.m
@@ -0,0 +1,24 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+#include <objc/objc.h>
+
+typedef int Integer;
+
+@class MyClass;
+
+typedef MyClass AClass;
+
+@protocol MyProtocol
+- (void) method;
+@end
+
+Class <MyProtocol> class_object; /* This is fine. */
+
+id <MyProtocol> object; /* This is fine. */
+
+AClass <MyProtocol> *object1; /* This is fine. */
+
+Integer <MyProtocol> *object2; /* { dg-error "only Objective-C object types can be qualified with a protocol" } */
+
+Integer <NonExistingProtocol> *object3; /* { dg-error "only Objective-C object types can be qualified with a protocol" } */
+/* { dg-error "cannot find protocol" "" { target *-*-* } 23 } */
diff --git a/gcc/testsuite/objc.dg/isa-field-1.m b/gcc/testsuite/objc.dg/isa-field-1.m
new file mode 100644
index 000000000..377280f0d
--- /dev/null
+++ b/gcc/testsuite/objc.dg/isa-field-1.m
@@ -0,0 +1,63 @@
+/* Ensure there are no bizarre difficulties with accessing the 'isa' field of objects. */
+/* { dg-do compile } */
+
+#include "../objc-obj-c++-shared/Object1.h"
+
+@interface Object (Test)
+- (Class) test1: (id)object;
+@end
+
+@interface Derived: Object
+- (Class) test2: (id)object;
+@end
+
+@implementation Object (Test)
+
+Class test1(id object) {
+#ifdef __NEXT_RUNTIME__
+ Class cls = object->isa;
+#else
+ Class cls = object->class_pointer;
+#endif
+ return cls;
+}
+- (Class) test1: (id)object {
+#ifdef __NEXT_RUNTIME__
+ Class cls = object->isa;
+#else
+ Class cls = object->class_pointer;
+#endif
+ return cls;
+}
+
+@end
+
+@implementation Derived
+
+Class test2(id object) {
+#ifdef __NEXT_RUNTIME__
+ Class cls = object->isa;
+#else
+ Class cls = object->class_pointer;
+#endif
+ return cls;
+}
+- (Class) test2: (id)object {
+#ifdef __NEXT_RUNTIME__
+ Class cls = object->isa;
+#else
+ Class cls = object->class_pointer;
+#endif
+ return cls;
+}
+
+@end
+
+Class test3(id object) {
+#ifdef __NEXT_RUNTIME__
+ Class cls = object->isa;
+#else
+ Class cls = object->class_pointer;
+#endif
+ return cls;
+}
diff --git a/gcc/testsuite/objc.dg/ivar-invalid-type-1.m b/gcc/testsuite/objc.dg/ivar-invalid-type-1.m
new file mode 100644
index 000000000..3e7785db8
--- /dev/null
+++ b/gcc/testsuite/objc.dg/ivar-invalid-type-1.m
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+#include <objc/objc.h>
+
+@interface MyRootClass
+{
+ Class isa;
+}
+@end
+
+@interface MySubClass
+{
+ volatile int a; /* This is allowed */
+ extern int b; /* { dg-error "expected" } */
+ static int c; /* { dg-error "expected" } */
+ inline int d; /* { dg-error "expected" } */
+ typedef int e; /* { dg-error "expected" } */
+ __thread int f; /* { dg-error "expected" } */
+}
+@end
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 000000000..4a8776805
--- /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/keywords-1.m b/gcc/testsuite/objc.dg/keywords-1.m
new file mode 100644
index 000000000..abb4537ae
--- /dev/null
+++ b/gcc/testsuite/objc.dg/keywords-1.m
@@ -0,0 +1,27 @@
+/* Test that 'in', 'out', 'inout', 'bycopy', 'byref', 'oneway'
+ are not keywords outside of a "protocol qualifier" context.
+*/
+/* { dg-do compile } */
+
+typedef int in;
+
+in out (in inout)
+{
+ int byref = inout * 2;
+
+ return byref + inout;
+}
+
+@class byref;
+
+@interface inout
+@end
+
+@protocol oneway;
+
+int main (void)
+{
+ in bycopy = (in)(out (0));
+
+ return (in)bycopy;
+}
diff --git a/gcc/testsuite/objc.dg/keywords-2.m b/gcc/testsuite/objc.dg/keywords-2.m
new file mode 100644
index 000000000..c81cb4d0c
--- /dev/null
+++ b/gcc/testsuite/objc.dg/keywords-2.m
@@ -0,0 +1,24 @@
+/* Test that 'encode', 'end', 'compatibility_alias', 'defs',
+ 'protocol', 'selector', finally', 'synchronized', 'interface',
+ 'implementation' are not keywords if not after a '@'.
+*/
+/* { dg-do compile } */
+
+int encode (int end)
+{
+ int compatibility_alias = end * 2;
+ int defs = compatibility_alias * 2;
+ int protocol = defs * 2;
+ int selector = protocol * 2;
+ int finally = selector * 2;
+ int synchronized = finally * 2;
+ int interface = synchronized * 2;
+ int implementation = interface * 2;
+
+ return implementation;
+}
+
+int main (void)
+{
+ return encode (0);
+}
diff --git a/gcc/testsuite/objc.dg/keywords-3.m b/gcc/testsuite/objc.dg/keywords-3.m
new file mode 100644
index 000000000..28c2cf50e
--- /dev/null
+++ b/gcc/testsuite/objc.dg/keywords-3.m
@@ -0,0 +1,20 @@
+/* Test that 'class', 'public', 'private', protected', 'try', 'catch',
+ 'throw' are not keywords in pure Objective-C if not after a '@'.
+*/
+/* { dg-do compile } */
+
+int class (int public)
+{
+ int private = public;
+ int protected = private * 2;
+ int try = protected * 2;
+ int catch = try * 2;
+ int throw = catch * 2;
+
+ return throw;
+}
+
+int main (void)
+{
+ return class (0);
+}
diff --git a/gcc/testsuite/objc.dg/layout-1.m b/gcc/testsuite/objc.dg/layout-1.m
new file mode 100644
index 000000000..f702eb2ba
--- /dev/null
+++ b/gcc/testsuite/objc.dg/layout-1.m
@@ -0,0 +1,15 @@
+/* Ensure that we do not get bizarre warnings referring to
+ __attribute__((packed)) or some such. */
+/* { dg-do compile } */
+/* { dg-options "-Wpadded -Wpacked" } */
+
+#include "../objc-obj-c++-shared/Object1.h"
+
+@interface Derived1: Object
+{ }
+@end
+
+@interface Derived2: Object
+- (id) foo;
+@end
+
diff --git a/gcc/testsuite/objc.dg/layout-2.m b/gcc/testsuite/objc.dg/layout-2.m
new file mode 100644
index 000000000..474fc0461
--- /dev/null
+++ b/gcc/testsuite/objc.dg/layout-2.m
@@ -0,0 +1,14 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, February 2011. */
+/* Ensure that -Wpadded generates no warnings during runtime structure metadata
+ generation. */
+/* { dg-do compile } */
+/* { dg-options "-Wpadded" } */
+
+#include "../objc-obj-c++-shared/Object1.h"
+
+/* Implement a class, so that the metadata generation happens. */
+@interface MyClass : Object
+@end
+
+@implementation MyClass
+@end
diff --git a/gcc/testsuite/objc.dg/libobjc-selector-1.m b/gcc/testsuite/objc.dg/libobjc-selector-1.m
new file mode 100644
index 000000000..49947d7b8
--- /dev/null
+++ b/gcc/testsuite/objc.dg/libobjc-selector-1.m
@@ -0,0 +1,39 @@
+/* Test a little inefficiency that was fixed in libobjc when dealing
+ with selectors (PR libobjc/45953). */
+
+/* { dg-do run } */
+/* { dg-skip-if "" { *-*-* } { "-fnext-runtime" } { "" } } */
+
+/* To get the modern GNU Objective-C Runtime API, you include
+ objc/runtime.h. */
+#include <objc/runtime.h>
+#include <stdlib.h>
+
+/* Test that registering a new selector, with the same name but a
+ different type than the previous one, does not change the original
+ name string. It is actually fine to change it (there is no
+ guarantee that it won't change), except for runtime performance /
+ memory consumption, since changing it means that the runtime is
+ doing an unneeded objc_malloc()/strcpy(), which is inefficient. */
+
+int main (void)
+{
+ SEL selector_1;
+ SEL selector_2;
+ const char *name_1;
+ const char *name_2;
+
+ /* These method type strings may well be invalid. Please don't use
+ them as examples. They are irrelevant for this test; any string
+ will do. */
+ selector_1 = sel_registerTypedName ("method", "v@:");
+ name_1 = sel_getName (selector_1);
+
+ selector_2 = sel_registerTypedName ("method", "i@:");
+ name_2 = sel_getName (selector_1);
+
+ if (name_1 != name_2)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/local-decl-1.m b/gcc/testsuite/objc.dg/local-decl-1.m
new file mode 100644
index 000000000..4a4bfdffe
--- /dev/null
+++ b/gcc/testsuite/objc.dg/local-decl-1.m
@@ -0,0 +1,25 @@
+/* Test for hiding of ivars by local variables. */
+/* Author: Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-do compile } */
+
+@interface Sprite {
+ int a;
+}
+@end
+
+Sprite *glob;
+
+@interface blah
+{
+ Sprite* sprite;
+}
+@end
+
+@implementation blah
+- (Sprite *)load
+{
+ Sprite *sprite = 0;
+ Sprite *glob = 0; /* ok */
+ return sprite; /* { dg-warning "hides instance variable" } */
+}
+@end
diff --git a/gcc/testsuite/objc.dg/local-decl-2.m b/gcc/testsuite/objc.dg/local-decl-2.m
new file mode 100644
index 000000000..b1af6d27b
--- /dev/null
+++ b/gcc/testsuite/objc.dg/local-decl-2.m
@@ -0,0 +1,42 @@
+/* Test for ivar access inside of class methods. It should be allowed (with a warning), but only
+ if no other declarations with the same name are seen. */
+/* Author: Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-do compile } */
+
+#include "../objc-obj-c++-shared/Object1.h"
+
+@interface Sprite: Object {
+ int sprite, spree;
+}
++ (void)setFoo:(int)foo;
++ (void)setSprite:(int)sprite;
+- (void)setFoo:(int)foo;
+- (void)setSprite:(int)sprite;
+@end
+
+int spree = 23;
+
+@implementation Sprite
++ (void)setFoo:(int)foo {
+ sprite = foo; /* { dg-warning "instance variable .sprite. accessed in class method" } */
+ spree = foo;
+}
++ (void)setSprite:(int)sprite {
+ int spree;
+ sprite = 15;
+ spree = 17;
+ ((Sprite *)self)->sprite = 16; /* NB: This is how one _should_ access */
+ ((Sprite *)self)->spree = 18; /* ivars from within class methods! */
+}
+- (void)setFoo:(int)foo {
+ sprite = foo;
+ spree = foo;
+}
+- (void)setSprite:(int)sprite {
+ int spree;
+ sprite = 15; /* { dg-warning "local declaration of .sprite. hides instance variable" } */
+ self->sprite = 16;
+ spree = 17; /* { dg-warning "local declaration of .spree. hides instance variable" } */
+ self->spree = 18;
+}
+@end
diff --git a/gcc/testsuite/objc.dg/lookup-1.m b/gcc/testsuite/objc.dg/lookup-1.m
new file mode 100644
index 000000000..737d58a68
--- /dev/null
+++ b/gcc/testsuite/objc.dg/lookup-1.m
@@ -0,0 +1,56 @@
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+/* { dg-additional-sources "../objc-obj-c++-shared/Object1.m" } */
+
+#include <stdlib.h>
+#include "../objc-obj-c++-shared/Object1.h"
+
+typedef struct MyWidget {
+ int a;
+} MyWidget;
+
+MyWidget gWidget = { 17 };
+
+@protocol MyProto
+- (MyWidget *)widget;
+@end
+
+@interface Foo: Object
+@end
+
+@interface Bar: Foo <MyProto>
+@end
+
+@interface Container: Object
++ (MyWidget *)elementForView:(Foo *)view;
+@end
+
+@implementation Foo
+@end
+
+@implementation Bar
+- (MyWidget *)widget {
+ return &gWidget;
+}
+@end
+
+@implementation Container
++ (MyWidget *)elementForView:(Foo *)view
+{
+ MyWidget *widget = (MyWidget *) nil;
+ if ([view conformsTo:@protocol(MyProto)]) {
+ widget = [(Foo <MyProto> *)view widget];
+ }
+ return widget;
+}
+@end
+
+int main(void) {
+ id view = [Bar new];
+ MyWidget *w = [Container elementForView: view];
+
+ if (!w || w->a != 17)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/lto/lto.exp b/gcc/testsuite/objc.dg/lto/lto.exp
new file mode 100644
index 000000000..f567cd93e
--- /dev/null
+++ b/gcc/testsuite/objc.dg/lto/lto.exp
@@ -0,0 +1,84 @@
+# Copyright (C) 2010 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 GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+#
+# Based on gcc/testsuite/gcc.dg/lto/lto.exp.
+
+# Test link-time optimization across multiple files.
+#
+# Programs are broken into multiple files. Each one is compiled
+# separately with LTO information. The final executable is generated
+# by collecting all the generated object files using regular LTO or WHOPR.
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+# Load procedures from common libraries.
+load_lib standard.exp
+load_lib objc-dg.exp
+
+# Load the language-independent compabibility support procedures.
+load_lib lto.exp
+
+# If LTO has not been enabled, bail.
+if { ![check_effective_target_lto] } {
+ return
+}
+
+global LTO_OPTIONS
+
+set LTO_OPTIONS [list \
+ {-O0 -flto -fgnu-runtime} \
+ {-O2 -flto -fgnu-runtime} \
+ {-O0 -flto -flto-partition=none -fgnu-runtime} \
+ {-O2 -flto -flto-partition=none -fgnu-runtime} \
+]
+
+objc_init
+lto_init no-mathlib
+
+# Define an identifier for use with this suite to avoid name conflicts
+# with other lto tests running at the same time.
+set sid "objc_lto"
+set tests [lsort [glob -nocomplain $srcdir/$subdir/*_0.m]]
+
+# Main loop.
+foreach src $tests {
+ # If we're only testing specific files and this isn't one of them, skip it.
+ if ![runtest_file_p $runtests $src] then {
+ continue
+ }
+ lto-execute $src $sid
+}
+
+# darwin targets can also run code with the NeXT runtime.
+if [istarget "*-*-darwin*" ] {
+set LTO_OPTIONS [list \
+ {-O0 -flto -fnext-runtime} \
+ {-O2 -flto -fnext-runtime} \
+ {-O0 -flto -flto-partition=none -fnext-runtime} \
+ {-O2 -flto -flto-partition=none -fnext-runtime} \
+]
+ foreach src $tests {
+ # If we're only testing specific files and this isn't one of them, skip it.
+ if ![runtest_file_p $runtests $src] then {
+ continue
+ }
+ lto-execute $src $sid
+ }
+}
+
+lto_finish
diff --git a/gcc/testsuite/objc.dg/lto/trivial-1_0.m b/gcc/testsuite/objc.dg/lto/trivial-1_0.m
new file mode 100644
index 000000000..076f2306c
--- /dev/null
+++ b/gcc/testsuite/objc.dg/lto/trivial-1_0.m
@@ -0,0 +1,37 @@
+/* { dg-lto-do run } */
+/* { dg-skip-if "" { "*-*-darwin*" && lp64 } { "*" } { "" } } */
+extern int printf (char *,...) ;
+
+typedef struct objc_class *Class;
+
+struct objc_class {
+ Class isa;
+ /* other stuff... */
+} ;
+
+@interface myRootObject {
+@public
+ Class isa;
+}
++initialize;
++(Class)class;
+
+@end
+
+@implementation myRootObject
++initialize {
+ return self;
+}
+
++(Class)class {
+ return (Class)self;
+}
+
+@end
+
+int main(void)
+{
+ [myRootObject class];
+ printf("trivial OK\n");
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/member-1.m b/gcc/testsuite/objc.dg/member-1.m
new file mode 100644
index 000000000..4c7b5ae35
--- /dev/null
+++ b/gcc/testsuite/objc.dg/member-1.m
@@ -0,0 +1,5 @@
+void foo()
+{
+ struct A a; /* { dg-error "storage size" } */
+ a.i;
+}
diff --git a/gcc/testsuite/objc.dg/method-1.m b/gcc/testsuite/objc.dg/method-1.m
new file mode 100644
index 000000000..194c64fac
--- /dev/null
+++ b/gcc/testsuite/objc.dg/method-1.m
@@ -0,0 +1,30 @@
+/* Tests of duplication. */
+/* { dg-do compile } */
+
+@interface class1
+- (int) meth1; /* { dg-message "previous declaration" } */
+- (void) meth1; /* { dg-error "duplicate declaration of method .\\-meth1." } */
+@end
+
+@interface class2
++ (void) meth1; /* { dg-message "previous declaration" } */
++ (int) meth1; /* { dg-error "duplicate declaration of method .\\+meth1." } */
+@end
+
+@interface class3
+- (int) meth1;
+@end
+
+@implementation class3
+- (int) meth1 { return 0; } /* { dg-message "previous definition" } */
+- (int) meth1 { return 0; } /* { dg-error "redefinition of" } */
+@end
+
+@interface class4
++ (void) meth1;
+@end
+
+@implementation class4
++ (void) meth1 {} /* { dg-message "previous definition" } */
++ (void) meth1 {} /* { dg-error "redefinition of" } */
+@end
diff --git a/gcc/testsuite/objc.dg/method-10.m b/gcc/testsuite/objc.dg/method-10.m
new file mode 100644
index 000000000..442df690a
--- /dev/null
+++ b/gcc/testsuite/objc.dg/method-10.m
@@ -0,0 +1,35 @@
+/* When there is only one candidate method available, make sure the
+ compiler uses its argument/return types when constructing the
+ message sends (so that proper C/C++ argument conversions may
+ take place). */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+#include "../objc-obj-c++-shared/Object1.h"
+
+extern void abort(void);
+#define CHECK_IF(expr) if(!(expr)) abort()
+
+static double d = 4.5920234e2;
+
+@interface Foo : Object
+-(void) brokenType: (int)x floatingPoint: (double)y;
+@end
+
+
+@implementation Foo
+-(void) brokenType: (int)x floatingPoint: (double)y
+{
+ CHECK_IF(x == 459);
+ CHECK_IF(y == d);
+}
+@end
+
+int main(void)
+{
+ Foo *foo=[Foo new];
+ [foo brokenType: d floatingPoint: d];
+ return 0;
+}
+
+#include "../objc-obj-c++-shared/Object1-implementation.h"
diff --git a/gcc/testsuite/objc.dg/method-11.m b/gcc/testsuite/objc.dg/method-11.m
new file mode 100644
index 000000000..ddd0121b0
--- /dev/null
+++ b/gcc/testsuite/objc.dg/method-11.m
@@ -0,0 +1,33 @@
+/* Ensure that we indeed cannot obtain the value of a message send
+ if the chosen method signature returns 'void'. There used to
+ exist a cheesy hack that allowed it. While at it, check that
+ the first lexically occurring method signature gets picked
+ when sending messages to 'id'. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com> */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+@interface Object1
+- (void)initWithData:(Object1 *)data;
+@end
+
+@interface Object2
+- (id)initWithData:(Object1 *)data;
+@end
+
+@interface Object3
+- (id)initWithData:(Object2 *)data;
+@end
+
+void foo(void) {
+ id obj1, obj2 = 0;
+ obj2 = [obj1 initWithData: obj2];
+ /* { dg-warning "multiple methods named .\\-initWithData:. found" "" { target *-*-* } 25 } */
+ /* { dg-message "using .\\-\\(void\\)initWithData:\\(Object1 \\*\\)data." "" { target *-*-* } 12 } */
+ /* { dg-message "also found .\\-\\(id\\)initWithData:\\(Object1 \\*\\)data." "" { target *-*-* } 16 } */
+ /* { dg-message "also found .\\-\\(id\\)initWithData:\\(Object2 \\*\\)data." "" { target *-*-* } 20 } */
+
+ /* The following error is a consequence of picking the "wrong" method signature. */
+ /* { dg-error "void value not ignored as it ought to be" "" { target *-*-* } 25 } */
+}
diff --git a/gcc/testsuite/objc.dg/method-12.m b/gcc/testsuite/objc.dg/method-12.m
new file mode 100644
index 000000000..411caac11
--- /dev/null
+++ b/gcc/testsuite/objc.dg/method-12.m
@@ -0,0 +1,25 @@
+/* Contributed by Igor Seleznev <selez@mail.ru>. */
+/* This used to be broken. */
+
+#include <objc/objc.h>
+
+@interface A
++ (A *)currentContext;
+@end
+
+@interface B
++ (B *)currentContext;
+@end
+
+int main()
+{
+ [A currentContext]; /* { dg-bogus "multiple declarations" } */
+ return 0;
+}
+
+@implementation A
++ (A *)currentContext { return nil; }
+@end
+@implementation B
++ (B *)currentContext { return nil; }
+@end
diff --git a/gcc/testsuite/objc.dg/method-13.m b/gcc/testsuite/objc.dg/method-13.m
new file mode 100644
index 000000000..b3e44bd25
--- /dev/null
+++ b/gcc/testsuite/objc.dg/method-13.m
@@ -0,0 +1,78 @@
+/* Test if instance methods of root classes are used as class methods, if no
+ "real" methods are found. For receivers of type 'id' and 'Class', all
+ root classes must be considered. */
+/* Author: Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+#include <objc/objc.h>
+
+#ifdef __NEXT_RUNTIME__
+#define OBJC_GETCLASS objc_getClass
+#else
+#define OBJC_GETCLASS objc_get_class
+#endif
+
+extern void abort(void);
+extern int strcmp(const char *, const char *);
+#define CHECK_IF(expr) if(!(expr)) abort()
+
+@protocol Proto
+- (const char *) method4;
+@end
+
+@interface Root
+{ Class isa; }
++ (const char *) method2;
+@end
+
+@interface Derived: Root
+- (const char *) method1;
+- (const char *) method2;
+- (const char *) method3;
+@end
+
+@interface Root (Categ)
+- (const char *) method3;
+@end
+
+@implementation Root (Categ)
+- (const char *) method3 { return "Root(Categ)::-method3"; }
+- (const char *) method4 { return "Root(Categ)::-method4"; }
+@end
+
+@implementation Derived
+- (const char *) method1 { return "Derived::-method1"; }
+- (const char *) method2 { return "Derived::-method2"; }
+- (const char *) method3 { return "Derived::-method3"; }
+@end
+
+@implementation Root
+#ifdef __NEXT_RUNTIME__
++ initialize { return self; }
+#endif
+- (const char *) method1 { return "Root::-method1"; }
++ (const char *) method2 { return "Root::+method2"; }
+@end
+
+int main(void)
+{
+ Class obj = OBJC_GETCLASS("Derived");
+
+ /* None of the following should elicit compiler-time warnings. */
+
+ CHECK_IF(!strcmp([Root method1], "Root::-method1"));
+ CHECK_IF(!strcmp([Root method2], "Root::+method2"));
+ CHECK_IF(!strcmp([Root method3], "Root(Categ)::-method3"));
+ CHECK_IF(!strcmp([Root method4], "Root(Categ)::-method4"));
+ CHECK_IF(!strcmp([Derived method1], "Root::-method1"));
+ CHECK_IF(!strcmp([Derived method2], "Root::+method2"));
+ CHECK_IF(!strcmp([Derived method3], "Root(Categ)::-method3"));
+ CHECK_IF(!strcmp([Derived method4], "Root(Categ)::-method4"));
+ CHECK_IF(!strcmp([obj method1], "Root::-method1"));
+ CHECK_IF(!strcmp([obj method2], "Root::+method2"));
+ CHECK_IF(!strcmp([obj method3], "Root(Categ)::-method3"));
+ CHECK_IF(!strcmp([obj method4], "Root(Categ)::-method4"));
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/method-14.m b/gcc/testsuite/objc.dg/method-14.m
new file mode 100644
index 000000000..96982254a
--- /dev/null
+++ b/gcc/testsuite/objc.dg/method-14.m
@@ -0,0 +1,17 @@
+/* Test if context-sensitive "in", "out", "byref", etc., qualifiers can be
+ used as method selectors. */
+/* Author: Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-do compile } */
+
+@interface Foo
+- (void)insertNewButtonImage:(Foo *)newButtonImage in:(Foo *)buttonCell;
++ (oneway void)oneway:(int)i2 byref:(int)i3 out:(float)f4 bycopy:(float)f5;
+@end
+
+@implementation Foo
+- (void)insertNewButtonImage:(Foo *)newButtonImage in:(Foo *)buttonCell { }
++ (oneway void)oneway:(int)i2 byref:(int)i3 out:(float)f4 bycopy:(float)f5 { }
+@end
+
+/* { dg-final { scan-assembler "insertNewButtonImage:in:" } } */
+/* { dg-final { scan-assembler "oneway:byref:out:bycopy:" } } */
diff --git a/gcc/testsuite/objc.dg/method-15.m b/gcc/testsuite/objc.dg/method-15.m
new file mode 100644
index 000000000..6a5aec6ac
--- /dev/null
+++ b/gcc/testsuite/objc.dg/method-15.m
@@ -0,0 +1,56 @@
+/* Test if prior method lookup at method @implementation time is not
+ overly aggressive, leading to methods being found in other classes. */
+/* Author: Ziemowit Laski <zlaski@apple.com>. */
+
+/* { dg-do compile } */
+
+#include "../objc-obj-c++-shared/Object1.h"
+
+@class NSString;
+
+@protocol NSMenuItem
++ (void)setUsesUserKeyEquivalents:(BOOL)flag;
++ (BOOL)usesUserKeyEquivalents;
+@end
+
+@interface NSMenuItem : Object <NSMenuItem> {
+ @private
+ id _menu;
+}
+@end
+
+@interface NSResponder : Object <NSMenuItem>
+{
+ id _nextResponder;
+}
+@end
+
+@interface Object(NSMenuValidation)
+- (BOOL)validateMenuItem:(id <NSMenuItem>)menuItem;
+@end
+
+@interface NSResponder (NSStandardKeyBindingMethods)
+- (void)insertText:(id)insertString;
+- (void)doCommandBySelector:(SEL)aSelector;
+@end
+
+@interface NSView : NSResponder
+{
+ id _superview;
+ id _subviews;
+}
+@end
+
+@interface SKTGraphicView : NSView {
+ @private
+ float _gridSpacing;
+}
+@end
+
+@implementation SKTGraphicView
+- (BOOL)validateMenuItem:(NSMenuItem *)item {
+ return (BOOL)1;
+}
+- (void)insertText:(NSString *)str {
+}
+@end
diff --git a/gcc/testsuite/objc.dg/method-16.m b/gcc/testsuite/objc.dg/method-16.m
new file mode 100644
index 000000000..c8394ffbb
--- /dev/null
+++ b/gcc/testsuite/objc.dg/method-16.m
@@ -0,0 +1,24 @@
+/* Do not warn about "slightly" mismatched method signatures if
+ -Wstrict-selector-match is off. */
+
+/* { dg-do compile } */
+/* { dg-options "-Wno-strict-selector-match" } */
+
+#include <objc/objc.h>
+
+@interface Base
+- (id) meth1: (Base *)arg1;
+- (id) window;
+@end
+
+@interface Derived: Base
+- (id) meth1: (Derived *)arg1;
+- (Base *)window;
+@end
+
+void foo(void) {
+ id r;
+
+ [r meth1:r];
+ [r window];
+}
diff --git a/gcc/testsuite/objc.dg/method-17.m b/gcc/testsuite/objc.dg/method-17.m
new file mode 100644
index 000000000..3f6d8d06a
--- /dev/null
+++ b/gcc/testsuite/objc.dg/method-17.m
@@ -0,0 +1,26 @@
+/* Test for spurious "may or may not return a value" warnings. */
+
+/* { dg-do compile } */
+/* { dg-options "-Wreturn-type -Wextra" } */
+
+#include "../objc-obj-c++-shared/Object1.h"
+
+@interface Foo: Object
+- (id) meth1;
+- (void) meth2;
+@end
+
+extern int bar;
+
+@implementation Foo
+- (id) meth1 {
+ if (bar)
+ return [Object new];
+ return; /* { dg-warning "'return' with no value, in function returning non-void" } */
+}
+- (void) meth2 {
+ if (!bar)
+ return;
+ bar = 0;
+} /* { dg-bogus "'return' with no value, in function returning non-void" } */
+@end
diff --git a/gcc/testsuite/objc.dg/method-18.m b/gcc/testsuite/objc.dg/method-18.m
new file mode 100644
index 000000000..77fd3ef1b
--- /dev/null
+++ b/gcc/testsuite/objc.dg/method-18.m
@@ -0,0 +1,29 @@
+/* Do not warn about "slightly" mismatched method signatures if
+ -Wstrict-selector-match is off. */
+/* { dg-do compile } */
+/* { dg-options "-Wno-strict-selector-match" } */
+
+#include <objc/objc.h>
+
+typedef enum { en1_1, en1_2 } En1;
+typedef enum { en2_1, en2_2 } En2;
+typedef struct { int a, b; } St1;
+typedef struct { unsigned a, b; } St2;
+
+@interface Base
+- (id) meth1: (En1)arg1;
+- (St1) window;
+@end
+
+@interface Derived: Base
+- (id) meth1: (En2)arg1;
+- (St2)window;
+@end
+
+void foo(void) {
+ id r;
+ En1 en;
+
+ [r meth1:en];
+ [r window];
+}
diff --git a/gcc/testsuite/objc.dg/method-19.m b/gcc/testsuite/objc.dg/method-19.m
new file mode 100644
index 000000000..362d55858
--- /dev/null
+++ b/gcc/testsuite/objc.dg/method-19.m
@@ -0,0 +1,17 @@
+/* The following should NOT generate "may not respond to" warnings, since a forward-declared
+ @class (instance) should be treated like a 'Class') ('id'). */
+
+/* { dg-do compile } */
+
+#include "../objc-obj-c++-shared/Object1.h"
+
+@class NotKnown;
+
+void foo(NotKnown *n) {
+ [NotKnown new];
+ [n nonexistent_method]; /* { dg-warning "no .\\-nonexistent_method. method found" } */
+}
+
+/* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 0 } */
+/* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 0 } */
+/* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/objc.dg/method-2.m b/gcc/testsuite/objc.dg/method-2.m
new file mode 100644
index 000000000..8bf211f87
--- /dev/null
+++ b/gcc/testsuite/objc.dg/method-2.m
@@ -0,0 +1,32 @@
+/* Test for lookup of class (factory) methods. */
+/* Author: Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-do compile } */
+
+@interface MyBase
+- (void) rootInstanceMethod;
+@end
+
+@interface MyIntermediate: MyBase
+@end
+
+@interface MyDerived: MyIntermediate
+- (void) instanceMethod;
++ (void) classMethod;
+@end
+
+@implementation MyDerived
+- (void) instanceMethod {
+}
+
++ (void) classMethod { /* If a class method is not found, the root */
+ [self rootInstanceMethod]; /* class is searched for an instance method */
+ [MyIntermediate rootInstanceMethod]; /* with the same name. */
+
+ [self instanceMethod]; /* { dg-warning ".MyDerived. may not respond to .\\+instanceMethod." } */
+ /* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 25 } */
+ /* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 25 } */
+ /* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 25 } */
+ [MyDerived instanceMethod]; /* { dg-warning ".MyDerived. may not respond to .\\+instanceMethod." } */
+}
+@end
+
diff --git a/gcc/testsuite/objc.dg/method-20.m b/gcc/testsuite/objc.dg/method-20.m
new file mode 100644
index 000000000..722463ce2
--- /dev/null
+++ b/gcc/testsuite/objc.dg/method-20.m
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+
+/* We used to crash after we found the type for int[m] was declared as invalid. */
+/* PR objc/29197 */
+
+@ implementation NGActiveSocket
++ (void) socketPair:(int[m]) _pair {} /* { dg-error "" } */
+ /* { dg-warning "" "" { target *-*-* } 7 } */
+@end
diff --git a/gcc/testsuite/objc.dg/method-20b.m b/gcc/testsuite/objc.dg/method-20b.m
new file mode 100644
index 000000000..733d8722b
--- /dev/null
+++ b/gcc/testsuite/objc.dg/method-20b.m
@@ -0,0 +1,45 @@
+/* Check if array and function parameters get decayed to pointers as
+ they should. */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+/* { dg-additional-sources "../objc-obj-c++-shared/Object1.m" } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+#include "../objc-obj-c++-shared/Object1.h"
+#include <string.h>
+#include <stdlib.h>
+
+static char global_buf[20];
+
+char *strcpy_like_callee(const char *s) {
+ strcpy(global_buf, s);
+ return global_buf;
+}
+
+typedef char io_string_t[512];
+typedef char *(func_type)(const char *);
+
+@interface DeviceObject: Object
+- (void) func:(func_type)func stucPathInIORegistry:(io_string_t)ioRegPath;
+@end
+@implementation DeviceObject
+- (void) func:(func_type)func stucPathInIORegistry:(io_string_t)ioRegPath
+{
+ func(ioRegPath);
+}
+@end
+
+int main (void) {
+ io_string_t my_string;
+ DeviceObject *obj = [DeviceObject new];
+
+ strcpy (my_string, "Hello!");
+ strcpy (global_buf, "Good-bye!");
+
+ [obj func:strcpy_like_callee stucPathInIORegistry:my_string];
+
+ if (strcmp (global_buf, "Hello!"))
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/method-3.m b/gcc/testsuite/objc.dg/method-3.m
new file mode 100644
index 000000000..abee4e065
--- /dev/null
+++ b/gcc/testsuite/objc.dg/method-3.m
@@ -0,0 +1,48 @@
+/* Test for sending messages to aliased classes (and instances thereof). */
+/* Author: Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-options "" } */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+#include "../objc-obj-c++-shared/Object1.h"
+
+extern void abort(void);
+#define CHECK_IF(expr) if(!(expr)) abort()
+
+@interface Int1: Object
++ (int) classMeth;
+- (int) instanceMeth;
+@end
+
+@interface Int2: Object
++ (int) classMeth;
+- (int) instanceMeth;
+@end
+
+@implementation Int1
++ (int) classMeth { return 345; }
+- (int) instanceMeth { return 697; }
+@end
+
+@implementation Int2
++ (int) classMeth { return 1345; }
+- (int) instanceMeth { return 1697; }
+@end
+
+typedef Int1 Int1Typedef;
+@compatibility_alias Int1Alias Int1Typedef;
+@compatibility_alias Int2Alias Int2;
+typedef Int2Alias Int2Typedef;
+
+int main(void) {
+ Int1Alias *int1alias = [[Int1Typedef alloc] init];
+ Int2Typedef *int2typedef = [[Int2Alias alloc] init];
+
+ CHECK_IF([Int1Typedef classMeth] == 345 && [Int2Alias classMeth] == 1345);
+ CHECK_IF([int1alias instanceMeth] == 697 && [int2typedef instanceMeth] == 1697);
+ CHECK_IF([(Int2Typedef *)int1alias instanceMeth] == 697);
+ CHECK_IF([(Int1Alias *)int2typedef instanceMeth] == 1697);
+ return 0;
+}
+
+#include "../objc-obj-c++-shared/Object1-implementation.h"
diff --git a/gcc/testsuite/objc.dg/method-4.m b/gcc/testsuite/objc.dg/method-4.m
new file mode 100644
index 000000000..df25bba21
--- /dev/null
+++ b/gcc/testsuite/objc.dg/method-4.m
@@ -0,0 +1,26 @@
+/* Check if class references (generated for the NeXT runtime) are appropriately
+ folded. */
+/* Author: Ziemowit Laski <zlaski@apple.com>. */
+/* The ABI is different for m64 darwin so skip this test for now */
+/* { dg-do compile { target { *-*-darwin* && { ! lp64 } } } } */
+/* { dg-skip-if "" { *-*-darwin* } { "-fgnu-runtime" } { "" } } */
+
+#include "../objc-obj-c++-shared/Object1.h"
+
+typedef Object ObjectTypedef1;
+typedef ObjectTypedef1 ObjectTypedef2;
+@compatibility_alias ObjectAlias1 ObjectTypedef2;
+@compatibility_alias ObjectAlias2 ObjectAlias1;
+typedef ObjectAlias2 ObjectTypedef3;
+
+void foo(void) {
+ id obj = [Object new];
+ obj = [ObjectTypedef1 new];
+ obj = [ObjectTypedef2 new];
+ obj = [ObjectTypedef3 new];
+ obj = [ObjectAlias1 new];
+ obj = [ObjectAlias2 new];
+}
+
+/* { dg-final { scan-assembler "_OBJC_ClassRefs_0" } } */
+/* { dg-final { scan-assembler-not "_OBJC_ClassRefs_1" } } */
diff --git a/gcc/testsuite/objc.dg/method-5.m b/gcc/testsuite/objc.dg/method-5.m
new file mode 100644
index 000000000..9fa8cb6d9
--- /dev/null
+++ b/gcc/testsuite/objc.dg/method-5.m
@@ -0,0 +1,20 @@
+/* Check if sending messages to "underspecified" objects is handled gracefully. */
+/* Author: Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-do compile } */
+
+@class UnderSpecified;
+typedef struct NotAClass {
+ int a, b;
+} NotAClass;
+
+void foo(UnderSpecified *u, NotAClass *n) {
+ [n nonexistent_method]; /* { dg-warning "invalid receiver type" } */
+ /* { dg-warning "no .\\-nonexistent_method. method found" "" { target *-*-* } 11 } */
+ [NotAClass nonexistent_method]; /* { dg-error ".NotAClass. is not an Objective\\-C class name or alias" } */
+ [u nonexistent_method]; /* { dg-warning "no .\\-nonexistent_method. method found" } */
+ [UnderSpecified nonexistent_method]; /* { dg-warning "no .\\+nonexistent_method. method found" } */
+}
+
+/* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 0 } */
+/* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 0 } */
+/* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/objc.dg/method-6.m b/gcc/testsuite/objc.dg/method-6.m
new file mode 100644
index 000000000..c46d9c450
--- /dev/null
+++ b/gcc/testsuite/objc.dg/method-6.m
@@ -0,0 +1,32 @@
+/* Check that sending messages to variables of type 'Class' does not involve instance methods,
+ unless they reside in root classes. */
+/* Author: Ziemowit Laski <zlaski@apple.com> */
+/* { dg-do compile } */
+/* { dg-options "-Wstrict-selector-match" } */
+
+#include "../objc-obj-c++-shared/Protocol1.h"
+
+@interface Base
+- (unsigned)port;
+@end
+
+@interface Derived: Base
+- (Object *)port;
++ (Protocol *)port;
+- (id)starboard;
+@end
+
+void foo(void) {
+ Class receiver;
+
+ [receiver port]; /* { dg-warning "multiple methods named .\\+port. found" } */
+ /* { dg-message "using .\\-\\(unsigned( int)?\\)port." "" { target *-*-* } 10 } */
+ /* { dg-message "also found .\\+\\(Protocol \\*\\)port." "" { target *-*-* } 15 } */
+
+ [receiver starboard]; /* { dg-warning "no .\\+starboard. method found" } */
+ /* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 26 } */
+ /* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 26 } */
+ /* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 26 } */
+
+ [Class port]; /* { dg-error ".Class. is not an Objective\\-C class name or alias" } */
+}
diff --git a/gcc/testsuite/objc.dg/method-7.m b/gcc/testsuite/objc.dg/method-7.m
new file mode 100644
index 000000000..d7a7b97b7
--- /dev/null
+++ b/gcc/testsuite/objc.dg/method-7.m
@@ -0,0 +1,29 @@
+/* Check if finding multiple signatures for a method is handled gracefully. */
+/* Author: Ziemowit Laski <zlaski@apple.com> */
+/* { dg-do compile } */
+/* { dg-options "-Wstrict-selector-match" } */
+
+
+#include "../objc-obj-c++-shared/Object1.h"
+
+@interface Class1
+- (void)setWindow:(Object *)wdw;
+@end
+
+@interface Class2
+- (void)setWindow:(Class1 *)window;
+@end
+
+id foo(void) {
+ Object *obj = [[Object alloc] init];
+ id obj2 = obj;
+ [obj setWindow:nil]; /* { dg-warning ".Object. may not respond to .\\-setWindow:." } */
+ /* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 20 } */
+ /* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 20 } */
+ /* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 20 } */
+ [obj2 setWindow:nil]; /* { dg-warning "multiple methods named .\\-setWindow:. found" } */
+ /* { dg-message "using .\\-\\(void\\)setWindow:\\(Object \\*\\)wdw." "" { target *-*-* } 10 } */
+ /* { dg-message "also found .\\-\\(void\\)setWindow:\\(Class1 \\*\\)window." "" { target *-*-* } 14 } */
+
+ return obj;
+}
diff --git a/gcc/testsuite/objc.dg/method-8.m b/gcc/testsuite/objc.dg/method-8.m
new file mode 100644
index 000000000..4a13b7d6c
--- /dev/null
+++ b/gcc/testsuite/objc.dg/method-8.m
@@ -0,0 +1,14 @@
+/* Check if casting the receiver type causes method lookup to succeed. This was broken
+ in Objective-C++. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com> */
+/* { dg-do compile } */
+
+@interface A
+@end
+
+@interface B: A
+- (void)f;
+@end
+
+void g(A *p) { [(B *)p f]; }
+
diff --git a/gcc/testsuite/objc.dg/method-9.m b/gcc/testsuite/objc.dg/method-9.m
new file mode 100644
index 000000000..d755d6ad8
--- /dev/null
+++ b/gcc/testsuite/objc.dg/method-9.m
@@ -0,0 +1,45 @@
+/* Check if finding multiple signatures for a method is handled gracefully
+ when method lookup succeeds (see also method-7.m). */
+/* Contributed by Ziemowit Laski <zlaski@apple.com> */
+/* { dg-do compile } */
+/* { dg-options "-Wstrict-selector-match" } */
+
+
+#include "../objc-obj-c++-shared/Object1.h"
+
+@protocol MyObject
+- (id)initWithData:(Object *)data;
+@end
+
+@protocol SomeOther
+- (id)initWithData:(int)data;
+@end
+
+@protocol MyCoding
+- (id)initWithData:(id<MyObject, MyCoding>)data;
+@end
+
+@interface NTGridDataObject: Object <MyCoding>
+{
+ Object<MyCoding> *_data;
+}
++ (NTGridDataObject*)dataObject:(id<MyObject, MyCoding>)data;
+@end
+
+@implementation NTGridDataObject
+- (id)initWithData:(id<MyObject, MyCoding>)data {
+ return data;
+}
++ (NTGridDataObject*)dataObject:(id<MyObject, MyCoding>)data
+{
+ NTGridDataObject *result = [[NTGridDataObject alloc] initWithData:data];
+ /* { dg-warning "multiple methods named .\\-initWithData:. found" "" { target *-*-* } 35 } */
+ /* { dg-message "using .\\-\\(id\\)initWithData:\\(Object \\*\\)data." "" { target *-*-* } 11 } */
+ /* { dg-message "also found .\\-\\(id\\)initWithData:\\(id <MyObject, MyCoding>\\)data." "" { target *-*-* } 19 } */
+ /* { dg-message "also found .\\-\\(id\\)initWithData:\\(int\\)data." "" { target *-*-* } 15 } */
+
+ /* The following warning is a consequence of picking the "wrong" method signature. */
+ /* { dg-warning "passing argument 1 of .initWithData:. from distinct Objective\\-C type" "" { target *-*-* } 35 } */
+ return result;
+}
+@end
diff --git a/gcc/testsuite/objc.dg/method-conflict-1.m b/gcc/testsuite/objc.dg/method-conflict-1.m
new file mode 100644
index 000000000..2cc96e4fd
--- /dev/null
+++ b/gcc/testsuite/objc.dg/method-conflict-1.m
@@ -0,0 +1,26 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+/* Test that you can not declare two methods, in the same protocol,
+ with the same name but conflicting method signatures. */
+
+@protocol MyProtocol
++ (int) method1: (int)x; /* { dg-message "previous declaration" } */
++ (float) method1: (int)x; /* { dg-error "duplicate declaration of method .\\+method1." } */
+
+- (int) method2: (int)x; /* { dg-message "previous declaration" } */
+- (int) method2: (float)x; /* { dg-error "duplicate declaration of method .\\-method2." } */
+
+@optional
++ (int *) method3: (int)x; /* { dg-message "previous declaration" } */
++ (int *) method3: (int **)x; /* { dg-error "duplicate declaration of method .\\+method3." } */
+
+- (id) method4: (id)x; /* { dg-message "previous declaration" } */
+- (void) method4: (id)x; /* { dg-error "duplicate declaration of method .\\-method4." } */
+@end
+
+/* We don't test conflicting types between @required and @optional
+ methods, as that is tested in method-conflict-2. */
+
diff --git a/gcc/testsuite/objc.dg/method-conflict-2.m b/gcc/testsuite/objc.dg/method-conflict-2.m
new file mode 100644
index 000000000..0b0612d77
--- /dev/null
+++ b/gcc/testsuite/objc.dg/method-conflict-2.m
@@ -0,0 +1,34 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+/* Test that you can not declare two methods, in the same protocol,
+ with the same name and method signature, but one as @required and
+ once as @optional. */
+
+/* First, @required conflicting with @optional. */
+@protocol MyProtocol
+
+@optional
++ (void) method1: (id)x; /* { dg-message "previous declaration" } */
+- (id) method2: (long)x; /* { dg-message "previous declaration" } */
+
+@required
++ (void) method1: (id)x; /* { dg-error "declared .@optional. and .@required. at the same time" } */
+- (id) method2: (long)x; /* { dg-error "declared .@optional. and .@required. at the same time" } */
+
+@end
+
+/* Second, @optional conflicting with @required. */
+@protocol MyProtocol2
+
+@required
++ (void) method3: (Class)x; /* { dg-message "previous declaration" } */
+- (id *) method4: (long)x; /* { dg-message "previous declaration" } */
+
+@optional
++ (void) method3: (Class)x; /* { dg-error "declared .@optional. and .@required. at the same time" } */
+- (id *) method4: (long)x; /* { dg-error "declared .@optional. and .@required. at the same time" } */
+
+@end
diff --git a/gcc/testsuite/objc.dg/method-conflict-3.m b/gcc/testsuite/objc.dg/method-conflict-3.m
new file mode 100644
index 000000000..cc4d2631f
--- /dev/null
+++ b/gcc/testsuite/objc.dg/method-conflict-3.m
@@ -0,0 +1,63 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+/* Test that the compiler can correctly compare protocols in types of
+ method signatures. */
+
+@protocol A, B, C;
+
+@interface MyClass
+- (void) method1: (id)x;
+- (void) method1: (id)x; /* Ok */
+
+- (void) method2: (id <A>)x;
+- (void) method2: (id <A>)x; /* Ok */
+
+- (void) method3: (id <A, B>)x;
+- (void) method3: (id <A, B>)x; /* Ok */
+
+- (void) method4: (id <A, B>)x;
+- (void) method4: (id <A, B, B>)x; /* Ok */
+
+- (void) method5: (id <A, A, B>)x;
+- (void) method5: (id <A, B, B>)x; /* Ok */
+
+- (void) method6: (id <A, A, B, B, C, C>)x;
+- (void) method6: (id <C, A, B>)x; /* Ok */
+
+- (void) method7: (id)x; /* { dg-message "previous declaration" } */
+- (void) method7: (id <A>)x; /* { dg-error "duplicate declaration" } */
+
+- (void) method8: (id <A>)x; /* { dg-message "previous declaration" } */
+- (void) method8: (id)x; /* { dg-error "duplicate declaration" } */
+
+- (void) method9: (id <A>)x; /* { dg-message "previous declaration" } */
+- (void) method9: (id <B>)x; /* { dg-error "duplicate declaration" } */
+
+- (void) methodA: (id <A>)x; /* { dg-message "previous declaration" } */
+- (void) methodA: (id <A, B>)x; /* { dg-error "duplicate declaration" } */
+
+- (void) methodB: (id <A, B>)x; /* { dg-message "previous declaration" } */
+- (void) methodB: (id <A>)x; /* { dg-error "duplicate declaration" } */
+
+- (void) methodC: (id <A, B, C>)x; /* { dg-message "previous declaration" } */
+- (void) methodC: (id <A, B>)x; /* { dg-error "duplicate declaration" } */
+
+- (void) methodD: (id <A, B, C>)x; /* { dg-message "previous declaration" } */
+- (void) methodD: (id <A, B, A>)x; /* { dg-error "duplicate declaration" } */
+
+- (void) methodE: (MyClass <A, B, C> *)x; /* { dg-message "previous declaration" } */
+- (void) methodE: (MyClass <A, B, A> *)x; /* { dg-error "duplicate declaration" } */
+
+- (void) methodF: (MyClass <A, B, A> *)x;
+- (void) methodF: (MyClass <A, B, A> *)x; /* Ok */
+
+- (void) methodG: (MyClass *)x; /* { dg-message "previous declaration" } */
+- (void) methodG: (MyClass <A, B, C> *)x; /* { dg-error "duplicate declaration" } */
+
+- (void) methodH: (MyClass <A, C>*)x; /* { dg-message "previous declaration" } */
+- (void) methodH: (MyClass *)x; /* { dg-error "duplicate declaration" } */
+
+@end
diff --git a/gcc/testsuite/objc.dg/method-conflict-4.m b/gcc/testsuite/objc.dg/method-conflict-4.m
new file mode 100644
index 000000000..a0c278294
--- /dev/null
+++ b/gcc/testsuite/objc.dg/method-conflict-4.m
@@ -0,0 +1,47 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+/* Test that the compiler can correctly compare protocols in types of
+ method signatures. In this test we look at protocols implementing
+ other protocols. The fact that one protocol implements another one
+ doesn't mean that they are identical. */
+
+@protocol A
+- (void) doSomething;
+@end
+
+@protocol B <A>
+- (void) doSomethingElse;
+@end
+
+@protocol C <A>
+- (void) doYetSomethingElse;
+@end
+
+@interface MyClass2
+- (void) aMethod: (id <A>)x; /* { dg-message "previous declaration" } */
+- (void) aMethod: (id <B>)x; /* { dg-error "duplicate declaration" } */
+
+- (void) bMethod: (id <B>)x; /* { dg-message "previous declaration" } */
+- (void) bMethod: (id <A>)x; /* { dg-error "duplicate declaration" } */
+
+- (void) cMethod: (id <A, B>)x;
+- (void) cMethod: (id <B>)x; /* Ok - because if you implement B, then you also implement A, so <B> == <A, B> */
+
+- (void) dMethod: (id <A, B>)x;
+- (void) dMethod: (id <B, A>)x; /* Ok */
+
+- (void) eMethod: (id <A>)x; /* { dg-message "previous declaration" } */
+- (void) eMethod: (id <B, C>)x; /* { dg-error "duplicate declaration" } */
+
+- (void) fMethod: (id <B, C>)x; /* { dg-message "previous declaration" } */
+- (void) fMethod: (id <A>)x; /* { dg-error "duplicate declaration" } */
+
+- (void) gMethod: (id <A>)x; /* { dg-message "previous declaration" } */
+- (void) gMethod: (id <A, B, C>)x; /* { dg-error "duplicate declaration" } */
+
+- (void) hMethod: (id <A, B, C>)x; /* { dg-message "previous declaration" } */
+- (void) hMethod: (id <A>)x; /* { dg-error "duplicate declaration" } */
+@end
diff --git a/gcc/testsuite/objc.dg/missing-proto-1.m b/gcc/testsuite/objc.dg/missing-proto-1.m
new file mode 100644
index 000000000..7132ead4b
--- /dev/null
+++ b/gcc/testsuite/objc.dg/missing-proto-1.m
@@ -0,0 +1,6 @@
+/* Test for graceful handling of missing protocol declarations. */
+/* Author: Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-do compile } */
+
+@interface Foo <Missing> /* { dg-error "cannot find protocol declaration for .Missing." } */
+@end
diff --git a/gcc/testsuite/objc.dg/missing-proto-2.m b/gcc/testsuite/objc.dg/missing-proto-2.m
new file mode 100644
index 000000000..cb121b496
--- /dev/null
+++ b/gcc/testsuite/objc.dg/missing-proto-2.m
@@ -0,0 +1,5 @@
+/* Test for graceful handling of missing protocol declarations. */
+/* Author: Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-do compile } */
+
+void *protRef = @protocol(Missing); /* { dg-error "cannot find protocol declaration for .Missing." } */
diff --git a/gcc/testsuite/objc.dg/missing-proto-3.m b/gcc/testsuite/objc.dg/missing-proto-3.m
new file mode 100644
index 000000000..6c610ce35
--- /dev/null
+++ b/gcc/testsuite/objc.dg/missing-proto-3.m
@@ -0,0 +1,26 @@
+/* Ensure that the compiler gracefully handles missing protocol declarations.
+ In addition to not crashing :-), the compiler should properly handle
+ valid protocol references, even when they're mixed with invalid ones. */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+@protocol DefinedProtocol
+- (id) missingMethod1;
+@end
+
+@interface MyClass <UndefinedProtocol, DefinedProtocol>
+/* { dg-error "cannot find protocol declaration for .UndefinedProtocol." "" { target *-*-* } 12 } */
+@end
+
+@implementation MyClass
++(Class)class
+{
+ return self;
+}
+@end
+
+/* { dg-warning "incomplete implementation of class .MyClass." "" { target *-*-* } 21 } */
+/* { dg-warning "method definition for .\\-missingMethod1. not found" "" { target *-*-* } 21 } */
+/* { dg-warning "class .MyClass. does not fully implement the .DefinedProtocol. protocol" "" { target *-*-* } 21 } */
+
diff --git a/gcc/testsuite/objc.dg/msg-in-protocol.m b/gcc/testsuite/objc.dg/msg-in-protocol.m
new file mode 100644
index 000000000..86b7c85a3
--- /dev/null
+++ b/gcc/testsuite/objc.dg/msg-in-protocol.m
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+@class Foo;
+
+@protocol Bar
+
+- (void)bang;
+
+@end
+
+void foo()
+{
+ Foo<Bar> *foo = nil;
+ [foo bang];
+}
+
diff --git a/gcc/testsuite/objc.dg/naming-1.m b/gcc/testsuite/objc.dg/naming-1.m
new file mode 100644
index 000000000..3528961bf
--- /dev/null
+++ b/gcc/testsuite/objc.dg/naming-1.m
@@ -0,0 +1,19 @@
+/* Test for obscuring of @interfaces with local vars. */
+/* Author: Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-do compile } */
+
+@interface View
+@end
+
+void foo(void)
+{
+ int View; /* ok */
+ View = 1; /* ok */
+ View *view; /* { dg-error "undeclared|only once|it appears" } */
+}
+
+void bar(void)
+{
+ View *view; /* ok */
+ View = 1; /* { dg-error "parse error|syntax error|expected" } */
+}
diff --git a/gcc/testsuite/objc.dg/naming-2.m b/gcc/testsuite/objc.dg/naming-2.m
new file mode 100644
index 000000000..6d087509e
--- /dev/null
+++ b/gcc/testsuite/objc.dg/naming-2.m
@@ -0,0 +1,12 @@
+/* Test for collision of @interfaces with global vars. */
+/* Author: Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-do compile } */
+
+@interface Foo
+@end
+float Foo; /* { dg-error "parse error|syntax error|expected|redeclaration" } */
+
+double Bar;
+@interface Bar
+@end /* { dg-error "redeclared as different kind of symbol" } */
+/* { dg-error "previous declaration of" "" { target *-*-* } 9 } */
diff --git a/gcc/testsuite/objc.dg/naming-3.m b/gcc/testsuite/objc.dg/naming-3.m
new file mode 100644
index 000000000..dea388c5b
--- /dev/null
+++ b/gcc/testsuite/objc.dg/naming-3.m
@@ -0,0 +1,17 @@
+/* Test for class name same as an unrelated struct field name. */
+/* { dg-do compile } */
+@interface PassThrough {
+
+}
+@end
+
+struct S {
+ int (*PassThrough)();
+};
+
+int main()
+{
+ PassThrough* pt;
+ struct S s;
+ s.PassThrough();
+}
diff --git a/gcc/testsuite/objc.dg/naming-4.m b/gcc/testsuite/objc.dg/naming-4.m
new file mode 100644
index 000000000..9a85229f6
--- /dev/null
+++ b/gcc/testsuite/objc.dg/naming-4.m
@@ -0,0 +1,27 @@
+/* Testing for detecting duplicate ivars. */
+/* { dg-do compile } */
+
+typedef struct S { int i; } NSDictionary;
+
+@interface A
+{
+ NSDictionary * _userInfo;
+}
+@end
+
+@interface B : A
+{
+ NSDictionary * _userInfo; /* { dg-error "duplicate member" } */
+ NSDictionary * _userInfo; /* { dg-error "duplicate member" } */
+}
+@end
+
+@interface C : A
+@end
+
+@interface D : C
+{
+ NSDictionary * _userInfo; /* { dg-error "duplicate member" } */
+ NSDictionary * _userInfo; /* { dg-error "duplicate member" } */
+}
+@end
diff --git a/gcc/testsuite/objc.dg/naming-5.m b/gcc/testsuite/objc.dg/naming-5.m
new file mode 100644
index 000000000..2e2786c41
--- /dev/null
+++ b/gcc/testsuite/objc.dg/naming-5.m
@@ -0,0 +1,42 @@
+/* Testing for detecting duplicate ivars. */
+/* { dg-do compile } */
+
+typedef struct S { int i; } NSDictionary;
+
+@interface A
+{
+ NSDictionary * _userInfo;
+ int i1;
+ int i2;
+ int i3;
+ int i4;
+ int i5;
+ int i6;
+ int i7;
+}
+@end
+
+@interface B : A
+{
+ NSDictionary * _userInfo; /* { dg-error "duplicate member" } */
+ int ii1;
+ int ii2;
+ int ii3;
+ int ii4;
+ int ii5;
+ int ii6;
+ int ii7;
+ NSDictionary * _userInfo; /* { dg-error "duplicate member" } */
+}
+@end
+
+@interface C : A
+@end
+
+@interface D : C
+{
+ NSDictionary * _userInfo; /* { dg-error "duplicate member" } */
+ NSDictionary * _userInfo; /* { dg-error "duplicate member" } */
+}
+@end
+
diff --git a/gcc/testsuite/objc.dg/next-runtime-1.m b/gcc/testsuite/objc.dg/next-runtime-1.m
new file mode 100644
index 000000000..c76b6166d
--- /dev/null
+++ b/gcc/testsuite/objc.dg/next-runtime-1.m
@@ -0,0 +1,20 @@
+/* Test that the correct version number (6) is set in the module descriptor
+ when compiling for the NeXT runtime ABI=0 - and that the MODULE descriptor
+ is not emitted at all for ABI 2. */
+/* modified from a testcase added by: Ziemowit Laski <zlaski@apple.com> */
+
+/* { dg-do compile { target *-*-darwin* } } */
+/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */
+/* { dg-skip-if "" { *-*-* } { "-fobjc-abi-version=1" } { "" } } */
+/* { dg-options "-fobjc-abi-version=0" { target { *-*-darwin* && { ! lp64 } } } } */
+
+@interface FooBar
+- (void)boo;
+@end
+
+@implementation FooBar
+- (void)boo { }
+@end
+
+/* { dg-final { scan-assembler "L_OBJC_Module:\n\[ \t\]*\.long\t6\n" { target { *-*-darwin* && { ! lp64 } } } } } */
+/* { dg-final { scan-assembler-not "L_OBJC_Module" { target { *-*-darwin* && { lp64 } } } } } */
diff --git a/gcc/testsuite/objc.dg/no-extra-load.m b/gcc/testsuite/objc.dg/no-extra-load.m
new file mode 100644
index 000000000..750353579
--- /dev/null
+++ b/gcc/testsuite/objc.dg/no-extra-load.m
@@ -0,0 +1,7 @@
+/* { dg-do compile { target *-*-darwin* } } */
+/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */
+
+#import <Foundation/Foundation.h>
+main() { [NSObject new]; }
+
+/* { dg-final { scan-assembler-not "L_objc_msgSend\\\$non_lazy_ptr" } } */
diff --git a/gcc/testsuite/objc.dg/objc-fast-4.m b/gcc/testsuite/objc.dg/objc-fast-4.m
new file mode 100644
index 000000000..b86e39529
--- /dev/null
+++ b/gcc/testsuite/objc.dg/objc-fast-4.m
@@ -0,0 +1,12 @@
+/* The code should call objc_msgSend directly, not through a pointer. */
+/* { dg-do compile { target *-*-darwin* } } */
+/* { dg-options "-O0" } */
+/* Radar 4015820 */
+
+#include "../objc-obj-c++-shared/Object1.h"
+
+void foo(void) {
+ Object *o;
+ [o++ free];
+}
+/* { dg-final { scan-assembler-not "L_objc_msgSend\\\$non_lazy_ptr" } } */
diff --git a/gcc/testsuite/objc.dg/objc-foreach-1.m b/gcc/testsuite/objc.dg/objc-foreach-1.m
new file mode 100644
index 000000000..81f5dae0c
--- /dev/null
+++ b/gcc/testsuite/objc.dg/objc-foreach-1.m
@@ -0,0 +1,41 @@
+/* Syntax check for the new foreach statement. */
+/* { dg-do compile } */
+
+typedef struct objc_class *Class;
+
+typedef struct objc_object {
+ Class isa;
+} *id;
+
+
+@interface MyList
+@end
+
+@implementation MyList
+- (unsigned int)countByEnumeratingWithState:(struct __objcFastEnumerationState *)state objects:(id *)items count:(unsigned int)stackcount
+{
+ return 0;
+}
+- (void)addObject:object {
+}
+
+@end
+
+@interface MyList (BasicTest)
+- (void)compilerTestAgainst;
+@end
+void BEGIN();
+void INFORLOOP();
+void END();
+@implementation MyList (BasicTest)
+- (void)compilerTestAgainst {
+
+ BEGIN();
+ for (id elem in (self))
+ if (elem)
+ INFORLOOP();
+
+ END();
+}
+@end
+
diff --git a/gcc/testsuite/objc.dg/objc-foreach-2.m b/gcc/testsuite/objc.dg/objc-foreach-2.m
new file mode 100644
index 000000000..a01f004fe
--- /dev/null
+++ b/gcc/testsuite/objc.dg/objc-foreach-2.m
@@ -0,0 +1,41 @@
+/* Syntax check for the new foreach statement. */
+/* { dg-do compile } */
+
+typedef struct objc_class *Class;
+
+typedef struct objc_object {
+ Class isa;
+} *id;
+
+
+@interface MyList
+@end
+
+@implementation MyList
+- (unsigned int)countByEnumeratingWithState:(struct __objcFastEnumerationState *)state objects:(id *)items count:(unsigned int)stackcount
+{
+ return 0;
+}
+- (void)addObject:object {
+}
+
+@end
+
+@interface MyList (BasicTest)
+- (void)compilerTestAgainst;
+@end
+void BEGIN();
+void INFORLOOP();
+void END();
+@implementation MyList (BasicTest)
+- (void)compilerTestAgainst {
+
+ id elem;
+ BEGIN();
+ for (elem in (self))
+ if (elem)
+ INFORLOOP();
+ END();
+}
+@end
+
diff --git a/gcc/testsuite/objc.dg/objc-foreach-3.m b/gcc/testsuite/objc.dg/objc-foreach-3.m
new file mode 100644
index 000000000..922db39e7
--- /dev/null
+++ b/gcc/testsuite/objc.dg/objc-foreach-3.m
@@ -0,0 +1,42 @@
+/* Syntax check for the new foreach statement.
+ Use of declaration in loop-header without requiring c99 mode. */
+/* { dg-do compile } */
+
+typedef struct objc_class *Class;
+
+typedef struct objc_object {
+ Class isa;
+} *id;
+
+
+@interface MyList
+@end
+
+@implementation MyList
+- (unsigned int)countByEnumeratingWithState:(struct __objcFastEnumerationState *)state objects:(id *)items count:(unsigned int)stackcount
+{
+ return 0;
+}
+- (void)addObject:object {
+}
+
+@end
+
+@interface MyList (BasicTest)
+- (void)compilerTestAgainst;
+@end
+void BEGIN();
+void INFORLOOP();
+void END();
+@implementation MyList (BasicTest)
+- (void)compilerTestAgainst {
+
+ BEGIN();
+ for (id elem in (self))
+ if (elem)
+ INFORLOOP();
+
+ END();
+}
+@end
+
diff --git a/gcc/testsuite/objc.dg/objc-foreach-4.m b/gcc/testsuite/objc.dg/objc-foreach-4.m
new file mode 100644
index 000000000..292a90885
--- /dev/null
+++ b/gcc/testsuite/objc.dg/objc-foreach-4.m
@@ -0,0 +1,26 @@
+/* Test for valid objc objects used in a for-each statement. */
+/* FIXME: Run this test with the GNU runtime as well. */
+/* { dg-do compile { target *-*-darwin* } } */
+/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */
+/* { dg-skip-if "No NeXT fast enum. pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */
+
+#include <objc/objc-api.h>
+#include <Foundation/Foundation.h>
+
+#if defined (__NEXT_RUNTIME__) && defined (__LP64__)
+/* Fudge the class reference until we implement the compiler-side
+ const strings. */
+extern void *_NSConstantStringClassReference;
+#endif
+
+// gcc -o foo foo.m -framework Foundation
+
+int main (int argc, char const* argv[]) {
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+ NSArray * arr = [NSArray arrayWithObjects:@"A", @"B", @"C", nil];
+ for (NSString * foo in arr) {
+ NSLog(@"foo is %@", foo);
+ }
+ [pool release];
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/objc-foreach-5.m b/gcc/testsuite/objc.dg/objc-foreach-5.m
new file mode 100644
index 000000000..cb1578199
--- /dev/null
+++ b/gcc/testsuite/objc.dg/objc-foreach-5.m
@@ -0,0 +1,39 @@
+/* FIXME: Run this test with the GNU runtime as well. */
+/* { dg-do compile { target *-*-darwin* } } */
+/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */
+/* { dg-skip-if "No NeXT fast enum. pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */
+
+#import <Foundation/Foundation.h>
+
+NSArray * createTestVictim(unsigned capacity) {
+ NSMutableArray * arr = [[NSMutableArray alloc] initWithCapacity:capacity];
+ int x = 0;
+
+ for(x = 0; x < capacity; x++) {
+ NSNumber * num = [NSNumber numberWithInteger:x];
+ [arr addObject:num];
+ }
+
+ NSArray * immutableCopy = [arr copy];
+ [arr release];
+
+ return immutableCopy;
+}
+
+void addStuffUp(NSArray * values) {
+ NSInteger accumulator = 0;
+// for (id item in values) {
+ id item;
+ for (item in values) {
+ accumulator += [item integerValue];
+ }
+}
+
+int main (int argc, char const* argv[]) {
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+ NSArray * target = createTestVictim(10);
+ addStuffUp(target);
+ [pool release];
+ return 0;
+}
+/* { dg-final { scan-assembler "_addStuffUp:" } } */
diff --git a/gcc/testsuite/objc.dg/objc-gc-4.m b/gcc/testsuite/objc.dg/objc-gc-4.m
new file mode 100644
index 000000000..097f35e9f
--- /dev/null
+++ b/gcc/testsuite/objc.dg/objc-gc-4.m
@@ -0,0 +1,64 @@
+/* Test looking up fields in superclasses in the context of write-barriers
+ (where component references get rewritten). */
+/* Contributed by Ziemowit Laski <zlaski@apple.com> */
+
+/* { dg-do compile } */
+/* { dg-options "-fobjc-gc" } */
+/* { dg-prune-output "cc1obj: warning: '-fobjc-gc' is ignored for '-fgnu-runtime'" } */
+
+#include "../objc-obj-c++-shared/Object1.h"
+
+@class MyWindow;
+
+@interface MyDocument : Object {
+ MyWindow *_window;
+}
+@end
+
+@interface MyFileDocument : MyDocument {
+ struct {
+ unsigned int autoClose:1;
+ unsigned int openForUI:1;
+ unsigned int isClosing:1;
+ unsigned int needsDiskCheck:1;
+ unsigned int isWritable:1;
+ unsigned int representsFileOnDisk:1;
+ unsigned int RESERVED:26;
+ } _fdFlags;
+}
+@end
+
+@interface MyTextFileDocument : MyFileDocument {
+ Object *_textStorage;
+ struct __tfdFlags {
+ unsigned int immutable:1;
+ unsigned int lineEnding:2;
+ unsigned int isClosing:1;
+ unsigned int settingsAreSet:1;
+ unsigned int usesTabs:1;
+ unsigned int isUTF8WithBOM:1;
+ unsigned int wrapsLines:1;
+ unsigned int usingDefaultLanguage:1;
+ unsigned int RESERVED:23;
+ } _tfdFlags;
+ int _tabWidth;
+ int _indentWidth;
+}
+@end
+
+@interface MyRTFFileDocument : MyTextFileDocument
+- (BOOL)readFromFile:(const char *)fileName ofType:(const char *)type;
+@end
+
+@implementation MyRTFFileDocument
+- (BOOL)readFromFile:(const char *)fileName ofType:(const char *)type {
+ if (_textStorage && fileName) {
+ [_textStorage free];
+ return YES;
+ } else if (type) {
+ _textStorage = [MyRTFFileDocument new];
+ return NO;
+ }
+ return (fileName && type);
+}
+@end
diff --git a/gcc/testsuite/objc.dg/objc-nofilename-1.m b/gcc/testsuite/objc.dg/objc-nofilename-1.m
new file mode 100644
index 000000000..21e0c53b7
--- /dev/null
+++ b/gcc/testsuite/objc.dg/objc-nofilename-1.m
@@ -0,0 +1,22 @@
+/* Test to make sure that file name does not appear in the binary. */
+/* { dg-do compile { target *-*-darwin* } } */
+
+#include <objc/objc.h>
+
+@interface Foo { Class isa; } @end
+@implementation Foo @end
+
+@interface Bar : Foo { Class Barisa; } @end
+
+@implementation Bar : Foo @end;
+
+@interface FINAL : Bar { Class FINALisa; } @end
+
+@implementation FINAL : Bar @end;
+
+int main(int argc, char **argv)
+{
+ return 0;
+}
+
+/* { dg-final { scan-assembler-not "objc-nofilename-1.m" } } */
diff --git a/gcc/testsuite/objc.dg/param-1.m b/gcc/testsuite/objc.dg/param-1.m
new file mode 100644
index 000000000..e796a3b51
--- /dev/null
+++ b/gcc/testsuite/objc.dg/param-1.m
@@ -0,0 +1,20 @@
+/* Test if compiler detects object as an parameter to a method
+ or not. It is not valid. */
+/* { dg-do compile } */
+
+@interface foo
+@end
+
+@implementation foo
+@end
+
+@interface bar
+-(void) my_method:(foo) my_param; /* { dg-error "can not use an object as parameter to a method" } */
+@end
+
+@implementation bar
+-(void) my_method:(foo) my_param /* { dg-error "can not use an object as parameter to a method" } */
+{
+}
+@end
+
diff --git a/gcc/testsuite/objc.dg/pch/interface-1.hs b/gcc/testsuite/objc.dg/pch/interface-1.hs
new file mode 100644
index 000000000..fe5255af1
--- /dev/null
+++ b/gcc/testsuite/objc.dg/pch/interface-1.hs
@@ -0,0 +1,4 @@
+@interface TestClass
++ (int) test;
+@end
+
diff --git a/gcc/testsuite/objc.dg/pch/interface-1.m b/gcc/testsuite/objc.dg/pch/interface-1.m
new file mode 100644
index 000000000..9bc7ef3a2
--- /dev/null
+++ b/gcc/testsuite/objc.dg/pch/interface-1.m
@@ -0,0 +1,14 @@
+#include "interface-1.h"
+
+@implementation TestClass
++ (int) test
+{
+ return 0;
+}
+@end
+
+int main (void)
+{
+ return [TestClass test];
+}
+
diff --git a/gcc/testsuite/objc.dg/pch/pch.exp b/gcc/testsuite/objc.dg/pch/pch.exp
new file mode 100644
index 000000000..0fca64125
--- /dev/null
+++ b/gcc/testsuite/objc.dg/pch/pch.exp
@@ -0,0 +1,64 @@
+# Copyright (C) 1997, 2002, 2003, 2007, 2008, 2010
+# 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 GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+# GCC testsuite for precompiled header interaction,
+# that uses the `dg.exp' driver.
+
+# Load support procs.
+load_lib objc-dg.exp
+load_lib dg-pch.exp
+load_lib torture-options.exp
+
+# Initialize `dg'.
+dg-init
+
+torture-init
+
+set-torture-options $DG_TORTURE_OPTIONS
+
+set old_dg_do_what_default "${dg-do-what-default}"
+
+global torture_without_loops
+set mytorture [concat [list {-O0 -g}] $torture_without_loops]
+
+# Main loop.
+foreach test [lsort [glob -nocomplain $srcdir/$subdir/*.m]] {
+
+ # We don't try to use the loop-optimizing options, since they are highly
+ # unlikely to make any difference to PCH. However, we do want to
+ # add -O0 -g, since users who want PCH usually want debugging and quick
+ # compiles.
+ dg-flags-pch $subdir $test "-fgnu-runtime" $mytorture ".h"
+}
+
+if [istarget "*-*-darwin*" ] {
+ foreach test [lsort [glob -nocomplain $srcdir/$subdir/*.m]] {
+ global torture_without_loops
+
+ # We don't try to use the loop-optimizing options, since they are highly
+ # unlikely to make any difference to PCH. However, we do want to
+ # add -O0 -g, since users who want PCH usually want debugging and quick
+ # compiles.
+ dg-flags-pch $subdir $test "-fnext-runtime" $mytorture ".h"
+ }
+}
+
+set dg-do-what-default "$old_dg_do_what_default"
+
+# All done.
+torture-finish
+dg-finish
diff --git a/gcc/testsuite/objc.dg/pr18255.m b/gcc/testsuite/objc.dg/pr18255.m
new file mode 100644
index 000000000..c9bb87c67
--- /dev/null
+++ b/gcc/testsuite/objc.dg/pr18255.m
@@ -0,0 +1,24 @@
+/* This is a test for a GNU Objective-C Runtime library bug. */
+/* { dg-do run } */
+/* { dg-skip-if "" { *-*-* } { "-fnext-runtime" } { "" } } */
+
+#include <objc/Protocol.h>
+#include <stdlib.h>
+
+@protocol a
+- aMethod;
+@end
+
+
+@protocol b <a>
+- bMethod;
+@end
+
+
+int main (int argc, char **argv)
+{
+ if ([@protocol(b) descriptionForInstanceMethod: @selector(aMethod)] == NULL)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/pr23214.m b/gcc/testsuite/objc.dg/pr23214.m
new file mode 100644
index 000000000..d8092a806
--- /dev/null
+++ b/gcc/testsuite/objc.dg/pr23214.m
@@ -0,0 +1,38 @@
+/* Test that there is no problem initializing multiple static
+ Protocol instances. */
+
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+#include <objc/Protocol.h>
+
+#ifdef __OBJC2__
+/* The ObjC V2 "Object" does not provide -class. */
+@interface Object (TS_CAT)
+- class;
+@end
+
+@implementation Object (TS_CAT)
+- class { return isa; }
+@end
+#endif
+
+@protocol A
+@end
+
+@protocol B
+@end
+
+@interface Dummy : Object <B>
+@end
+
+int main ()
+{
+ [@protocol(A) class];
+ [@protocol(B) class];
+
+ return 0;
+}
+
+@implementation Dummy
+@end
diff --git a/gcc/testsuite/objc.dg/pr23709.m b/gcc/testsuite/objc.dg/pr23709.m
new file mode 100644
index 000000000..7ff9b6052
--- /dev/null
+++ b/gcc/testsuite/objc.dg/pr23709.m
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+
+@interface A
++(void)method: (int)parameter {} /* { dg-error "expected" } */
+@end
+
+@implementation A
++(void)method: (int)parameter
+{
+ *parameter; /* { dg-error "invalid type argument" } */
+}
+@end
diff --git a/gcc/testsuite/objc.dg/pr24393.m b/gcc/testsuite/objc.dg/pr24393.m
new file mode 100644
index 000000000..269d84d9c
--- /dev/null
+++ b/gcc/testsuite/objc.dg/pr24393.m
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+#include <objc/objc.h>
+
+@interface Foo
+{
+ Class isa;
+}
+- (void) doSomething:(id object; /* { dg-error "xpected .\\)." } */
+- (void) someOtherMethod;
+@end
diff --git a/gcc/testsuite/objc.dg/pr28049.m b/gcc/testsuite/objc.dg/pr28049.m
new file mode 100644
index 000000000..d5ba4a10b
--- /dev/null
+++ b/gcc/testsuite/objc.dg/pr28049.m
@@ -0,0 +1,2 @@
+/* { dg-do compile } */
++ /* { dg-error "expected" } */
diff --git a/gcc/testsuite/objc.dg/pr28050.m b/gcc/testsuite/objc.dg/pr28050.m
new file mode 100644
index 000000000..efd9216f7
--- /dev/null
+++ b/gcc/testsuite/objc.dg/pr28050.m
@@ -0,0 +1,2 @@
+/* { dg-do compile } */
+int i = [0]; /* { dg-error "expected .:. before .\\]. token" } */
diff --git a/gcc/testsuite/objc.dg/pr44509.m b/gcc/testsuite/objc.dg/pr44509.m
new file mode 100644
index 000000000..7c50bd0fc
--- /dev/null
+++ b/gcc/testsuite/objc.dg/pr44509.m
@@ -0,0 +1,9 @@
+/* PR bootstrap/44509 */
+/* { dg-do compile } */
+/* { dg-options "--param ggc-min-expand=0 --param ggc-min-heapsize=0" } */
+
+double
+foo (void)
+{
+ return __DBL_MAX__ - __FLT_MAX__;
+}
diff --git a/gcc/testsuite/objc.dg/pr45735.m b/gcc/testsuite/objc.dg/pr45735.m
new file mode 100644
index 000000000..395698bdb
--- /dev/null
+++ b/gcc/testsuite/objc.dg/pr45735.m
@@ -0,0 +1,4 @@
+/* { dg-do compile } */
+@interface Fraction
+-(void) setNumerator: (int) :(int) ; /* { dg-error "expected identifier" } */
+@end
diff --git a/gcc/testsuite/objc.dg/pr45878.m b/gcc/testsuite/objc.dg/pr45878.m
new file mode 100644
index 000000000..39fd6c3cd
--- /dev/null
+++ b/gcc/testsuite/objc.dg/pr45878.m
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fexceptions" } */
+
+typedef struct objc_object { Class class_pointer; } *id;
+typedef unsigned char BOOL;
+
+@interface Object
+{
+ Class isa;
+}
+- (BOOL)isEqual:anObject;
+@end
+
+#ifdef __NEXT_RUNTIME__
+@interface NSConstantString: Object
+{
+ char *c_string;
+ unsigned int len;
+}
+@end
+extern void *_NSConstantStringClassReference;
+#else
+@interface NXConstantString: Object
+{
+ char *c_string;
+ unsigned int len;
+}
+@end
+#endif
+
+void function (void)
+{
+ if ([@"strings" isEqual: (id)0])
+ {
+ ;
+ }
+}
+
diff --git a/gcc/testsuite/objc.dg/pr48177.m b/gcc/testsuite/objc.dg/pr48177.m
new file mode 100644
index 000000000..0d7ff2979
--- /dev/null
+++ b/gcc/testsuite/objc.dg/pr48177.m
@@ -0,0 +1,35 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, May 2011. */
+/* { dg-do run } */
+/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */
+
+#include <objc/runtime.h>
+#include <stdlib.h>
+
+int main(int argc, void **args)
+{
+#ifdef __GNU_LIBOBJC__
+ /* This special test tests that, if you have a selector already
+ registered in the runtime with full type information, you can use
+ sel_registerTypedName() to get it even if you specify the type
+ with incorrect argframe information. This is helpful as
+ selectors generated by the compiler (which have correct argframe
+ information) are usually registered before hand-written ones
+ (which often have incorrect argframe information, but need the
+ correct one).
+
+ Note that in this hand-written test, even the type information of
+ the first selector may be wrong (on this machine); but that's OK
+ as we'll never actually use the selectors. */
+ SEL selector1 = sel_registerTypedName ("testMethod", "i8@0:4");
+ SEL selector2 = sel_registerTypedName ("testMethod", "i8@8:8");
+
+ /* We compare the selectors using ==, not using sel_isEqual(). This
+ is because we are testing internals of the runtime and we know
+ that in the current implementation they should be identical if
+ the stuff is to work as expected. Don't do this at home. */
+ if (selector1 != selector2)
+ abort ();
+#endif
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/pragma-1.m b/gcc/testsuite/objc.dg/pragma-1.m
new file mode 100644
index 000000000..e9527e39e
--- /dev/null
+++ b/gcc/testsuite/objc.dg/pragma-1.m
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* ??? Is there a better pragma that is handled for all targets, not
+ handled by the preprocessor, that would be better for testing here? */
+
+@interface a {}
+#pragma mark --- Output ---
+@end
diff --git a/gcc/testsuite/objc.dg/private-1.m b/gcc/testsuite/objc.dg/private-1.m
new file mode 100644
index 000000000..a11183c8e
--- /dev/null
+++ b/gcc/testsuite/objc.dg/private-1.m
@@ -0,0 +1,59 @@
+/* Test errors for accessing @private and @protected variables. */
+/* Author: Nicola Pero <nicola@brainstorm.co.uk>. */
+/* { dg-do compile } */
+#include <objc/objc.h>
+
+@interface MySuperClass
+{
+@private
+ int private;
+
+@protected
+ int protected;
+
+@public
+ int public;
+}
+- (void) test;
+@end
+
+@implementation MySuperClass
+- (void) test
+{
+ private = 12; /* Ok */
+ protected = 12; /* Ok */
+ public = 12; /* Ok */
+}
+@end
+
+
+@interface MyClass : MySuperClass
+@end
+
+@implementation MyClass
+- (void) test
+{
+ /* Private variables simply don't exist in the subclass. */
+ private = 12; /* { dg-error "instance variable" } */
+ /* { dg-message "function it appears in" "" { target *-*-* } { 37 } } */
+
+ protected = 12; /* Ok */
+ public = 12; /* Ok */
+}
+@end
+
+int main (void)
+{
+ MyClass *m = nil;
+
+ if (m != nil)
+ {
+ int access;
+
+ access = m->private; /* { dg-warning "is @private" } */
+ access = m->protected; /* { dg-warning "is @protected" } */
+ access = m->public; /* Ok */
+ }
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/private-2.m b/gcc/testsuite/objc.dg/private-2.m
new file mode 100644
index 000000000..eff376a0c
--- /dev/null
+++ b/gcc/testsuite/objc.dg/private-2.m
@@ -0,0 +1,54 @@
+/* Test warnings for shadowing instance variables. */
+/* Author: Nicola Pero <nicola@brainstorm.co.uk>. */
+/* { dg-do compile } */
+#include <objc/objc.h>
+
+@interface MySuperClass
+{
+@private
+ int private;
+
+@protected
+ int protected;
+
+@public
+ int public;
+}
+- (void) test;
+@end
+
+@implementation MySuperClass
+- (void) test
+{
+ /* FIXME: I wonder if the warnings shouldn't be better generated
+ when the variable is declared, rather than used! */
+ int private = 12;
+ int protected = 12;
+ int public = 12;
+ int a;
+
+ a = private; /* { dg-warning "hides instance variable" } */
+ a = protected; /* { dg-warning "hides instance variable" } */
+ a = public; /* { dg-warning "hides instance variable" } */
+}
+@end
+
+
+@interface MyClass : MySuperClass
+@end
+
+@implementation MyClass
+- (void) test
+{
+ int private = 12;
+ int protected = 12;
+ int public = 12;
+ int a;
+
+ /* The private variable can be shadowed without warnings, because
+ * it's invisible, and not accessible, to the subclass! */
+ a = private; /* Ok */
+ a = protected; /* { dg-warning "hides instance variable" } */
+ a = public; /* { dg-warning "hides instance variable" } */
+}
+@end
diff --git a/gcc/testsuite/objc.dg/property/at-property-1.m b/gcc/testsuite/objc.dg/property/at-property-1.m
new file mode 100644
index 000000000..4ff269d0f
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-1.m
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+@interface MyRootClass
+{
+ Class isa;
+}
+@property; /* { dg-error "expected" } */
+@property int; /* { dg-error "expected identifier" } */
+ /* { dg-warning "declaration does not declare anything" "" { target *-*-* } 10 } */
+@property int a;
+@property int b, c;
+@property () int d; /* { dg-error "expected identifier" } */
+@property (readonly) int e;
+@property (readonly,) int f; /* { dg-error "expected identifier" } */
+@property (xxx) int g; /* { dg-error "unknown property attribute" } */
+@property (readonly,xxx) int h; /* { dg-error "unknown property attribute" } */
+@property ( int i; /* { dg-error "unknown property attribute" } */
+/* Because the last syntax error opens a '(' and never closes it, we get to the end of input. */
+@end /* { dg-error "expected ..end. at end of input" } */
diff --git a/gcc/testsuite/objc.dg/property/at-property-10.m b/gcc/testsuite/objc.dg/property/at-property-10.m
new file mode 100644
index 000000000..79d2ecdbb
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-10.m
@@ -0,0 +1,100 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* Test the property syntax in a number of expressions. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+ int a;
+}
+/* Use the simplest synthesized accessor (assign, nonatomic) as we are
+ not testing the synthesized accessors in this test, just the
+ property syntax. */
+@property (nonatomic) int a;
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+@synthesize a;
+@end
+
+int
+test (int g)
+{
+ return g;
+}
+
+int main (void)
+{
+ MyRootClass *object = [[MyRootClass alloc] init];
+ MyRootClass *object2 = [[MyRootClass alloc] init];
+
+ object.a = 14;
+ object.a = object.a + object.a;
+
+ if (object.a != 28)
+ abort ();
+
+ object.a = 99;
+ object.a++;
+
+ if (object.a != 100)
+ abort ();
+
+ object.a = 99;
+ object.a *= 2;
+
+ if (object.a != 198)
+ abort ();
+
+ {
+ int f = object.a;
+
+ if (f != 198)
+ abort ();
+
+ if (f != object.a)
+ abort ();
+
+ if (object.a != f)
+ abort ();
+
+ object.a = object.a;
+
+ if (object.a != 198)
+ abort ();
+ }
+
+ if (test (object.a) != 198)
+ abort ();
+
+ object.a = -object.a;
+
+ if (object.a != -198)
+ abort ();
+
+ for (object.a = 0; object.a < 99; object.a++)
+ object2.a = object.a;
+
+ if (object2.a != object.a - 1)
+ abort ();
+
+ if (object2.a != 98)
+ abort ();
+
+ if (object.a != 99)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/property/at-property-11.m b/gcc/testsuite/objc.dg/property/at-property-11.m
new file mode 100644
index 000000000..33baee9d6
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-11.m
@@ -0,0 +1,47 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* Test that properties are found even if implemented in superclasses. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+ int a;
+}
+/* Use the simplest synthesized accessor (assign, nonatomic) as we are
+ not testing the synthesized accessors in this test, just the
+ property syntax. */
+@property (nonatomic) int a;
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+@synthesize a;
+@end
+
+@interface MySubClass : MyRootClass
+@end
+
+@implementation MySubClass
+@end
+
+int main (void)
+{
+ MySubClass *object = [[MySubClass alloc] init];
+
+ object.a = 40;
+ if (object.a != 40)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/property/at-property-12.m b/gcc/testsuite/objc.dg/property/at-property-12.m
new file mode 100644
index 000000000..e36f57aaa
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-12.m
@@ -0,0 +1,47 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* Test atomic, assign synthesized methods. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+ int a;
+ id b;
+}
+@property int a;
+@property (assign) id b;
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+@synthesize a;
+@synthesize b;
+@end
+
+int main (void)
+{
+ MyRootClass *object = [[MyRootClass alloc] init];
+
+ object.a = 40;
+ if (object.a != 40)
+ abort ();
+
+ object.b = object;
+ if (object.b != object)
+ abort ();
+
+ return 0;
+}
+
+
diff --git a/gcc/testsuite/objc.dg/property/at-property-13.m b/gcc/testsuite/objc.dg/property/at-property-13.m
new file mode 100644
index 000000000..89bf748a2
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-13.m
@@ -0,0 +1,72 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* Test retain and copy synthesized methods. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+ int copy_count;
+ id a;
+ id b;
+}
+@property (copy) id a;
+@property (retain) id b;
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+- (id) copyWithZone: (void *)zone;
+- (int) copyCount;
+- (id) autorelease;
+- (oneway void) release;
+- (id) retain;
+@end
+
+/* This class implements copyWithZone, which doesn't do anything other
+ than increasing a counter of how many copies were made. */
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+- (id) copyWithZone: (void *)zone { copy_count++; return self; }
+- (int) copyCount { return copy_count; }
+- (id) autorelease { return self; }
+- (oneway void) release { return; }
+- (id) retain { return self; }
+@synthesize a;
+@synthesize b;
+@end
+
+int main (void)
+{
+ MyRootClass *object = [[MyRootClass alloc] init];
+ MyRootClass *argument = [[MyRootClass alloc] init];
+
+ /* This should copy argument. */
+ object.a = argument;
+ if (object.a != argument)
+ abort ();
+
+ /* Test that it was copied. */
+ if ([object.a copyCount] != 1)
+ abort ();
+
+ /* We just test that the retain accessors seem to work and that they
+ don't copy. We don't test that retain was actually called,
+ because if garbage collection is enabled, it may never be
+ called! */
+ object.b = argument;
+ if (object.b != argument)
+ abort ();
+
+ /* Test that it was not copied. */
+ if ([object.b copyCount] != 1)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/property/at-property-14.m b/gcc/testsuite/objc.dg/property/at-property-14.m
new file mode 100644
index 000000000..ccf842b7f
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-14.m
@@ -0,0 +1,20 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+@interface MyRootClass
+{
+ Class isa;
+}
+
+/* Test the warnings on 'assign'. */
+@property id property_a; /* { dg-warning "object property .property.a. has no .assign., .retain. or .copy. attribute" } */
+ /* { dg-message ".assign. can be unsafe for Objective-C objects" "" { target *-*-* } 12 } */
+
+@property (readonly) id property_b; /* No 'assign' warning (assign semantics do not matter if the property is readonly). */
+@property id *property_c; /* No 'assign' warning (the type is not an Objective-C object). */
+@property Class property_d; /* No 'assign' warning (Classes are static objects so assign semantics do not matter for them). */
+@property MyRootClass *property_e; /* { dg-warning "object property .property.e. has no .assign., .retain. or .copy. attribute" } */
+ /* { dg-message ".assign. can be unsafe for Objective-C objects" "" { target *-*-* } 18 } */
+@end
diff --git a/gcc/testsuite/objc.dg/property/at-property-15.m b/gcc/testsuite/objc.dg/property/at-property-15.m
new file mode 100644
index 000000000..ef5344246
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-15.m
@@ -0,0 +1,20 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+/* { dg-options "-Wno-property-assign-default" } */
+
+#include <objc/objc.h>
+
+/* Test that -Wno-property-assign-default turns off all "object
+ property xxx has no assign, return or copy attribute" warnings. */
+
+@interface MyRootClass
+{
+ Class isa;
+}
+
+@property id property_a; /* Would normally generate a warning. */
+@property (readonly) id property_b;
+@property id *property_c;
+@property Class property_d;
+@property MyRootClass *property_e; /* Would normally generate a warning. */
+@end
diff --git a/gcc/testsuite/objc.dg/property/at-property-16.m b/gcc/testsuite/objc.dg/property/at-property-16.m
new file mode 100644
index 000000000..95f82e41b
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-16.m
@@ -0,0 +1,55 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+/* Test that if you have a property declared in a class and a
+ sub-class, the attributes match. */
+
+@interface MyRootClass
+{
+ Class isa;
+}
+@property (assign) id a;
+@property (retain) id b;
+@property int c;
+@property (nonatomic) int d;
+@property int e;
+@property int f;
+@property int g;
+@property (readonly) int h;
+@property (readonly,getter=getMe) int i;
+@end
+
+@interface MyClass : MyRootClass
+@property (assign) id a;
+@property (retain) id b;
+@property int c;
+@property (nonatomic) int d;
+@property int e;
+@property int f;
+@property int g;
+@property (readonly) int h;
+@property (readonly,getter=getMe) int i;
+@end
+
+@interface MyClass2 : MyRootClass
+@property (retain) id a; /* { dg-warning "assign semantics attributes of property .a. conflict with previous declaration" } */
+ /* { dg-message "originally specified here" "" { target *-*-* } 13 } */
+@property (assign) id b; /* { dg-warning "assign semantics attributes of property .b. conflict with previous declaration" } */
+ /* { dg-message "originally specified here" "" { target *-*-* } 14 } */
+@property (nonatomic) int c; /* { dg-warning ".nonatomic. attribute of property .c. conflicts with previous declaration" } */
+ /* { dg-message "originally specified here" "" { target *-*-* } 15 } */
+@property int d; /* { dg-warning ".nonatomic. attribute of property .d. conflicts with previous declaration" } */
+ /* { dg-message "originally specified here" "" { target *-*-* } 16 } */
+@property (setter=setX:) int e; /* { dg-warning ".setter. attribute of property .e. conflicts with previous declaration" } */
+ /* { dg-message "originally specified here" "" { target *-*-* } 17 } */
+@property (getter=x) int f; /* { dg-warning ".getter. attribute of property .f. conflicts with previous declaration" } */
+ /* { dg-message "originally specified here" "" { target *-*-* } 18 } */
+@property (readonly) int g; /* { dg-warning ".readonly. attribute of property .g. conflicts with previous declaration" } */
+ /* { dg-message "originally specified here" "" { target *-*-* } 19 } */
+@property (readwrite) int h; /* Ok */
+@property (readonly) int i; /* { dg-warning ".getter. attribute of property .i. conflicts with previous declaration" } */
+ /* { dg-message "originally specified here" "" { target *-*-* } 21 } */
+@end
+
diff --git a/gcc/testsuite/objc.dg/property/at-property-17.m b/gcc/testsuite/objc.dg/property/at-property-17.m
new file mode 100644
index 000000000..efb62d6f7
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-17.m
@@ -0,0 +1,98 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+/* Test that if you have a property declared in a class, with
+ getters/setters in the superclass, there are no warnings. */
+
+@interface MyRootClass
+{
+ Class isa;
+ int myCount;
+ int myCount2;
+ int myCount3;
+}
+- (int)count;
+- (void)setCount: (int)number;
+- (int)count2;
+- (void)setCount2: (int)number;
+- (int)count3;
+@end
+
+@implementation MyRootClass
+- (int) count
+{
+ return myCount;
+}
+- (void) setCount: (int)number
+{
+ myCount = number;
+}
+- (int) count2
+{
+ return myCount2;
+}
+- (void) setCount2: (int)number
+{
+ myCount2 = number;
+}
+- (int) count3
+{
+ return myCount3;
+}
+@end
+
+
+
+/* Try with a subclass. */
+@interface MyClass : MyRootClass
+@property int count;
+@end
+
+@implementation MyClass
+@end /* No warnings. */
+
+
+
+/* Try with a category. */
+@interface MyRootClass (count)
+@property int count;
+@end
+
+@implementation MyRootClass (count)
+@end /* No warnings. */
+
+
+
+/* Try with a category of a subclass. */
+@interface MyClass2 : MyClass
+@end
+
+@implementation MyClass2
+@end
+
+@interface MyClass2 (count2)
+@property int count2;
+@end
+
+@implementation MyClass2 (count2)
+@end /* No warnings. */
+
+
+
+/* Now, try with a category of a subclass, but with a missing setter,
+ which should generate a warning. */
+@interface MyClass3 : MyClass
+@end
+
+@implementation MyClass3
+@end
+
+@interface MyClass3 (count3)
+@property int count3;
+@end
+
+@implementation MyClass3 (count3)
+@end /* { dg-warning "incomplete implementation" } */
+/* { dg-warning "method definition for .-setCount3:. not found" "" { target *-*-* } 97 } */
diff --git a/gcc/testsuite/objc.dg/property/at-property-18.m b/gcc/testsuite/objc.dg/property/at-property-18.m
new file mode 100644
index 000000000..e6ffb39cb
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-18.m
@@ -0,0 +1,47 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+/* Test that if you have a property declared in a class and a
+ category, the attributes match. This is almost the same as
+ at-property-16.m, but for a category. It is a separate file
+ because it is difficult to test multiple messages for the same
+ line. */
+
+@interface MyRootClass
+{
+ Class isa;
+}
+@property (assign) id a;
+@property (retain) id b;
+@property int c;
+@property (nonatomic) int d;
+@property int e;
+@property int f;
+@property int g;
+@property (readonly) int h;
+@property (readonly,getter=getMe) int i;
+@property (nonatomic) float j;
+@end
+
+@interface MyRootClass (Category)
+@property (retain) id a; /* { dg-warning "assign semantics attributes of property .a. conflict with previous declaration" } */
+ /* { dg-message "originally specified here" "" { target *-*-* } 16 } */
+@property (assign) id b; /* { dg-warning "assign semantics attributes of property .b. conflict with previous declaration" } */
+ /* { dg-message "originally specified here" "" { target *-*-* } 17 } */
+@property (nonatomic) int c; /* { dg-warning ".nonatomic. attribute of property .c. conflicts with previous declaration" } */
+ /* { dg-message "originally specified here" "" { target *-*-* } 18 } */
+@property int d; /* { dg-warning ".nonatomic. attribute of property .d. conflicts with previous declaration" } */
+ /* { dg-message "originally specified here" "" { target *-*-* } 19 } */
+@property (setter=setX:) int e; /* { dg-warning ".setter. attribute of property .e. conflicts with previous declaration" } */
+ /* { dg-message "originally specified here" "" { target *-*-* } 20 } */
+@property (getter=x) int f; /* { dg-warning ".getter. attribute of property .f. conflicts with previous declaration" } */
+ /* { dg-message "originally specified here" "" { target *-*-* } 21 } */
+@property (readonly) int g; /* { dg-warning ".readonly. attribute of property .g. conflicts with previous declaration" } */
+ /* { dg-message "originally specified here" "" { target *-*-* } 22 } */
+@property (readwrite) int h; /* Ok */
+@property (readonly) int i; /* { dg-warning ".getter. attribute of property .i. conflicts with previous declaration" } */
+ /* { dg-message "originally specified here" "" { target *-*-* } 24 } */
+@property (nonatomic) float j; /* Ok */
+@end
diff --git a/gcc/testsuite/objc.dg/property/at-property-19.m b/gcc/testsuite/objc.dg/property/at-property-19.m
new file mode 100644
index 000000000..be898e218
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-19.m
@@ -0,0 +1,74 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* Test looking up a @property in a protocol of a category of a superclass. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+ int a;
+}
++ (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 getter/setter, so that the only way to compile
+ object.count is to find the actual @property. */
+@protocol count
+@property (getter=number, setter=setNumber:) int count;
+@end
+
+@interface MySubClass : MyRootClass
+- (int) testMe;
+@end
+
+@interface MySubClass (Category) <count>
+@end
+
+@implementation MySubClass (Category)
+- (int) number
+{
+ return a;
+}
+- (void) setNumber: (int)count
+{
+ a = count;
+}
+@end
+
+@implementation MySubClass
+- (int) testMe
+{
+ self.count = 400;
+ if (self.count != 400)
+ abort ();
+
+ return self.count;
+}
+@end
+
+int main (void)
+{
+ MySubClass *object = [[MySubClass alloc] init];
+
+ object.count = 44;
+ if (object.count != 44)
+ abort ();
+
+ if ([object testMe] != 400)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/property/at-property-2.m b/gcc/testsuite/objc.dg/property/at-property-2.m
new file mode 100644
index 000000000..19d59fdaa
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-2.m
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+@interface MyRootClass
+{
+ Class isa;
+}
+@property int name __attribute__((deprecated));
+@property int table __attribute__((xxx)); /* { dg-warning ".xxx. attribute directive ignored" } */
+@property void function (void); /* { dg-error "declared as a function" } */
+@property typedef int j; /* { dg-error "expected" } */
+@end
diff --git a/gcc/testsuite/objc.dg/property/at-property-20.m b/gcc/testsuite/objc.dg/property/at-property-20.m
new file mode 100644
index 000000000..1bb49da2b
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-20.m
@@ -0,0 +1,81 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+/* Test that if you have a property declared in a class and a
+ sub-class, the types match (unless it's a readonly property, in
+ which case a "specialization" is enough). */
+
+@protocol MyProtocolA
+- (void) doNothingA;
+@end
+
+@protocol MyProtocolB
+- (void) doNothingB;
+@end
+
+@interface MyRootClass
+{
+ Class isa;
+}
+@end
+
+@interface MySubClass1 : MyRootClass
+@end
+
+@interface MySubClass2 : MyRootClass
+@end
+
+@interface MySubClass3 : MyRootClass <MyProtocolA>
+@end
+
+@interface MySubClass4 : MySubClass1
+@end
+
+/* Now, the test. */
+
+@interface MyClass : MyRootClass
+{ }
+@property (assign) id <MyProtocolA> a; /* { dg-message "originally specified here" } */
+@property int b; /* { dg-message "originally specified here" } */
+@property float c; /* { dg-message "originally specified here" } */
+@property (assign) MyRootClass *d; /* { dg-message "originally specified here" } */
+@property (assign) MySubClass1 *e; /* { dg-message "originally specified here" } */
+@property (assign, readonly) MySubClass1 *f; /* { dg-message "originally specified here" } */
+@property (assign) MySubClass3 *g; /* { dg-message "originally specified here" } */
+@property (assign, readonly) MySubClass3 *h; /* { dg-message "originally specified here" } */
+@end
+
+/* The following are all OK because they are identical. */
+@interface MyClass2 : MyClass
+{ }
+@property (assign) id a;
+@property int b;
+@property float c;
+@property (assign) MyRootClass *d;
+@property (assign) MySubClass1 *e;
+@property (assign, readonly) MySubClass1 *f;
+@property (assign) MySubClass3 *g;
+@property (assign, readonly) MySubClass3 *h;
+@end
+
+/* The following are not OK. */
+@interface MyClass3 : MyClass
+{ }
+@property (assign) MySubClass1 *a; /* { dg-warning "type of property .a. conflicts with previous declaration" } */
+@property float b; /* { dg-warning "type of property .b. conflicts with previous declaration" } */
+@property int c; /* { dg-warning "type of property .c. conflicts with previous declaration" } */
+@property (assign) id d; /* { dg-warning "type of property .d. conflicts with previous declaration" } */
+@property (assign) MyRootClass *e; /* { dg-warning "type of property .e. conflicts with previous declaration" } */
+@property (assign, readonly) MyRootClass *f; /* { dg-warning "type of property .f. conflicts with previous declaration" } */
+@property (assign) MySubClass2 *g; /* { dg-warning "type of property .g. conflicts with previous declaration" } */
+@property (assign, readonly) MySubClass2 *h; /* { dg-warning "type of property .h. conflicts with previous declaration" } */
+@end
+
+/* The following are OK. */
+@interface MyClass4 : MyClass
+{ }
+@property (assign, readonly) MySubClass4 *f;
+@property (assign, readonly) MySubClass3 <MyProtocolB> *h;
+@end
diff --git a/gcc/testsuite/objc.dg/property/at-property-21.m b/gcc/testsuite/objc.dg/property/at-property-21.m
new file mode 100644
index 000000000..d1f54b1cd
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-21.m
@@ -0,0 +1,23 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+@protocol MyProtocol
+- (void) message;
+@end
+
+@interface MyRootClass
+{
+ Class isa;
+}
+
+/* Test the warnings on 'assign' with protocols. */
+@property id <MyProtocol> property_a; /* { dg-warning "object property .property.a. has no .assign., .retain. or .copy. attribute" } */
+ /* { dg-message ".assign. can be unsafe for Objective-C objects" "" { target *-*-* } 16 } */
+
+@property MyRootClass <MyProtocol> *property_b; /* { dg-warning "object property .property.b. has no .assign., .retain. or .copy. attribute" } */
+ /* { dg-message ".assign. can be unsafe for Objective-C objects" "" { target *-*-* } 19 } */
+
+@property Class <MyProtocol> property_c; /* No 'assign' warning (Classes are static objects so assign semantics do not matter for them). */
+@end
diff --git a/gcc/testsuite/objc.dg/property/at-property-22.m b/gcc/testsuite/objc.dg/property/at-property-22.m
new file mode 100644
index 000000000..03b3d0bb4
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-22.m
@@ -0,0 +1,172 @@
+/* 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 properties of different types. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+enum colour { Red, Black };
+
+@interface MyRootClass
+{
+ Class isa;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
++ (Class) class;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
++ (Class) class { return self; }
+@end
+
+
+@interface MyClass : MyRootClass
+{
+ /* A bunch of C types. */
+ char pchar;
+ short pshort;
+ int pint;
+ long plong;
+ float pfloat;
+ double pdouble;
+ enum colour penum;
+
+ /* A bunch of pointers to C types. */
+ char *pcharp;
+ short *pshortp;
+ int *pintp;
+ long *plongp;
+ float *pfloatp;
+ double *pdoublep;
+ enum colour *penump;
+
+ /* A bunch of Objective-C types. */
+ id pid;
+ Class pclass;
+ MyClass *pMyClassp;
+}
+@property (assign) char pchar;
+@property (assign) short pshort;
+@property (assign) int pint;
+@property (assign) long plong;
+@property (assign) float pfloat;
+@property (assign) double pdouble;
+@property (assign) enum colour penum;
+
+@property (assign) char *pcharp;
+@property (assign) short *pshortp;
+@property (assign) int *pintp;
+@property (assign) long *plongp;
+@property (assign) float *pfloatp;
+@property (assign) double *pdoublep;
+@property (assign) enum colour *penump;
+
+@property (assign) id pid;
+@property (assign) Class pclass;
+@property (assign) MyClass *pMyClassp;
+@end
+
+@implementation MyClass
+@synthesize pchar;
+@synthesize pshort;
+@synthesize pint;
+@synthesize plong;
+@synthesize pfloat;
+@synthesize pdouble;
+@synthesize penum;
+
+@synthesize pcharp;
+@synthesize pshortp;
+@synthesize pintp;
+@synthesize plongp;
+@synthesize pfloatp;
+@synthesize pdoublep;
+@synthesize penump;
+
+@synthesize pid;
+@synthesize pclass;
+@synthesize pMyClassp;
+@end
+
+int main (void)
+{
+ MyClass *object = [[MyClass alloc] init];
+
+ object.pchar = 1;
+ if (object.pchar != 1)
+ abort ();
+
+ object.pshort = 2;
+ if (object.pshort != 2)
+ abort ();
+
+ object.pint = 3;
+ if (object.pint != 3)
+ abort ();
+
+ object.plong = 4;
+ if (object.plong != 4)
+ abort ();
+
+ object.pfloat = 0;
+ if (object.pfloat != 0)
+ abort ();
+
+ object.pdouble = 0;
+ if (object.pdouble != 0)
+ abort ();
+
+ object.penum = Black;
+ if (object.penum != Black)
+ abort ();
+
+ object.pcharp = (char *)0;
+ if (object.pcharp != 0)
+ abort ();
+
+ object.pshortp = (short *)0;
+ if (object.pshortp != 0)
+ abort ();
+
+ object.pintp = (int *)0;
+ if (object.pintp != 0)
+ abort ();
+
+ object.plongp = (long *)0;
+ if (object.plongp != 0)
+ abort ();
+
+ object.pfloatp = (float *)0;
+ if (object.pfloatp != 0)
+ abort ();
+
+ object.pdoublep = (double *)0;
+ if (object.pdoublep != 0)
+ abort ();
+
+ object.penump = (enum colour *)0;
+ if (object.penump != 0)
+ abort ();
+
+ object.pid = object;
+ if (object.pid != object)
+ abort ();
+
+ object.pclass = [MyClass class];
+ if (object.pclass != [MyClass class])
+ abort ();
+
+ object.pMyClassp = object;
+ if (object.pMyClassp != object)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/property/at-property-23.m b/gcc/testsuite/objc.dg/property/at-property-23.m
new file mode 100644
index 000000000..c1fd29df4
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-23.m
@@ -0,0 +1,17 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+/* Test that properties of type arrays or bitfields are rejected. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+}
+@property int a[8]; /* { dg-error "property can not be an array" } */
+@property int b:8; /* { dg-error "property can not be a bit-field" } */
+@property int c[]; /* { dg-error "property can not be an array" } */
+@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 000000000..b4a7699f6
--- /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 000000000..422a29e55
--- /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/property/at-property-26.m b/gcc/testsuite/objc.dg/property/at-property-26.m
new file mode 100644
index 000000000..c45757e23
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-26.m
@@ -0,0 +1,85 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* Test @properties in class extensions. */
+
+#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 count4
+/* Use a different getters/setters, so that the only way to compile
+ object.countX is to find the actual @property. */
+@property (getter=number4, setter=setNumber4:) int count4;
+@end
+
+@interface MySubClass : MyRootClass
+{
+ int count1;
+ int count2;
+ int count3;
+ int count4;
+}
+@property (getter=number1, setter=setNumber1:) int count1;
+@end
+
+@interface MySubClass ()
+@property (getter=number2, setter=setNumber2:) int count2;
+@end
+
+@interface MySubClass () <count4>
+@property (getter=number3, setter=setNumber3:) int count3;
+@end
+
+@implementation MySubClass
+@synthesize count1;
+@synthesize count2;
+- (int) number3
+{
+ return count3;
+}
+- (void) setNumber3: (int)value
+{
+ count3 = value;
+}
+@synthesize count4;
+@end
+
+int main (void)
+{
+ MySubClass *object = [[MySubClass alloc] init];
+
+ object.count1 = 20;
+ if (object.count1 != 20)
+ abort ();
+
+ object.count2 = 11;
+ if (object.count2 != 11)
+ abort ();
+
+ object.count3 = 19;
+ if (object.count3 != 19)
+ abort ();
+
+ object.count4 = 74;
+ if (object.count4 != 74)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/property/at-property-27.m b/gcc/testsuite/objc.dg/property/at-property-27.m
new file mode 100644
index 000000000..727834684
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-27.m
@@ -0,0 +1,66 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* Test overriding a readonly @property with a readwrite one in a class extension. */
+
+#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 count2
+/* Use a different getters/setters, so that the only way to compile
+ object.countX is to find the actual @property. */
+@property (readonly, getter=number2) int count2;
+@end
+
+@interface MySubClass : MyRootClass
+{
+ int count1;
+ int count2;
+}
+@property (readonly, getter=number1) int count1;
+@end
+
+@interface MySubClass ()
+@property (readwrite, getter=number1, setter=setNumber1:) int count1;
+@end
+
+@interface MySubClass () <count2>
+@property (readwrite, getter=number2, setter=setNumber2:) int count2;
+@end
+
+@implementation MySubClass
+@synthesize count1;
+@synthesize count2;
+@end
+
+int main (void)
+{
+ MySubClass *object = [[MySubClass alloc] init];
+
+ object.count1 = 20;
+ if (object.count1 != 20)
+ abort ();
+
+ object.count2 = 11;
+ if (object.count2 != 11)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/property/at-property-28.m b/gcc/testsuite/objc.dg/property/at-property-28.m
new file mode 100644
index 000000000..de5122443
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-28.m
@@ -0,0 +1,29 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
+/* { dg-do compile } */
+
+/* Test errors when extending a property in a class extension. */
+
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+}
+@property (readonly, retain) id property1; /* { dg-message "originally specified here" } */
+@property (readonly) int property2; /* { dg-message "originally specified here" } */
+@property (readonly, getter=y) int property3; /* { dg-message "originally specified here" } */
+@property (readonly) int property4; /* Ok */
+@property (readonly) int property5; /* { dg-message "originally specified here" } */
+@end
+
+@interface MyRootClass ()
+@property (readwrite, copy) id property1; /* { dg-warning "assign semantics attributes of property .property1. conflict with previous declaration" } */
+@property (readwrite, nonatomic) int property2; /* { dg-warning ".nonatomic. attribute of property .property2. conflicts with previous declaration" } */
+@property (readwrite, getter=x) int property3; /* { dg-warning ".getter. attribute of property .property3. conflicts with previous declaration" } */
+@property (readwrite) int property4; /* Ok */
+@property (readwrite) float property5; /* { dg-warning "type of property .property5. conflicts with previous declaration" } */
+@end
+
+
+
diff --git a/gcc/testsuite/objc.dg/property/at-property-29.m b/gcc/testsuite/objc.dg/property/at-property-29.m
new file mode 100644
index 000000000..0f31617f8
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-29.m
@@ -0,0 +1,14 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, January 2011. */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+@interface MyRootClass
+{
+ Class isa;
+}
+/* Test missing '=' in setter/getter attributes. */
+@property (getter) int property_a; /* { dg-error "missing .=. .after .getter. attribute." } */
+@property (setter) int property_b; /* { dg-error "missing .=. .after .setter. attribute." } */
+@property (assign, getter) int property_c; /* { dg-error "missing .=. .after .getter. attribute." } */
+@end
diff --git a/gcc/testsuite/objc.dg/property/at-property-3.m b/gcc/testsuite/objc.dg/property/at-property-3.m
new file mode 100644
index 000000000..70b522cba
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-3.m
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+@interface MyRootClass
+{
+ Class isa;
+}
+@property volatile int a; /* This is allowed */
+@property extern int b; /* { dg-error "expected" } */
+@property static int c; /* { dg-error "expected" } */
+@property inline int d; /* { dg-error "expected" } */
+@property typedef int e; /* { dg-error "expected" } */
+@property __thread int f; /* { dg-error "expected" } */
+@end
diff --git a/gcc/testsuite/objc.dg/property/at-property-4.m b/gcc/testsuite/objc.dg/property/at-property-4.m
new file mode 100644
index 000000000..941aab8e3
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-4.m
@@ -0,0 +1,40 @@
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+@interface MyRootClass
+{
+ Class isa;
+}
+- (int) myGetter;
+- (int) myGetterB;
+- (int) myGetter2;
+- (void) mySetter: (int)property;
+- (void) mySetterB: (int)property;
+- (void) mySetter2: (int)property;
+
+/* Test that all the new property attributes can be parsed. */
+@property (assign) id property_a;
+@property (copy) id property_b;
+@property (nonatomic) int property_c;
+@property (readonly) int property_d;
+@property (readwrite) int property_e;
+@property (retain) id property_f;
+@property (release) int property_g; /* { dg-error "unknown property attribute" } */
+
+@property (getter=myGetter) int property_h;
+@property (setter=mySetter:) int property_i;
+
+/* Now test various problems. */
+
+@property (readonly, readwrite) int a; /* { dg-error ".readonly. attribute conflicts with .readwrite. attribute" } */
+@property (readonly, setter=mySetterB:) int b; /* { dg-error ".readonly. attribute conflicts with .setter. attribute" } */
+
+@property (assign, retain) id c; /* { dg-error ".assign. attribute conflicts with .retain. attribute" } */
+@property (assign, copy) id d; /* { dg-error ".assign. attribute conflicts with .copy. attribute" } */
+@property (copy, retain) id e; /* { dg-error ".retain. attribute conflicts with .copy. attribute" } */
+
+@property (setter=mySetter:,setter=mySetter2:) int f; /* { dg-error ".setter. attribute may only be specified once" } */
+@property (getter=myGetter, getter=myGetter2 ) int g; /* { dg-error ".getter. attribute may only be specified once" } */
+
+@end
diff --git a/gcc/testsuite/objc.dg/property/at-property-5.m b/gcc/testsuite/objc.dg/property/at-property-5.m
new file mode 100644
index 000000000..bd8949b7f
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-5.m
@@ -0,0 +1,34 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+@interface MyRootClass
+{
+ Class isa;
+ id property_a;
+ int property_b;
+ int property_c;
+ int property_d;
+ id property_e;
+ id property_f;
+ id property_g;
+ id property_h;
+}
+
+/* Test various error messages. */
+@property id property_a; /* { dg-warning "object property .property.a. has no .assign., .retain. or .copy. attribute" } */
+ /* { dg-message ".assign. can be unsafe for Objective-C objects" "" { target *-*-* } 20 } */
+@property int property_b = 4; /* { dg-error "expected" } */
+@property (retain) int property_c; /* { dg-error ".retain. attribute is only valid for Objective-C objects" } */
+@property (copy) int property_d; /* { dg-error ".copy. attribute is only valid for Objective-C objects" } */
+
+@property (retain) id property_e;
+@property (retain) id property_f;
+@property (retain) id property_g;
+@property (retain) id property_h;
+@property (retain) id property_e; /* { dg-error "redeclaration of property .property_e." } */
+ /* { dg-message "originally specified here" "" { target *-*-* } 26 } */
+@end
+
+@property id test; /* { dg-error "property declaration not in .interface or .protocol context" } */
diff --git a/gcc/testsuite/objc.dg/property/at-property-6.m b/gcc/testsuite/objc.dg/property/at-property-6.m
new file mode 100644
index 000000000..b3584cc40
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-6.m
@@ -0,0 +1,61 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* Test the property syntax with non-synthesized setter/getter
+ and with standard names. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+ int a;
+}
+@property (nonatomic) int a;
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+
+- (int) a
+{
+ return a;
+}
+- (void) setA: (int)value
+{
+ a = value;
+}
+@end
+
+int main (void)
+{
+ MyRootClass *object = [[MyRootClass alloc] init];
+
+ if (object.a != 0)
+ abort ();
+
+ object.a = 14;
+
+ if (object.a != 14)
+ abort ();
+
+ object.a = 23;
+
+ if (object.a != 23)
+ abort ();
+
+ object.a = 78;
+
+ if (object.a != 78)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/property/at-property-7.m b/gcc/testsuite/objc.dg/property/at-property-7.m
new file mode 100644
index 000000000..6f5cedaac
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-7.m
@@ -0,0 +1,58 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* Test the property syntax with non-synthesized setter/getter
+ and with a non-standard name for the getter. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+ int a;
+}
+@property (getter = getA, nonatomic) int a;
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+
+- (int) getA
+{
+ return a;
+}
+- (void) setA: (int)value
+{
+ a = value;
+}
+@end
+
+int main (void)
+{
+ MyRootClass *object = [[MyRootClass alloc] init];
+
+ object.a = 14;
+
+ if (object.a != 14)
+ abort ();
+
+ object.a = 23;
+
+ if (object.a != 23)
+ abort ();
+
+ object.a = 78;
+
+ if (object.a != 78)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/property/at-property-8.m b/gcc/testsuite/objc.dg/property/at-property-8.m
new file mode 100644
index 000000000..497dedca7
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-8.m
@@ -0,0 +1,58 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* Test the property syntax with non-synthesized setter/getter
+ and with a non-standard name for the setter. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+ int a;
+}
+@property (setter = writeA:, nonatomic) int a;
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+
+- (int) a
+{
+ return a;
+}
+- (void) writeA: (int)value
+{
+ a = value;
+}
+@end
+
+int main (void)
+{
+ MyRootClass *object = [[MyRootClass alloc] init];
+
+ object.a = 14;
+
+ if (object.a != 14)
+ abort ();
+
+ object.a = 23;
+
+ if (object.a != 23)
+ abort ();
+
+ object.a = 78;
+
+ if (object.a != 78)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/property/at-property-9.m b/gcc/testsuite/objc.dg/property/at-property-9.m
new file mode 100644
index 000000000..0f144fad2
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-9.m
@@ -0,0 +1,53 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* Test the property syntax with synthesized setter/getter
+ and with a non-standard name for the getter and setter. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+ int a;
+}
+/* Use the simplest synthesized accessor (assign, nonatomic) as we are
+ not testing the synthesized accessors in this test, just the
+ property syntax. */
+@property (getter = giveMeA, setter = writeA:, nonatomic) int a;
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+@synthesize a;
+@end
+
+int main (void)
+{
+ MyRootClass *object = [[MyRootClass alloc] init];
+
+ object.a = 14;
+
+ if (object.a != 14)
+ abort ();
+
+ object.a = 23;
+
+ if (object.a != 23)
+ abort ();
+
+ object.a = 78;
+
+ if (object.a != 78)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/property/at-property-deprecated-1.m b/gcc/testsuite/objc.dg/property/at-property-deprecated-1.m
new file mode 100644
index 000000000..e52047771
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-deprecated-1.m
@@ -0,0 +1,37 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */
+/* { dg-do compile } */
+
+/* Test that properties can be deprecated. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+ int a;
+}
+@property int a __attribute__((deprecated));
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+@synthesize a;
+@end
+
+int main (void)
+{
+ MyRootClass *object = [[MyRootClass alloc] init];
+
+ object.a = 40; /* { dg-warning "is deprecated" } */
+ if (object.a != 40) /* { dg-warning "is deprecated" } */
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/property/at-property-deprecated-2.m b/gcc/testsuite/objc.dg/property/at-property-deprecated-2.m
new file mode 100644
index 000000000..d2901a55b
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-deprecated-2.m
@@ -0,0 +1,25 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */
+/* { dg-do compile } */
+
+/* Test that deprecation warnings are produced when a setter/getter of
+ a @property is used directly. */
+
+#include <objc/objc.h>
+
+@interface MyClass
+{
+ Class isa;
+ int variable;
+}
+@property (assign, nonatomic) int property __attribute__ ((deprecated));
+@end
+
+void foo (void)
+{
+ MyClass *object = nil;
+
+ if ([object property] > 0) /* { dg-warning "is deprecated" } */
+ {
+ [object setProperty: 43]; /* { dg-warning "is deprecated" } */
+ }
+}
diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-1.m b/gcc/testsuite/objc.dg/property/dotsyntax-1.m
new file mode 100644
index 000000000..8922f5f03
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dotsyntax-1.m
@@ -0,0 +1,63 @@
+/* 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 the 'dot syntax' without a declarated property. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+ int a;
+ id b;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+- (int) count;
+- (void) setCount: (int)value;
+- (id) next;
+- (void) setNext: (id)value;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+- (int) count
+{
+ return a;
+}
+- (void) setCount: (int)value
+{
+ a = value;
+}
+- (id) next
+{
+ return b;
+}
+- (void) setNext: (id)value
+{
+ b = value;
+}
+@end
+
+int main (void)
+{
+ MyRootClass *object = [[MyRootClass alloc] init];
+
+ object.count = 40;
+ if (object.count != 40)
+ abort ();
+
+ object.next = object;
+ if (object.next != object)
+ abort ();
+
+ return 0;
+}
+
+
diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-10.m b/gcc/testsuite/objc.dg/property/dotsyntax-10.m
new file mode 100644
index 000000000..433595f3d
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dotsyntax-10.m
@@ -0,0 +1,86 @@
+/* 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 dot-syntax with 'super'. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+static int c;
+
+@interface MyRootClass
+{
+ Class isa;
+ int a;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+- (int) count;
+- (void) setCount: (int)count;
++ (int) classCount;
++ (void) setClassCount: (int)count;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+- (int) count
+{
+ return a;
+}
+- (void) setCount: (int)count
+{
+ a = count;
+}
++ (int) classCount
+{
+ return c;
+}
++ (void) setClassCount: (int)count
+{
+ c = count;
+}
+@end
+
+@interface MySubClass : MyRootClass
++ (int) testMe;
+- (int) testMe;
+@end
+
+@implementation MySubClass
+- (int) testMe
+{
+ super.count = 400;
+ if (super.count != 400)
+ abort ();
+
+ return super.count;
+}
++ (int) testMe
+{
+ super.classCount = 4000;
+ if (super.classCount != 4000)
+ abort ();
+
+ return super.classCount;
+}
+@end
+
+int main (void)
+{
+ MySubClass *object = [[MySubClass alloc] init];
+
+ if ([object testMe] != 400)
+ abort ();
+
+ if ([MySubClass testMe] != 4000)
+ abort ();
+
+ return 0;
+}
+
+
diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-11.m b/gcc/testsuite/objc.dg/property/dotsyntax-11.m
new file mode 100644
index 000000000..6c9d924ca
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dotsyntax-11.m
@@ -0,0 +1,61 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+/* Test the error reporting for the dot-syntax in the scenario where
+ we have a setter, but not a getter, yet a getter is requested. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+static int c;
+
+@interface MyRootClass
+{
+ Class isa;
+ int a;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+- (void) setCount: (int)count;
++ (void) setClassCount: (int)count;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+- (void) setCount: (int)count
+{
+ a = count;
+}
++ (void) setClassCount: (int)count
+{
+ c = count;
+}
+@end
+
+@interface MySubClass : MyRootClass
++ (int) testMe;
+- (int) testMe;
+@end
+
+@implementation MySubClass
+- (int) testMe
+{
+ super.count = 400;
+ if (super.count != 400) /* { dg-error "no .count. getter found" } */
+ abort ();
+
+ return super.count; /* { dg-error "no .count. getter found" } */
+}
++ (int) testMe
+{
+ super.classCount = 4000;
+ if (super.classCount != 4000) /* { dg-error "no .classCount. getter found" } */
+ abort ();
+
+ return super.classCount; /* { dg-error "no .classCount. getter found" } */
+}
+@end
diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-12.m b/gcc/testsuite/objc.dg/property/dotsyntax-12.m
new file mode 100644
index 000000000..20882f909
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dotsyntax-12.m
@@ -0,0 +1,105 @@
+/* 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 looking up a setter or getter which are in a protocol attached
+ to a category of a superclass. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+static int c;
+
+@interface MyRootClass
+{
+ Class isa;
+ int a;
+}
++ (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
+- (int) count;
+- (void) setCount: (int)count;
+@end
+
+@protocol classCount
++ (int) classCount;
++ (void) setClassCount: (int)count;
+@end
+
+@interface MyRootClass (Category) <count, classCount>
+@end
+
+@implementation MyRootClass (Category)
+- (int) count
+{
+ return a;
+}
+- (void) setCount: (int)count
+{
+ a = count;
+}
++ (int) classCount
+{
+ return c;
+}
++ (void) setClassCount: (int)count
+{
+ c = count;
+}
+@end
+
+@interface MySubClass : MyRootClass
++ (int) testMe;
+- (int) testMe;
+@end
+
+@implementation MySubClass
+- (int) testMe
+{
+ self.count = 400;
+ if (self.count != 400)
+ abort ();
+
+ return self.count;
+}
++ (int) testMe
+{
+ self.classCount = 4000;
+ if (self.classCount != 4000)
+ abort ();
+
+ return self.classCount;
+}
+@end
+
+int main (void)
+{
+ MySubClass *object = [[MySubClass alloc] init];
+
+ object.count = 44;
+ if (object.count != 44)
+ abort ();
+
+ MySubClass.classCount = 40;
+ if (MySubClass.classCount != 40)
+ abort ();
+
+ if ([object testMe] != 400)
+ abort ();
+
+ if ([MySubClass testMe] != 4000)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-13.m b/gcc/testsuite/objc.dg/property/dotsyntax-13.m
new file mode 100644
index 000000000..c5a4b3301
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dotsyntax-13.m
@@ -0,0 +1,53 @@
+/* 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 dot-syntax with a local variable. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+ int a;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+- (int) count;
+- (void) setCount: (int)count;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+- (int) count
+{
+ return a;
+}
+- (void) setCount: (int)count
+{
+ a = count;
+}
+@end
+
+int main (void)
+{
+ MyRootClass *object = [[MyRootClass alloc] init];
+ int i;
+
+ for (i = 0; i < 10; i++)
+ {
+ object.count = i;
+
+ if (object.count != i)
+ abort ();
+ }
+
+ return 0;
+}
+
+
diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-14.m b/gcc/testsuite/objc.dg/property/dotsyntax-14.m
new file mode 100644
index 000000000..0606ec4a2
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dotsyntax-14.m
@@ -0,0 +1,77 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+/* Test dot-syntax with accessors to be looked up in protocol @properties. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@protocol ProtocolA
+@property int countA;
+@end
+
+@protocol ProtocolB
+@property int countB;
+@end
+
+@protocol ProtocolC
+@property int countC;
+@end
+
+@interface MyRootClass
+{
+ Class isa;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+@end
+
+@interface MySubClass <ProtocolA, ProtocolB, ProtocolC>
+@end
+
+int function (MySubClass *object, int x)
+{
+ object.countA = x;
+ object.countB = x;
+ object.countC = object.countB;
+
+ return object.countC;
+}
+
+int function2 (MyRootClass <ProtocolA, ProtocolB, ProtocolC> *object, int x)
+{
+ object.countA = x;
+ object.countB = x;
+ object.countC = object.countB;
+
+ return object.countC;
+}
+
+int function3 (MyRootClass <ProtocolA, ProtocolB> *object, int x)
+{
+ object.countA = x;
+ object.countB = x;
+ object.countC = object.countB; /* { dg-error "request for member .countC. in something not a structure or union" } */
+
+ return object.countC; /* { dg-error "request for member .countC. in something not a structure or union" } */
+}
+
+int function4 (id <ProtocolA, ProtocolB, ProtocolC> object, int x)
+{
+ object.countA = x;
+ object.countB = x;
+ object.countC = object.countB;
+
+ return object.countC;
+}
+
+int function5 (id <ProtocolA, ProtocolB> object, int x)
+{
+ object.countA = x;
+ object.countB = x;
+ object.countC = object.countB; /* { dg-error "request for member .countC. in something not a structure or union" } */
+
+ return object.countC; /* { dg-error "request for member .countC. in something not a structure or union" } */
+}
diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-15.m b/gcc/testsuite/objc.dg/property/dotsyntax-15.m
new file mode 100644
index 000000000..767f6a2b8
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dotsyntax-15.m
@@ -0,0 +1,80 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+/* Test dot-syntax with accessors to be looked up in protocols. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@protocol ProtocolA
+- (int) countA;
+- (void) setCountA: (int)aNumber;
+@end
+
+@protocol ProtocolB
+- (int) countB;
+- (void) setCountB: (int)aNumber;
+@end
+
+@protocol ProtocolC
+- (int) countC;
+- (void) setCountC: (int)aNumber;
+@end
+
+@interface MyRootClass
+{
+ Class isa;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+@end
+
+@interface MySubClass <ProtocolA, ProtocolB, ProtocolC>
+@end
+
+int function (MySubClass *object, int x)
+{
+ object.countA = x;
+ object.countB = x;
+ object.countC = object.countB;
+
+ return object.countC;
+}
+
+int function2 (MyRootClass <ProtocolA, ProtocolB, ProtocolC> *object, int x)
+{
+ object.countA = x;
+ object.countB = x;
+ object.countC = object.countB;
+
+ return object.countC;
+}
+
+int function3 (MyRootClass <ProtocolA, ProtocolB> *object, int x)
+{
+ object.countA = x;
+ object.countB = x;
+ object.countC = object.countB; /* { dg-error "request for member .countC. in something not a structure or union" } */
+
+ return object.countC; /* { dg-error "request for member .countC. in something not a structure or union" } */
+}
+
+int function4 (id <ProtocolA, ProtocolB, ProtocolC> object, int x)
+{
+ object.countA = x;
+ object.countB = x;
+ object.countC = object.countB;
+
+ return object.countC;
+}
+
+int function5 (id <ProtocolA, ProtocolB> object, int x)
+{
+ object.countA = x;
+ object.countB = x;
+ object.countC = object.countB; /* { dg-error "request for member .countC. in something not a structure or union" } */
+
+ return object.countC; /* { dg-error "request for member .countC. in something not a structure or union" } */
+}
diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-16.m b/gcc/testsuite/objc.dg/property/dotsyntax-16.m
new file mode 100644
index 000000000..893db69d9
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dotsyntax-16.m
@@ -0,0 +1,91 @@
+/* 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 dot-syntax with pre/post increment and decrement. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+ int a;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+- (int) count;
+- (void) setCount: (int)count;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+- (int) count
+{
+ return a;
+}
+- (void) setCount: (int)count
+{
+ a = count;
+}
+@end
+
+int main (void)
+{
+ MyRootClass *object = [[MyRootClass alloc] init];
+
+ object.count = 10;
+ if (object.count != 10)
+ abort ();
+
+ /* First, test that they increment/decrement as expected. */
+ object.count++;
+ if (object.count != 11)
+ abort ();
+
+ ++object.count;
+ if (object.count != 12)
+ abort ();
+
+ object.count--;
+ if (object.count != 11)
+ abort ();
+
+ --object.count;
+ if (object.count != 10)
+ abort ();
+
+ /* Now, test that they are pre/post increment/decrement, as
+ expected. */
+ if (object.count++ != 10)
+ abort ();
+
+ if (object.count != 11)
+ abort ();
+
+ if (++object.count != 12)
+ abort ();
+
+ if (object.count != 12)
+ abort ();
+
+ if (object.count-- != 12)
+ abort ();
+
+ if (object.count != 11)
+ abort ();
+
+ if (--object.count != 10)
+ abort ();
+
+ if (object.count != 10)
+ abort ();
+
+ return 0;
+}
+
+
diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-17.m b/gcc/testsuite/objc.dg/property/dotsyntax-17.m
new file mode 100644
index 000000000..c28e11f48
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dotsyntax-17.m
@@ -0,0 +1,67 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+/* Test errors with the dot-syntax with pre/post increment and decrement. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+ int count;
+ int a;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+@property (assign, readonly) int count;
+- (void) setWriteOnlyCount: (int)value;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+@synthesize count;
+- (void) setWriteOnlyCount: (int)value
+{
+ a = value;
+}
+@end
+
+int main (void)
+{
+ MyRootClass *object = [[MyRootClass alloc] init];
+
+ object.count = 10; /* { dg-error "readonly property can not be set" } */
+ if (object.count != 10) /* Ok */
+ abort ();
+
+ /* Test errors when trying to change a readonly property using
+ pre/post increment/decrement operators. */
+ object.count++; /* { dg-error "readonly property can not be set" } */
+
+ ++object.count; /* { dg-error "readonly property can not be set" } */
+
+ object.count--; /* { dg-error "readonly property can not be set" } */
+
+ --object.count; /* { dg-error "readonly property can not be set" } */
+
+ /* Test errors when trying to change something using Objective-C 2.0
+ dot-syntax but there is a setter but no getter. */
+ object.writeOnlyCount = 10; /* Ok */
+
+ object.writeOnlyCount++; /* { dg-error "no .writeOnlyCount. getter found" } */
+
+ ++object.writeOnlyCount; /* { dg-error "no .writeOnlyCount. getter found" } */
+
+ object.writeOnlyCount--; /* { dg-error "no .writeOnlyCount. getter found" } */
+
+ --object.writeOnlyCount; /* { dg-error "no .writeOnlyCount. getter found" } */
+
+ return 0;
+}
+
+
diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-18.m b/gcc/testsuite/objc.dg/property/dotsyntax-18.m
new file mode 100644
index 000000000..5697d311d
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dotsyntax-18.m
@@ -0,0 +1,90 @@
+/* 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 dot-syntax with tricky assignments. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+ int a;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+- (int) count;
+- (void) setCount: (int)count;
+- (int) somethingToExecuteOnlyOnce;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+- (int) count
+{
+ return a;
+}
+- (void) setCount: (int)count
+{
+ a = count;
+}
+- (int) somethingToExecuteOnlyOnce
+{
+ a++;
+ return 10;
+}
+@end
+
+int main (void)
+{
+ MyRootClass *object1 = [[MyRootClass alloc] init];
+ MyRootClass *object2 = [[MyRootClass alloc] init];
+ MyRootClass *object3 = [[MyRootClass alloc] init];
+ int i;
+
+ object1.count = 10;
+ if (object1.count != 10)
+ abort ();
+
+ object2.count = 10;
+ if (object2.count != 10)
+ abort ();
+
+ /* Test multiple assignments to a constant. */
+ object1.count = object2.count = 20;
+
+ if (object1.count != 20 || object2.count != 20)
+ abort ();
+
+ i = object1.count = 30;
+
+ if (i != 30 || object1.count != 30)
+ abort ();
+
+ i = object2.count = 30;
+
+ if (i != 30 || object2.count != 30)
+ abort ();
+
+ /* Test a simple assignment to something with a side-effect; the
+ 'rhs' should be evaluated only once. */
+ object1.count = ([object2 somethingToExecuteOnlyOnce] > 0 ? 30 : 45);
+
+ if (object1.count != 30 || object2.count != 31)
+ abort ();
+
+ /* Test multiple assignments with side effects. */
+ object3.count = object1.count = ([object2 somethingToExecuteOnlyOnce] > 0 ? 30 : 45);
+
+ if (object1.count != 30 || object2.count != 32 || object3.count != 30)
+ abort ();
+
+ return 0;
+}
+
+
diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-19.m b/gcc/testsuite/objc.dg/property/dotsyntax-19.m
new file mode 100644
index 000000000..df4867b0a
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dotsyntax-19.m
@@ -0,0 +1,113 @@
+/* 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 dot-syntax with more tricky assignments. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+ id a;
+ id b;
+ int p1;
+ float p2;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+
+@property (assign) id object1;
+@property (assign) id object2;
+- (id) test;
+- (id) myself;
+- (id) nilObject;
+
+@property int p1;
+@property float p2;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+@synthesize object1 = a;
+@synthesize object2 = b;
+- (id) test
+{
+ /* Test multiple assignments with 'self'. */
+ self.object1 = self.object2 = self;
+
+ if (self.object1 != self || self.object2 != self)
+ abort ();
+
+ /* Test multiple assignments with a conditional and method calls. */
+ self.object1 = self.object2 = (self ? [self myself] : [self nilObject]);
+
+ if (self.object1 != self || self.object2 != self)
+ abort ();
+
+ self.object1 = self.object2 = (self ? [self nilObject] : [self myself]);
+
+ if (self.object1 != nil || self.object2 != nil)
+ abort ();
+
+ return self.object1;
+}
+- (id) myself
+{
+ return self;
+}
+- (id) nilObject
+{
+ return nil;
+}
+
+@synthesize p1;
+@synthesize p2;
+@end
+
+int main (void)
+{
+ MyRootClass *object = [[MyRootClass alloc] init];
+ MyRootClass *object1 = [[MyRootClass alloc] init];
+
+ [object test];
+
+ /* Now, test multiple assignments with different types. Use
+ int/float as they seem to happily crash the compiler in gimplify
+ if proper conversions are not being generated by the
+ frontend. ;-) */
+ object.p1 = object.p2 = 12;
+
+ if (object.p1 != 12 || object.p2 != 12)
+ abort ();
+
+ object.p1 = object.p2 = 2.7;
+
+ if (object.p1 != 2)
+ abort ();
+
+ /* Just try a different loop, mixing in a few different standard C
+ constructs to cover a few other cases. */
+ object.p1 = 10;
+ object1.p1 = 0;
+ while (object.p1)
+ {
+ object1.p1 += ((object.p2 = 4.56) ? 0 : object.p1);
+ object.p1--;
+ }
+
+ if (object.p1 != 0 || object1.p1 != 0)
+ abort ();
+
+ if ((object.p1 = 0))
+ abort ();
+
+ return 0;
+}
+
+
diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-2.m b/gcc/testsuite/objc.dg/property/dotsyntax-2.m
new file mode 100644
index 000000000..03e49aebc
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dotsyntax-2.m
@@ -0,0 +1,72 @@
+/* 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 the 'dot syntax' without a declarated property. This tests the case where
+ only the setter (or only the getter) exists. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+ int a;
+ id b;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+- (int) a;
+- (void) setCount: (int)value;
+- (id) b;
+- (void) setNext: (id)value;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+- (int) a
+{
+ return a;
+}
+- (void) setCount: (int)value
+{
+ a = value;
+}
+- (id) b
+{
+ return b;
+}
+- (void) setNext: (id)value
+{
+ b = value;
+}
+@end
+
+int main (void)
+{
+ MyRootClass *object = [[MyRootClass alloc] init];
+
+ /* This should work because -setCount: exists (even if -count does
+ not). */
+ object.count = 40;
+
+ /* This should work because -a exists (even if -setA: does not). */
+ if (object.a != 40)
+ abort ();
+
+ /* This should work because -setNext: exists (even if -next does
+ not). */
+ object.next = object;
+
+ /* This should work because -b exists (even if -setB: does not). */
+ if (object.b != object)
+ abort ();
+
+ return 0;
+}
+
+
diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-20.m b/gcc/testsuite/objc.dg/property/dotsyntax-20.m
new file mode 100644
index 000000000..f1dd48e61
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dotsyntax-20.m
@@ -0,0 +1,67 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+/* { dg-options "-Wall" } */
+
+/* Test warnings with the dot-syntax. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+ id a;
+ id b;
+ int p1;
+ int p2;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+
+@property int p1;
+@property int p2;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+@synthesize p1;
+@synthesize p2;
+@end
+
+int main (void)
+{
+ MyRootClass *object = [[MyRootClass alloc] init];
+
+ /* First, test that the artificial code generated by dot-syntax does
+ not generate unexpected warnings. */
+
+ /* All of the following should generate no warnings. */
+ object.p1 = 0;
+ object.p2 = 0;
+ object.p1 = object.p2 = 0;
+ if (object.p1 > 0)
+ object.p2 = 0;
+
+ object.p1++;
+ ++object.p1;
+ object.p1--;
+ --object.p1;
+
+ while (object.p1)
+ object.p1--;
+
+ /* Now test some warnings. */
+ object.p1; /* { dg-warning "value computed is not used" } */
+
+ /* TODO: It would be good to get the following to warn. */
+ if (object.p1 = 0) /* dg-warning "suggest parentheses around assignment used as truth value" */
+ abort ();
+
+ return 0;
+}
+
+
diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-21.m b/gcc/testsuite/objc.dg/property/dotsyntax-21.m
new file mode 100644
index 000000000..4b8945ed6
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dotsyntax-21.m
@@ -0,0 +1,113 @@
+/* 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 dot-syntax with super in a category. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+ int a;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+- (int) count;
+- (void) setCount: (int)count;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+- (int) count
+{
+ return a;
+}
+- (void) setCount: (int)count
+{
+ a = count;
+}
+@end
+
+/* First, test 'super' in the main implementation of a subclass. */
+@interface MySubClass : MyRootClass
+- (int) superCount;
+- (void) setSuperCount: (int)count;
+@end
+
+@implementation MySubClass
+- (int) superCount
+{
+ return super.count;
+}
+- (void) setSuperCount: (int)count
+{
+ super.count = count;
+}
+@end
+
+/* Now, test 'super' in a category of a subclass. */
+@interface MySubClass (Category)
+- (int) superCount2;
+- (void) setSuperCount2: (int)count;
+- (int) test: (int)x;
+@end
+
+@implementation MySubClass (Category)
+- (int) superCount2
+{
+ return super.count;
+}
+- (void) setSuperCount2: (int)count
+{
+ super.count = count;
+}
+- (int) test: (int)x
+{
+ /* For positive x, the following will leave super.count
+ unchanged. */
+ super.count++;
+ --super.count;
+
+ super.count = (x < 0 ? x : super.count);
+
+ if ((x = super.count))
+ super.count += 1;
+
+ if ((x = super.count))
+ super.count -= 1;
+
+ /* Finally, also put a bit of self.count in the mix. */
+ self.count++;
+ super.count--;
+
+ return super.count;
+}
+@end
+
+int main (void)
+{
+ MySubClass *object = [[MySubClass alloc] init];
+
+ object.count = 10;
+ if (object.count != 10)
+ abort ();
+
+ object.superCount = 11;
+ if (object.superCount != 11)
+ abort ();
+
+ object.superCount2 = 12;
+ if (object.superCount2 != 12)
+ abort ();
+
+ if ([object test: 45] != 12)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-22.m b/gcc/testsuite/objc.dg/property/dotsyntax-22.m
new file mode 100644
index 000000000..cc5834822
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dotsyntax-22.m
@@ -0,0 +1,19 @@
+/* PR objc/47784. This testcase used to crash the compiler. */
+
+typedef struct {
+ float x;
+} SomeType;
+
+@interface MyClass
+
+@property(assign,readwrite) SomeType position;
+
+@end
+
+void example (MyClass *x)
+{
+ const SomeType SomeTypeZero = {0.0f};
+
+ x.position= SomeTypeZero;
+}
+
diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-3.m b/gcc/testsuite/objc.dg/property/dotsyntax-3.m
new file mode 100644
index 000000000..d34780628
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dotsyntax-3.m
@@ -0,0 +1,64 @@
+/* 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 the 'dot syntax' without a declarated property. This tests the case where
+ the object is a Class. */
+
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+static int a;
+static id b;
+
+@interface MyRootClass
+{
+ Class isa;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
++ (int) count;
++ (void) setCount: (int)value;
++ (id) next;
++ (void) setNext: (id)value;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
++ (int) count
+{
+ return a;
+}
++ (void) setCount: (int)value
+{
+ a = value;
+}
++ (id) next
+{
+ return b;
+}
++ (void) setNext: (id)value
+{
+ b = value;
+}
+@end
+
+int main (void)
+{
+ MyRootClass *object = [[MyRootClass alloc] init];
+
+ MyRootClass.count = 40;
+ if (MyRootClass.count != 40)
+ abort ();
+
+ MyRootClass.next = object;
+ if (MyRootClass.next != object)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-4.m b/gcc/testsuite/objc.dg/property/dotsyntax-4.m
new file mode 100644
index 000000000..2db067f1f
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dotsyntax-4.m
@@ -0,0 +1,42 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+/* Test the 'dot syntax' without a declarated property. This tests
+ syntax errors in the case where the object is a Class. */
+
+
+#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
+
+int main (void)
+{
+ MyRootClass.invalid = 40; /* { dg-error "could not find setter.getter" } */
+ if (MyRootClass.invalid != 40) /* { dg-error "could not find setter.getter" } */
+ abort ();
+
+ MyRootClass.; /* { dg-error "expected identifier" } */
+ if (MyRootClass.) /* { dg-error "expected identifier" } */
+ abort ();
+
+ MyRootClass.int; /* { dg-error "expected identifier" } */
+ if (MyRootClass.int) /* { dg-error "expected identifier" } */
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-5.m b/gcc/testsuite/objc.dg/property/dotsyntax-5.m
new file mode 100644
index 000000000..06e113032
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dotsyntax-5.m
@@ -0,0 +1,78 @@
+/* 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 the 'dot syntax' with self, both in instance and class methods. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+static int c;
+
+@interface MyRootClass
+{
+ Class isa;
+ int a;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+- (int) count;
+- (void) setCount: (int)count;
++ (int) classCount;
++ (void) setClassCount: (int)count;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+- (int) count
+{
+ return a;
+}
+- (void) setCount: (int)count
+{
+ a = count;
+}
++ (int) classCount
+{
+ return c;
+}
++ (void) setClassCount: (int)count
+{
+ c = count;
+}
+- (int) testMe
+{
+ self.count = 400;
+ if (self.count != 400)
+ abort ();
+
+ return self.count;
+}
++ (int) testMe
+{
+ self.classCount = 4000;
+ if (self.classCount != 4000)
+ abort ();
+
+ return self.classCount;
+}
+@end
+
+int main (void)
+{
+ MyRootClass *object = [[MyRootClass alloc] init];
+
+ if ([object testMe] != 400)
+ abort ();
+
+ if ([MyRootClass testMe] != 4000)
+ abort ();
+
+ return 0;
+}
+
+
diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-6.m b/gcc/testsuite/objc.dg/property/dotsyntax-6.m
new file mode 100644
index 000000000..7ecd34e3d
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dotsyntax-6.m
@@ -0,0 +1,106 @@
+/* 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 nested 'dot syntax' (xxx.yyy.zzz or [xxx yyy].zzz). */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@class MyRootClass;
+
+static MyRootClass *shared_root = nil;
+
+@interface MyRootClass
+{
+ Class isa;
+ int a;
+ int b;
+ MyRootClass *next;
+}
+@property int b;
+@property (assign) MyRootClass *next;
++ (id) initialize;
++ (MyRootClass *)sharedInstance;
++ (id) alloc;
+- (id) init;
+- (MyRootClass *)same;
+- (int) count;
+- (void) setCount: (int)count;
+@end
+
+@implementation MyRootClass
+@synthesize b;
+@synthesize next;
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
++ (MyRootClass *)sharedInstance
+{
+ if (!shared_root)
+ shared_root = [[self alloc] init];
+
+ return shared_root;
+}
+- (MyRootClass *)same
+{
+ return self;
+}
+- (int) count
+{
+ return a;
+}
+- (void) setCount: (int)count
+{
+ a = count;
+}
+@end
+
+int main (void)
+{
+ MyRootClass *object = [[MyRootClass alloc] init];
+
+ /* Test ClassName.accessor.accessor. */
+ MyRootClass.sharedInstance.count = 500;
+ if (MyRootClass.sharedInstance.count != 500)
+ abort ();
+
+ /* Test object.accessor.accessor. */
+ object.same.count = 1000;
+ if (object.same.count != 1000)
+ abort ();
+
+ /* Test object.accessor.property. */
+ object.same.next = object;
+ if (object.same.next != object)
+ abort ();
+
+ /* Test lots of nesting. */
+ if (object.next.next.same.same.next.next.same != object)
+ abort ();
+
+ /* Test more nesting. */
+ MyRootClass.sharedInstance.next = object;
+ MyRootClass.sharedInstance.next.next.next.next.next.count = 2000;
+ if (MyRootClass.sharedInstance.next.next.next.next.next.count != 2000)
+ abort ();
+
+ /* Test more nesting. */
+ MyRootClass.sharedInstance.same.same.same.same.same.count = 3000;
+ if (MyRootClass.sharedInstance.same.same.same.same.same.count != 3000)
+ abort ();
+
+ /* Test [object method].property. */
+ [MyRootClass sharedInstance].count = 5000;
+ if ([MyRootClass sharedInstance].count != 5000)
+ abort ();
+
+ /* Just a final check. */
+ if (shared_root.count != 5000)
+ abort ();
+
+ return 0;
+}
+
+
diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-7.m b/gcc/testsuite/objc.dg/property/dotsyntax-7.m
new file mode 100644
index 000000000..15c1725d8
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dotsyntax-7.m
@@ -0,0 +1,48 @@
+/* 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 dot syntax of a casted expression. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+ int a;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+- (int) count;
+- (void) setCount: (int)count;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+- (int) count
+{
+ return a;
+}
+- (void) setCount: (int)count
+{
+ a = count;
+}
+@end
+
+int main (void)
+{
+ id object = [[MyRootClass alloc] init];
+
+ ((MyRootClass *)object).count = 200;
+ if (((MyRootClass *)object).count != 200)
+ abort ();
+
+ return 0;
+}
+
+
diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-8.m b/gcc/testsuite/objc.dg/property/dotsyntax-8.m
new file mode 100644
index 000000000..35dfda40c
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dotsyntax-8.m
@@ -0,0 +1,62 @@
+/* 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 the 'dot syntax' with typedefs. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+static int c;
+
+@interface MyRootClass
+{
+ Class isa;
+ int a;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+- (int) count;
+- (void) setCount: (int)count;
++ (int) classCount;
++ (void) setClassCount: (int)count;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+- (int) count
+{
+ return a;
+}
+- (void) setCount: (int)count
+{
+ a = count;
+}
++ (int) classCount
+{
+ return c;
+}
++ (void) setClassCount: (int)count
+{
+ c = count;
+}
+@end
+
+typedef MyRootClass MyType;
+
+int main (void)
+{
+ MyType *object = [[MyRootClass alloc] init];
+
+ object.count = 1974;
+ if (object.count != 1974)
+ abort ();
+
+ return 0;
+}
+
+
diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-9.m b/gcc/testsuite/objc.dg/property/dotsyntax-9.m
new file mode 100644
index 000000000..61a5c0eb8
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dotsyntax-9.m
@@ -0,0 +1,77 @@
+/* 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 that setter/getters for dot-syntax are properly found even if
+ not declared in the @interface, but available in the local
+ @implementation before the current line (ie, [object name] can be
+ compiled in that case, so object.name should be compiled too). */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+static int c;
+
+@interface MyRootClass
+{
+ Class isa;
+ int a;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+- (int) count
+{
+ return a;
+}
+- (void) setCount: (int)count
+{
+ a = count;
+}
++ (int) classCount
+{
+ return c;
+}
++ (void) setClassCount: (int)count
+{
+ c = count;
+}
+- (int) testMe
+{
+ self.count = 400;
+ if (self.count != 400)
+ abort ();
+
+ return self.count;
+}
++ (int) testMe
+{
+ self.classCount = 4000;
+ if (self.classCount != 4000)
+ abort ();
+
+ return self.classCount;
+}
+@end
+
+int main (void)
+{
+ MyRootClass *object = [[MyRootClass alloc] init];
+
+ if ([object testMe] != 400)
+ abort ();
+
+ if ([MyRootClass testMe] != 4000)
+ abort ();
+
+ return 0;
+}
+
+
diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-deprecated-1.m b/gcc/testsuite/objc.dg/property/dotsyntax-deprecated-1.m
new file mode 100644
index 000000000..ad627a8c1
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dotsyntax-deprecated-1.m
@@ -0,0 +1,41 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */
+/* { dg-do compile } */
+
+/* Test the 'dot syntax' with deprecated methods. */
+
+#include <objc/objc.h>
+
+@interface MyClass
+{
+ Class isa;
+}
++ (int) classCount __attribute__ ((deprecated));
++ (void) setClassCount: (int)value __attribute__ ((deprecated));
+
+- (int) count __attribute__ ((deprecated));
+- (void) setCount: (int)value __attribute__ ((deprecated));
+
+- (int) classCount2;
+- (void) setClassCount2: (int)value;
+
+- (int) count2;
+- (void) setCount2: (int)value;
+@end
+
+void foo (void)
+{
+ MyClass *object = nil;
+
+
+ if (object.count > 0) /* { dg-warning "is deprecated" } */
+ object.count = 20; /* { dg-warning "is deprecated" } */
+
+ if (MyClass.classCount < -7) /* { dg-warning "is deprecated" } */
+ MyClass.classCount = 11; /* { dg-warning "is deprecated" } */
+
+ if (object.classCount2 > 0)
+ object.classCount2 = 19;
+
+ if (object.count2 < -7)
+ object.count2 = 74;
+}
diff --git a/gcc/testsuite/objc.dg/property/dynamic-1.m b/gcc/testsuite/objc.dg/property/dynamic-1.m
new file mode 100644
index 000000000..8f9737139
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dynamic-1.m
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+@interface MyRootClass
+{
+ Class isa;
+}
+@end
+
+@implementation MyRootClass
+@end
+
+@dynamic isa; /* { dg-error ".@dynamic. not in @implementation context" } */
+
+@interface Test : MyRootClass
+{
+ int v1;
+ int v2;
+ int v3;
+ int v4;
+}
+@property int v1;
+@property int v2;
+@property int v3;
+@property int v4;
+@end
+
+@implementation Test
+@dynamic; /* { dg-error "expected identifier" } */
+@dynamic v1, ; /* { dg-error "expected identifier" } */
+@dynamic v1, v2, v3;
+@dynamic v4;
+@end
diff --git a/gcc/testsuite/objc.dg/property/dynamic-2.m b/gcc/testsuite/objc.dg/property/dynamic-2.m
new file mode 100644
index 000000000..203ba34a1
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dynamic-2.m
@@ -0,0 +1,45 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+@interface MyRootClass
+{
+ Class isa;
+}
+@end
+
+@implementation MyRootClass
+@end
+
+@dynamic isa; /* { dg-error ".@dynamic. not in @implementation context" } */
+
+@interface Test : MyRootClass
+{
+ int v1;
+}
+@end
+@implementation Test
+@end
+
+
+@interface Test (Category)
+@property int v1;
+@end
+@implementation Test (Category)
+@dynamic v1;
+@end
+
+
+@interface AnotherTest : MyRootClass
+{
+}
+@property int one;
+@end
+
+@implementation AnotherTest
+@dynamic one;
+@dynamic one; /* { dg-error "property .one. already specified in .@dynamic." } */
+ /* { dg-message "originally specified here" "" { target *-*-* } 41 } */
+@dynamic three; /* { dg-error "no declaration of property .three. found in the interface" } */
+@end
diff --git a/gcc/testsuite/objc.dg/property/dynamic-3.m b/gcc/testsuite/objc.dg/property/dynamic-3.m
new file mode 100644
index 000000000..e8a6693b0
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dynamic-3.m
@@ -0,0 +1,49 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+@interface MyRootClass
+{
+ Class isa;
+}
+@end
+
+@implementation MyRootClass
+@end
+
+/* Test @property/@dynamic in a category. First, a case where
+ @dynamic should turn off all warnings. */
+
+@interface MyRootClass (Category)
+@property int a;
+- (int) test;
+@end
+@implementation MyRootClass (Category)
+@dynamic a;
+- (int) test
+{
+ return self.a; /* This should compile into [self a] with no warnings. */
+}
+@end
+
+
+
+/* Test @property/@dynamic in a category. Second, a case with a
+ missing setter and no @dynamic. A warning should be generated. */
+
+@interface MyRootClass (Category2)
+@property int b;
+- (int) test;
+@end
+@implementation MyRootClass (Category2)
+- (int) b
+{
+ return 0;
+}
+- (int) test
+{
+ return self.b;
+}
+@end /* { dg-warning "incomplete implementation" } */
+/* { dg-warning "method definition for .-setB:. not found" "" { target *-*-* } 48 } */
diff --git a/gcc/testsuite/objc.dg/property/dynamic-4.m b/gcc/testsuite/objc.dg/property/dynamic-4.m
new file mode 100644
index 000000000..84998d6b4
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dynamic-4.m
@@ -0,0 +1,45 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+@interface MyRootClass
+{
+ Class isa;
+}
+@end
+
+@implementation MyRootClass
+@end
+
+/* Test @property/@dynamic with protocols. */
+
+@protocol MyProtocol
+@property int a;
+@end
+
+
+/* This class is declared to conform to the protocol, but because of
+ @dynamic, no warnings are issued even if the getter/setter for the
+ @property are missing. */
+@interface MyClass1 : MyRootClass <MyProtocol>
+@end
+
+@implementation MyClass1
+@dynamic a;
+@end
+
+
+/* This class is declared to conform to the protocol and warnings are
+ issued because the setter for the @property is missing. */
+@interface MyClass2 : MyRootClass <MyProtocol>
+@end
+
+@implementation MyClass2
+- (int) a
+{
+ return 0;
+}
+@end /* { dg-warning "incomplete implementation" } */
+/* { dg-warning "method definition for .-setA:. not found" "" { target *-*-* } 43 } */
+/* { dg-warning "class .MyClass2. does not fully implement the .MyProtocol. protocol" "" { target *-*-* } 43 } */
diff --git a/gcc/testsuite/objc.dg/property/dynamic-5.m b/gcc/testsuite/objc.dg/property/dynamic-5.m
new file mode 100644
index 000000000..77e81411a
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dynamic-5.m
@@ -0,0 +1,53 @@
+/* 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 @dynamic in the real scenario where a class declares a
+ @property, uses @dynamic to avoid implementing it, then subclasses
+ implement it. */
+
+#include <objc/objc.h>
+#include <objc/runtime.h>
+#include <stdlib.h>
+
+@interface MyRootClass
+{
+ Class isa;
+}
+@property int a;
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+@dynamic a;
+@end
+
+@interface Test : MyRootClass
+{
+ int v1;
+}
+@end
+
+@implementation Test
+@synthesize a = v1;
+@end
+
+int main (void)
+{
+ /* Note how 'object' is declared to be of class 'MyRootClass', but
+ actually is of the subclass which implements the property for
+ real. */
+ MyRootClass *object = [[Test alloc] init];
+
+ object.a = 40;
+
+ if (object.a != 40)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/property/dynamic-6.m b/gcc/testsuite/objc.dg/property/dynamic-6.m
new file mode 100644
index 000000000..23a7a8905
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dynamic-6.m
@@ -0,0 +1,26 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+/* Test case when an accessor from a @property matches a method
+ required by a protocol. If the @property is @dynamic, then no
+ warning should be generated. */
+
+#include <objc/objc.h>
+#include <objc/runtime.h>
+#include <stdlib.h>
+
+@protocol Count
+- (int) count;
+@end
+
+@interface MyRootClass <Count>
+{
+ Class isa;
+}
+@property int count;
+@end
+
+@implementation MyRootClass
+/* This @dynamic turns off any warnings for -count and -setCount:. */
+@dynamic count;
+@end
diff --git a/gcc/testsuite/objc.dg/property/fsf-property-basic.m b/gcc/testsuite/objc.dg/property/fsf-property-basic.m
new file mode 100644
index 000000000..ddc0589e0
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/fsf-property-basic.m
@@ -0,0 +1,62 @@
+/* Basic test, auto-generated getter/setter based on property name. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+extern int printf (char *fmt,...) ;
+extern void abort (void);
+
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface Bar
+{
+@public
+ Class isa;
+ int FooBar;
+}
++ (id) initialize;
++ (id) alloc ;
+- (id) init;
+- (int) whatIsFooBar;
+@property int FooBar;
+@end
+
+@implementation Bar
+
++initialize { return self;}
++ (id) alloc { return class_createInstance (self, 0); }
+
+- (id) init {return self;}
+
+- (int) whatIsFooBar { return self->FooBar; }
+@synthesize FooBar;
+@end
+
+int main(int argc, char *argv[]) {
+ int res;
+ Bar *f = [[Bar alloc] init];
+
+ /* First, establish that the property getter & setter have been synthesized
+ and operate correctly. */
+ [f setFooBar:1];
+
+ if ([f whatIsFooBar] != 1)
+ { printf ("setFooBar did not set FooBar\n"); abort ();}
+
+ res = [f FooBar];
+
+ if (res != 1 )
+ { printf ("[f FooBar] = %d\n", res); abort ();}
+
+ /* Now check the short-cut object.property syntax. */
+ /* Read... */
+ res = f.FooBar;
+ if (res != 1 )
+ { printf ("f.FooBar = %d\n", res); abort ();}
+
+ /* .... write. */
+ f.FooBar = 0;
+ /* printf ("seems OK\n", res); */
+ return f.FooBar;
+}
+
diff --git a/gcc/testsuite/objc.dg/property/fsf-property-method-access.m b/gcc/testsuite/objc.dg/property/fsf-property-method-access.m
new file mode 100644
index 000000000..01eea5bf7
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/fsf-property-method-access.m
@@ -0,0 +1,67 @@
+/* test access in methods, auto-generated getter/setter based on property name. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+extern int printf (char *fmt,...) ;
+extern void abort (void);
+
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface Bar
+{
+@public
+ Class isa;
+ int FooBar;
+}
++ (id) initialize;
++ (id) alloc ;
+- (id) init;
+
+- (int) lookAtProperty;
+- (void) setProperty: (int) v;
+
+@property int FooBar;
+@end
+
+@implementation Bar
+
++initialize { return self;}
++ (id) alloc { return class_createInstance(self, 0);}
+
+- (id) init {return self;}
+
+@synthesize FooBar;
+
+- (int) lookAtProperty { return FooBar; }
+- (void) setProperty: (int) v { FooBar = v; }
+
+@end
+
+int main(int argc, char *argv[]) {
+ int res;
+ Bar *f = [[Bar alloc] init];
+
+ /* First, establish that the property getter & setter have been synthesized
+ and operate correctly. */
+ [f setProperty:11];
+
+ if (f.FooBar != 11)
+ { printf ("setProperty did not set FooBar\n"); abort ();}
+
+ res = [f lookAtProperty];
+ if (res != 11 )
+ { printf ("[f lookAtProperty] = %d\n", res); abort ();}
+
+ /* Make sure we haven't messed up the shortcut form. */
+ /* read ... */
+ res = f.FooBar;
+ if (res != 11 )
+ { printf ("f.FooBar = %d\n", res); abort ();}
+
+ /* ... write. */
+ f.FooBar = 0;
+ /* printf ("seems OK\n", res); */
+ return f.FooBar;
+}
+
diff --git a/gcc/testsuite/objc.dg/property/fsf-property-named-ivar.m b/gcc/testsuite/objc.dg/property/fsf-property-named-ivar.m
new file mode 100644
index 000000000..545856850
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/fsf-property-named-ivar.m
@@ -0,0 +1,61 @@
+/* Basic test, auto-generated getter/setter based on named ivar */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+extern int printf (char *fmt,...) ;
+extern void abort (void);
+
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface Bar
+{
+@public
+ Class isa;
+ int var;
+}
++ (id) initialize;
++ (id) alloc ;
+- (id) init;
+
+@property int FooBar;
+@end
+
+@implementation Bar
+
++initialize { return self;}
++ (id) alloc { return class_createInstance (self, 0); }
+
+- (id) init {return self;}
+
+@synthesize FooBar = var;
+@end
+
+int main(int argc, char *argv[]) {
+ int res;
+ Bar *f = [[Bar alloc] init];
+
+ /* First, establish that the property getter & setter have been synthesized
+ and operate correctly. */
+ [f setFooBar:1234];
+
+ if (f->var != 1234)
+ { printf ("setFooBar did not set var correctly\n"); abort ();}
+
+ res = [f FooBar];
+
+ if (res != 1234 )
+ { printf ("[f FooBar] = %d\n", res); abort ();}
+
+ /* Now check the short-cut object.property syntax. */
+ /* Read .... */
+ res = f.FooBar;
+ if (res != 1234 )
+ { printf ("f.FooBar = %d\n", res); abort ();}
+
+ /* ... and write. */
+ f.FooBar = 0;
+ /* printf ("seems OK\n", res); */
+ return f.FooBar;
+}
+
diff --git a/gcc/testsuite/objc.dg/property/property-1.m b/gcc/testsuite/objc.dg/property/property-1.m
new file mode 100644
index 000000000..147f007b9
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/property-1.m
@@ -0,0 +1,32 @@
+/* This program tests use of property provided setter/getter functions. */
+/* { dg-options "-std=c99" } */
+/* { dg-do run } */
+/* { dg-additional-sources "../../objc-obj-c++-shared/Object1.m" } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+#import "../../objc-obj-c++-shared/Object1.h"
+
+@interface Bar : Object
+{
+ int iVar;
+}
+@property (setter=MySetter:) int FooBar;
+@end
+
+@implementation Bar
+@synthesize FooBar=iVar;
+
+- (void) MySetter : (int) value { iVar = value; }
+
+@end
+
+int main(int argc, char *argv[]) {
+ Bar *f = [Bar new];
+ f.FooBar = 1;
+
+ f.FooBar += 3;
+
+ f.FooBar -= 4;
+ return f.FooBar;
+}
+
diff --git a/gcc/testsuite/objc.dg/property/property-encoding-1.m b/gcc/testsuite/objc.dg/property/property-encoding-1.m
new file mode 100644
index 000000000..dc12c3137
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/property-encoding-1.m
@@ -0,0 +1,182 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, March 2011. */
+/* Test encoding properties. */
+/* { dg-do run } */
+/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */
+
+#include <objc/runtime.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+@interface MyRootClass
+{ Class isa; }
++ alloc;
+- init;
++ initialize;
+@end
+
+@implementation MyRootClass
++ alloc { return class_createInstance (self, 0); }
+- init { return self; }
++ initialize { return self; }
+@end
+
+@interface MySubClass : MyRootClass
+{
+ char char_property;
+ short short_property;
+ int int_property;
+ long long_property;
+ float float_property;
+ double double_property;
+ int *int_pointer_property;
+
+ id propertyA;
+ id propertyB;
+ id propertyC;
+ id propertyD;
+ int propertyE;
+ id propertyF;
+
+ id other_variable;
+}
+@property char char_property;
+@property short short_property;
+@property int int_property;
+@property long long_property;
+@property float float_property;
+@property double double_property;
+@property int *int_pointer_property;
+
+@property (assign, getter=getP, setter=setP:) id propertyA;
+@property (assign) id propertyB;
+@property (copy) id propertyC;
+@property (retain) id propertyD;
+@property (nonatomic) int propertyE;
+@property (nonatomic, readonly, copy) id propertyF;
+
+@property (assign) id propertyG;
+@property (assign, readonly, getter=X) id propertyH;
+@end
+
+@implementation MySubClass
+@synthesize char_property;
+@synthesize short_property;
+@synthesize int_property;
+@synthesize long_property;
+@synthesize float_property;
+@synthesize double_property;
+@synthesize int_pointer_property;
+
+@synthesize propertyA;
+@synthesize propertyB;
+@synthesize propertyC;
+@synthesize propertyD;
+@synthesize propertyE;
+@synthesize propertyF;
+
+@synthesize propertyG = other_variable;
+@dynamic propertyH;
+@end
+
+#ifdef __OBJC2__
+void error (objc_property_t p)
+{
+ printf ("Error - property_getAttributes (\"%s\") returns \"%s\"\n",
+ property_getName (p),
+ property_getAttributes (p));
+ abort ();
+}
+
+/* Concatenate 3 strings and return the result. */
+char *concat (const char *a, const char *b, const char *c)
+{
+ /* We happily leak memory here. This is a test. */
+ char *x = (char *)malloc (sizeof (char) * 128);
+ snprintf (x, 128, "%s%s%s", a, b, c);
+ return x;
+}
+
+#endif
+
+int main (void)
+{
+#ifdef __OBJC2__
+ Class c = objc_getClass ("MySubClass");
+ objc_property_t p;
+
+ p = class_getProperty (c, "char_property");
+ /* Usually we expect "Tc,Vchar_property", but if a char is of
+ different size, it may be encoded differently than "c". */
+ if (strcmp (concat ("T", @encode (char), ",Vchar_property"),
+ property_getAttributes (p)) != 0)
+ error (p);
+
+ p = class_getProperty (c, "short_property");
+ if (strcmp (concat ("T", @encode (short), ",Vshort_property"),
+ property_getAttributes (p)) != 0)
+ error (p);
+
+ p = class_getProperty (c, "int_property");
+ if (strcmp (concat ("T", @encode (int), ",Vint_property"),
+ property_getAttributes (p)) != 0)
+ error (p);
+
+ p = class_getProperty (c, "long_property");
+ if (strcmp (concat ("T", @encode (long), ",Vlong_property"),
+ property_getAttributes (p)) != 0)
+ error (p);
+
+ p = class_getProperty (c, "float_property");
+ if (strcmp (concat ("T", @encode (float), ",Vfloat_property"),
+ property_getAttributes (p)) != 0)
+ error (p);
+
+ p = class_getProperty (c, "double_property");
+ if (strcmp (concat ("T", @encode (double), ",Vdouble_property"),
+ property_getAttributes (p)) != 0)
+ error (p);
+
+ p = class_getProperty (c, "int_pointer_property");
+ if (strcmp (concat ("T", @encode (int *), ",Vint_pointer_property"),
+ property_getAttributes (p)) != 0)
+ error (p);
+
+ /* Objects are always encoded as '@' hence the string does not
+ depend on the architecture. */
+ p = class_getProperty (c, "propertyA");
+ if (strcmp ("T@,GgetP,SsetP:,VpropertyA", property_getAttributes (p)) != 0)
+ error (p);
+
+ p = class_getProperty (c, "propertyB");
+ if (strcmp ("T@,VpropertyB", property_getAttributes (p)) != 0)
+ error (p);
+
+ p = class_getProperty (c, "propertyC");
+ if (strcmp ("T@,C,VpropertyC", property_getAttributes (p)) != 0)
+ error (p);
+
+ p = class_getProperty (c, "propertyD");
+ if (strcmp ("T@,&,VpropertyD", property_getAttributes (p)) != 0)
+ error (p);
+
+ p = class_getProperty (c, "propertyE");
+ if (strcmp (concat ("T", @encode (int), ",N,VpropertyE"),
+ property_getAttributes (p)) != 0)
+ error (p);
+
+ p = class_getProperty (c, "propertyF");
+ if (strcmp ("T@,R,C,N,VpropertyF", property_getAttributes (p)) != 0)
+ error (p);
+
+ p = class_getProperty (c, "propertyG");
+ if (strcmp ("T@,Vother_variable", property_getAttributes (p)) != 0)
+ error (p);
+
+ p = class_getProperty (c, "propertyH");
+ if (strcmp ("T@,R,D,GX", property_getAttributes (p)) != 0)
+ error (p);
+#endif
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/property/property-neg-1.m b/gcc/testsuite/objc.dg/property/property-neg-1.m
new file mode 100644
index 000000000..cae1a5615
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/property-neg-1.m
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+
+@interface Bar
+{
+ int iVar;
+}
+@property int fooBar;
+@end
+
+@implementation Bar
+@end /* { dg-warning "incomplete implementation of class .Bar." } */
+ /* { dg-warning "method definition for .-setFooBar:. not found" "" { target *-*-* } 11 } */
+ /* { dg-warning "method definition for .-fooBar. not found" "" { target *-*-* } 11 } */
diff --git a/gcc/testsuite/objc.dg/property/property-neg-2.m b/gcc/testsuite/objc.dg/property/property-neg-2.m
new file mode 100644
index 000000000..f730fe846
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/property-neg-2.m
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+
+@interface Bar
+@end
+
+@implementation Bar
+@property int FooBar; /* { dg-error "property declaration not in @interface or @protocol context" } */
+@end
diff --git a/gcc/testsuite/objc.dg/property/property-neg-3.m b/gcc/testsuite/objc.dg/property/property-neg-3.m
new file mode 100644
index 000000000..0b30931a8
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/property-neg-3.m
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+
+@interface Person
+{
+ char *firstName;
+}
+@property char *firstName;
+@end
+
+@implementation Person
+@dynamic firstName;
+@synthesize firstName; /* { dg-error "property .firstName. already specified in .@dynamic." } */
+ /* { dg-message "originally specified here" "" { target *-*-* } 11 } */
+@end
diff --git a/gcc/testsuite/objc.dg/property/property-neg-4.m b/gcc/testsuite/objc.dg/property/property-neg-4.m
new file mode 100644
index 000000000..cc25d84af
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/property-neg-4.m
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+
+@interface Person
+{
+ char *fullName;
+}
+@property char *fullName;
++ (void) testClass;
+@end
+
+
+@implementation Person
+@synthesize fullName;
++ (void) testClass {
+ self.fullName = "MyName"; /* { dg-error "request for member .fullName." } */
+}
+@end
diff --git a/gcc/testsuite/objc.dg/property/property-neg-5.m b/gcc/testsuite/objc.dg/property/property-neg-5.m
new file mode 100644
index 000000000..464470cba
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/property-neg-5.m
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+
+@interface Foo
+@property ( readonly, getter = HELLO, setter = THERE : ) int value; /* { dg-error ".readonly. attribute conflicts with .setter. attribute" } */
+@end
diff --git a/gcc/testsuite/objc.dg/property/property-neg-6.m b/gcc/testsuite/objc.dg/property/property-neg-6.m
new file mode 100644
index 000000000..7059a56f0
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/property-neg-6.m
@@ -0,0 +1,9 @@
+/* Check for proper declaration of @property. */
+/* { dg-do compile } */
+
+@interface Bar
+{
+ int iVar;
+}
+@property int FooBar /* { dg-error "expected ':', ',', ';', '\}' or '__attribute__' at end of input" } */
+/* { dg-error "expected ..end. at end of input" "" { target *-*-* } 8 } */
diff --git a/gcc/testsuite/objc.dg/property/property-neg-7.m b/gcc/testsuite/objc.dg/property/property-neg-7.m
new file mode 100644
index 000000000..4c3d5d7d3
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/property-neg-7.m
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+
+@interface NSArray
+{
+ int count;
+}
+@property(readonly) int count;
+@end
+
+@implementation NSArray
+@synthesize count;
+@end
+
+void foo (NSArray *ans[], id pid, id apid[], int i) {
+ NSArray *test;
+ test.count = 1; /* { dg-error "readonly property can not be set" } */
+ ((NSArray *)pid).count = 1; /* { dg-error "readonly property can not be set" } */
+ ((NSArray *)apid[i]).count = 1; /* { dg-error "readonly property can not be set" } */
+ ans[i].count = 3; /* { dg-error "readonly property can not be set" } */
+}
diff --git a/gcc/testsuite/objc.dg/property/property.exp b/gcc/testsuite/objc.dg/property/property.exp
new file mode 100644
index 000000000..e87730188
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/property.exp
@@ -0,0 +1,43 @@
+# GCC Objective-C testsuite that uses the `dg.exp' driver.
+# Copyright (C) 1997, 2001, 2007, 2010 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 GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+# Load support procs.
+load_lib objc-dg.exp
+
+# If a testcase doesn't have special options, use these.
+global DEFAULT_CFLAGS
+if ![info exists DEFAULT_CFLAGS] then {
+ set DEFAULT_CFLAGS ""
+}
+
+# Initialize `dg'.
+dg-init
+
+# Gather a list of all tests.
+set tests [lsort [glob -nocomplain $srcdir/$subdir/*.m]]
+
+# Main loop.
+dg-runtest $tests "-fgnu-runtime" $DEFAULT_CFLAGS
+
+# Darwin targets can also run code with the NeXT runtime.
+# but Properties are not supported by the runtime lib before Darwin 9.
+if [istarget "*-*-darwin\[9123\]*" ] {
+ dg-runtest $tests "-fnext-runtime" $DEFAULT_CFLAGS
+}
+
+# All done.
+dg-finish
diff --git a/gcc/testsuite/objc.dg/property/synthesize-1.m b/gcc/testsuite/objc.dg/property/synthesize-1.m
new file mode 100644
index 000000000..fbc8e03ee
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/synthesize-1.m
@@ -0,0 +1,53 @@
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+@interface MyRootClass
+{
+ Class isa;
+}
+@end
+
+@implementation MyRootClass
+@end
+
+@synthesize isa; /* { dg-error ".@synthesize. not in @implementation context" } */
+
+@interface Test : MyRootClass
+{
+ int v1;
+ int v2;
+ int v3;
+ int v4;
+ int v5;
+ int v6;
+ int v7;
+ int v8;
+}
+@property int v1;
+@property int v2;
+@property int v3;
+@property int v4;
+@property int v5;
+@property int v6;
+@property int v7;
+@property int v8;
+@end
+
+@implementation Test
+@synthesize; /* { dg-error "expected identifier" } */
+@synthesize v1, ; /* { dg-error "expected identifier" } */
+@synthesize v2, v3 = ; /* { dg-error "expected identifier" } */
+@synthesize v4, v5=v6, v6 = v5,v7;
+@synthesize v8;
+/* Some of the @synthesize above will fail due to syntax errors. The
+ compiler will then complain that the methods implementing the
+ properties are missing. That is correct, but we are not
+ interested. The following ones shut up the compiler. */
+- (int) v1 { return v1; }
+- (void) setV1: (int)a { v1 = a; }
+- (int) v2 { return v2; }
+- (void) setV2: (int)a { v2 = a; }
+- (int) v3 { return v3; }
+- (void) setV3: (int)a { v3 = a; }
+@end
diff --git a/gcc/testsuite/objc.dg/property/synthesize-10.m b/gcc/testsuite/objc.dg/property/synthesize-10.m
new file mode 100644
index 000000000..fc4683187
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/synthesize-10.m
@@ -0,0 +1,53 @@
+/* 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 @synthesize with bitfield instance variables. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+ int countA : 2;
+ int countB : 3;
+ int countC : 4;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+@property (nonatomic) int countA;
+@property (nonatomic) int countB;
+@property (nonatomic) int countC;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+@synthesize countA;
+@synthesize countB;
+@synthesize countC;
+@end
+
+int main (void)
+{
+ MyRootClass *object = [[MyRootClass alloc] init];
+
+ object.countA = 1;
+ object.countB = 3;
+ object.countC = 4;
+
+ if (object.countA != 1)
+ abort ();
+
+ if (object.countB != 3)
+ abort ();
+
+ if (object.countC != 4)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/property/synthesize-11.m b/gcc/testsuite/objc.dg/property/synthesize-11.m
new file mode 100644
index 000000000..e49d23424
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/synthesize-11.m
@@ -0,0 +1,31 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+/* Test errors when @synthesize is used with bitfield instance variables in an incorrect way. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+ int countA : 2; /* { dg-message "originally specified here" } */
+ int countB : 3; /* { dg-message "originally specified here" } */
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+@property int countA;
+@property (nonatomic) short countB;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+@synthesize countA; /* { dg-error ".atomic. property .countA. is using bit-field instance variable .countA." } */
+@synthesize countB; /* { dg-error "property .countB. is using instance variable .countB. of incompatible type" } */
+@end /* { dg-warning "incomplete implementation of class" } */
+/* { dg-warning "method definition for ..setCountA.. not found" "" { target *-*-* } 29 } */
+/* { dg-warning "method definition for ..countA. not found" "" { target *-*-* } 29 } */
diff --git a/gcc/testsuite/objc.dg/property/synthesize-2.m b/gcc/testsuite/objc.dg/property/synthesize-2.m
new file mode 100644
index 000000000..92170678f
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/synthesize-2.m
@@ -0,0 +1,51 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+#include <objc/objc.h>
+#include <objc/runtime.h>
+#include <stdlib.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
+
+@interface Test : MyRootClass
+{
+ int v1;
+}
+@property int v1;
+/* TODO: Test more types of properties with different semantics
+ (retain, copy, atomic, nonatomic, and test various C and
+ Objective-C types). */
+@end
+
+@implementation Test
+@synthesize v1;
+@end
+
+int main (void)
+{
+ Test *object = [[Test alloc] init];
+
+ /* Check that the synthesized methods exist and work. Do not invoke
+ them via property syntax - that is another test. Here we just
+ want to test the synthesis of the methods. */
+ [object setV1: 400];
+
+ if ([object v1] != 400)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/property/synthesize-3.m b/gcc/testsuite/objc.dg/property/synthesize-3.m
new file mode 100644
index 000000000..866990531
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/synthesize-3.m
@@ -0,0 +1,66 @@
+/* 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 @synthesize for a @property which is not declared directly in
+ the @interface, but in a @protocol that the @interface conforms
+ to. */
+
+#include <objc/objc.h>
+#include <objc/runtime.h>
+#include <stdlib.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 MyProtocol
+@property int v1;
+@end
+
+@protocol MyProtocol2
+@property int v2;
+@end
+
+@interface Test : MyRootClass <MyProtocol, MyProtocol2>
+{
+ int v1;
+ int _v2;
+}
+@end
+
+@implementation Test
+@synthesize v1;
+@synthesize v2 = _v2;
+@end
+
+int main (void)
+{
+ Test *object = [[Test alloc] init];
+
+ /* Check that the synthesized methods exist and work. Do not invoke
+ them via property syntax - that is another test. Here we just
+ want to test the synthesis of the methods. */
+ [object setV1: 400];
+
+ if ([object v1] != 400)
+ abort ();
+
+ [object setV2: 31];
+
+ if ([object v2] != 31)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/property/synthesize-4.m b/gcc/testsuite/objc.dg/property/synthesize-4.m
new file mode 100644
index 000000000..602dc68b4
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/synthesize-4.m
@@ -0,0 +1,67 @@
+/* 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 @synthesize for a @property where the setter/getter are also
+ declared by the user. This is fine. */
+
+#include <objc/objc.h>
+#include <objc/runtime.h>
+#include <stdlib.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 MyProtocol
+@property int v1;
+@end
+
+@protocol MyProtocol2
+@property int v2;
+@end
+
+@interface Test : MyRootClass <MyProtocol, MyProtocol2>
+{
+ int v1;
+ int _v2;
+}
+- (int)v1;
+- (void)setV1: (int)aNumber;
+- (int)v2;
+@end
+
+@implementation Test
+@synthesize v1;
+@synthesize v2 = _v2;
+@end
+
+int main (void)
+{
+ Test *object = [[Test alloc] init];
+
+ /* We use dot-syntax here as this is just a general test that
+ user-declared setters/getters don't cause confusion. */
+ object.v1 = 400;
+
+ if (object.v1 != 400)
+ abort ();
+
+ object.v2 = 31;
+
+ if (object.v2 != 31)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/property/synthesize-5.m b/gcc/testsuite/objc.dg/property/synthesize-5.m
new file mode 100644
index 000000000..0871b63ee
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/synthesize-5.m
@@ -0,0 +1,18 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+/* Test that @synthesize does not ICE if asked to use a non-existing
+ ivar. */
+
+#include <objc/objc.h>
+
+@interface Test
+@property int v1;
+@end
+
+@implementation Test
+@synthesize v1; /* { dg-error "must be an existing ivar" } */
+@end
+/* { dg-warning "incomplete implementation" "" { target *-*-* } 15 } */
+/* { dg-warning "method definition for .-setV1:. not found" "" { target *-*-* } 15 } */
+/* { dg-warning "method definition for .-v1. not found" "" { target *-*-* } 15 } */
diff --git a/gcc/testsuite/objc.dg/property/synthesize-6.m b/gcc/testsuite/objc.dg/property/synthesize-6.m
new file mode 100644
index 000000000..19f7c9534
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/synthesize-6.m
@@ -0,0 +1,32 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+/* Test that each @synthesize is using a different instance variable,
+ and that it must belong to the class (not to a superclass). */
+
+#include <objc/objc.h>
+
+@interface Test
+{
+ int v;
+ int w;
+}
+@property int v1;
+@property int v2;
+@end
+
+@implementation Test
+@synthesize v1 = v; /* { dg-message "originally specified here" } */
+@synthesize v2 = v; /* { dg-error "property .v2. is using the same instance variable as property .v1." } */
+@end
+
+@interface Test2 : Test
+@property int w1;
+@end
+
+@implementation Test2
+@synthesize w1; /* { dg-error "ivar .w1. used by .@synthesize. declaration must be an existing ivar" } */
+@end
+/* { dg-warning "incomplete implementation" "" { target *-*-* } 29 } */
+/* { dg-warning "method definition for .-setW1:. not found" "" { target *-*-* } 29 } */
+/* { dg-warning "method definition for .-w1. not found" "" { target *-*-* } 29 } */
diff --git a/gcc/testsuite/objc.dg/property/synthesize-7.m b/gcc/testsuite/objc.dg/property/synthesize-7.m
new file mode 100644
index 000000000..929e3803b
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/synthesize-7.m
@@ -0,0 +1,86 @@
+/* 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 @synthesize with protocols of protocols. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@protocol ProtocolA
+@property int countA;
+@end
+
+@protocol ProtocolB <ProtocolA>
+@property int countB;
+@end
+
+@protocol ProtocolC <ProtocolB>
+@property int countC;
+@end
+
+@protocol ProtocolD
+@property int countD;
+@end
+
+@interface MyRootClass <ProtocolC>
+{
+ Class isa;
+ int countA;
+ int countB;
+ int countC;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+@synthesize countA;
+@synthesize countB;
+@synthesize countC;
+@end
+
+@interface MySubClass : MyRootClass <ProtocolD>
+{
+ int countD;
+}
+@end
+
+@implementation MySubClass
+@synthesize countD;
+@end
+
+int main (void)
+{
+ MySubClass *object = [[MySubClass alloc] init];
+ int i;
+
+ for (i = 0; i < 10; i++)
+ {
+ object.countA += i;
+ object.countB += i + 1;
+ object.countC += i + 2;
+ object.countD += i + 3;
+ }
+
+ if (object.countA != 45)
+ abort ();
+
+ if (object.countB != 55)
+ abort ();
+
+ if (object.countC != 65)
+ abort ();
+
+ if (object.countD != 75)
+ abort ();
+
+ return 0;
+}
+
+
diff --git a/gcc/testsuite/objc.dg/property/synthesize-8.m b/gcc/testsuite/objc.dg/property/synthesize-8.m
new file mode 100644
index 000000000..4af3ecc74
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/synthesize-8.m
@@ -0,0 +1,80 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+/* Test that when using @synthesize the instance variable and the
+ property have exactly the same type. */
+
+#include <objc/objc.h>
+
+@protocol MyProtocol
+- (void)aMethod;
+@end
+
+@interface ClassA
+@end
+
+@interface ClassB : ClassA
+@end
+
+
+/* This is all OK. */
+@interface Test
+{
+ int v;
+ float w;
+ id x;
+ Test *y;
+ id <MyProtocol> *z;
+ ClassA *a;
+ ClassB *b;
+ ClassA <MyProtocol> *c;
+}
+@property (assign) int v;
+@property (assign) float w;
+@property (assign) id x;
+@property (assign) Test *y;
+@property (assign) id <MyProtocol> *z;
+@property (assign) ClassA *a;
+@property (assign) ClassB *b;
+@end
+
+@implementation Test
+@synthesize v;
+@synthesize w;
+@synthesize x;
+@synthesize y;
+@synthesize z;
+@synthesize a;
+@synthesize b;
+@end
+
+
+/* This is not OK. */
+@interface Test2
+{
+ int v; /* { dg-message "originally specified here" } */
+ float w; /* { dg-message "originally specified here" } */
+ id x; /* { dg-message "originally specified here" } */
+ Test *y; /* { dg-message "originally specified here" } */
+ id <MyProtocol> *z; /* { dg-message "originally specified here" } */
+ ClassA *a; /* { dg-message "originally specified here" } */
+ ClassB *b; /* { dg-message "originally specified here" } */
+}
+@property (assign) float v;
+@property (assign) id w;
+@property (assign) int x;
+@property (assign) id y;
+@property (assign) Test *z;
+@property (assign) ClassB *a;
+@property (assign) ClassA *b;
+@end
+
+@implementation Test2
+@synthesize v; /* { dg-error "property .v. is using instance variable .v. of incompatible type" } */
+@synthesize w; /* { dg-error "property .w. is using instance variable .w. of incompatible type" } */
+@synthesize x; /* { dg-error "property .x. is using instance variable .x. of incompatible type" } */
+@synthesize y; /* { dg-error "property .y. is using instance variable .y. of incompatible type" } */
+@synthesize z; /* { dg-error "property .z. is using instance variable .z. of incompatible type" } */
+@synthesize a; /* { dg-error "property .a. is using instance variable .a. of incompatible type" } */
+@synthesize b; /* { dg-error "property .b. is using instance variable .b. of incompatible type" } */
+@end
diff --git a/gcc/testsuite/objc.dg/property/synthesize-9.m b/gcc/testsuite/objc.dg/property/synthesize-9.m
new file mode 100644
index 000000000..7eae31d3f
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/synthesize-9.m
@@ -0,0 +1,80 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+/* Test that when using @synthesize with a readonly property, the
+ instance variable can be a specialization of the property type. */
+
+#include <objc/objc.h>
+
+@protocol MyProtocol
+- (void)aMethod;
+@end
+
+@interface ClassA
+@end
+
+@interface ClassB : ClassA
+@end
+
+
+/* This is all OK. */
+@interface Test
+{
+ int v;
+ float w;
+ id x;
+ Test *y;
+ id <MyProtocol> *z;
+ ClassA *a;
+ ClassB *b;
+ ClassA <MyProtocol> *c;
+}
+@property (assign, readonly) int v;
+@property (assign, readonly) float w;
+@property (assign, readonly) id x;
+@property (assign, readonly) Test *y;
+@property (assign, readonly) id <MyProtocol> *z;
+@property (assign, readonly) ClassA *a;
+@property (assign, readonly) ClassB *b;
+@end
+
+@implementation Test
+@synthesize v;
+@synthesize w;
+@synthesize x;
+@synthesize y;
+@synthesize z;
+@synthesize a;
+@synthesize b;
+@end
+
+
+/* This is sometimes OK, sometimes not OK. */
+@interface Test2
+{
+ int v; /* { dg-message "originally specified here" } */
+ float w; /* { dg-message "originally specified here" } */
+ id x; /* { dg-message "originally specified here" } */
+ Test *y;
+ id <MyProtocol> *z; /* { dg-message "originally specified here" } */
+ ClassA *a; /* { dg-message "originally specified here" } */
+ ClassB *b;
+}
+@property (assign, readonly) float v;
+@property (assign, readonly) id w;
+@property (assign, readonly) int x;
+@property (assign, readonly) id y;
+@property (assign, readonly) Test *z;
+@property (assign, readonly) ClassB *a;
+@property (assign, readonly) ClassA *b;
+@end
+
+@implementation Test2
+@synthesize v; /* { dg-error "property .v. is using instance variable .v. of incompatible type" } */
+@synthesize w; /* { dg-error "property .w. is using instance variable .w. of incompatible type" } */
+@synthesize x; /* { dg-error "property .x. is using instance variable .x. of incompatible type" } */
+@synthesize y;
+@synthesize z; /* { dg-error "property .z. is using instance variable .z. of incompatible type" } */
+@synthesize a; /* { dg-error "property .a. is using instance variable .a. of incompatible type" } */
+@synthesize b;
+@end
diff --git a/gcc/testsuite/objc.dg/proto-hier-1.m b/gcc/testsuite/objc.dg/proto-hier-1.m
new file mode 100644
index 000000000..99dcbc567
--- /dev/null
+++ b/gcc/testsuite/objc.dg/proto-hier-1.m
@@ -0,0 +1,58 @@
+/* Test for handling of protocol hierarchies. */
+/* Author: Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-do compile } */
+
+/* One-line substitute for objc/objc.h */
+typedef struct objc_object { struct objc_class *class_pointer; } *id;
+
+@protocol NSObj
+- (void)someMethod;
+@end
+
+@protocol NSCopying
+- (void)someOtherMethod;
+@end
+
+@interface NSObject <NSObj>
+- (void)someMethod;
+@end
+
+@implementation NSObject
+- (void)someMethod {}
+@end
+
+@protocol Booing <NSObj>
+- (void)boo;
+@end
+
+@interface Boo: NSObject <Booing> // protocol has only one parent
+@end
+
+@implementation Boo
+- (void)boo {}
+@end
+
+@protocol Fooing <NSCopying, NSObj> // Fooing has two parent protocols
+- (void)foo;
+@end
+
+@interface Foo: NSObject <Fooing>
+@end
+
+@implementation Foo
+- (void)foo {}
+- (void)someOtherMethod {}
+@end
+
+int foo(void) {
+ id<Booing, Fooing> stupidVar;
+ [stupidVar boo];
+ [stupidVar foo];
+ [stupidVar anotherMsg]; /* { dg-warning ".\\-anotherMsg. not found in protocol" } */
+ /* { dg-warning "no .\\-anotherMsg. method found" "" { target *-*-* } 51 } */
+ return 0;
+}
+
+/* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 0 } */
+/* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 0 } */
+/* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/objc.dg/proto-hier-2.m b/gcc/testsuite/objc.dg/proto-hier-2.m
new file mode 100644
index 000000000..819cf4a50
--- /dev/null
+++ b/gcc/testsuite/objc.dg/proto-hier-2.m
@@ -0,0 +1,49 @@
+/* Test protocol warning. */
+/* Contributed by Devang Patel <dpatel@apple.com>. */
+/* { dg-do compile } */
+
+typedef struct objc_object { struct objc_class *class_pointer; } *id;
+
+@protocol Bar
+@end
+
+id <Bar> Foo_Bar () { }
+
+typedef struct
+{
+ int i;
+} MyStruct;
+
+@interface Foo
+{
+ id _mainData;
+ MyStruct *_anotherData;
+}
+
+-(id) mainDataSource;
+-(id) anotherDataSource;
+-(id) my_method: (int) i;
+@end
+
+@implementation Foo
+-(id) anotherDataSource
+{
+ return (id)_anotherData;
+}
+
+-(id) mainDataSource
+{
+ return _mainData;
+}
+
+-(id) my_method: (int) i
+{
+ id one = [self anotherDataSource];
+
+ i = i - 1;
+ // Do not issue warning about my_method not found in protocol
+ return [(one ? [self mainDataSource] : one) my_method:i];
+}
+
+@end
+
diff --git a/gcc/testsuite/objc.dg/proto-init-mimatch-1.m b/gcc/testsuite/objc.dg/proto-init-mimatch-1.m
new file mode 100644
index 000000000..64e52e812
--- /dev/null
+++ b/gcc/testsuite/objc.dg/proto-init-mimatch-1.m
@@ -0,0 +1,35 @@
+/* Test to warn on protocol mismatch in a variety of initializations. */
+
+/* { dg-do compile } */
+
+typedef struct objc_class *Class;
+
+typedef struct objc_object {
+ Class isa;
+} *id;
+
+@protocol NSObject
+@end
+
+@interface NSObject <NSObject>
+@end
+
+@protocol NSCopying
+- (void)copyWithZone;
+@end
+
+@interface Foo:NSObject <NSCopying>
+@end
+
+
+extern id <NSObject> NSCopyObject();
+
+@implementation Foo
+- (void)copyWithZone {
+ Foo *copy = NSCopyObject(); /* { dg-warning "type \\'id <NSObject>\\' does not conform to the \\'NSCopying\\' protocol" } */
+
+ Foo<NSObject,NSCopying> *g = NSCopyObject(); /* { dg-warning "type \\'id <NSObject>\\' does not conform to the \\'NSCopying\\' protocol" } */
+
+ id<NSObject,NSCopying> h = NSCopyObject(); /* { dg-warning "type \\'id <NSObject>\\' does not conform to the \\'NSCopying\\' protocol" } */
+}
+@end
diff --git a/gcc/testsuite/objc.dg/proto-lossage-1.m b/gcc/testsuite/objc.dg/proto-lossage-1.m
new file mode 100644
index 000000000..2f7eb9861
--- /dev/null
+++ b/gcc/testsuite/objc.dg/proto-lossage-1.m
@@ -0,0 +1,44 @@
+/* Test for situations in which protocol conformance information
+ may be lost, leading to superfluous warnings. */
+/* Author: Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-do compile } */
+
+/* One-line substitute for objc/objc.h */
+typedef struct objc_object { struct objc_class *class_pointer; } *id;
+
+@protocol NSObject
+- (int)someValue;
+@end
+
+@interface NSObject <NSObject>
+@end
+
+@protocol PlateMethods
+- (void)someMethod;
+@end
+
+@interface Foo {
+ NSObject <PlateMethods> *plate;
+ id <PlateMethods> plate1;
+ NSObject *plate2;
+}
+- (id <PlateMethods>) getPlate;
+- (id <NSObject>) getPlate1;
+- (int) getValue;
+@end
+
+@implementation Foo
+- (id <PlateMethods>) getPlate {
+ return plate; /* { dg-bogus "does not implement" } */
+}
+- (id <NSObject>) getPlate1 {
+ return (id <NSObject>)plate1; /* { dg-bogus "does not conform" } */
+}
+- (int) getValue {
+ int i = [plate1 someValue]; /* { dg-warning ".\\-someValue. not found in protocol\\(s\\)" } */
+
+ int j = [(id <NSObject>)plate1 someValue]; /* { dg-bogus "not found in protocol" } */
+ int k = [(id)plate1 someValue]; /* { dg-bogus "not found in protocol" } */
+ return i + j + k;
+}
+@end
diff --git a/gcc/testsuite/objc.dg/proto-lossage-2.m b/gcc/testsuite/objc.dg/proto-lossage-2.m
new file mode 100644
index 000000000..361bb9087
--- /dev/null
+++ b/gcc/testsuite/objc.dg/proto-lossage-2.m
@@ -0,0 +1,20 @@
+/* Don't forget to look in protocols if a class (and its superclasses) do not
+ provide a suitable method. */
+/* { dg-do compile } */
+
+#include "../objc-obj-c++-shared/Object1.h"
+
+@protocol Zot
+-(void) zot;
+@end
+
+@interface Foo : Object <Zot>
+@end
+
+int foo()
+{
+ Foo *f=nil;
+ [f zot]; /* There should be no warnings here! */
+ return 0;
+}
+
diff --git a/gcc/testsuite/objc.dg/proto-lossage-3.m b/gcc/testsuite/objc.dg/proto-lossage-3.m
new file mode 100644
index 000000000..1cb7b1d91
--- /dev/null
+++ b/gcc/testsuite/objc.dg/proto-lossage-3.m
@@ -0,0 +1,26 @@
+/* Crash due to descriptionFor(Instance|Class)Method applied to
+ a protocol with no instance/class methods respectively.
+ Problem report and original fix by richard@brainstorm.co.uk. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+#include "../objc-obj-c++-shared/Protocol1.h"
+#include "../objc-obj-c++-shared/Object1.h"
+#include <objc/objc.h>
+
+@protocol NoInstanceMethods
++ testMethod;
+@end
+
+@protocol NoClassMethods
+- testMethod;
+@end
+
+int
+main()
+{
+[@protocol(NoInstanceMethods) descriptionForInstanceMethod: @selector(name)];
+[@protocol(NoInstanceMethods) descriptionForClassMethod: @selector(name)];
+[@protocol(NoClassMethods) descriptionForInstanceMethod: @selector(name)];
+[@protocol(NoClassMethods) descriptionForClassMethod: @selector(name)];
+return 0;
+}
diff --git a/gcc/testsuite/objc.dg/proto-lossage-4.m b/gcc/testsuite/objc.dg/proto-lossage-4.m
new file mode 100644
index 000000000..9800d493c
--- /dev/null
+++ b/gcc/testsuite/objc.dg/proto-lossage-4.m
@@ -0,0 +1,54 @@
+/* Test for situations in which protocol conformance information
+ may be lost while casting. */
+/* Author: Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+/* One-line substitute for objc/objc.h */
+typedef struct objc_object { struct objc_class *class_pointer; } *id;
+
+@protocol Proto
+- (intptr_t)someValue;
+@end
+
+@interface Obj
+- (intptr_t)anotherValue;
+@end
+
+long foo(void) {
+ intptr_t receiver = 2;
+ Obj *objrcvr;
+ Obj <Proto> *objrcvr2;
+
+ /* NB: Since 'receiver' is an invalid ObjC message receiver, the compiler
+ should warn but then search for methods as if we were messaging 'id'. */
+
+ receiver += [receiver someValue]; /* { dg-warning "invalid receiver type .intptr_t." } */
+ receiver += [receiver anotherValue]; /* { dg-warning "invalid receiver type .intptr_t." } */
+
+ receiver += [(Obj *)receiver someValue]; /* { dg-warning ".Obj. may not respond to .\\-someValue." } */
+/* { dg-warning "assignment makes integer from pointer without a cast" "" { target *-*-* } 30 } */
+
+ receiver += [(Obj *)receiver anotherValue];
+ receiver += [(Obj <Proto> *)receiver someValue];
+ receiver += [(Obj <Proto> *)receiver anotherValue];
+ receiver += [objrcvr someValue]; /* { dg-warning ".Obj. may not respond to .\\-someValue." } */
+/* { dg-warning "assignment makes integer from pointer without a cast" "" { target *-*-* } 36 } */
+
+ receiver += [objrcvr anotherValue];
+ receiver += [(Obj <Proto> *)objrcvr someValue];
+ receiver += [(Obj <Proto> *)objrcvr anotherValue];
+ receiver += [objrcvr2 someValue];
+ receiver += [objrcvr2 anotherValue];
+ receiver += [(Obj *)objrcvr2 someValue]; /* { dg-warning ".Obj. may not respond to .\\-someValue." } */
+/* { dg-warning "assignment makes integer from pointer without a cast" "" { target *-*-* } 44 } */
+
+ receiver += [(Obj *)objrcvr2 anotherValue];
+
+ return receiver;
+}
+
+/* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 0 } */
+/* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 0 } */
+/* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/objc.dg/proto-lossage-5.m b/gcc/testsuite/objc.dg/proto-lossage-5.m
new file mode 100644
index 000000000..35c0956ed
--- /dev/null
+++ b/gcc/testsuite/objc.dg/proto-lossage-5.m
@@ -0,0 +1,22 @@
+/* Do not lose references to forward-declared protocols. */
+/* { dg-do compile } */
+@class MyBaseClass;
+@class MyClassThatFails;
+@protocol _MyProtocol;
+
+@interface MyClassThatFails
+- (MyBaseClass<_MyProtocol> *) aMethod;
+@end
+
+@interface MyBaseClass
+@end
+
+@protocol _MyProtocol
+@end
+
+@implementation MyClassThatFails
+- (MyBaseClass<_MyProtocol> *) aMethod
+{
+ return 0;
+}
+@end
diff --git a/gcc/testsuite/objc.dg/proto-lossage-6.m b/gcc/testsuite/objc.dg/proto-lossage-6.m
new file mode 100644
index 000000000..2b8720c36
--- /dev/null
+++ b/gcc/testsuite/objc.dg/proto-lossage-6.m
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+@class Base;
+@protocol _Protocol;
+
+@interface ClassA {
+}
+-(void) func1:(Base<_Protocol> *)inTarget;
+@end
+
+int main()
+{
+ ClassA* theA = 0;
+ Base<_Protocol>* myBase = 0;
+ [theA func1:myBase];
+
+ return 0;
+}
+
diff --git a/gcc/testsuite/objc.dg/proto-lossage-7.m b/gcc/testsuite/objc.dg/proto-lossage-7.m
new file mode 100644
index 000000000..b7746d7a1
--- /dev/null
+++ b/gcc/testsuite/objc.dg/proto-lossage-7.m
@@ -0,0 +1,28 @@
+/* Check that typedefs of ObjC classes preserve
+ any @protocol qualifiers. */
+/* { dg-do compile } */
+#include <objc/Object.h>
+
+@protocol CanDoStuff;
+
+typedef Object<CanDoStuff> CanDoStuffType;
+typedef Object<CanDoStuff> *CanDoStuffTypePtr;
+
+@protocol CanDoStuff
+- (int) dostuff;
+@end
+
+@protocol MoreStuff
+- (int) morestuff;
+@end
+
+int main(void)
+{
+ CanDoStuffTypePtr dice = nil;
+ CanDoStuffType *nodice = nil;
+ int count;
+ count = [dice dostuff];
+ count = [nodice dostuff];
+ return 0;
+}
+
diff --git a/gcc/testsuite/objc.dg/proto-qual-1.m b/gcc/testsuite/objc.dg/proto-qual-1.m
new file mode 100644
index 000000000..59daec5a4
--- /dev/null
+++ b/gcc/testsuite/objc.dg/proto-qual-1.m
@@ -0,0 +1,70 @@
+/* Check that protocol qualifiers are compiled and encoded properly. */
+/* Author: Ziemowit Laski <zlaski@apple.com> */
+
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+#include <objc/Protocol.h>
+#ifndef __NEXT_RUNTIME__
+#include <objc/objc-api.h>
+#endif
+#include "../objc-obj-c++-shared/next-mapping.h"
+
+/* The encoded parameter sizes will be rounded up to match pointer alignment. */
+#define ROUND(s,a) (a * ((s + a - 1) / a))
+#define aligned_sizeof(T) ROUND(sizeof(T),__alignof(void *))
+
+extern int sscanf(const char *str, const char *format, ...);
+extern void abort(void);
+#define CHECK_IF(expr) if(!(expr)) abort()
+
+@protocol Retain
++ (oneway void)retainArgument:(out bycopy id)arg1 with:(in signed char **)arg2;
+- (bycopy) address:(byref inout id)location with:(out short unsigned **)arg2;
+@end
+
+@interface Foo <Retain>
++ (oneway void)retainArgument:(out bycopy id)arg with:(in signed char **)arg2;
+@end
+
+@implementation Foo
++ (oneway void)retainArgument:(out bycopy id)arg1 with:(in signed char **)arg2 { }
+- (bycopy) address:(byref inout id)location with:(out short unsigned **)arg2 { return nil; }
+@end
+
+Protocol *proto;
+struct objc_method_description *meth;
+#ifdef NEXT_OBJC_USE_NEW_INTERFACE
+struct objc_method_description meth_object;
+#endif
+unsigned totsize, offs0, offs1, offs2, offs3, offs4, offs5, offs6, offs7;
+
+static void scan_initial(const char *pattern) {
+ totsize = offs0 = offs1 = offs2 = offs3 = offs4 = offs5 = offs6 = offs7 = (unsigned)-1;
+ sscanf(meth->types, pattern, &totsize, &offs0, &offs1, &offs2, &offs3,
+ &offs4, &offs5, &offs6, &offs7);
+ CHECK_IF(!offs0 && offs1 == aligned_sizeof(id) && offs2 == offs1 + aligned_sizeof(SEL) && totsize >= offs2);
+}
+
+int main(void) {
+ proto = @protocol(Retain);
+#ifdef NEXT_OBJC_USE_NEW_INTERFACE
+ meth_object = protocol_getMethodDescription (proto,
+ @selector(address:with:), YES, YES);
+ meth = &meth_object;
+#else
+ meth = [proto descriptionForInstanceMethod: @selector(address:with:)];
+#endif
+ scan_initial("O@%u@%u:%uNR@%uo^^S%u");
+ CHECK_IF(offs3 == offs2 + aligned_sizeof(id) && totsize == offs3 + aligned_sizeof(unsigned));
+#ifdef NEXT_OBJC_USE_NEW_INTERFACE
+ meth_object = protocol_getMethodDescription (proto,
+ @selector(retainArgument:with:), YES, NO);
+ meth = &meth_object;
+#else
+ meth = [proto descriptionForClassMethod: @selector(retainArgument:with:)];
+#endif
+ scan_initial("Vv%u@%u:%uOo@%un^*%u");
+ CHECK_IF(offs3 == offs2 + aligned_sizeof(id) && totsize == offs3 + aligned_sizeof(char **));
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/protocol-forward-1.m b/gcc/testsuite/objc.dg/protocol-forward-1.m
new file mode 100644
index 000000000..df8dcd70f
--- /dev/null
+++ b/gcc/testsuite/objc.dg/protocol-forward-1.m
@@ -0,0 +1,26 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
+/* { dg-do compile } */
+
+/* Test that all protocols appearing in @interface declarations are
+ real (ie, we saw a full @protocol definition with list of methods),
+ and not just forward-references (ie, "@protocol NSObject;"). */
+
+#include <objc/objc.h>
+
+@protocol MyProtocol;
+
+@protocol MyProtocol2
+- (int)method2;
+@end
+
+@interface MyClass <MyProtocol> /* { dg-warning "definition of protocol .MyProtocol. not found" } */
+@end
+
+@interface MyClass2 <MyProtocol2> /* Ok */
+@end
+
+@interface MyClass2 (Category) <MyProtocol> /* { dg-warning "definition of protocol .MyProtocol. not found" } */
+@end
+
+@protocol MyProtocol3 <MyProtocol> /* Ok */
+@end
diff --git a/gcc/testsuite/objc.dg/protocol-forward-2.m b/gcc/testsuite/objc.dg/protocol-forward-2.m
new file mode 100644
index 000000000..9217ca8d5
--- /dev/null
+++ b/gcc/testsuite/objc.dg/protocol-forward-2.m
@@ -0,0 +1,95 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
+/* { dg-do compile } */
+
+/* Test that all protocols appearing in @interface declarations are
+ real (ie, we saw a full @protocol definition with list of methods),
+ and not just forward-references (ie, "@protocol NSObject;"). This
+ test checks protocols implemented by other protocols. */
+
+#include <objc/objc.h>
+
+@protocol MyProtocol;
+
+@interface MyClass <MyProtocol> /* { dg-warning "definition of protocol .MyProtocol. not found" } */
+@end
+
+
+@protocol MyProtocol2 <MyProtocol>
+- (int)method2;
+@end
+
+@interface MyClass2 <MyProtocol2> /* { dg-warning "definition of protocol .MyProtocol. not found" } */
+- (int)method2;
+@end
+
+
+@protocol MyProtocol3 <MyProtocol2>
+- (int)method3;
+@end
+
+@interface MyClass3 <MyProtocol3> /* { dg-warning "definition of protocol .MyProtocol. not found" } */
+- (int)method2;
+- (int)method3;
+@end
+
+
+@protocol MyProtocol4 <MyProtocol3, MyProtocol2>
+- (int)method4;
+@end
+
+@interface MyClass4 <MyProtocol4> /* { dg-warning "definition of protocol .MyProtocol. not found" } */
+- (int)method2;
+- (int)method3;
+- (int)method4;
+@end
+
+
+@protocol MyProtocol5
+- (int)method5;
+@end
+
+@interface MyClass5 <MyProtocol5> /* Ok */
+- (int)method5;
+@end
+
+
+@protocol MyProtocol6 <MyProtocol5>
+- (int)method6;
+@end
+
+@interface MyClass6 <MyProtocol6> /* Ok */
+- (int)method5;
+- (int)method6;
+@end
+
+
+@protocol MyProtocol7 <MyProtocol5, MyProtocol4>
+- (int)method7;
+@end
+
+@interface MyClass7 <MyProtocol7> /* { dg-warning "definition of protocol .MyProtocol. not found" } */
+- (int)method2;
+- (int)method3;
+- (int)method4;
+- (int)method5;
+- (int)method7;
+@end
+
+
+/* Now test that if we finally define MyProtocol, the warnings go away. */
+@protocol MyProtocol
+- (int)method;
+@end
+
+@protocol MyProtocol8 <MyProtocol5, MyProtocol4>
+- (int)method8;
+@end
+
+@interface MyClass8 <MyProtocol8> /* Ok */
+- (int)method;
+- (int)method2;
+- (int)method3;
+- (int)method4;
+- (int)method5;
+- (int)method8;
+@end
diff --git a/gcc/testsuite/objc.dg/protocol-inheritance-1.m b/gcc/testsuite/objc.dg/protocol-inheritance-1.m
new file mode 100644
index 000000000..6c23a4663
--- /dev/null
+++ b/gcc/testsuite/objc.dg/protocol-inheritance-1.m
@@ -0,0 +1,54 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+/* { dg-options "-Wno-protocol" } */
+
+#include <objc/objc.h>
+
+/* Test the -Wno-protocol flag. With this, at a class is accepted
+ (with no warnings) as conforming to a protocol even if some
+ protocol methods are implemented in the superclass. */
+
+@protocol MyProtocol
+- (int)method;
+@end
+
+@protocol MyProtocol2
+- (int)method2;
+@end
+
+/* The superclass implements the method required by the protocol. */
+@interface MyRootClass
+{
+ Class isa;
+}
+- (int)method;
+@end
+
+@implementation MyRootClass
+- (int)method
+{
+ return 23;
+}
+@end
+
+/* The subclass inherits the method (does not implement it directly)
+ but that still makes it conform to the protocol. No warnings. */
+@interface MySubClass : MyRootClass <MyProtocol>
+@end
+
+@implementation MySubClass
+@end /* No warnings here. */
+
+
+/* The subclass instead does not inherit the method method2 (and does
+ not implement it directly) so it does not conform to the
+ protocol MyProtocol2. */
+@interface MySubClass2 : MyRootClass <MyProtocol2>
+@end
+
+@implementation MySubClass2
+@end /* Warnings here, below. */
+
+/* { dg-warning "incomplete implementation of class .MySubClass2." "" { target *-*-* } 50 } */
+/* { dg-warning "method definition for .\\-method2. not found" "" { target *-*-* } 50 } */
+/* { dg-warning "class .MySubClass2. does not fully implement the .MyProtocol2. protocol" "" { target *-*-* } 50 } */
diff --git a/gcc/testsuite/objc.dg/protocol-inheritance-2.m b/gcc/testsuite/objc.dg/protocol-inheritance-2.m
new file mode 100644
index 000000000..d76994945
--- /dev/null
+++ b/gcc/testsuite/objc.dg/protocol-inheritance-2.m
@@ -0,0 +1,57 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+/* Test standard warnings when a class conforms to a protocol but some
+ methods are implemented in the superclass. Use -Wno-protocol to
+ turn these off. */
+
+@protocol MyProtocol
+- (int)method;
+@end
+
+@protocol MyProtocol2
+- (int)method2;
+@end
+
+/* The superclass implements the method required by the protocol. */
+@interface MyRootClass
+{
+ Class isa;
+}
+- (int)method;
+@end
+
+@implementation MyRootClass
+- (int)method
+{
+ return 23;
+}
+@end
+
+/* The subclass inherits the method (does not implement it directly)
+ and unless -Wno-protocol is used, we emit a warning. */
+@interface MySubClass : MyRootClass <MyProtocol>
+@end
+
+@implementation MySubClass
+@end
+
+/* { dg-warning "incomplete implementation of class .MySubClass." "" { target *-*-* } 39 } */
+/* { dg-warning "method definition for .\\-method. not found" "" { target *-*-* } 39 } */
+/* { dg-warning "class .MySubClass. does not fully implement the .MyProtocol. protocol" "" { target *-*-* } 39 } */
+
+
+/* The subclass instead does not inherit the method method2 (and does
+ not implement it directly) so it does not conform to the
+ protocol MyProtocol2. */
+@interface MySubClass2 : MyRootClass <MyProtocol2>
+@end
+
+@implementation MySubClass2
+@end /* Warnings here, below. */
+
+/* { dg-warning "incomplete implementation of class .MySubClass2." "" { target *-*-* } 53 } */
+/* { dg-warning "method definition for .\\-method2. not found" "" { target *-*-* } 53 } */
+/* { dg-warning "class .MySubClass2. does not fully implement the .MyProtocol2. protocol" "" { target *-*-* } 53 } */
diff --git a/gcc/testsuite/objc.dg/protocol-optional-1.m b/gcc/testsuite/objc.dg/protocol-optional-1.m
new file mode 100644
index 000000000..bc4a3d07e
--- /dev/null
+++ b/gcc/testsuite/objc.dg/protocol-optional-1.m
@@ -0,0 +1,48 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+/* Test that @optional for @protocol works. */
+
+@protocol MyProtocol
++ (int)classMethod;
+- (int)method;
+@optional
++ (int)optionalClassMethod;
+- (int)optionalMethod;
+@end
+
+@interface MyRootClass <MyProtocol>
+@end
+
+/* The implementation implements both the @required methods, but none
+ of the @optional ones. There should be no warnings as the
+ @optional methods are optional. ;-) */
+@implementation MyRootClass
++ (int)classMethod
+{
+ return 20;
+}
+- (int)method
+{
+ return 11;
+}
+@end
+
+int function (id <MyProtocol> object1,
+ MyRootClass *object2)
+{
+ /* Test that there are no warnings if you try to use an @optional
+ method with an object of the class. */
+ int i = 0;
+
+ i += [object1 method];
+ i += [object2 method];
+ i += [MyRootClass classMethod];
+ i += [object1 optionalMethod];
+ i += [object2 optionalMethod];
+ i += [MyRootClass optionalClassMethod];
+
+ return i;
+}
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 000000000..c84bfbfa2
--- /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 000000000..fd25d8ff6
--- /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 } */
+}
diff --git a/gcc/testsuite/objc.dg/selector-1.m b/gcc/testsuite/objc.dg/selector-1.m
new file mode 100644
index 000000000..f0781b68c
--- /dev/null
+++ b/gcc/testsuite/objc.dg/selector-1.m
@@ -0,0 +1,27 @@
+/* Test warning for non existing selectors. */
+/* Contributed by Devang Patel <dpatel@apple.com>. */
+/* { dg-options "-Wselector" } */
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */
+
+typedef struct objc_object { struct objc_class *class_pointer; } *id;
+typedef struct objc_selector *SEL;
+
+@interface Foo
+- (void) foo;
+- (void) bar;
+@end
+
+@implementation Foo
+- (void) bar
+{
+}
+
+- (void) foo
+{
+ SEL a,b,c;
+ a = @selector(b1ar); /* { dg-warning "creating selector for nonexistent method .b1ar." } */
+ b = @selector(bar);
+}
+@end
+
diff --git a/gcc/testsuite/objc.dg/selector-2.m b/gcc/testsuite/objc.dg/selector-2.m
new file mode 100644
index 000000000..ab8eb3e45
--- /dev/null
+++ b/gcc/testsuite/objc.dg/selector-2.m
@@ -0,0 +1,16 @@
+/* Test that we don't ICE when issuing a -Wselector warning. */
+/* { dg-options "-Wselector" } */
+/* { dg-do compile } */
+
+#include "../objc-obj-c++-shared/Object1.h"
+
+@interface Foo
+@end
+@implementation Foo
+-(void) foo
+{
+ SEL a;
+ a = @selector(b1ar);
+}
+@end
+/* { dg-warning "creating selector for nonexistent method .b1ar." "" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/objc.dg/selector-3.m b/gcc/testsuite/objc.dg/selector-3.m
new file mode 100644
index 000000000..c0c5f3d8f
--- /dev/null
+++ b/gcc/testsuite/objc.dg/selector-3.m
@@ -0,0 +1,30 @@
+/* Test warning for non-existent selectors. */
+/* This is the "-fgnu-runtime" variant of objc.dg/selector-1.m. */
+/* { dg-options "-Wselector" } */
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-fnext-runtime" } { "" } } */
+
+typedef struct objc_object { struct objc_class *class_pointer; } *id;
+typedef const struct objc_selector *SEL;
+
+@interface Foo
+- (void) foo;
+- (void) bar;
+@end
+
+@implementation Foo
+- (void) bar
+{
+}
+
+- (void) foo
+{
+ SEL a,b,c;
+ a = @selector(b1ar);
+ b = @selector(bar);
+}
+@end
+
+/* FIXME: The error message should be on the correct line. */
+/* { dg-warning "creating selector for nonexistent method .b1ar." "" { target *-*-* } 0 } */
+
diff --git a/gcc/testsuite/objc.dg/selector-4.m b/gcc/testsuite/objc.dg/selector-4.m
new file mode 100644
index 000000000..d34f8c89c
--- /dev/null
+++ b/gcc/testsuite/objc.dg/selector-4.m
@@ -0,0 +1,30 @@
+/* Test whether including C++ keywords such as 'and', 'or',
+ 'not', etc., is allowed inside ObjC selectors (as it must be). */
+/* Author: Ziemowit Laski <zlaski@apple.com>. */
+
+/* { dg-do compile } */
+
+@interface Int1
++ (int)and_eq:(int)arg1 and:(int)arg2;
+- (int)or_eq:(int)arg1 or:(int)arg3;
+- (int)not:(int)arg1 xor:(int)arg2;
+- (void)bitand:(char)c1 bitor:(char)c2;
+- (void)compl:(float)f1 xor_eq:(double)d1;
+- (void)not_eq;
+@end
+
+@implementation Int1
++ (int)and_eq:(int)arg1 and:(int)arg2 { return arg1 + arg2; }
+- (int)or_eq:(int)arg1 or:(int)arg3 { return arg1 + arg3; }
+- (int)not:(int)arg1 xor:(int)arg2 { return arg1 + arg2; }
+- (void)bitand:(char)c1 bitor:(char)c2 { }
+- (void)compl:(float)f1 xor_eq:(double)d1 { }
+- (void)not_eq { }
+@end
+
+/* { dg-final { scan-assembler "\\+\\\[Int1 and_eq:and:\\]|c_Int1__and_eq_and" } } */
+/* { dg-final { scan-assembler "\\-\\\[Int1 or_eq:or:\\]|i_Int1__or_eq_or" } } */
+/* { dg-final { scan-assembler "\\-\\\[Int1 not:xor:\\]|i_Int1__not_xor" } } */
+/* { dg-final { scan-assembler "\\-\\\[Int1 bitand:bitor:\\]|i_Int1__bitand_bitor" } } */
+/* { dg-final { scan-assembler "\\-\\\[Int1 compl:xor_eq:\\]|i_Int1__compl_xor_eq" } } */
+/* { dg-final { scan-assembler "\\-\\\[Int1 not_eq\\]|i_Int1__not_eq" } } */
diff --git a/gcc/testsuite/objc.dg/selector-warn-1.m b/gcc/testsuite/objc.dg/selector-warn-1.m
new file mode 100644
index 000000000..b4b308d7b
--- /dev/null
+++ b/gcc/testsuite/objc.dg/selector-warn-1.m
@@ -0,0 +1,16 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, January 2011. */
+/* { dg-options "-Wselector" } */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+@interface RootObject
+@end
+
+@interface MyObject : RootObject
+- (void) method; /* { dg-message "found" } */
+@end
+
+@interface MyObject2 : RootObject
+- (int) method; /* { dg-message "also found" } */
+@end /* { dg-warning "multiple selectors named .-method. found" } */
diff --git a/gcc/testsuite/objc.dg/set-not-used-1.m b/gcc/testsuite/objc.dg/set-not-used-1.m
new file mode 100644
index 000000000..6380ec9df
--- /dev/null
+++ b/gcc/testsuite/objc.dg/set-not-used-1.m
@@ -0,0 +1,36 @@
+
+/* { dg-do compile } */
+/* { dg-options "-Wunused-but-set-variable" } */
+
+#import "../objc-obj-c++-shared/Object1.h"
+#include <objc/objc-api.h>
+
+@interface obj : Object
+{
+ int value;
+}
+- (int) value;
+- (void) setValue: (int)number;
+@end
+
+@implementation obj : Object
+
+- (int) value { return value; }
+- (void) setValue: (int)number { value = number; }
+
+@end
+
+int main (void)
+{
+ obj *a; /* { dg-bogus "set but not used" } */
+ obj *b; /* { dg-bogus "set but not used" } */
+ obj *c; /* { dg-warning "set but not used" } */
+
+ a = [obj new];
+ b = [obj new];
+ c = [obj new];
+
+ [b setValue: [a value]];
+
+ return [a value];
+}
diff --git a/gcc/testsuite/objc.dg/sizeof-1.m b/gcc/testsuite/objc.dg/sizeof-1.m
new file mode 100644
index 000000000..ae505c1e8
--- /dev/null
+++ b/gcc/testsuite/objc.dg/sizeof-1.m
@@ -0,0 +1,34 @@
+/* Check that the sizeof() operator works with ObjC classes and their aliases. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-options "" } */
+/* { dg-do run } */
+
+#include "../objc-obj-c++-shared/Object1.h"
+#include <objc/objc.h>
+
+extern void abort(void);
+#define CHECK_IF(expr) if(!(expr)) abort();
+
+@interface Foo: Object {
+ int a, b;
+ float c, d;
+}
+@end
+
+@implementation Foo
+@end
+
+typedef Object MyObject;
+typedef struct Foo Foo_type;
+
+@compatibility_alias AliasObject Object;
+
+int main(void) {
+ CHECK_IF(sizeof(Foo) > sizeof(Object) && sizeof(Object) > 0);
+ CHECK_IF(sizeof(Foo) == sizeof(Foo_type));
+ CHECK_IF(sizeof(Object) == sizeof(MyObject));
+ CHECK_IF(sizeof(Object) == sizeof(AliasObject));
+ return 0;
+}
+
+#include "../objc-obj-c++-shared/Object1-implementation.h"
diff --git a/gcc/testsuite/objc.dg/special/load-category-1.h b/gcc/testsuite/objc.dg/special/load-category-1.h
new file mode 100644
index 000000000..7810487df
--- /dev/null
+++ b/gcc/testsuite/objc.dg/special/load-category-1.h
@@ -0,0 +1,20 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
+
+/* Test that +load works when a category is defined in a different
+ module than the main class. */
+
+/* This function should be called any time +load is invoked, so we can
+ keep the count. */
+extern int increase_load_count (void);
+
+@interface TestClass1
+{
+ id isa;
+}
+@end
+
+@interface TestClass2
+{
+ id isa;
+}
+@end
diff --git a/gcc/testsuite/objc.dg/special/load-category-1.m b/gcc/testsuite/objc.dg/special/load-category-1.m
new file mode 100644
index 000000000..cb221436f
--- /dev/null
+++ b/gcc/testsuite/objc.dg/special/load-category-1.m
@@ -0,0 +1,39 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+
+#include "load-category-1.h"
+
+@implementation TestClass1
++ initialize { return self; }
++ load
+{
+ increase_load_count ();
+}
+@end
+
+@implementation TestClass2 (Category)
++ load
+{
+ increase_load_count ();
+}
+@end
+
+
+static int load_count = 0;
+
+int increase_load_count (void)
+{
+ load_count++;
+}
+
+int main (void)
+{
+ if (load_count != 4)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/special/load-category-1a.m b/gcc/testsuite/objc.dg/special/load-category-1a.m
new file mode 100644
index 000000000..cdcb7d829
--- /dev/null
+++ b/gcc/testsuite/objc.dg/special/load-category-1a.m
@@ -0,0 +1,21 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+
+#include "load-category-1.h"
+
+@implementation TestClass2
++ initialize { return self; }
++ load
+{
+ increase_load_count ();
+}
+@end
+
+@implementation TestClass1 (Category)
++ load
+{
+ increase_load_count ();
+}
+@end
diff --git a/gcc/testsuite/objc.dg/special/load-category-2.h b/gcc/testsuite/objc.dg/special/load-category-2.h
new file mode 100644
index 000000000..ae7e84278
--- /dev/null
+++ b/gcc/testsuite/objc.dg/special/load-category-2.h
@@ -0,0 +1,19 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
+
+/* Test the order of calling +load between classes and categories. */
+
+void complete_load_step (int load_step);
+void check_that_load_step_was_completed (int load_step);
+void check_that_load_step_was_not_completed (int load_step);
+
+@interface TestClass1
+{
+ id isa;
+}
+@end
+
+@interface TestClass2 : TestClass1
+@end
+
+@interface TestClass3 : TestClass2
+@end
diff --git a/gcc/testsuite/objc.dg/special/load-category-2.m b/gcc/testsuite/objc.dg/special/load-category-2.m
new file mode 100644
index 000000000..7dc745952
--- /dev/null
+++ b/gcc/testsuite/objc.dg/special/load-category-2.m
@@ -0,0 +1,105 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <objc/objc.h>
+
+#include "load-category-2.h"
+
+/* This test tests that +load is called in the correct order for
+ classes and categories. +load needs to be called in superclasses
+ before subclasses, and in the main class before categories. */
+
+/* Compile the classes in random order to prevent the runtime from
+ sending +load in the correct order just because the classes happen
+ to have been compiled in that order. */
+@implementation TestClass2
++ load
+{
+ printf ("[TestClass2 +load]\n");
+ /* Check superclasses/subclasses +load order. */
+ check_that_load_step_was_completed (0);
+ check_that_load_step_was_not_completed (1);
+ check_that_load_step_was_not_completed (2);
+
+ /* Check that the corresponding category's +load was not done. */
+ check_that_load_step_was_not_completed (4);
+
+ complete_load_step (1);
+}
+@end
+
+@implementation TestClass3
++ load
+{
+ printf ("[TestClass3 +load]\n");
+
+ /* Check superclasses/subclasses +load order. */
+ check_that_load_step_was_completed (0);
+ check_that_load_step_was_completed (1);
+ check_that_load_step_was_not_completed (2);
+
+ /* Check that the corresponding category's +load was not done. */
+ check_that_load_step_was_not_completed (5);
+
+ complete_load_step (2);
+}
+@end
+
+@implementation TestClass1
++ initialize { return self; }
++ load
+{
+ printf ("[TestClass1 +load]\n");
+
+ /* Check superclasses/subclasses +load order. */
+ check_that_load_step_was_not_completed (0);
+ check_that_load_step_was_not_completed (1);
+ check_that_load_step_was_not_completed (2);
+
+ /* Check that the corresponding category's +load was not done. */
+ check_that_load_step_was_not_completed (3);
+
+ complete_load_step (0);
+}
+@end
+
+
+static BOOL load_step_completed[6] = { NO, NO, NO, NO, NO, NO };
+
+void complete_load_step (int load_step)
+{
+ load_step_completed[load_step] = YES;
+}
+
+void check_that_load_step_was_completed (int load_step)
+{
+ if (load_step_completed[load_step] == NO)
+ {
+ printf ("Load step %d was not completed but should have been\n", load_step);
+ abort ();
+ }
+}
+
+void check_that_load_step_was_not_completed (int load_step)
+{
+ if (load_step_completed[load_step] == YES)
+ {
+ printf ("Load step %d was completed but shouldn't have been\n", load_step);
+ abort ();
+ }
+}
+
+int main (void)
+{
+ check_that_load_step_was_completed (0);
+ check_that_load_step_was_completed (1);
+ check_that_load_step_was_completed (2);
+ check_that_load_step_was_completed (3);
+ check_that_load_step_was_completed (4);
+ check_that_load_step_was_completed (5);
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/special/load-category-2a.m b/gcc/testsuite/objc.dg/special/load-category-2a.m
new file mode 100644
index 000000000..6b81240db
--- /dev/null
+++ b/gcc/testsuite/objc.dg/special/load-category-2a.m
@@ -0,0 +1,46 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <objc/objc.h>
+
+#include "load-category-2.h"
+
+/* Compile the categories in random order to prevent the runtime from
+ sending +load in the correct order just because the classes happen
+ to have been compiled in that order. */
+@implementation TestClass2 (Category)
++ load
+{
+ printf ("[TestClass2(Category) +load]\n");
+
+ /* Check that the corresponding class's +load was done. */
+ check_that_load_step_was_completed (1);
+
+ complete_load_step (4);
+}
+@end
+
+@implementation TestClass3 (Category)
++ load
+{
+ printf ("[TestClass3(Category) +load]\n");
+
+ /* Check that the corresponding class's +load was done. */
+ check_that_load_step_was_completed (2);
+
+ complete_load_step (5);
+}
+@end
+
+@implementation TestClass1 (Category)
++ load
+{
+ printf ("[TestClass1(Category) +load]\n");
+
+ /* Check that the corresponding class's +load was done. */
+ check_that_load_step_was_completed (0);
+
+ complete_load_step (3);
+}
+@end
diff --git a/gcc/testsuite/objc.dg/special/load-category-3.h b/gcc/testsuite/objc.dg/special/load-category-3.h
new file mode 100644
index 000000000..9d6d8acc9
--- /dev/null
+++ b/gcc/testsuite/objc.dg/special/load-category-3.h
@@ -0,0 +1,17 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
+
+void complete_load_step (int load_step);
+void check_that_load_step_was_completed (int load_step);
+void check_that_load_step_was_not_completed (int load_step);
+
+@interface TestClass1
+{
+ id isa;
+}
+@end
+
+@interface TestClass2 : TestClass1
+@end
+
+@interface TestClass3 : TestClass2
+@end
diff --git a/gcc/testsuite/objc.dg/special/load-category-3.m b/gcc/testsuite/objc.dg/special/load-category-3.m
new file mode 100644
index 000000000..b89d8f152
--- /dev/null
+++ b/gcc/testsuite/objc.dg/special/load-category-3.m
@@ -0,0 +1,87 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* This test is identical to load-category-2, but the classes and
+ categories are created in inverted order in the modules, to test
+ that you can load classes first, or categories first, and it all
+ still works in both cases. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <objc/objc.h>
+
+#include "load-category-3.h"
+
+@implementation TestClass2 (Category)
++ load
+{
+ printf ("[TestClass2(Category) +load]\n");
+
+ /* Check that the corresponding class's +load was done. */
+ check_that_load_step_was_completed (1);
+
+ complete_load_step (4);
+}
+@end
+
+@implementation TestClass3 (Category)
++ load
+{
+ printf ("[TestClass3(Category) +load]\n");
+
+ /* Check that the corresponding class's +load was done. */
+ check_that_load_step_was_completed (2);
+
+ complete_load_step (5);
+}
+@end
+
+@implementation TestClass1 (Category)
++ load
+{
+ printf ("[TestClass1(Category) +load]\n");
+
+ /* Check that the corresponding class's +load was done. */
+ check_that_load_step_was_completed (0);
+
+ complete_load_step (3);
+}
+@end
+
+static BOOL load_step_completed[6] = { NO, NO, NO, NO, NO, NO };
+
+void complete_load_step (int load_step)
+{
+ load_step_completed[load_step] = YES;
+}
+
+void check_that_load_step_was_completed (int load_step)
+{
+ if (load_step_completed[load_step] == NO)
+ {
+ printf ("Load step %d was not completed but should have been\n", load_step);
+ abort ();
+ }
+}
+
+void check_that_load_step_was_not_completed (int load_step)
+{
+ if (load_step_completed[load_step] == YES)
+ {
+ printf ("Load step %d was completed but shouldn't have been\n", load_step);
+ abort ();
+ }
+}
+
+int main (void)
+{
+ check_that_load_step_was_completed (0);
+ check_that_load_step_was_completed (1);
+ check_that_load_step_was_completed (2);
+ check_that_load_step_was_completed (3);
+ check_that_load_step_was_completed (4);
+ check_that_load_step_was_completed (5);
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/special/load-category-3a.m b/gcc/testsuite/objc.dg/special/load-category-3a.m
new file mode 100644
index 000000000..5ce5fac65
--- /dev/null
+++ b/gcc/testsuite/objc.dg/special/load-category-3a.m
@@ -0,0 +1,65 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
+
+/* This test is identical to load-category-2, but the classes and
+ categories are created in inverted order in the modules, to test
+ that you can load classes first, or categories first, and it all
+ still works. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <objc/objc.h>
+
+#include "load-category-3.h"
+
+@implementation TestClass2
++ load
+{
+ printf ("[TestClass2 +load]\n");
+ /* Check superclasses/subclasses +load order. */
+ check_that_load_step_was_completed (0);
+ check_that_load_step_was_not_completed (1);
+ check_that_load_step_was_not_completed (2);
+
+ /* Check that the corresponding category's +load was not done. */
+ check_that_load_step_was_not_completed (4);
+
+ complete_load_step (1);
+}
+@end
+
+@implementation TestClass3
++ load
+{
+ printf ("[TestClass3 +load]\n");
+
+ /* Check superclasses/subclasses +load order. */
+ check_that_load_step_was_completed (0);
+ check_that_load_step_was_completed (1);
+ check_that_load_step_was_not_completed (2);
+
+ /* Check that the corresponding category's +load was not done. */
+ check_that_load_step_was_not_completed (5);
+
+ complete_load_step (2);
+}
+@end
+
+@implementation TestClass1
++ initialize { return self; }
++ load
+{
+ printf ("[TestClass1 +load]\n");
+
+ /* Check superclasses/subclasses +load order. */
+ check_that_load_step_was_not_completed (0);
+ check_that_load_step_was_not_completed (1);
+ check_that_load_step_was_not_completed (2);
+
+ /* Check that the corresponding category's +load was not done. */
+ check_that_load_step_was_not_completed (3);
+
+ complete_load_step (0);
+}
+@end
+
+
diff --git a/gcc/testsuite/objc.dg/special/special.exp b/gcc/testsuite/objc.dg/special/special.exp
new file mode 100644
index 000000000..bab6798d9
--- /dev/null
+++ b/gcc/testsuite/objc.dg/special/special.exp
@@ -0,0 +1,145 @@
+# GCC Objective-C testsuite that uses the `dg.exp' driver.
+# Copyright (C) 1997, 2001, 2007, 2010 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 GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+# Load support procs.
+load_lib objc-dg.exp
+
+# If a testcase doesn't have special options, use these.
+global DEFAULT_CFLAGS
+if ![info exists DEFAULT_CFLAGS] then {
+ set DEFAULT_CFLAGS ""
+}
+
+# Initialize `dg'.
+dg-init
+
+# TODO: All these testcases compile and link two Objective-C modules.
+# Remove code duplication and factor the common code out.
+
+#
+# unclaimed-category-1 test
+#
+# This test is special because we must compile two different modules,
+# unclaimed-category-1a.m and unclaimed-category-1.m, then link
+# together, then run the resulting executable.
+# for all systems we point to the libobjc includes and use the -fgnu-runtime
+set add_flags "additional_flags=-I${srcdir}/../../libobjc"
+lappend add_flags "additional_flags=-fgnu-runtime"
+set lines [objc_target_compile "$srcdir/$subdir/unclaimed-category-1a.m" "unclaimed-category-1a.o" object $add_flags ]
+if ![string match "" $lines] then {
+ fail "unclaimed-category-1a.o"
+} else {
+ dg-runtest "$srcdir/$subdir/unclaimed-category-1.m" "unclaimed-category-1a.o" "-I${srcdir}/../../libobjc -fgnu-runtime"
+ file delete unclaimed-category-1a.o
+}
+
+if [istarget "*-*-darwin*" ] {
+set add_flags ""
+lappend add_flags "additional_flags=-fnext-runtime"
+set lines [objc_target_compile "$srcdir/$subdir/unclaimed-category-1a.m" "unclaimed-category-1a.o" object $add_flags ]
+if ![string match "" $lines] then {
+ fail "unclaimed-category-1a.o"
+} else {
+ dg-runtest "$srcdir/$subdir/unclaimed-category-1.m" "unclaimed-category-1a.o" "-fnext-runtime"
+ file delete unclaimed-category-1a.o
+}
+}
+
+#
+# load-category-1 test
+#
+# This test is similar to the one above. We compile load-category-1.m
+# and load-category-1a.m, link them together, and execute the result.
+set add_flags "additional_flags=-I${srcdir}/../../libobjc"
+lappend add_flags "additional_flags=-fgnu-runtime"
+set lines [objc_target_compile "$srcdir/$subdir/load-category-1a.m" "load-category-1a.o" object $add_flags ]
+if ![string match "" $lines] then {
+ fail "load-category-1a.o"
+} else {
+ dg-runtest "$srcdir/$subdir/load-category-1.m" "load-category-1a.o" "-I${srcdir}/../../libobjc -fgnu-runtime"
+ file delete load-category-1a.o
+}
+
+if [istarget "*-*-darwin*" ] {
+set add_flags ""
+lappend add_flags "additional_flags=-fnext-runtime"
+set lines [objc_target_compile "$srcdir/$subdir/load-category-1a.m" "load-category-1a.o" object $add_flags ]
+if ![string match "" $lines] then {
+ fail "load-category-1a.o"
+} else {
+ dg-runtest "$srcdir/$subdir/load-category-1.m" "load-category-1a.o" "-fnext-runtime"
+ file delete load-category-1a.o
+}
+}
+
+#
+# load-category-2 test
+#
+# This test is similar to the one above. We compile load-category-2.m
+# and load-category-2a.m, link them together, and execute the result.
+set add_flags "additional_flags=-I${srcdir}/../../libobjc"
+lappend add_flags "additional_flags=-fgnu-runtime"
+set lines [objc_target_compile "$srcdir/$subdir/load-category-2a.m" "load-category-2a.o" object $add_flags ]
+if ![string match "" $lines] then {
+ fail "load-category-2a.o"
+} else {
+ dg-runtest "$srcdir/$subdir/load-category-2.m" "load-category-2a.o" "-I${srcdir}/../../libobjc -fgnu-runtime"
+ file delete load-category-2a.o
+}
+
+if [istarget "*-*-darwin*" ] {
+set add_flags ""
+lappend add_flags "additional_flags=-fnext-runtime"
+set lines [objc_target_compile "$srcdir/$subdir/load-category-2a.m" "load-category-2a.o" object $add_flags ]
+if ![string match "" $lines] then {
+ fail "load-category-2a.o"
+} else {
+ dg-runtest "$srcdir/$subdir/load-category-2.m" "load-category-2a.o" "-fnext-runtime"
+ file delete load-category-2a.o
+}
+}
+
+#
+# load-category-3 test
+#
+# This test is similar to the one above. We compile load-category-3.m
+# and load-category-3a.m, link them together, and execute the result.
+set add_flags "additional_flags=-I${srcdir}/../../libobjc"
+lappend add_flags "additional_flags=-fgnu-runtime"
+set lines [objc_target_compile "$srcdir/$subdir/load-category-3a.m" "load-category-3a.o" object $add_flags ]
+if ![string match "" $lines] then {
+ fail "load-category-3a.o"
+} else {
+ dg-runtest "$srcdir/$subdir/load-category-3.m" "load-category-3a.o" "-I${srcdir}/../../libobjc -fgnu-runtime"
+ file delete load-category-3a.o
+}
+
+if [istarget "*-*-darwin*" ] {
+set add_flags ""
+lappend add_flags "additional_flags=-fnext-runtime"
+set lines [objc_target_compile "$srcdir/$subdir/load-category-3a.m" "load-category-3a.o" object $add_flags ]
+if ![string match "" $lines] then {
+ fail "load-category-3a.o"
+} else {
+ dg-runtest "$srcdir/$subdir/load-category-3.m" "load-category-3a.o" "-fnext-runtime"
+ file delete load-category-3a.o
+}
+}
+
+# All done.
+dg-finish
+
diff --git a/gcc/testsuite/objc.dg/special/unclaimed-category-1.h b/gcc/testsuite/objc.dg/special/unclaimed-category-1.h
new file mode 100644
index 000000000..bf507a788
--- /dev/null
+++ b/gcc/testsuite/objc.dg/special/unclaimed-category-1.h
@@ -0,0 +1,29 @@
+/* Contributed by Nicola Pero - Fri Dec 14 08:36:00 GMT 2001 */
+
+/* Test loading unclaimed categories - categories of a class defined
+ separately from the class itself. */
+
+@interface TestClass
+{
+#ifdef __OBJC2__
+ Class isa;
+#else
+ id isa;
+#endif
+}
+- (int)D;
+@end
+
+@interface TestClass (A)
+- (int)A;
+@end
+
+@interface TestClass (B)
+- (int)B;
+@end
+
+@interface TestClass (C)
+- (int)C;
+@end
+
+
diff --git a/gcc/testsuite/objc.dg/special/unclaimed-category-1.m b/gcc/testsuite/objc.dg/special/unclaimed-category-1.m
new file mode 100644
index 000000000..88e3d8ea7
--- /dev/null
+++ b/gcc/testsuite/objc.dg/special/unclaimed-category-1.m
@@ -0,0 +1,75 @@
+/* Contributed by Nicola Pero - Fri Dec 14 08:36:00 GMT 2001 */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+#include <objc/objc.h>
+#ifndef __NEXT_RUNTIME__
+#include <objc/objc-api.h>
+#endif
+#include "../../objc-obj-c++-shared/next-mapping.h"
+
+extern void abort (void);
+
+/* Test loading unclaimed categories - categories of a class defined
+ separately from the class itself. */
+
+
+/* unclaimed-category-1.m contains only the class definition but not
+ the categories. unclaimed-category-1a.m contains only the
+ categories of the class, but not the class itself. We want to
+ check that the runtime can load the class from one module (file)
+ and the categories from another module (file). */
+
+#include "unclaimed-category-1.h"
+
+@implementation TestClass
+- (int)D
+{
+ return 4;
+}
+#ifdef __NEXT_RUNTIME__
++ initialize { return self; }
+#endif
+@end
+
+
+int main (void)
+{
+ TestClass *test;
+ Class testClass;
+
+ testClass = objc_get_class ("TestClass");
+ if (testClass == Nil)
+ {
+ abort ();
+ }
+
+ test = (TestClass *)(class_create_instance (testClass));
+ if (test == nil)
+ {
+ abort ();
+ }
+
+ if ([test A] != 1)
+ {
+ abort ();
+ }
+
+ if ([test B] != 2)
+ {
+ abort ();
+ }
+
+ if ([test C] != 3)
+ {
+ abort ();
+ }
+
+
+ if ([test D] != 4)
+ {
+ abort ();
+ }
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/special/unclaimed-category-1a.m b/gcc/testsuite/objc.dg/special/unclaimed-category-1a.m
new file mode 100644
index 000000000..4fb2d4619
--- /dev/null
+++ b/gcc/testsuite/objc.dg/special/unclaimed-category-1a.m
@@ -0,0 +1,29 @@
+/* Contributed by Nicola Pero - Fri Dec 14 08:36:00 GMT 2001 */
+
+/* Test loading unclaimed categories - categories of a class defined
+ separately from the class itself. */
+
+#include "unclaimed-category-1.h"
+
+@implementation TestClass (A)
+- (int)A
+{
+ return 1;
+}
+@end
+
+@implementation TestClass (B)
+- (int)B
+{
+ return 2;
+}
+@end
+
+@implementation TestClass (C)
+- (int)C
+{
+ return 3;
+}
+@end
+
+
diff --git a/gcc/testsuite/objc.dg/stabs-1.m b/gcc/testsuite/objc.dg/stabs-1.m
new file mode 100644
index 000000000..f1f2e8e12
--- /dev/null
+++ b/gcc/testsuite/objc.dg/stabs-1.m
@@ -0,0 +1,18 @@
+/* Check if the final SO STABS record goes into the .text section. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com> */
+
+/* { dg-do compile } */
+/* { dg-skip-if "No stabs" { mmix-*-* *-*-aix* alpha*-*-* hppa*64*-*-* ia64-*-* } { "*" } { "" } } */
+/* { dg-options "-gstabs" } */
+
+@interface MyClass
++ newWithArg: arg;
+@end
+
+@implementation MyClass
++ newWithArg: arg
+{
+}
+@end
+
+/* { dg-final { scan-assembler "(.SUBSPA.*\[\$\]CODE\[\$\]|.text\"?)\n\t.stabs.*100,0,0,(\[\.\$\])?L?L\[\$\]?etext\[0-9\]*\n(\[\.\$\])?L?L\[\$\]?etext" } } */
diff --git a/gcc/testsuite/objc.dg/static-1.m b/gcc/testsuite/objc.dg/static-1.m
new file mode 100644
index 000000000..d62015859
--- /dev/null
+++ b/gcc/testsuite/objc.dg/static-1.m
@@ -0,0 +1,33 @@
+/* Test out static (non-heap) allocations of ObjC class instances.
+ These should elicit errors. */
+/* Developed by Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-do compile } */
+
+@interface Object {
+ struct objc_class *isa;
+}
+@end
+
+@compatibility_alias MyObject Object;
+
+@interface Foo: Object {
+ int a;
+ Object *b;
+ Object c; /* { dg-error "statically allocated instance of Objective-C class .Object." } */
+}
+@end
+
+@compatibility_alias MyFoo Foo;
+
+typedef Foo FooAlias1;
+typedef FooAlias1 FooAlias2;
+typedef Object ObjectAlias1;
+typedef struct Object ObjectAlias2;
+Object staticObject1; /* { dg-error "statically allocated instance of Objective-C class .Object." } */
+struct Object staticObject2; /* { dg-error "statically allocated instance of Objective-C class .Object." } */
+static ObjectAlias1 staticObject3; /* { dg-error "statically allocated instance of Objective-C class .Object." } */
+FooAlias1 staticFoo1; /* { dg-error "statically allocated instance of Objective-C class .Foo." } */
+extern FooAlias2 externFoo1; /* { dg-error "statically allocated instance of Objective-C class .Foo." } */
+static Foo staticFoo2; /* { dg-error "statically allocated instance of Objective-C class .Foo." } */
+MyObject staticMyObject1; /* { dg-error "statically allocated instance of Objective-C class .Object." } */
+MyFoo staticMyFoo1; /* { dg-error "statically allocated instance of Objective-C class .Foo." } */
diff --git a/gcc/testsuite/objc.dg/stret-1.m b/gcc/testsuite/objc.dg/stret-1.m
new file mode 100644
index 000000000..cae7d6dd6
--- /dev/null
+++ b/gcc/testsuite/objc.dg/stret-1.m
@@ -0,0 +1,65 @@
+/* Test for handling of struct-returning methods. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+#include "../objc-obj-c++-shared/Object1.h"
+
+extern void abort(void);
+#define CHECK_IF(expr) if(!(expr)) abort()
+
+struct astruct {
+ float a, b;
+} globa = { 1.0, 2.0 };
+
+struct bstruct {
+ float a, b, c, d, e, f;
+} globb = { 1, 2, 3, 4, 5, 6 };
+
+@interface foo : Object
+- (struct astruct) stret;
+- (struct bstruct) stretb;
+@end
+
+@implementation foo : Object
+- (struct astruct) stret { return globa; }
+- (struct bstruct) stretb { return globb; }
+@end
+
+@interface bar: foo
+- (struct astruct) stret;
+- (struct bstruct) stretb;
+@end
+
+@implementation bar
+- (struct astruct) stret { struct astruct a = [super stret]; a.b = 77; return a; }
+- (struct bstruct) stretb { struct bstruct b = [super stretb]; b.e = 99; return b; }
+@end
+
+int main(void)
+{
+ foo *obj = [foo new];
+ bar *obj2 = [bar new];
+ struct astruct loc, loc2;
+ struct bstruct locb, locb2;
+
+ loc = [obj stret];
+ CHECK_IF(loc.a == 1.0 && loc.b == 2.0);
+
+ locb = [obj stretb];
+ CHECK_IF(locb.f == 6 && locb.c == 3);
+ CHECK_IF(locb.e == 5 && locb.b == 2);
+ CHECK_IF(locb.d == 4 && locb.a == 1);
+
+ loc2 = [obj2 stret];
+ CHECK_IF(loc2.a == 1.0 && loc2.b == 77);
+
+ locb2 = [obj2 stretb];
+ CHECK_IF(locb2.f == 6 && locb2.c == 3);
+ CHECK_IF(locb2.e == 99 && locb2.b == 2);
+ CHECK_IF(locb2.d == 4 && locb2.a == 1);
+
+ return 0;
+}
+
+#include "../objc-obj-c++-shared/Object1-implementation.h"
diff --git a/gcc/testsuite/objc.dg/stret-2.m b/gcc/testsuite/objc.dg/stret-2.m
new file mode 100644
index 000000000..e0fd8c2d8
--- /dev/null
+++ b/gcc/testsuite/objc.dg/stret-2.m
@@ -0,0 +1,49 @@
+/* Test for handling of struct-returning methods
+ for the Mac OS X ("NeXT") runtime (which uses specialized entry
+ points). */
+/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-do compile { target *-*-darwin* } } */
+/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */
+/* { dg-require-effective-target ilp32 } */
+
+#include "../objc-obj-c++-shared/Object1.h"
+
+struct astruct {
+ float a, b;
+ char c;
+} glob = { 1.0, 2.0, 'a' };
+
+struct bstruct {
+ float a, b, c, d, e, f;
+} globb = { 1, 2, 3, 4, 5, 6 };
+
+@interface foo : Object
+- (struct astruct) stret;
+- (struct bstruct) stretb;
+@end
+
+@implementation foo : Object
+- (struct astruct) stret { return glob; }
+- (struct bstruct) stretb { return globb; }
+@end
+
+@interface bar: foo
+- (struct astruct) stret;
+- (struct bstruct) stretb;
+@end
+
+@implementation bar
+- (struct astruct) stret { return [super stret]; }
+- (struct bstruct) stretb { return [super stretb]; }
+@end
+
+struct astruct afunc(foo *foo_obj) {
+ return [foo_obj stret];
+}
+
+/* { dg-final { scan-assembler "objc_msgSend_stret" } } */
+/* { dg-final { scan-assembler "objc_msgSendSuper_stret" } } */
+
+/* { dg-final { scan-assembler-not "objc_msgSend\[^_S\]" } } */
+/* { dg-final { scan-assembler-not "objc_msgSendSuper\[^_\]" } } */
+
diff --git a/gcc/testsuite/objc.dg/strings/const-cfstring-2.m b/gcc/testsuite/objc.dg/strings/const-cfstring-2.m
new file mode 100644
index 000000000..14ae68c6c
--- /dev/null
+++ b/gcc/testsuite/objc.dg/strings/const-cfstring-2.m
@@ -0,0 +1,27 @@
+/* Test the -Wnonportable-cfstrings option, which should give
+ warnings if non-ASCII characters are embedded in constant
+ CFStrings. This will only work on MacOS X 10.2 and later. */
+/* Developed by Ziemowit Laski <zlaski@apple.com>. */
+
+/* So far, CFString is darwin-only. */
+/* { dg-do compile { target *-*-darwin* } } */
+/* { dg-skip-if "NeXT only" { *-*-* } { "-fgnu-runtime" } { "" } } */
+/* { dg-options "-mconstant-cfstrings -Wnonportable-cfstrings" } */
+
+#import <Foundation/NSString.h>
+#import <CoreFoundation/CFString.h>
+
+#ifndef __CONSTANT_CFSTRINGS__
+#error The -fconstant-cfstrings option is not functioning properly
+#endif
+
+void foo(void) {
+ NSString *s1 = @"Compile-time string literal";
+ CFStringRef s2 = CFSTR("Compile-time string literal");
+ NSString *s3 = @"Non-ASCII literal - \222"; /* { dg-warning "non-ASCII character in CFString literal" } */
+ CFStringRef s4 = CFSTR("\222 - Non-ASCII literal"); /* { dg-warning "non-ASCII character in CFString literal" } */
+ CFStringRef s5 = CFSTR("Non-ASCII (\222) literal"); /* { dg-warning "non-ASCII character in CFString literal" } */
+ NSString *s6 = @"\0Embedded NUL"; /* { dg-warning "embedded NUL in CFString literal" } */
+ CFStringRef s7 = CFSTR("Embedded \0NUL"); /* { dg-warning "embedded NUL in CFString literal" } */
+ CFStringRef s8 = CFSTR("Embedded NUL\0"); /* { dg-warning "embedded NUL in CFString literal" } */
+}
diff --git a/gcc/testsuite/objc.dg/strings/const-cfstring-5.m b/gcc/testsuite/objc.dg/strings/const-cfstring-5.m
new file mode 100644
index 000000000..13cb78957
--- /dev/null
+++ b/gcc/testsuite/objc.dg/strings/const-cfstring-5.m
@@ -0,0 +1,26 @@
+/* Test if constant CFStrings may be passed back as ObjC strings. */
+/* Author: Ziemowit Laski */
+
+/* So far, CFString is darwin-only. */
+/* { dg-do compile { target *-*-darwin* } } */
+/* { dg-skip-if "NeXT only" { *-*-* } { "-fgnu-runtime" } { "" } } */
+/* { dg-options "-mconstant-cfstrings" } */
+
+#include <objc/Object.h>
+
+@interface Foo: Object {
+ char *cString;
+ unsigned int len;
+}
++ (Foo *)description;
+@end
+
+@interface Bar: Object
++ (Foo *) getString: (int) which;
+@end
+
+@implementation Bar
++ (Foo *) getString: (int) which {
+ return which? [Foo description]: @"Hello";
+}
+@end
diff --git a/gcc/testsuite/objc.dg/strings/const-str-1.m b/gcc/testsuite/objc.dg/strings/const-str-1.m
new file mode 100644
index 000000000..754c99bf1
--- /dev/null
+++ b/gcc/testsuite/objc.dg/strings/const-str-1.m
@@ -0,0 +1,25 @@
+/* Test errors for constant strings. */
+/* { dg-do compile } */
+/* { dg-options "-mno-constant-cfstrings" { target *-*-darwin* } } */
+
+#ifdef __cplusplus
+extern void baz(...);
+#endif
+
+void foo()
+{
+ baz(@"hiya"); /* { dg-error "annot find interface declaration" } */
+}
+
+@interface NXConstantString
+{
+ void *isa;
+ char *str;
+ int len;
+}
+@end
+
+void bar()
+{
+ baz(@"howdah");
+}
diff --git a/gcc/testsuite/objc.dg/strings/const-str-12.m b/gcc/testsuite/objc.dg/strings/const-str-12.m
new file mode 100644
index 000000000..930590186
--- /dev/null
+++ b/gcc/testsuite/objc.dg/strings/const-str-12.m
@@ -0,0 +1,16 @@
+/* { dg-options "-Wall -funit-at-a-time" } */
+/* { dg-do compile } */
+/* PR objc/27438, make sure that the decl produced by the front-end
+ does not cause a warning to be produced. */
+/* { dg-skip-if "" { *-*-* } { "-fnext-runtime" } { "" } } */
+
+@interface NXConstantString
+{
+ void *isa;
+ const char * const nxcsptr;
+ const unsigned int nxcslen;
+}
+@end
+NXConstantString *a = @"NSInconsistentArchiveException"; /* { dg-bogus "defined but not used" } */
+
+
diff --git a/gcc/testsuite/objc.dg/strings/const-str-12b.m b/gcc/testsuite/objc.dg/strings/const-str-12b.m
new file mode 100644
index 000000000..430ab5db2
--- /dev/null
+++ b/gcc/testsuite/objc.dg/strings/const-str-12b.m
@@ -0,0 +1,28 @@
+/* Test if ObjC types play nice in conditional expressions. */
+/* Author: Ziemowit Laski */
+
+/* { dg-do compile } */
+/* { dg-options "-fconstant-string-class=Foo" } */
+/* { dg-options "-mno-constant-cfstrings -fconstant-string-class=Foo" { target *-*-darwin* } } */
+
+#include <objc/Object.h>
+#include "../../objc-obj-c++-shared/objc-test-suite-types.h"
+
+@interface Foo: Object {
+ char *cString;
+ unsigned int len;
+}
++ (id)description;
+@end
+
+@interface Bar: Object
++ (Foo *) getString: (int) which;
+@end
+
+TNS_STRING_REF_T _FooClassReference; /* Only used by NeXT. */
+
+@implementation Bar
++ (Foo *) getString: (int) which {
+ return which? [Foo description]: @"Hello";
+}
+@end
diff --git a/gcc/testsuite/objc.dg/strings/const-str-2.m b/gcc/testsuite/objc.dg/strings/const-str-2.m
new file mode 100644
index 000000000..49ab06304
--- /dev/null
+++ b/gcc/testsuite/objc.dg/strings/const-str-2.m
@@ -0,0 +1,8 @@
+/* Test the -fconstant-string-class flag error. */
+/* { dg-do compile } */
+/* { dg-options "-fconstant-string-class=" { target *-*-* } } */
+/* { dg-options "-mno-constant-cfstrings -fconstant-string-class=" { target *-*-darwin* } } */
+
+{ dg-error "no class name specified|missing argument" "" { target *-*-* } 0 }
+
+void foo () {}
diff --git a/gcc/testsuite/objc.dg/strings/const-str-5.m b/gcc/testsuite/objc.dg/strings/const-str-5.m
new file mode 100644
index 000000000..42071767a
--- /dev/null
+++ b/gcc/testsuite/objc.dg/strings/const-str-5.m
@@ -0,0 +1,28 @@
+/* Positive test case for constant string layout. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
+
+/* { dg-do compile } */
+/* { dg-options "-fconstant-string-class=MyConstantString" } */
+/* { dg-options "-mno-constant-cfstrings -fconstant-string-class=MyConstantString" { target *-*-darwin* } } */
+
+@interface MyBase {
+ const char *p;
+}
+@end
+
+@interface MyConstantString: MyBase {
+ union {
+ void *u;
+ unsigned char *c;
+ } _contents;
+ unsigned int _count;
+}
+@end
+
+/* The NeXT runtime initializes the 'isa' pointer of string constants at
+ compile time. */
+#ifdef __NEXT_RUNTIME__
+extern void *_MyConstantStringClassReference;
+#endif
+
+MyConstantString *str = @"Hello";
diff --git a/gcc/testsuite/objc.dg/strings/const-str-6.m b/gcc/testsuite/objc.dg/strings/const-str-6.m
new file mode 100644
index 000000000..fca7643af
--- /dev/null
+++ b/gcc/testsuite/objc.dg/strings/const-str-6.m
@@ -0,0 +1,28 @@
+/* Negative test case for constant string layout. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
+
+/* { dg-do compile } */
+/* { dg-options "-fconstant-string-class=MyConstantString" } */
+/* { dg-options "-mno-constant-cfstrings -fconstant-string-class=MyConstantString" { target *-*-darwin* } } */
+
+@interface MyBase {
+ char p;
+}
+@end
+
+@interface MyConstantString: MyBase {
+ union {
+ void *u;
+ unsigned char *c;
+ } _contents;
+ char _count;
+}
+@end
+
+/* The NeXT runtime initializes the 'isa' pointer of string constants at
+ compile time. */
+#ifdef __NEXT_RUNTIME__
+extern void *_MyConstantStringClassReference;
+#endif
+
+MyConstantString *str = @"Hello"; /* { dg-error "interface .MyConstantString. does not have valid constant string layout" } */
diff --git a/gcc/testsuite/objc.dg/strings/strings-1.m b/gcc/testsuite/objc.dg/strings/strings-1.m
new file mode 100644
index 000000000..fc3f21185
--- /dev/null
+++ b/gcc/testsuite/objc.dg/strings/strings-1.m
@@ -0,0 +1,33 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+#include "../../objc-obj-c++-shared/Object1.h"
+#include "../../objc-obj-c++-shared/next-mapping.h"
+#ifndef __NEXT_RUNTIME__
+#include <objc/NXConstStr.h>
+#endif
+
+/* The following are correct. */
+id test_valid1 = @"test";
+id test_valid2 = @"te" @"st";
+id test_valid3 = @"te" @"s" @"t";
+id test_valid4 = @ "t" @ "e" @ "s" @ "t";
+
+/* The following are accepted too; you can concat an ObjC string to a
+ C string, the result being an ObjC string. */
+id test_valid5 = @"te" "st";
+id test_valid6 = @"te" "s" @"t";
+id test_valid7 = @"te" @"s" "t";
+
+/* The following are not correct. */
+id test_invalid1 = @@"test"; /* { dg-error "stray .@. in program" } */
+const char *test_invalid2 = "test"@; /* { dg-error "stray .@. in program" } */
+const char *test_invalid3 = "test"@@; /* { dg-error "stray .@. in program" } */
+const char *test_invalid4 = "te" @"st"; /* { dg-error "expected" } */
+id test_invalid5 = @"te" @@"st"; /* { dg-error "repeated .@. before Objective-C string" } */
+id test_invalid6 = @@"te" @"st"; /* { dg-error "stray .@. in program" } */
+id test_invalid7 = @"te" @"s" @@"t"; /* { dg-error "repeated .@. before Objective-C string" } */
+id test_invalid8 = @"te" @@"s" @"t"; /* { dg-error "repeated .@. before Objective-C string" } */
+id test_invalid9 = @"te" @"s" @"t" @; /* { dg-error "stray .@. in program" } */
+id test_invalidA = @"te" @ st; /* { dg-error "stray .@. in program" } */
+ /* { dg-error "expected" "" { target *-*-* } 32 } */
diff --git a/gcc/testsuite/objc.dg/strings/strings-2.m b/gcc/testsuite/objc.dg/strings/strings-2.m
new file mode 100644
index 000000000..b07ac0f78
--- /dev/null
+++ b/gcc/testsuite/objc.dg/strings/strings-2.m
@@ -0,0 +1,67 @@
+/* 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" } { "" } } */
+/* { dg-options "-fconstant-string-class=MyTestString" } */
+/* { dg-options "-mno-constant-cfstrings -fconstant-string-class=MyTestString" { target *-*-darwin* } } */
+
+#include "../../objc-obj-c++-shared/objc-test-suite-types.h"
+
+#include <stdlib.h> /* For abort() */
+
+@interface MyTestString
+{
+ void *dummy_class_ptr;
+ char *string;
+ unsigned int len;
+}
++ initialize;
+/* All strings should contain the C string 'test'. Call -check to
+ test that this is true. */
+- (void) check;
+@end
+
+@implementation MyTestString
++ initialize {return self;}
+
+- (void) check
+{
+ if (len != 4 || string[0] != 't' || string[1] != 'e'
+ || string[2] != 's' || string[3] != 't' || string[4] != '\0')
+ abort ();
+}
+@end
+
+TNS_STRING_REF_T _MyTestStringClassReference; /* Only used by NeXT. */
+
+int main (void)
+{
+ MyTestString *test_valid1 = @"test";
+ MyTestString *test_valid2 = @"te" @"st";
+ MyTestString *test_valid3 = @"te" @"s" @"t";
+ MyTestString *test_valid4 = @ "t" @ "e" @ "s" @ "t";
+ MyTestString *test_valid5 = @ "t" "e" "s" "t";
+ MyTestString *test_valid6 = @ "t" "e" "s" @ "t";
+
+ [test_valid1 check];
+ [test_valid2 check];
+ [test_valid3 check];
+ [test_valid4 check];
+ [test_valid5 check];
+ [test_valid6 check];
+
+ return 0;
+}
+
+#ifdef __NEXT_RUNTIME__
+/* The MyTestString metaclass will need to be initialized before we can
+ send messages to strings. */
+#include <string.h>
+
+void testsuite_mytest_string_init (void) __attribute__((constructor));
+void testsuite_mytest_string_init (void) {
+ memcpy (&_MyTestStringClassReference,
+ objc_getClass ("MyTestString"),
+ sizeof (_MyTestStringClassReference));
+}
+#endif \ No newline at end of file
diff --git a/gcc/testsuite/objc.dg/strings/strings.exp b/gcc/testsuite/objc.dg/strings/strings.exp
new file mode 100644
index 000000000..823c2871a
--- /dev/null
+++ b/gcc/testsuite/objc.dg/strings/strings.exp
@@ -0,0 +1,46 @@
+# String tests that only need to run at default optimization.
+
+# Copyright (C) 2010 Free Software Foundation, Inc.
+#
+# This file is part of GCC.
+#
+# GCC 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, or (at your option)
+# any later version.
+#
+# GCC 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 GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+# Load support procs.
+
+load_lib objc-dg.exp
+
+# If a testcase doesn't have special options, use these.
+global DEFAULT_CFLAGS
+if ![info exists DEFAULT_CFLAGS] then {
+ set DEFAULT_CFLAGS ""
+}
+
+# Initialize `dg'.
+dg-init
+
+# Gather a list of all tests.
+set tests [lsort [glob -nocomplain $srcdir/$subdir/*.m]]
+
+# Main loop.
+dg-runtest $tests "-fgnu-runtime" $DEFAULT_CFLAGS
+
+# darwin targets can also run code with the NeXT runtime.
+if [istarget "*-*-darwin*" ] {
+ dg-runtest $tests "-fnext-runtime" $DEFAULT_CFLAGS
+}
+
+# All done.
+dg-finish
diff --git a/gcc/testsuite/objc.dg/stubify-1.m b/gcc/testsuite/objc.dg/stubify-1.m
new file mode 100644
index 000000000..91bf73a14
--- /dev/null
+++ b/gcc/testsuite/objc.dg/stubify-1.m
@@ -0,0 +1,35 @@
+/* All calls must be properly stubified. Complain about any "call
+ _objc_msgSend<end-of-line>" without the $stub suffix. */
+
+/* { dg-do compile { target *-*-darwin* } } */
+/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-options "-Os -mdynamic-no-pic -mmacosx-version-min=10.4" } */
+
+typedef struct objc_object { } *id ;
+int x = 41 ;
+extern id objc_msgSend(id self, char * op, ...);
+extern int bogonic (int, int, int) ;
+@interface Document {}
+- (Document *) window;
+- (Document *) class;
+- (Document *) close;
+@end
+@implementation Document
+- (Document *) class { }
+- (Document *) close { }
+- (Document *) window { }
+- (void)willEndCloseSheet:(void *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo {
+ [[self window] close];
+ ((void (*)(id, char *, int))objc_msgSend)([self class], (char *)contextInfo, 1);
+ ((void (*)(id, char *, int))bogonic)([self class], (char *)contextInfo, 1);
+ bogonic (3, 4, 5);
+ x++;
+}
+@end
+
+/* { dg-final { scan-assembler-not "\(bl|call\)\[ \t\]+_objc_msgSend\n" } } */
+/* { dg-final { scan-assembler "\(bl|call\)\[ \t\]+L_objc_msgSend\\\$stub\n" } } */
+/* { dg-final { scan-assembler-not "\(bl|call\)\[ \t\]+_bogonic\n" } } */
+/* { dg-final { scan-assembler "\(bl|call\)\[ \t\]+L_bogonic\\\$stub\n" } } */
+/* { dg-final { scan-assembler-not "\\\$non_lazy_ptr" } } */
diff --git a/gcc/testsuite/objc.dg/stubify-2.m b/gcc/testsuite/objc.dg/stubify-2.m
new file mode 100644
index 000000000..eaf4b964e
--- /dev/null
+++ b/gcc/testsuite/objc.dg/stubify-2.m
@@ -0,0 +1,33 @@
+/* All calls must be properly stubified, m32 only. */
+/* Testcase extracted from TextEdit:Document.m. */
+
+/* { dg-do compile { target powerpc*-*-darwin* } } */
+/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-options "-mdynamic-no-pic -fdump-rtl-jump -mmacosx-version-min=10.4" } */
+
+typedef struct objc_object { } *id ;
+int x = 41 ;
+extern id objc_msgSend(id self, char * op, ...);
+extern int bogonic (int, int, int) ;
+@interface Document {}
+- (Document *) window;
+- (Document *) class;
+- (Document *) close;
+@end
+@implementation Document
+- (Document *) class { }
+- (Document *) close { }
+- (Document *) window { }
+- (void)willEndCloseSheet:(void *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo {
+ [[self window] close];
+ ((void (*)(id, char *, int))objc_msgSend)([self class], (char *)contextInfo, 1);
+ ((void (*)(id, char *, int))bogonic)([self class], (char *)contextInfo, 1);
+ bogonic (3, 4, 5);
+ x++;
+}
+@end
+
+/* Any symbol_ref of an un-stubified objc_msgSend is an error; look
+ for "objc_msgSend" in quotes, without the $stub suffix. */
+/* { dg-final { scan-rtl-dump-not "symbol_ref.*\"objc_msgSend\"" "jump" } } */
diff --git a/gcc/testsuite/objc.dg/super-class-1.m b/gcc/testsuite/objc.dg/super-class-1.m
new file mode 100644
index 000000000..9c8ab86d3
--- /dev/null
+++ b/gcc/testsuite/objc.dg/super-class-1.m
@@ -0,0 +1,5 @@
+/* Test super classes. */
+/* { dg-do compile } */
+
+@interface class0 : supclass0
+@end /* { dg-error "annot find interface declaration for .*, superclass" } */
diff --git a/gcc/testsuite/objc.dg/super-class-2.m b/gcc/testsuite/objc.dg/super-class-2.m
new file mode 100644
index 000000000..144ea81b5
--- /dev/null
+++ b/gcc/testsuite/objc.dg/super-class-2.m
@@ -0,0 +1,44 @@
+/* Test calling super from within a category class method. */
+/* Author: Ziemowit Laski <zlaski@apple.com> */
+/* { dg-do compile } */
+
+typedef struct objc_object { struct objc_class *isa; } *id;
+
+@interface NSObject
++ (int) test_func0;
+@end
+@interface NSMenuItem: NSObject
++ (int) test_func0;
+@end
+
+@implementation NSObject
++ (int) test_func0
+{}
+@end
+
+@implementation NSMenuItem
++ (int) test_func0
+{
+ return [super test_func0];
+}
+@end
+
+@interface NSObject (Test)
++ (int) test_func;
+@end
+
+@implementation NSObject (Test)
++ (int) test_func
+{}
+@end
+
+@interface NSMenuItem (Test)
++ (int) test_func;
+@end
+
+@implementation NSMenuItem (Test)
++ (int) test_func
+{
+ return [super test_func]; /* { dg-bogus "dereferencing pointer to incomplete type" } */
+}
+@end
diff --git a/gcc/testsuite/objc.dg/super-class-3.m b/gcc/testsuite/objc.dg/super-class-3.m
new file mode 100644
index 000000000..fc74871db
--- /dev/null
+++ b/gcc/testsuite/objc.dg/super-class-3.m
@@ -0,0 +1,46 @@
+/* Ensure that the compiler does not emit spurious extern declarations named '_Foo', where 'Foo'
+ is an ObjC class name. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+#include "../objc-obj-c++-shared/Object1.h"
+
+#include <stdlib.h>
+#define CHECK_IF(expr) if(!(expr)) abort()
+
+@interface _Child: Object
++ (int) flashCache;
+@end
+
+@interface Child: _Child
++ (int) flushCache1;
+@end
+
+@interface Child (Categ)
++ (int) flushCache2;
+@end
+
+int _Object = 23; /* Should not conflict with @interface Object. */
+
+@implementation _Child
++ (int) flashCache { return 12 + _Object; }
+@end
+
+@implementation Child
++ (int) flushCache1 { return 7 + [super flashCache]; }
+@end
+
+@implementation Child (Categ)
++ (int) flushCache2 { return 9 + [super flashCache]; }
+@end
+
+int main(void) {
+ CHECK_IF([_Child flashCache] == 35);
+ CHECK_IF([Child flushCache1] == 42);
+ CHECK_IF([Child flushCache2] == 44);
+
+ return 0;
+}
+
+#include "../objc-obj-c++-shared/Object1-implementation.h"
diff --git a/gcc/testsuite/objc.dg/super-class-4.m b/gcc/testsuite/objc.dg/super-class-4.m
new file mode 100644
index 000000000..a5ff9088b
--- /dev/null
+++ b/gcc/testsuite/objc.dg/super-class-4.m
@@ -0,0 +1,34 @@
+/* Bail out gracefully if attempting to derive from a class that has only been
+ forward-declared (via @class). Conversely, @compatibility_alias declarations
+ should be traversed to find the @interface. */
+/* { dg-do compile } */
+
+#include "../objc-obj-c++-shared/Object1.h"
+
+@class MyWpModule;
+
+@compatibility_alias MyObject Object;
+@compatibility_alias FictitiousModule MyWpModule;
+
+@protocol MySelTarget
+- (id) meth1;
+@end
+
+@protocol Img
+- (id) meth2;
+@end
+
+@interface FunnyModule: FictitiousModule <Img> /* { dg-error ".MyWpModule., superclass of .FunnyModule." } */
+- (id) meth2;
+@end
+
+@interface MyProjWpModule : MyWpModule <MySelTarget, Img> /* { dg-error ".MyWpModule., superclass of .MyProjWpModule." } */ {
+ id i1, i2;
+}
+- (id) meth1;
+- (id) meth2;
+@end
+
+@interface AnotherModule: MyObject <MySelTarget>
+- (id) meth1;
+@end
diff --git a/gcc/testsuite/objc.dg/super-dealloc-1.m b/gcc/testsuite/objc.dg/super-dealloc-1.m
new file mode 100644
index 000000000..0ab177bb7
--- /dev/null
+++ b/gcc/testsuite/objc.dg/super-dealloc-1.m
@@ -0,0 +1,46 @@
+/* Check for warnings about missing [super dealloc] calls. */
+/* Author: Ziemowit Laski <zlaski@apple.com> */
+
+/* { dg-do compile } */
+
+@interface Foo {
+ void *isa;
+}
+- (void) dealloc;
+- (void) some_other;
+@end
+
+@interface Bar: Foo {
+ void *casa;
+}
+- (void) dealloc;
+@end
+
+@interface Baz: Bar {
+ void *usa;
+}
+- (void) dealloc;
+@end
+
+@implementation Foo
+- (void) dealloc {
+ isa = 0; /* Should not warn here. */
+}
+- (void) some_other {
+ isa = (void *)-1;
+}
+@end
+
+@implementation Bar
+- (void) dealloc {
+ casa = 0;
+ [super some_other];
+} /* { dg-warning "method possibly missing a .super dealloc. call" } */
+@end
+
+@implementation Baz
+- (void) dealloc {
+ usa = 0;
+ [super dealloc]; /* Should not warn here. */
+}
+@end
diff --git a/gcc/testsuite/objc.dg/super-dealloc-2.m b/gcc/testsuite/objc.dg/super-dealloc-2.m
new file mode 100644
index 000000000..80dcf4950
--- /dev/null
+++ b/gcc/testsuite/objc.dg/super-dealloc-2.m
@@ -0,0 +1,46 @@
+/* Check for warnings about missing [super dealloc] calls. */
+/* Author: Ziemowit Laski <zlaski@apple.com> */
+
+/* { dg-do compile } */
+
+@interface Foo {
+ void *isa;
+}
+- (void) dealloc;
+- (void) some_other;
+@end
+
+@interface Bar: Foo {
+ void *casa;
+}
+- (void) dealloc0;
+@end
+
+@interface Baz: Bar {
+ void *usa;
+}
+- (void) dealloc;
+@end
+
+@implementation Foo
+- (void) dealloc {
+ isa = 0; /* Should not warn here. */
+}
+- (void) some_other {
+ isa = (void *)-1;
+}
+@end
+
+@implementation Bar
+- (void) dealloc0 {
+ casa = 0;
+ [super some_other]; /* Should not warn here. */
+}
+@end
+
+@implementation Baz
+- (void) dealloc {
+ usa = 0;
+ [super dealloc0];
+} /* { dg-warning "method possibly missing a .super dealloc. call" } */
+@end
diff --git a/gcc/testsuite/objc.dg/symtab-1.m b/gcc/testsuite/objc.dg/symtab-1.m
new file mode 100644
index 000000000..936f8d494
--- /dev/null
+++ b/gcc/testsuite/objc.dg/symtab-1.m
@@ -0,0 +1,27 @@
+/* Check if the objc_symtab descriptor is being laid out correctly. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
+
+/* { dg-do compile { target { *-*-darwin* } } } */
+/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */
+
+#include <objc/Object.h>
+
+@interface Base: Object
+- (void)setValues;
+@end
+
+@interface Derived: Base
+- (void)checkValues;
+@end
+
+@implementation Base
+-(void)setValues { }
+@end
+
+@implementation Derived
+-(void)checkValues { }
+@end
+
+/* { dg-final { scan-assembler "L_OBJC_Symbols.*:\n\t.long\t0\n\t.long\t0\n\t.word\t2\n\t.word\t0\n\t.long\tL_OBJC_Class_Derived.*\n\t.long\tL_OBJC_Class_Base.*\n" { target { *86*-*-darwin* && { ! lp64 } } } } } */
+/* { dg-final { scan-assembler "L_OBJC_Symbols.*:\n\t.long\t0\n\t.long\t0\n\t.short\t2\n\t.short\t0\n\t.long\tL_OBJC_Class_Derived.*\n\t.long\tL_OBJC_Class_Base.*\n" { target { powerpc*-*-darwin* && { ! lp64 } } } } } */
+/* { dg-final { scan-assembler-not "L_OBJC_Symbols" { target { *-*-darwin* && { lp64 } } } } } */
diff --git a/gcc/testsuite/objc.dg/sync-1.m b/gcc/testsuite/objc.dg/sync-1.m
new file mode 100644
index 000000000..fe1f65c78
--- /dev/null
+++ b/gcc/testsuite/objc.dg/sync-1.m
@@ -0,0 +1,12 @@
+/* Make sure that @synchronized parses. */
+/* { dg-options "-fobjc-exceptions" } */
+/* { dg-do compile } */
+
+#include "../objc-obj-c++-shared/Object1.h"
+
+void foo(id sem)
+{
+ @synchronized (sem) {
+ return;
+ }
+}
diff --git a/gcc/testsuite/objc.dg/sync-2.m b/gcc/testsuite/objc.dg/sync-2.m
new file mode 100644
index 000000000..c2143a4e9
--- /dev/null
+++ b/gcc/testsuite/objc.dg/sync-2.m
@@ -0,0 +1,35 @@
+/* Make sure that @synchronized parses and a very basic test runs. */
+/* { dg-options "-fobjc-exceptions -fgnu-runtime" } */
+
+#include "../objc-obj-c++-shared/Object1.h"
+
+int main (void)
+{
+ Object *a = [Object new];
+ Object *b = [Object new];
+ Object *c = [Object new];
+
+ /* This single-threaded test just checks that @synchronized() uses a
+ recursive mutex, and that the runtime at least doesn't crash
+ immediately upon finding it.
+ */
+ @synchronized (a)
+ {
+ @synchronized (a)
+ {
+ @synchronized (b)
+ {
+ @synchronized (b)
+ {
+ @synchronized (c)
+ {
+ @synchronized (c)
+ {
+ return 0;
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/gcc/testsuite/objc.dg/sync-3.m b/gcc/testsuite/objc.dg/sync-3.m
new file mode 100644
index 000000000..5cee890bb
--- /dev/null
+++ b/gcc/testsuite/objc.dg/sync-3.m
@@ -0,0 +1,128 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
+/* { dg-options "-fobjc-exceptions" } */
+/* { dg-do compile } */
+
+/* Test that the compiler is checking the argument of @synchronized(),
+ 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;
+
+typedef struct { float x; float y; } point, *point_ptr;
+
+int test (id object)
+{
+ int dummy = 0;
+
+ {
+ int x;
+ @synchronized (x) /* { dg-error ".@synchronized. argument is not an object" } */
+ { dummy++; }
+ }
+
+ {
+ intTypedef x;
+ @synchronized (x) /* { dg-error ".@synchronized. argument is not an object" } */
+ { dummy++; }
+ }
+
+ {
+ int *x;
+ @synchronized (x) /* { dg-error ".@synchronized. argument is not an object" } */
+ { dummy++; }
+ }
+
+ {
+ point x;
+ @synchronized (x) /* { dg-error ".@synchronized. argument is not an object" } */
+ { dummy++; }
+ }
+
+ {
+ point_ptr x;
+ @synchronized (x) /* { dg-error ".@synchronized. argument is not an object" } */
+ { dummy++; }
+ }
+
+ {
+ id x;
+ @synchronized (x) /* Ok */
+ { dummy++; }
+ }
+
+ {
+ id <MyProtocol> x;
+ @synchronized (x) /* Ok */
+ { dummy++; }
+ }
+
+ {
+ MyObject *x;
+ @synchronized (x) /* Ok */
+ { dummy++; }
+ }
+
+ {
+ MyObject <MyProtocol> *x;
+ @synchronized (x) /* Ok */
+ { dummy++; }
+ }
+
+ {
+ static MyObject *x;
+ @synchronized (x) /* Ok */
+ { dummy++; }
+ }
+
+ {
+ MyObjectTypedef *x;
+ @synchronized (x) /* Ok */
+ { dummy++; }
+ }
+
+ {
+ MyObjectTypedef <MyProtocol> *x;
+ @synchronized (x) /* Ok */
+ { dummy++; }
+ }
+
+ {
+ MyObjectPtrTypedef x;
+ @synchronized (x) /* Ok */
+ { dummy++; }
+ }
+
+ {
+ Class x;
+ @synchronized (x) /* Ok */
+ { dummy++; }
+ }
+
+ @synchronized (1) /* { dg-error ".@synchronized. argument is not an object" } */
+ { dummy++; }
+
+ @synchronized ("Test") /* { dg-error ".@synchronized. argument is not an object" } */
+ { dummy++; }
+
+ @synchronized () /* { dg-error "expected expression" } */
+ { dummy++; }
+
+ @synchronized (int) /* { dg-error "expected expression" } */
+ { dummy++; }
+
+ return dummy;
+}
diff --git a/gcc/testsuite/objc.dg/threedotthree-abi-1.m b/gcc/testsuite/objc.dg/threedotthree-abi-1.m
new file mode 100644
index 000000000..5eb00014e
--- /dev/null
+++ b/gcc/testsuite/objc.dg/threedotthree-abi-1.m
@@ -0,0 +1,69 @@
+/* This file tests that things are encoded using the gcc-3.3 ABI which is only
+ used by the NeXT runtime. */
+/* { dg-do run { target *-*-darwin* } } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */
+
+#include "../objc-obj-c++-shared/Protocol1.h"
+#include <stdio.h>
+#include <string.h>
+
+extern void abort();
+
+@protocol CommonProtocol
+
+-(oneway void)methodCall_On:(in bycopy id)someValue_On;
+-(oneway void)methodCall_nO:(bycopy in id)someValue_nO;
+
+-(oneway void)methodCall_Oo:(out bycopy id)someValue_Oo;
+-(oneway void)methodCall_oO:(bycopy out id)someValue_oO;
+
+-(oneway void)methodCall_rn:(in const id)someValue_rn;
+
+-(oneway void)methodCall_oOn:(in bycopy out id)someValue_oOn;
+
+@end
+
+@interface ObjCClass <CommonProtocol>
+{
+
+}
+
+@end
+
+@implementation ObjCClass
+-(oneway void)methodCall_On:(in bycopy id)someValue_On { }
+-(oneway void)methodCall_nO:(bycopy in id)someValue_nO { }
+
+-(oneway void)methodCall_Oo:(out bycopy id)someValue_Oo { }
+-(oneway void)methodCall_oO:(bycopy out id)someValue_oO { }
+
+-(oneway void)methodCall_rn:(in const id)someValue_rn { }
+-(oneway void)methodCall_oOn:(in bycopy out id)someValue_oOn { }
+@end
+
+Protocol *proto = @protocol(CommonProtocol);
+struct objc_method_description *meth;
+
+int main()
+{
+ meth = [proto descriptionForInstanceMethod: @selector(methodCall_On:)];
+ if (strcmp (meth->types, "Vv12@0:4On@8"))
+ abort();
+ meth = [proto descriptionForInstanceMethod: @selector(methodCall_nO:)];
+ if (strcmp (meth->types, "Vv12@0:4nO@8"))
+ abort();
+ meth = [proto descriptionForInstanceMethod: @selector(methodCall_Oo:)];
+ if (strcmp (meth->types, "Vv12@0:4Oo@8"))
+ abort();
+ meth = [proto descriptionForInstanceMethod: @selector(methodCall_oO:)];
+ if (strcmp (meth->types, "Vv12@0:4oO@8"))
+ abort();
+ meth = [proto descriptionForInstanceMethod: @selector(methodCall_rn:)];
+ if (strcmp (meth->types, "Vv12@0:4rn@8"))
+ abort();
+ meth = [proto descriptionForInstanceMethod: @selector(methodCall_oOn:)];
+ if (strcmp (meth->types, "Vv12@0:4oOn@8"))
+ abort();
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/tls/diag-2.m b/gcc/testsuite/objc.dg/tls/diag-2.m
new file mode 100644
index 000000000..4f22281eb
--- /dev/null
+++ b/gcc/testsuite/objc.dg/tls/diag-2.m
@@ -0,0 +1,26 @@
+/* Invalid __thread specifiers. */
+/* { dg-require-effective-target tls } */
+
+__thread extern int g1; /* { dg-error "'__thread' before 'extern'" } */
+__thread static int g2; /* { dg-error "'__thread' before 'static'" } */
+__thread __thread int g3; /* { dg-error "duplicate '__thread'" } */
+typedef __thread int g4; /* { dg-error " '__thread' used with 'typedef'" } */
+
+void foo()
+{
+ __thread int l1; /* { dg-error "implicitly auto and declared '__thread'" } */
+ auto __thread int l2; /* { dg-error "'__thread' used with 'auto'" } */
+ __thread extern int l3; /* { dg-error "'__thread' before 'extern'" } */
+ register __thread int l4; /* { dg-error "'__thread' used with 'register'" } */
+}
+
+__thread void f1 (); /* { dg-error "invalid storage class for function 'f1'" } */
+extern __thread void f2 (); /* { dg-error "invalid storage class for function 'f2'" } */
+static __thread void f3 (); /* { dg-error "invalid storage class for function 'f3'" } */
+__thread void f4 () { } /* { dg-error "function definition declared '__thread'" } */
+
+void bar(__thread int p1); /* { dg-error "(invalid in parameter)|(specified for parameter)" } */
+
+struct A {
+ __thread int i; /* { dg-error "expected specifier-qualifier-list before '__thread'" } */
+};
diff --git a/gcc/testsuite/objc.dg/tls/diag-3.m b/gcc/testsuite/objc.dg/tls/diag-3.m
new file mode 100644
index 000000000..c71f66fb8
--- /dev/null
+++ b/gcc/testsuite/objc.dg/tls/diag-3.m
@@ -0,0 +1,11 @@
+/* Report invalid extern and __thread combinations. */
+/* { dg-require-effective-target tls } */
+
+extern int j; /* { dg-message "previous declaration of 'j' was here" } */
+__thread int j; /* { dg-error "follows non-thread-local" } */
+
+extern __thread int i; /* { dg-message "previous declaration of 'i' was here" } */
+int i; /* { dg-error "follows thread-local" } */
+
+extern __thread int k; /* This is fine. */
+__thread int k;
diff --git a/gcc/testsuite/objc.dg/tls/diag-4.m b/gcc/testsuite/objc.dg/tls/diag-4.m
new file mode 100644
index 000000000..38a5b3aba
--- /dev/null
+++ b/gcc/testsuite/objc.dg/tls/diag-4.m
@@ -0,0 +1,10 @@
+/* Invalid __thread specifiers. */
+/* { dg-require-effective-target tls } */
+
+__thread typedef int g4; /* { dg-error "'__thread' used with 'typedef'" } */
+
+void foo()
+{
+ __thread auto int l2; /* { dg-error "'__thread' used with 'auto'" } */
+ __thread register int l4; /* { dg-error "'__thread' used with 'register'" } */
+}
diff --git a/gcc/testsuite/objc.dg/tls/diag-5.m b/gcc/testsuite/objc.dg/tls/diag-5.m
new file mode 100644
index 000000000..ac78cb295
--- /dev/null
+++ b/gcc/testsuite/objc.dg/tls/diag-5.m
@@ -0,0 +1,4 @@
+/* __thread specifiers on empty declarations. */
+/* { dg-require-effective-target tls } */
+
+__thread struct foo; /* { dg-warning "useless '__thread' in empty declaration" } */
diff --git a/gcc/testsuite/objc.dg/tls/init-1.m b/gcc/testsuite/objc.dg/tls/init-1.m
new file mode 100644
index 000000000..fa4208dce
--- /dev/null
+++ b/gcc/testsuite/objc.dg/tls/init-1.m
@@ -0,0 +1,5 @@
+/* Invalid initializations. */
+/* { dg-require-effective-target tls } */
+
+extern __thread int i;
+int *p = &i; /* { dg-error "initializer element is not constant" } */
diff --git a/gcc/testsuite/objc.dg/tls/init-2.m b/gcc/testsuite/objc.dg/tls/init-2.m
new file mode 100644
index 000000000..882e5f809
--- /dev/null
+++ b/gcc/testsuite/objc.dg/tls/init-2.m
@@ -0,0 +1,14 @@
+/* Invalid initializations. */
+/* { dg-require-effective-target tls } */
+
+extern __thread int i;
+__thread int *p = &i; /* { dg-error "initializer element is not constant" } */
+
+extern int f();
+__thread int j = f(); /* { dg-error "initializer element is not constant" } */
+
+struct S
+{
+ S(); /* { dg-error "expected specifier-qualifier-list before 'S'" } */
+};
+__thread S s; /* { dg-error "unknown type name" } */
diff --git a/gcc/testsuite/objc.dg/tls/tls.exp b/gcc/testsuite/objc.dg/tls/tls.exp
new file mode 100644
index 000000000..5b30a70ff
--- /dev/null
+++ b/gcc/testsuite/objc.dg/tls/tls.exp
@@ -0,0 +1,26 @@
+
+# Load support procs.
+load_lib objc-dg.exp
+
+# If a testcase doesn't have special options, use these.
+global DEFAULT_CFLAGS
+if ![info exists DEFAULT_CFLAGS] then {
+ set DEFAULT_CFLAGS ""
+}
+
+# Initialize `dg'.
+dg-init
+
+# Gather a list of all tests.
+set tests [lsort [glob -nocomplain $srcdir/$subdir/*.m]]
+
+# Main loop.
+dg-runtest $tests "-fgnu-runtime" $DEFAULT_CFLAGS
+
+# darwin targets can also run code with the NeXT runtime.
+if [istarget "*-*-darwin*" ] {
+ dg-runtest $tests "-fnext-runtime" $DEFAULT_CFLAGS
+}
+
+# All done.
+dg-finish
diff --git a/gcc/testsuite/objc.dg/too-many-args.m b/gcc/testsuite/objc.dg/too-many-args.m
new file mode 100644
index 000000000..6fee1b31b
--- /dev/null
+++ b/gcc/testsuite/objc.dg/too-many-args.m
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+
+@interface SomeClass
++ method:(int)foo;
+@end
+
+int main(void) {
+ [SomeClass method:3, 4]; /* { dg-error "too many arguments to method \\'method:\\'" } */
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/torture/dg-torture.exp b/gcc/testsuite/objc.dg/torture/dg-torture.exp
new file mode 100644
index 000000000..4b1869e9c
--- /dev/null
+++ b/gcc/testsuite/objc.dg/torture/dg-torture.exp
@@ -0,0 +1,17 @@
+# This harness is for tests that should be run at all optimisation levels.
+
+load_lib objc-dg.exp
+
+dg-init
+
+# Gather a list of all tests.
+set tests [lsort [glob -nocomplain $srcdir/$subdir/*.m]]
+
+objc-dg-runtest $tests "-fgnu-runtime"
+
+# darwin targets can also run code with the NeXT runtime.
+if [istarget "*-*-darwin*" ] {
+ objc-dg-runtest $tests "-fnext-runtime"
+}
+
+dg-finish
diff --git a/gcc/testsuite/objc.dg/torture/forward-1.m b/gcc/testsuite/objc.dg/torture/forward-1.m
new file mode 100644
index 000000000..bccf4a112
--- /dev/null
+++ b/gcc/testsuite/objc.dg/torture/forward-1.m
@@ -0,0 +1,87 @@
+/* { dg-do run } */
+/* See if -forward::/-performv:: is able to work. */
+/* { dg-xfail-run-if "PR36610" { ! { { i?86-*-* x86_64-*-* } && ilp32 } } { "-fgnu-runtime" } { "" } } */
+/* { dg-skip-if "Needs OBJC2 Implementation" { *-*-darwin* && { lp64 } } { "-fnext-runtime" } { "" } } */
+/* There is no implementation of forward: in the NeXT m64 libobjc/Object
+ neither have we implemented this in our extensions - so we have to skip it
+ for now. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifndef __NEXT_RUNTIME__
+# include <objc/objc-api.h>
+#endif
+#include <objc/Object.h>
+
+#define VALUETOUSE 1234567890
+
+id forwarder, receiver;
+
+@interface Forwarder: Object
+{
+ id receiver;
+}
+
+-initWithReceiver:theReceiver;
+
+@end
+
+@interface Receiver:Object
+{
+ int foo;
+}
+-display;
+-initWithFoo:(int)theFoo;
+@end
+@implementation Receiver
+
+-initWithFoo: (int)theFoo
+{
+ foo = theFoo;
+ return self;
+}
+
+-display
+{
+ /* Check to see if we are really the reciever. */
+ if (self != receiver)
+ abort ();
+ /* And the value of foo is set correctly. */
+ if (foo != VALUETOUSE)
+ abort ();
+ return self;
+}
+
+@end
+
+@implementation Forwarder
+-initWithReceiver: theReceiver
+{
+ [super init];
+ receiver = theReceiver;
+ return self;
+}
+#ifdef __NEXT_RUNTIME__
+- forward: (SEL)theSel: (marg_list)theArgFrame
+#else
+-(retval_t) forward: (SEL)theSel: (arglist_t)theArgFrame
+#endif
+{
+ /* If we have a reciever try to perform on that object */
+ if (receiver)
+ return [receiver performv: theSel: theArgFrame];
+ return [self doesNotRecognize:theSel];
+}
+@end
+int main()
+{
+ /* Init the reciever. */
+ receiver = [[Receiver alloc] initWithFoo: VALUETOUSE];
+ /* Init the fowarder. */
+ forwarder = [[Forwarder alloc] initWithReceiver: receiver];
+ /* Call display on the forwarder which in turns calls display on
+ the reciever. */
+ [forwarder display];
+ exit(0);
+}
diff --git a/gcc/testsuite/objc.dg/torture/strings/const-cfstring-1.m b/gcc/testsuite/objc.dg/torture/strings/const-cfstring-1.m
new file mode 100644
index 000000000..7e9891564
--- /dev/null
+++ b/gcc/testsuite/objc.dg/torture/strings/const-cfstring-1.m
@@ -0,0 +1,62 @@
+/* Test the -fconstant-cfstrings option for constructing
+ compile-time immutable CFStrings, and their interoperation
+ with both Cocoa and CoreFoundation. This will only work
+ on MacOS X 10.1.2 and later. */
+/* Developed by Ziemowit Laski <zlaski@apple.com>. */
+
+/* So far, CFString is darwin-only. */
+/* { dg-do run { target *-*-darwin* } } */
+/* { dg-skip-if "NeXT only" { *-*-* } { "-fgnu-runtime" } { "" } } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+/* { dg-options "-mconstant-cfstrings -framework Cocoa" } */
+/* Darwin10's linker emits a warning that the constant strings are incompatible with writable ones.
+ Well, we don't implement writable ones at this juncture. */
+/* { dg-options "-mconstant-cfstrings -framework Cocoa -Wl,-w" { target *-*-darwin[123]* } } */
+
+#import <Foundation/NSString.h>
+#import <CoreFoundation/CFString.h>
+#include <stdlib.h>
+
+void printOut(NSString *str) {
+ NSLog(@"The value of str is: %@", str);
+}
+
+CFStringRef s0a = CFSTR("Compile-time string literal");
+CFStringRef s0b = CFSTR("Compile-time string literal");
+
+void checkNSRange(NSRange r) {
+ if (r.location != 6 || r.length != 5) {
+ printOut(@"Range check failed");
+ abort();
+ }
+}
+
+void checkCFRange(CFRange r) {
+ if (r.location != 6 || r.length != 5) {
+ printOut(@"Range check failed");
+ abort();
+ }
+}
+
+int main(void) {
+ const NSString *s1 = @"Compile-time string literal";
+ CFStringRef s2 = CFSTR("Compile-time string literal");
+
+ checkNSRange([@"Hello World" rangeOfString:@"World"]);
+ checkNSRange([(id)CFSTR("Hello World") rangeOfString:@"World"]);
+ checkNSRange([@"Hello World" rangeOfString:(id)CFSTR("World")]);
+ checkNSRange([(id)CFSTR("Hello World") rangeOfString:(id)CFSTR("World")]);
+
+ checkCFRange(CFStringFind((CFStringRef)@"Hello World", (CFStringRef)@"World", 0));
+ checkCFRange(CFStringFind(CFSTR("Hello World"), (CFStringRef)@"World", 0));
+ checkCFRange(CFStringFind((CFStringRef)@"Hello World", CFSTR("World"), 0));
+ checkCFRange(CFStringFind(CFSTR("Hello World"), CFSTR("World"), 0));
+
+ /* Check for string uniquing. */
+ if (s0a != s0b || s0a != s2 || s1 != (id)s2) {
+ NSLog(@"String uniquing failed");
+ abort ();
+ }
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/torture/strings/const-cfstring-3.m b/gcc/testsuite/objc.dg/torture/strings/const-cfstring-3.m
new file mode 100644
index 000000000..4a6142988
--- /dev/null
+++ b/gcc/testsuite/objc.dg/torture/strings/const-cfstring-3.m
@@ -0,0 +1,27 @@
+/* Test for assigning compile-time constant-string objects to static variables. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com> */
+
+/* So far, CFString is darwin-only. */
+/* { dg-do run { target *-*-darwin* } } */
+/* { dg-skip-if "NeXT only" { *-*-* } { "-fgnu-runtime" } { "" } } */
+/* { dg-options "-mconstant-cfstrings -framework Foundation" } */
+
+#include <stdlib.h>
+
+typedef const struct __CFString * CFStringRef;
+static CFStringRef appKey = (CFStringRef) @"com.apple.soundpref";
+
+static int CFPreferencesSynchronize (CFStringRef ref) {
+ return ref == appKey;
+}
+
+static void PrefsSynchronize()
+{
+ if(!CFPreferencesSynchronize(appKey))
+ abort();
+}
+
+int main(void) {
+ PrefsSynchronize();
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/torture/strings/const-cfstring-4.m b/gcc/testsuite/objc.dg/torture/strings/const-cfstring-4.m
new file mode 100644
index 000000000..1155db5f8
--- /dev/null
+++ b/gcc/testsuite/objc.dg/torture/strings/const-cfstring-4.m
@@ -0,0 +1,21 @@
+/* Test if constant CFStrings get placed in the correct section and that the
+ layout of the object is correct for both m32 and m64. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com> */
+
+/* So far, CFString is darwin-only. */
+/* { dg-do compile { target *-*-darwin* } } */
+/* { dg-skip-if "NeXT only" { *-*-* } { "-fgnu-runtime" } { "" } } */
+/* { dg-options "-mconstant-cfstrings" } */
+
+typedef const struct __CFString * CFStringRef;
+static CFStringRef appKey = (CFStringRef) @"com.apple.soundpref";
+
+void *foo (void)
+{
+ void *a = (void *)appKey;
+ return a;
+}
+
+/* { dg-final { scan-assembler ".section __DATA, __cfstring" } } */
+/* { dg-final { scan-assembler ".long\t___CFConstantStringClassReference\n\t.long\t1992\n\t.long\t.*\n\t.long\t19\n" { target { *-*-darwin* && { ! lp64 } } } } } */
+/* { dg-final { scan-assembler ".quad\t___CFConstantStringClassReference\n\t.long\t1992\n\t.space 4\n\t.quad\t.*\n\t.quad\t19\n" { target { *-*-darwin* && { lp64 } } } } } */
diff --git a/gcc/testsuite/objc.dg/torture/strings/const-str-10.m b/gcc/testsuite/objc.dg/torture/strings/const-str-10.m
new file mode 100644
index 000000000..f0f28238d
--- /dev/null
+++ b/gcc/testsuite/objc.dg/torture/strings/const-str-10.m
@@ -0,0 +1,35 @@
+/* Test if ObjC constant string layout is checked properly, regardless of how
+ constant string classes get derived. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com> */
+
+/* { dg-do compile { target { *-*-darwin* } } } */
+/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */
+/* { dg-options "-mno-constant-cfstrings" { target *-*-darwin* } } */
+
+#include "../../../objc-obj-c++-shared/Object1.h"
+
+@interface NSString: Object
+@end
+
+@interface NSSimpleCString : NSString {
+@protected
+ char *bytes;
+ unsigned int numBytes;
+}
+@end
+
+@interface NSConstantString : NSSimpleCString
+@end
+
+#ifndef NEXT_OBJC_USE_NEW_INTERFACE
+extern struct objc_class _NSConstantStringClassReference;
+#else
+extern Class _NSConstantStringClassReference;
+#endif
+
+const NSConstantString *appKey = @"MyApp";
+
+/* { dg-final { scan-assembler ".section __OBJC, __cstring_object" { target { *-*-darwin* && { ! lp64 } } } } } */
+/* { dg-final { scan-assembler ".section __DATA, __objc_stringobj" { target { *-*-darwin* && { lp64 } } } } } */
+/* { dg-final { scan-assembler ".long\t__NSConstantStringClassReference\n\t.long\t.*\n\t.long\t5\n\t.data" { target { *-*-darwin* && { ! lp64 } } } } } */
+/* { dg-final { scan-assembler ".quad\t_OBJC_CLASS_._NSConstantString\n\t.quad\t.*\n\t.long\t5\n\t.space" { target { *-*-darwin* && { lp64 } } } } } */
diff --git a/gcc/testsuite/objc.dg/torture/strings/const-str-11.m b/gcc/testsuite/objc.dg/torture/strings/const-str-11.m
new file mode 100644
index 000000000..fa9dbd985
--- /dev/null
+++ b/gcc/testsuite/objc.dg/torture/strings/const-str-11.m
@@ -0,0 +1,35 @@
+/* Test if ObjC constant string layout is checked properly, regardless of how
+ constant string classes get derived. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com> */
+
+/* { dg-do compile { target *-*-darwin* } } */
+/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */
+/* { dg-options "-fconstant-string-class=XStr" } */
+/* { dg-options "-mno-constant-cfstrings -fconstant-string-class=XStr" { target *-*-darwin* } } */
+
+#include "../../../objc-obj-c++-shared/Object1.h"
+
+@interface XString: Object {
+@protected
+ char *bytes;
+}
+@end
+
+@interface XStr : XString {
+@public
+ unsigned int len;
+}
+@end
+
+#ifndef NEXT_OBJC_USE_NEW_INTERFACE
+extern struct objc_class _XStrClassReference;
+#else
+extern Class _XStrClassReference;
+#endif
+
+const XStr *appKey = @"MyApp";
+
+/* { dg-final { scan-assembler ".section __OBJC, __cstring_object" { target { *-*-darwin* && { ! lp64 } } } } } */
+/* { dg-final { scan-assembler ".section __DATA, __objc_stringobj" { target { *-*-darwin* && { lp64 } } } } } */
+/* { dg-final { scan-assembler ".long\t__XStrClassReference\n\t.long\t.*\n\t.long\t5\n\t.data" { target { *-*-darwin* && { ! lp64 } } } } } */
+/* { dg-final { scan-assembler ".quad\t_OBJC_CLASS_._XStr\n\t.quad\t.*\n\t.long\t5\n\t.space" { target { *-*-darwin* && { lp64 } } } } } */
diff --git a/gcc/testsuite/objc.dg/torture/strings/const-str-3.m b/gcc/testsuite/objc.dg/torture/strings/const-str-3.m
new file mode 100644
index 000000000..0eb2d6a01
--- /dev/null
+++ b/gcc/testsuite/objc.dg/torture/strings/const-str-3.m
@@ -0,0 +1,54 @@
+/* Test the -fconstant-string-class=Foo option under the NeXT runtime. */
+/* Developed by Markus Hitter <mah@jump-ing.de>. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+/* { dg-options "-fconstant-string-class=Foo" } */
+/* { dg-options "-mno-constant-cfstrings -fconstant-string-class=Foo" { target *-*-darwin* } } */
+
+#include "../../../objc-obj-c++-shared/objc-test-suite-types.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+@interface Foo {
+ void *dummy_class_ref;
+ char *cString;
+ unsigned int len;
+}
++ initialize;
+- (char *)customString;
+@end
+
+TNS_STRING_REF_T _FooClassReference; /* Only used by NeXT. */
+
+@implementation Foo
++ initialize {return self;}
+
+- (char *)customString {
+ return cString;
+}
+@end
+
+int main () {
+ Foo *string = @"bla";
+ Foo *string2 = @"bla";
+
+ if(string != string2)
+ abort();
+ printf("Strings are being uniqued properly\n");
+
+#ifdef __NEXT_RUNTIME__
+ /* This memcpy has to be done before the first message is sent to a
+ constant string object. Can't be moved to +initialize since _that_
+ is already a message. */
+
+ memcpy(&_FooClassReference, objc_getClass("Foo"), sizeof(_FooClassReference));
+#endif
+ if (strcmp ([string customString], "bla")) {
+ abort ();
+ }
+
+ printf([@"This is a working constant string object\n" customString]);
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/torture/strings/const-str-4.m b/gcc/testsuite/objc.dg/torture/strings/const-str-4.m
new file mode 100644
index 000000000..446b075da
--- /dev/null
+++ b/gcc/testsuite/objc.dg/torture/strings/const-str-4.m
@@ -0,0 +1,32 @@
+/* Ensure that the preprocessor handles ObjC string constants gracefully. */
+/* Author: Ziemowit Laski <zlaski@apple.com> */
+/* { dg-do run } */
+/* { dg-options "-fconstant-string-class=MyString " } */
+/* { dg-options "-mno-constant-cfstrings -fconstant-string-class=MyString " { target *-*-darwin* } } */
+
+extern void abort(void);
+
+@interface MyString
+{
+ void *isa;
+ char *str;
+ int len;
+}
+@end
+
+#define kMyStringMacro1 "My String"
+#define kMyStringMacro2 @"My String"
+
+void *_MyStringClassReference;
+
+@implementation MyString
+@end
+
+int main(void) {
+ MyString* aString1 = @kMyStringMacro1;
+ MyString* aString2 = kMyStringMacro2;
+ if(aString1 != aString2) {
+ abort();
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/torture/strings/const-str-7.m b/gcc/testsuite/objc.dg/torture/strings/const-str-7.m
new file mode 100644
index 000000000..7221e28d4
--- /dev/null
+++ b/gcc/testsuite/objc.dg/torture/strings/const-str-7.m
@@ -0,0 +1,42 @@
+/* Test to make sure that the const objc strings are the same across scopes. */
+/* Developed by Andrew Pinski <pinskia@physics.uc.edu> */
+/* { dg-do run } */
+/* { dg-options "-fconstant-string-class=Foo " } */
+/* { dg-options "-mno-constant-cfstrings -fconstant-string-class=Foo" { target *-*-darwin* } } */
+/* { dg-additional-sources "../../../objc-obj-c++-shared/Object1.m" } */
+
+#include "../../../objc-obj-c++-shared/Object1.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+@interface Foo: Object {
+ char *cString;
+ unsigned int len;
+}
+- (char *)customString;
+@end
+
+#ifdef NEXT_OBJC_USE_NEW_INTERFACE
+Class _FooClassReference;
+#else
+struct objc_class _FooClassReference;
+#endif
+
+@implementation Foo : Object
+- (char *)customString {
+ return cString;
+}
+@end
+
+int main () {
+ Foo *string = @"bla";
+ {
+ Foo *string2 = @"bla";
+
+ if(string != string2)
+ abort();
+ printf("Strings are being uniqued properly\n");
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/torture/strings/const-str-8.m b/gcc/testsuite/objc.dg/torture/strings/const-str-8.m
new file mode 100644
index 000000000..c5bacaf43
--- /dev/null
+++ b/gcc/testsuite/objc.dg/torture/strings/const-str-8.m
@@ -0,0 +1,43 @@
+/* Test for assigning compile-time constant-string objects to static variables. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com> */
+/* { dg-do run } */
+/* { dg-options "-fconstant-string-class=Foo" } */
+/* { dg-options "-mno-constant-cfstrings -fconstant-string-class=Foo" { target *-*-darwin* } } */
+/* { dg-additional-sources "../../../objc-obj-c++-shared/Object1.m" } */
+
+#include "../../../objc-obj-c++-shared/Object1.h"
+#include <stdlib.h>
+
+@interface Foo: Object {
+ char *cString;
+ unsigned int len;
+}
+@end
+
+#ifdef NEXT_OBJC_USE_NEW_INTERFACE
+Class _FooClassReference;
+#else
+struct objc_class _FooClassReference;
+#endif
+
+@implementation Foo : Object
+- (char *)customString {
+ return cString;
+}
+@end
+
+static const Foo *appKey = @"MyApp";
+static int CFPreferencesSynchronize (const Foo *ref) {
+ return ref == appKey;
+}
+
+static void PrefsSynchronize(void)
+{
+ if(!CFPreferencesSynchronize(appKey))
+ abort();
+}
+
+int main () {
+ PrefsSynchronize();
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/torture/strings/const-str-9.m b/gcc/testsuite/objc.dg/torture/strings/const-str-9.m
new file mode 100644
index 000000000..39bd10274
--- /dev/null
+++ b/gcc/testsuite/objc.dg/torture/strings/const-str-9.m
@@ -0,0 +1,27 @@
+/* Test if ObjC constant strings get placed in the correct section. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com> */
+
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */
+/* { dg-options "-mno-constant-cfstrings" { target *-*-darwin* } } */
+
+#include "../../../objc-obj-c++-shared/Object1.h"
+
+@interface NSConstantString: Object {
+ char *cString;
+ unsigned int len;
+}
+@end
+
+#ifndef NEXT_OBJC_USE_NEW_INTERFACE
+extern struct objc_class _NSConstantStringClassReference;
+#else
+Class _NSConstantStringClassReference;
+#endif
+
+const NSConstantString *appKey = @"MyApp";
+
+/* { dg-final { scan-assembler ".section __OBJC, __cstring_object" { target { *-*-darwin* && { ! lp64 } } } } } */
+/* { dg-final { scan-assembler ".section __DATA, __objc_stringobj" { target { *-*-darwin* && { lp64 } } } } } */
+/* { dg-final { scan-assembler ".long\t__NSConstantStringClassReference\n\t.long\t.*\n\t.long\t5\n\t.data" { target { *-*-darwin* && { ! lp64 } } } } } */
+/* { dg-final { scan-assembler ".quad\t_OBJC_CLASS_._NSConstantString\n\t.quad\t.*\n\t.long\t5\n\t.space" { target { *-*-darwin* && { lp64 } } } } } */
diff --git a/gcc/testsuite/objc.dg/torture/strings/string1.m b/gcc/testsuite/objc.dg/torture/strings/string1.m
new file mode 100644
index 000000000..455b5f1bf
--- /dev/null
+++ b/gcc/testsuite/objc.dg/torture/strings/string1.m
@@ -0,0 +1,22 @@
+/* Based on a test case contributed by Nicola Pero. */
+
+/* { dg-do run } */
+/* { dg-options "-mno-constant-cfstrings -Wno-deprecated-declarations" { target *-*-darwin* } } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+/* { dg-additional-sources "../../../objc-obj-c++-shared/nsconstantstring-class-impl.m" } */
+
+#include <string.h>
+#include <stdlib.h>
+
+#ifndef __NEXT_RUNTIME__
+#include <objc/NXConstStr.h>
+#else
+#include "../../../objc-obj-c++-shared/nsconstantstring-class.h"
+#endif
+
+int main(int argc, void **args)
+{
+ if (strcmp ([@"this is a string" cString], "this is a string"))
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/torture/strings/string2.m b/gcc/testsuite/objc.dg/torture/strings/string2.m
new file mode 100644
index 000000000..030ba602d
--- /dev/null
+++ b/gcc/testsuite/objc.dg/torture/strings/string2.m
@@ -0,0 +1,23 @@
+/* Based on a test case contributed by Nicola Pero. */
+
+/* { dg-do run } */
+/* { dg-options "-mno-constant-cfstrings -Wno-deprecated-declarations" { target *-*-darwin* } } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+/* { dg-additional-sources "../../../objc-obj-c++-shared/nsconstantstring-class-impl.m" } */
+
+#include <string.h>
+#include <stdlib.h>
+
+#ifndef __NEXT_RUNTIME__
+#include <objc/NXConstStr.h>
+#else
+#include "../../../objc-obj-c++-shared/nsconstantstring-class.h"
+#endif
+
+int main(int argc, void **args)
+{
+ if (strcmp ([@"this " @"is " @"a " @"string" cString],
+ "this " "is " "a " "string"))
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/torture/strings/string3.m b/gcc/testsuite/objc.dg/torture/strings/string3.m
new file mode 100644
index 000000000..b08dfb242
--- /dev/null
+++ b/gcc/testsuite/objc.dg/torture/strings/string3.m
@@ -0,0 +1,24 @@
+/* Based on a test case contributed by Nicola Pero. */
+
+/* { dg-do run } */
+/* { dg-options "-mno-constant-cfstrings -Wno-deprecated-declarations" { target *-*-darwin* } } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+/* { dg-additional-sources "../../../objc-obj-c++-shared/nsconstantstring-class-impl.m" } */
+
+#include <string.h>
+#include <stdlib.h>
+
+#ifndef __NEXT_RUNTIME__
+#include <objc/NXConstStr.h>
+#else
+#include "../../../objc-obj-c++-shared/nsconstantstring-class.h"
+#endif
+
+#define STRING "this is a string"
+
+int main (int argc, void **args)
+{
+ if (strcmp ([@STRING cString], STRING))
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/torture/strings/string4.m b/gcc/testsuite/objc.dg/torture/strings/string4.m
new file mode 100644
index 000000000..425ccc080
--- /dev/null
+++ b/gcc/testsuite/objc.dg/torture/strings/string4.m
@@ -0,0 +1,22 @@
+/* Based on a test case contributed by Nicola Pero. */
+
+/* { dg-do run } */
+/* { dg-options "-mno-constant-cfstrings -Wno-deprecated-declarations" { target *-*-darwin* } } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+/* { dg-additional-sources "../../../objc-obj-c++-shared/nsconstantstring-class-impl.m" } */
+
+#include <string.h>
+#include <stdlib.h>
+
+#ifndef __NEXT_RUNTIME__
+#include <objc/NXConstStr.h>
+#else
+#include "../../../objc-obj-c++-shared/nsconstantstring-class.h"
+#endif
+
+int main(int argc, void **args)
+{
+ if ([@"this is a string" length] != strlen ("this is a string"))
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/torture/strings/strings.exp b/gcc/testsuite/objc.dg/torture/strings/strings.exp
new file mode 100644
index 000000000..e30918613
--- /dev/null
+++ b/gcc/testsuite/objc.dg/torture/strings/strings.exp
@@ -0,0 +1,34 @@
+# String tests that should be run at all optimization levels.
+
+# Copyright (C) 2010 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 GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+load_lib objc-dg.exp
+load_lib target-supports-dg.exp
+
+dg-init
+
+# Gather a list of all tests.
+set tests [lsort [glob -nocomplain $srcdir/$subdir/*.m]]
+
+objc-dg-runtest $tests "-fgnu-runtime"
+
+# Darwin targets also test with the NeXT runtime.
+if [istarget "*-*-darwin*" ] {
+ objc-dg-runtest $tests "-fnext-runtime"
+}
+
+dg-finish
diff --git a/gcc/testsuite/objc.dg/torture/tls/diag-1.m b/gcc/testsuite/objc.dg/torture/tls/diag-1.m
new file mode 100644
index 000000000..7c3245d9f
--- /dev/null
+++ b/gcc/testsuite/objc.dg/torture/tls/diag-1.m
@@ -0,0 +1,12 @@
+// Valid __thread specifiers.
+// { dg-require-effective-target tls }
+
+__thread int g1;
+extern __thread int g2;
+static __thread int g3;
+
+void foo()
+{
+ extern __thread int l1;
+ static __thread int l2;
+}
diff --git a/gcc/testsuite/objc.dg/torture/tls/thr-init-2.m b/gcc/testsuite/objc.dg/torture/tls/thr-init-2.m
new file mode 100644
index 000000000..cdbef4d77
--- /dev/null
+++ b/gcc/testsuite/objc.dg/torture/tls/thr-init-2.m
@@ -0,0 +1,43 @@
+// { dg-do run }
+// { dg-require-effective-target tls_runtime }
+// { dg-add-options tls }
+
+extern void _exit(int);
+
+__thread int glb =1 ;
+
+static __thread int fstat = 2;
+
+int fa(int a)
+{
+static __thread int as = 3;
+ as += a ;
+ return as;
+}
+
+int fb(int b)
+{
+static __thread int bs = 4;
+ bs += b ;
+ glb = bs;
+ return bs;
+}
+
+int main (int ac, char *av[])
+{
+ int a = 1;
+
+ a = fa(fstat);
+ if ( a != 5 )
+ _exit (-(__LINE__)) ;
+
+ a = fa(glb);
+ if ( a != 6 )
+ _exit (-(__LINE__)) ;
+
+ a = fb(a);
+ if ( a != 10 || glb != 10 )
+ _exit (-(__LINE__)) ;
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/torture/tls/thr-init-3.m b/gcc/testsuite/objc.dg/torture/tls/thr-init-3.m
new file mode 100644
index 000000000..b52c87391
--- /dev/null
+++ b/gcc/testsuite/objc.dg/torture/tls/thr-init-3.m
@@ -0,0 +1,39 @@
+/* { dg-do run } */
+/* { dg-require-effective-target tls_runtime } */
+/* { dg-add-options tls } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+/* { dg-additional-sources "../../../objc-obj-c++-shared/Object1.m" } */
+
+#include "../../../objc-obj-c++-shared/Object1.h"
+extern void _exit(int);
+
+@interface tsObj: Object {
+ int ai ;
+}
+
+- (int) fa:(int) n;
+
+@end
+
+@implementation tsObj
+
+- (int) fa:(int) n
+{
+static __thread int as = 3;
+ as += n ;
+ return as ;
+}
+
+@end
+
+int main (int ac, char *av[])
+{
+ int a ;
+ tsObj *to = [tsObj new];
+
+ a = [to fa:5];
+ if ( a != 8 )
+ _exit (-(__LINE__)) ;
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/torture/tls/thr-init.m b/gcc/testsuite/objc.dg/torture/tls/thr-init.m
new file mode 100644
index 000000000..986b425f7
--- /dev/null
+++ b/gcc/testsuite/objc.dg/torture/tls/thr-init.m
@@ -0,0 +1,26 @@
+/* { dg-do run } */
+/* { dg-require-effective-target tls_runtime } */
+/* { dg-add-options tls } */
+
+extern void _exit(int);
+
+static __thread int fstat ;
+
+static __thread int fstat = 1;
+
+static __thread int fstat ;
+
+int test_code(int b)
+{
+ fstat += b ;
+ return fstat;
+}
+
+int main (int ac, char *av[])
+{
+ int a = test_code(1);
+
+ if ( a != 2 || fstat != 2 ) _exit (-(__LINE__)) ;
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/torture/tls/tls.exp b/gcc/testsuite/objc.dg/torture/tls/tls.exp
new file mode 100644
index 000000000..4b1869e9c
--- /dev/null
+++ b/gcc/testsuite/objc.dg/torture/tls/tls.exp
@@ -0,0 +1,17 @@
+# This harness is for tests that should be run at all optimisation levels.
+
+load_lib objc-dg.exp
+
+dg-init
+
+# Gather a list of all tests.
+set tests [lsort [glob -nocomplain $srcdir/$subdir/*.m]]
+
+objc-dg-runtest $tests "-fgnu-runtime"
+
+# darwin targets can also run code with the NeXT runtime.
+if [istarget "*-*-darwin*" ] {
+ objc-dg-runtest $tests "-fnext-runtime"
+}
+
+dg-finish
diff --git a/gcc/testsuite/objc.dg/torture/tls/trivial.m b/gcc/testsuite/objc.dg/torture/tls/trivial.m
new file mode 100644
index 000000000..e2b8f45b8
--- /dev/null
+++ b/gcc/testsuite/objc.dg/torture/tls/trivial.m
@@ -0,0 +1,3 @@
+// { dg-require-effective-target tls }
+
+__thread int i;
diff --git a/gcc/testsuite/objc.dg/torture/trivial.m b/gcc/testsuite/objc.dg/torture/trivial.m
new file mode 100644
index 000000000..a1ac22ed4
--- /dev/null
+++ b/gcc/testsuite/objc.dg/torture/trivial.m
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+/* { dg-additional-sources "../../objc-obj-c++-shared/Object1.m" } */
+
+#import "../../objc-obj-c++-shared/Object1.h"
+
+int main(void)
+{
+ [Object class];
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/try-catch-1.m b/gcc/testsuite/objc.dg/try-catch-1.m
new file mode 100644
index 000000000..5b2a209dd
--- /dev/null
+++ b/gcc/testsuite/objc.dg/try-catch-1.m
@@ -0,0 +1,41 @@
+/* Test if the compiler accepts @throw / @try..@catch..@finally syntax. */
+/* Developed by Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-options "-fobjc-exceptions" } */
+/* { dg-do compile } */
+
+#include "../objc-obj-c++-shared/Object1.h"
+#include <stdio.h>
+#include <setjmp.h>
+
+@interface Frob: Object
+@end
+
+@implementation Frob: Object
+@end
+
+static int exc_control = 0;
+
+int proc() {
+ if(exc_control) {
+ printf ("Throwing (%d)... ", exc_control);
+ @throw [Frob new];
+ }
+ return 1;
+}
+
+int foo()
+{
+ @try {
+ return proc();
+ }
+ @catch (Frob* ex) {
+ if(exc_control > 1) {
+ printf("Rethrowing (%d)... ", exc_control);
+ @throw;
+ }
+ return 0;
+ }
+ @finally {
+ printf("In @finally block (%d)... ", exc_control);
+ }
+}
diff --git a/gcc/testsuite/objc.dg/try-catch-10.m b/gcc/testsuite/objc.dg/try-catch-10.m
new file mode 100644
index 000000000..49e2c0cef
--- /dev/null
+++ b/gcc/testsuite/objc.dg/try-catch-10.m
@@ -0,0 +1,40 @@
+/* Ensure that @try/@catch blocks do not mess with types of
+ local objects (other than their volatile bits). */
+
+/* { dg-options "-fobjc-exceptions" } */
+/* { dg-do compile } */
+
+#include "../objc-obj-c++-shared/Object1.h"
+
+@protocol Proto1
+- (int)meth1;
+@end
+
+@protocol Proto2
+- (int)meth2;
+@end
+
+@interface MyClass: Object <Proto2> {
+ int a;
+}
+- (int)meth2;
+- (Object *)parm1: (id)p1 parm2: (id<Proto1>)p2;
+@end
+
+MyClass *mc1, *mc2;
+
+@implementation MyClass
+- (int)meth2 {
+ return a;
+}
+- (Object *)parm1: (id)p1 parm2: (id<Proto1>)p2 {
+ @try {
+ mc2 = p2; /* { dg-warning "type .id <Proto1>. does not conform to the .Proto2. protocol" } */
+ }
+ @catch (id exc) {
+ return exc;
+ }
+ mc1 = p1; /* no warning here! */
+ return self;
+}
+@end
diff --git a/gcc/testsuite/objc.dg/try-catch-11.m b/gcc/testsuite/objc.dg/try-catch-11.m
new file mode 100644
index 000000000..e08f321e8
--- /dev/null
+++ b/gcc/testsuite/objc.dg/try-catch-11.m
@@ -0,0 +1,51 @@
+/* Ensure that typeof()-typed variables inside the @try { } block that
+ "inherit" their EH-volatileness from other variables in the stack frame
+ do not trigger "discards qualifiers from target pointer type" warnings. */
+
+/* { dg-options "-fobjc-exceptions" } */
+/* { dg-do compile } */
+
+typedef volatile int IOSharedLockData;
+
+@interface TestMyTests
+- (void) testSpoon;
+@end
+
+extern void some_func (int *);
+
+@implementation TestMyTests
+- (void) testSpoon {
+ int i = 5;
+
+ do {
+ @try {
+ typeof(i) j = 6;
+ some_func (&j);
+ }
+ @catch (id exc) {
+ @throw;
+ }
+ } while(0);
+
+ do {
+ @try {
+ typeof(i) j = 7;
+ some_func (&j);
+ }
+ @catch (id exc) {
+ @throw;
+ }
+ } while(0);
+
+ do {
+ @try {
+ typeof(i) j = 8;
+ some_func (&j);
+ }
+ @catch (id exc) {
+ @throw;
+ }
+ } while(0);
+
+}
+@end
diff --git a/gcc/testsuite/objc.dg/try-catch-12.m b/gcc/testsuite/objc.dg/try-catch-12.m
new file mode 100644
index 000000000..61e27031d
--- /dev/null
+++ b/gcc/testsuite/objc.dg/try-catch-12.m
@@ -0,0 +1,63 @@
+/* Ensure that variables declared volatile by the user (as opposed to
+ synthesized by the EH-volatization machinery) _do_ trigger
+ "discards qualifiers from target pointer type" warnings. */
+
+/* { dg-options "-fobjc-exceptions" } */
+/* { dg-do compile } */
+
+@interface TestMyTests
+- (void) testSpoon;
+@end
+
+extern void some_func (int *);
+
+@implementation TestMyTests
+- (void) testSpoon {
+ volatile int i = 5;
+ int q = 99;
+
+ do {
+ @try {
+ typeof(i) j = 6;
+ typeof(q) k = 66;
+ some_func (&j); /* { dg-warning "discards .volatile. qualifier from pointer target type" } */
+ /* { dg-message "but argument is of type" "" { target *-*-* } 12 } */
+ some_func (&k);
+ }
+ @catch (id exc) {
+ @throw;
+ }
+ } while(0);
+
+ do {
+ @try {
+ typeof(i) j = 7;
+ typeof(q) k = 77;
+ some_func (&k);
+ some_func (&j); /* { dg-warning "discards .volatile. qualifier from pointer target type" } */
+ /* The following is disabled as it is already checked above and the testsuites seems
+ to count multiple different identical errors on the same line only once */
+ /* dg-message "but argument is of type" "" { target *-*-* } 12 */
+ }
+ @catch (id exc) {
+ @throw;
+ }
+ } while(0);
+
+ do {
+ @try {
+ typeof(q) k = 88;
+ typeof(i) j = 8;
+ some_func (&j); /* { dg-warning "discards .volatile. qualifier from pointer target type" } */
+ /* The following is disabled as it is already checked above and the testsuites seems
+ to count multiple different identical errors on the same line only once */
+ /* dg-message "but argument is of type" "" { target *-*-* } 12 */
+ some_func (&k);
+ }
+ @catch (id exc) {
+ @throw;
+ }
+ } while(0);
+
+}
+@end
diff --git a/gcc/testsuite/objc.dg/try-catch-3.m b/gcc/testsuite/objc.dg/try-catch-3.m
new file mode 100644
index 000000000..2094d29ce
--- /dev/null
+++ b/gcc/testsuite/objc.dg/try-catch-3.m
@@ -0,0 +1,19 @@
+/* Test if caught exception objects are accessible inside the
+ @catch block. (Yes, I managed to break this.) */
+/* Author: Ziemowit Laski <zlaski@apple.com> */
+
+/* { dg-do compile } */
+/* { dg-options "-fobjc-exceptions" } */
+
+#include "../objc-obj-c++-shared/Object1.h"
+
+const char *foo(void)
+{
+ @try {
+ return "foo";
+ }
+ @catch (Object* theException) {
+ return [theException name];
+ }
+}
+
diff --git a/gcc/testsuite/objc.dg/try-catch-4.m b/gcc/testsuite/objc.dg/try-catch-4.m
new file mode 100644
index 000000000..dedcc4ec4
--- /dev/null
+++ b/gcc/testsuite/objc.dg/try-catch-4.m
@@ -0,0 +1,26 @@
+/* Check that the compiler does not incorrectly complain about
+ exceptions being caught by previous @catch blocks. */
+/* Author: Ziemowit Laski <zlaski@apple.com> */
+
+/* { dg-do compile } */
+/* { dg-options "-Wall -fobjc-exceptions" } */
+
+@interface Exception
+@end
+
+@interface FooException : Exception
+@end
+
+extern void foo();
+
+void test()
+{
+ @try {
+ foo();
+ }
+ @catch (FooException* fe) {
+ }
+ @catch (Exception* e) {
+ }
+}
+
diff --git a/gcc/testsuite/objc.dg/try-catch-5.m b/gcc/testsuite/objc.dg/try-catch-5.m
new file mode 100644
index 000000000..f943e9c7e
--- /dev/null
+++ b/gcc/testsuite/objc.dg/try-catch-5.m
@@ -0,0 +1,27 @@
+/* Check that the compiler does correctly complain about
+ exceptions being caught by previous @catch blocks. */
+/* Force the use of NeXT runtime to see that we don't ICE after
+ generating the warning message. */
+
+/* { dg-do compile } */
+/* { dg-options "-Wall -fobjc-exceptions" } */
+
+@interface Exception
+@end
+
+@interface FooException : Exception
+@end
+
+extern void foo();
+
+void test()
+{
+ @try {
+ foo();
+ }
+ @catch (Exception* e) { /* { dg-warning "earlier handler" } */
+ }
+ @catch (FooException* fe) { /* { dg-warning "will be caught" } */
+ }
+}
+
diff --git a/gcc/testsuite/objc.dg/try-catch-6.m b/gcc/testsuite/objc.dg/try-catch-6.m
new file mode 100644
index 000000000..548c320b4
--- /dev/null
+++ b/gcc/testsuite/objc.dg/try-catch-6.m
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-fobjc-exceptions" } */
+
+#include "../objc-obj-c++-shared/Object1.h"
+
+int main (int argc, const char * argv[]) {
+ Object * pool = [Object new];
+ int a;
+
+ if ( 1 ) {
+
+ @try {
+ a = 1;
+ }
+ @catch (Object *e) {
+ a = 2;
+ }
+ @finally {
+ a = 3;
+ }
+ }
+
+ [pool free];
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/try-catch-7.m b/gcc/testsuite/objc.dg/try-catch-7.m
new file mode 100644
index 000000000..b66662370
--- /dev/null
+++ b/gcc/testsuite/objc.dg/try-catch-7.m
@@ -0,0 +1,27 @@
+/* Test for graceful compilation of @synchronized statements. */
+
+/* { dg-do compile } */
+/* { dg-options "-fobjc-exceptions" } */
+
+#include "../objc-obj-c++-shared/Object1.h"
+
+@interface Derived: Object
+- (id) meth;
+@end
+
+@implementation Derived
+- (id) meth {
+ return self;
+}
+
+static Derived* rewriteDict(void) {
+ static Derived *sDict = 0;
+ if (sDict == 0) {
+ @synchronized ([Derived class]) {
+ if (sDict == 0)
+ sDict = [Derived new];
+ }
+ }
+ return sDict;
+}
+@end
diff --git a/gcc/testsuite/objc.dg/try-catch-9.m b/gcc/testsuite/objc.dg/try-catch-9.m
new file mode 100644
index 000000000..454e841b3
--- /dev/null
+++ b/gcc/testsuite/objc.dg/try-catch-9.m
@@ -0,0 +1,24 @@
+/* Check that taking the address of a local variable marked 'volatile'
+ by the compiler does not generate untoward errors. */
+/* Developed by Ziemowit Laski <zlaski@apple.com>. */
+
+/* { dg-options "-fobjc-exceptions" } */
+/* { dg-do compile } */
+
+void foo (int *arg1, int *arg2)
+{
+ *arg1 = *arg2;
+}
+
+void bar (int arg) {
+ int rcvr;
+
+ @try {
+ rcvr = arg;
+ }
+ @finally {
+ int *rcvr0 = &rcvr;
+ foo (rcvr0, &arg);
+ }
+}
+
diff --git a/gcc/testsuite/objc.dg/two-types-1.m b/gcc/testsuite/objc.dg/two-types-1.m
new file mode 100644
index 000000000..da902a3e3
--- /dev/null
+++ b/gcc/testsuite/objc.dg/two-types-1.m
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-std=gnu89" } // suppress default -pedantic-errors */
+
+@interface foo
+struct f {}
+struct g { int a; }; /* { dg-error "expected ';', identifier or " "" } */
+
+- (struct f *) a;
+- (struct g *) b;
+@end
+
+int f(struct g *x)
+{
+ return x->a; /* { dg-bogus " has no member " "" } */
+}
diff --git a/gcc/testsuite/objc.dg/type-size-1.m b/gcc/testsuite/objc.dg/type-size-1.m
new file mode 100644
index 000000000..f2fdae5c3
--- /dev/null
+++ b/gcc/testsuite/objc.dg/type-size-1.m
@@ -0,0 +1,17 @@
+/* Reject ivars with an unknown size. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-do compile } */
+
+struct unknownStruct;
+
+@interface ArrayTest
+{
+ short unknownSize[unknownValue]; /* { dg-error ".unknownValue. (undeclared|was not declared)" } */
+ /* { dg-error "instance variable .unknownSize. has unknown size" "" { target *-*-* } 9 } */
+ struct unknownStruct unknownObj; /* { dg-error "field .unknownObj. has incomplete type" } */
+ /* { dg-error "instance variable .unknownObj. has unknown size" "" { target *-*-* } 11 } */
+ long knownSize[3]; /* ok */
+ char zeroSize[2 - 2]; /* ok (apparently) */
+ int missingSize[]; /* { dg-error "instance variable .missingSize. has unknown size" } */
+}
+@end
diff --git a/gcc/testsuite/objc.dg/type-size-2.m b/gcc/testsuite/objc.dg/type-size-2.m
new file mode 100644
index 000000000..656d85a57
--- /dev/null
+++ b/gcc/testsuite/objc.dg/type-size-2.m
@@ -0,0 +1,75 @@
+/* Make sure that array arguments to methods are given the size of pointers. */
+/* As in the case of ivars, arrays without size (e.g., 'int []') are
+ encoded as pointers. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+/* { dg-additional-sources "../objc-obj-c++-shared/Object1.m" } */
+
+#include "../objc-obj-c++-shared/Object1.h"
+#include "../objc-obj-c++-shared/next-mapping.h"
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef __NEXT_RUNTIME__
+#include <objc/objc-runtime.h>
+#define METHOD Method
+#else
+#include <objc/objc-api.h>
+#define METHOD Method_t
+#define method_get_types(M) (M)->method_types
+#endif
+
+extern int sscanf(const char *str, const char *format, ...);
+extern void abort(void);
+#define CHECK_IF(expr) if(!(expr)) abort()
+
+enum Enum { one, two, three, four };
+
+@interface ArrayTest
+- (const char *)str:(signed char [])arg1 with:(unsigned char *)arg2 and:(enum Enum[4])en;
+- (int)meth1:(int [])arg1 with:(int [0])arg2 with:(int [2])arg3;
+@end
+
+@implementation ArrayTest
+- (int)meth1:(int [])arg1 with:(int [0])arg2 with:(int [2])arg3 { return 0; }
+- (const char *)str:(signed char [])arg1 with:(unsigned char *)arg2 and:(enum Enum[4])en { return "str"; }
+@end
+
+Class cls;
+METHOD meth ;
+
+unsigned totsize, offs0, offs1, offs2, offs3, offs4, offs5, offs6, offs7;
+
+static void scan_initial(const char *pattern) {
+ totsize = offs0 = offs1 = offs2 = offs3 = offs4 = offs5 = offs6 = offs7 = (unsigned)-1;
+ sscanf(method_get_types(meth), pattern, &totsize, &offs0, &offs1, &offs2, &offs3,
+ &offs4, &offs5, &offs6, &offs7);
+ CHECK_IF(!offs0 && offs1 == sizeof(id) && offs2 == offs1 + sizeof(SEL) && totsize >= offs2);
+}
+
+int main(void) {
+ cls = objc_get_class("ArrayTest");
+
+ meth = class_get_instance_method(cls, @selector(str:with:and:));
+
+ /* Here we have the complication that 'enum Enum' could be encoded
+ as 'i' on __NEXT_RUNTIME_, and (most likely) as 'I' on the GNU
+ runtime. So we get the @encode(enum Enum), then put it into the
+ string in place of the traditional 'i'.
+ */
+ /* scan_initial("r*%u@%u:%u*%u*%u[4i]%u"); */
+ {
+ char pattern[1024];
+
+ sprintf (pattern, "r*%%u@%%u:%%u*%%u*%%u[4%s]%%u", @encode(enum Enum));
+ scan_initial(pattern);
+ }
+
+ CHECK_IF(offs3 == offs2 + sizeof(signed char *) && offs4 == offs3 + sizeof(unsigned char *));
+ CHECK_IF(totsize == offs4 + sizeof(enum Enum *));
+ meth = class_get_instance_method(cls, @selector(meth1:with:with:));
+ scan_initial("i%u@%u:%u^i%u[0i]%u[2i]%u");
+ CHECK_IF(offs3 == offs2 + sizeof(int *) && offs4 == offs3 + sizeof(int *));
+ CHECK_IF(totsize == offs4 + sizeof(int *));
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/type-size-3.m b/gcc/testsuite/objc.dg/type-size-3.m
new file mode 100644
index 000000000..bc66b0be6
--- /dev/null
+++ b/gcc/testsuite/objc.dg/type-size-3.m
@@ -0,0 +1,18 @@
+/* Reject ivars that use flexible array members. */
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com> */
+/* { dg-do compile } */
+
+typedef struct
+{
+ unsigned long int a;
+ double b[];
+} test_type;
+
+@interface Test
+{
+ test_type c; /* { dg-error "instance variable .c. uses flexible array member" } */
+}
+@end
+
+@implementation Test
+@end
diff --git a/gcc/testsuite/objc.dg/type-size-4.m b/gcc/testsuite/objc.dg/type-size-4.m
new file mode 100644
index 000000000..7e26da34a
--- /dev/null
+++ b/gcc/testsuite/objc.dg/type-size-4.m
@@ -0,0 +1,23 @@
+/* Allow ivars that are pointers to structs with an unknown size. */
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com> */
+/* PR objc/47832 */
+/* { dg-do compile } */
+
+typedef struct
+{
+ unsigned long int a;
+ double b[];
+} test_type;
+
+@interface Test
+{
+ /* These are all fine. */
+ double *a;
+ struct { int x; double y[]; } *b;
+ test_type *c;
+ union union_type { int x; test_type y; } *d;
+}
+@end
+
+@implementation Test
+@end
diff --git a/gcc/testsuite/objc.dg/type-size-5.m b/gcc/testsuite/objc.dg/type-size-5.m
new file mode 100644
index 000000000..d89af32b4
--- /dev/null
+++ b/gcc/testsuite/objc.dg/type-size-5.m
@@ -0,0 +1,22 @@
+/* Reject ivars that use flexible array members. */
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com> */
+/* { dg-do compile } */
+
+typedef struct
+{
+ unsigned long int a;
+ double b[];
+} test_type;
+
+@interface Test
+{
+ double a[]; /* { dg-error "instance variable .a. has unknown size" } */
+ struct { int x; double y[]; } b; /* { dg-error "instance variable .b. uses flexible array member" } */
+ test_type c; /* { dg-error "instance variable .c. uses flexible array member" } */
+ test_type d[4]; /* { dg-error "instance variable .d. uses flexible array member" } */
+ union union_type { int x; test_type y; } e; /* { dg-error "instance variable .e. uses flexible array member" } */
+}
+@end
+
+@implementation Test
+@end
diff --git a/gcc/testsuite/objc.dg/type-stream-1.m b/gcc/testsuite/objc.dg/type-stream-1.m
new file mode 100644
index 000000000..9f2d509fb
--- /dev/null
+++ b/gcc/testsuite/objc.dg/type-stream-1.m
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-fnext-runtime" } { "" } } */
+
+/* Test warning for deprecated typedstream functions. These functions
+ will be removed in the release after 4.6.0, at which point this
+ testcase can be removed too.
+ */
+
+#include <objc/typedstream.h>
+
+void dummy (void)
+{
+ TypedStream* t = objc_open_typed_stream_for_file ("dummy", 0); /* { dg-warning "deprecated" } */
+
+ objc_write_object (t, nil); /* { dg-warning "deprecated" } */
+ objc_read_object (t, NULL); /* { dg-warning "deprecated" } */
+}
diff --git a/gcc/testsuite/objc.dg/typedef-alias-1.m b/gcc/testsuite/objc.dg/typedef-alias-1.m
new file mode 100644
index 000000000..79db8765e
--- /dev/null
+++ b/gcc/testsuite/objc.dg/typedef-alias-1.m
@@ -0,0 +1,16 @@
+/* Typedefs of ObjC types should work without any bogus warnings. */
+/* { dg-do compile } */
+
+#include "../objc-obj-c++-shared/Object1.h"
+
+typedef Object MyObject;
+
+int main (int argc, const char * argv[])
+{
+ Object* a = nil;
+ MyObject* b = a;
+ Object* c = b;
+
+ return 0;
+}
+
diff --git a/gcc/testsuite/objc.dg/undeclared-selector.m b/gcc/testsuite/objc.dg/undeclared-selector.m
new file mode 100644
index 000000000..1cfc6c834
--- /dev/null
+++ b/gcc/testsuite/objc.dg/undeclared-selector.m
@@ -0,0 +1,48 @@
+/* Test for -Wundeclared-selector. */
+/* Author: Nicola Pero <nicola@brainstorm.co.uk>. */
+/* { dg-do compile } */
+/* { dg-options "-Wundeclared-selector" } */
+
+#include <objc/objc.h>
+
+@interface MyClass
+
++ (void) methodA;
+- (void) methodB;
++ (void) methodD;
+- (void) methodF;
+
+@end
+
+@implementation MyClass
+
++ (void) methodA {}
+- (void) methodB {}
++ (void) methodD
+{
+ SEL d = @selector(methodD); /* Ok */
+ SEL e = @selector(methodE); /* { dg-warning "undeclared selector" } */
+}
+
+- (void) methodE
+{
+ SEL e = @selector(methodE); /* Ok */
+}
+
+- (void) methodF
+{
+ SEL e = @selector(methodE); /* Ok */
+}
+
+@end
+
+int main (void)
+{
+ SEL a = @selector(methodA); /* Ok */
+ SEL b = @selector(methodB); /* Ok */
+ SEL c = @selector(methodC); /* { dg-warning "undeclared selector" } */
+ SEL d = @selector(methodD); /* Ok */
+ SEL e = @selector(methodE); /* Ok */
+ return 0;
+
+}
diff --git a/gcc/testsuite/objc.dg/va-meth-1.m b/gcc/testsuite/objc.dg/va-meth-1.m
new file mode 100644
index 000000000..15bbe97c9
--- /dev/null
+++ b/gcc/testsuite/objc.dg/va-meth-1.m
@@ -0,0 +1,73 @@
+/* Based on objc/execute/va_method.m, by Nicola Pero */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+#include "../objc-obj-c++-shared/Object1.h"
+
+#include <stdarg.h>
+#include <stdlib.h>
+
+/* Test methods with "C-style" trailing arguments, with or without ellipsis. */
+
+@interface MathClass: Object
+/* sum positive numbers; -1 ends the list */
++ (int) sum: (int)firstNumber, int secondNumber, ...;
++ (int) prod: (int) firstNumber, int secondNumber, int thirdNumber;
++ (int) minimum: (int) firstNumber, ...;
+@end
+
+@implementation MathClass
++ (int) sum: (int)firstNumber, int secondNumber, ...
+{
+ va_list ap;
+ int sum = 0, number = 0;
+
+ va_start (ap, secondNumber);
+ number = firstNumber + secondNumber;
+
+ while (number >= 0)
+ {
+ sum += number;
+ number = va_arg (ap, int);
+ }
+
+ va_end (ap);
+
+ return sum;
+}
++ (int) prod: (int) firstNumber, int secondNumber, int thirdNumber {
+ return firstNumber * secondNumber * thirdNumber;
+}
++ (int) minimum: (int)firstNumber, ...
+{
+ va_list ap;
+ int minimum = 999, number = 0;
+
+ va_start (ap, firstNumber);
+ number = firstNumber;
+
+ while (number >= 0)
+ {
+ minimum = (minimum < number ? minimum: number);
+ number = va_arg (ap, int);
+ }
+
+ va_end (ap);
+
+ return minimum;
+}
+@end
+
+int main (void)
+{
+ if ([MathClass sum: 1, 2, 3, 4, 5, -1] != 15)
+ abort ();
+ if ([MathClass prod: 4, 5, 6] != 120)
+ abort ();
+ if ([MathClass minimum: 17, 9, 133, 84, 35, -1] != 9)
+ abort ();
+
+ return 0;
+}
+
+#include "../objc-obj-c++-shared/Object1-implementation.h"
diff --git a/gcc/testsuite/objc.dg/volatile-1.m b/gcc/testsuite/objc.dg/volatile-1.m
new file mode 100644
index 000000000..8b5381a98
--- /dev/null
+++ b/gcc/testsuite/objc.dg/volatile-1.m
@@ -0,0 +1,18 @@
+/* Test for proper handling of volatile parameters in ObjC methods. */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* Contributed by Ziemowit Laski <zlaski@apple.com> */
+
+@interface Test
+-(void) test2: (volatile int) a;
+@end
+
+@implementation Test
+-(void) test2: (volatile int) a
+{
+ /* The following assignment should NOT be optimized away. */
+ a = 1;
+}
+@end
+
+/* { dg-final { scan-assembler "li r\[0-9\]+,1" { target powerpc*-*-darwin* } } } */
diff --git a/gcc/testsuite/objc.dg/weak-1.m b/gcc/testsuite/objc.dg/weak-1.m
new file mode 100644
index 000000000..f39fbc4bb
--- /dev/null
+++ b/gcc/testsuite/objc.dg/weak-1.m
@@ -0,0 +1,13 @@
+/* Test for #pragma weak where the weak alias symbol isn't declared,
+ although the symbol it is an alias for is defined in the
+ translation unit. Bug 7544. */
+/* Origin: Joseph Myers <joseph@codesourcery.com> */
+/* { dg-do compile } */
+/* { dg-require-weak "" } */
+/* { dg-require-alias "" } */
+/* { dg-options "-fno-common" } */
+
+/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?bar1" } } */
+
+#pragma weak bar1 = foo1
+void foo1 (void) {}
diff --git a/gcc/testsuite/objc.dg/zero-link-1.m b/gcc/testsuite/objc.dg/zero-link-1.m
new file mode 100644
index 000000000..c04003111
--- /dev/null
+++ b/gcc/testsuite/objc.dg/zero-link-1.m
@@ -0,0 +1,31 @@
+/* Check if the '-fzero-link' flag correctly emits an objc_getClass() call. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
+
+/* { dg-do compile { target *-*-darwin* } } */
+/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */
+/* { dg-options "-fzero-link" } */
+
+#include "../objc-obj-c++-shared/Object1.h"
+#include <objc/objc.h>
+
+extern void abort(void);
+#define CHECK_IF(expr) if(!(expr)) abort();
+
+@interface Base: Object
++ (int) getValue;
+@end
+
+@implementation Base
++ (int) getValue { return 1593; }
+@end
+
+int main(void) {
+ int val = [Base getValue];
+ CHECK_IF(val == 1593);
+ return 0;
+}
+
+/* { dg-final { scan-assembler-not "_OBJC_ClassRefs_0" { target { *-*-darwin* && { ! lp64 } } } } } */
+/* { dg-final { scan-assembler-not "_OBJC_ClassRef_Base" { target { *-*-darwin* && { lp64 } } } } } */
+/* { dg-final { scan-assembler "objc_getClass" } } */
+
diff --git a/gcc/testsuite/objc.dg/zero-link-2.m b/gcc/testsuite/objc.dg/zero-link-2.m
new file mode 100644
index 000000000..ff82e5ed6
--- /dev/null
+++ b/gcc/testsuite/objc.dg/zero-link-2.m
@@ -0,0 +1,29 @@
+/* Check if the '-fno-zero-link' flag correctly _omits_ an objc_getClass() call. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
+
+/* { dg-do compile { target *-*-darwin* } } */
+/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */
+/* { dg-options "-fno-zero-link" } */
+
+#include <objc/Object.h>
+
+extern void abort(void);
+#define CHECK_IF(expr) if(!(expr)) abort();
+
+@interface Base: Object
++ (int) getValue;
+@end
+
+@implementation Base
++ (int) getValue { return 1593; }
+@end
+
+int main(void) {
+ int val = [Base getValue];
+ CHECK_IF(val == 1593);
+ return 0;
+}
+
+/* { dg-final { scan-assembler "_OBJC_ClassRefs_0" { target { *-*-darwin* && { ! lp64 } } } } } */
+/* { dg-final { scan-assembler "_OBJC_ClassRef_Base" { target { *-*-darwin* && { lp64 } } } } } */
+/* { dg-final { scan-assembler-not "objc_getClass" } } */
diff --git a/gcc/testsuite/objc.dg/zero-link-3.m b/gcc/testsuite/objc.dg/zero-link-3.m
new file mode 100644
index 000000000..2b95b952b
--- /dev/null
+++ b/gcc/testsuite/objc.dg/zero-link-3.m
@@ -0,0 +1,28 @@
+/* Check that the '-fzero-link' flag doesn't prevent messaging from working. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
+
+/* { dg-do run { target *-*-darwin* } } */
+/* { dg-options "-fzero-link" } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+#include "../objc-obj-c++-shared/Object1.h"
+//#import <objc/objc.h>
+
+extern void abort(void);
+#define CHECK_IF(expr) if(!(expr)) abort();
+
+@interface Base: Object
++ (int) getValue;
+@end
+
+@implementation Base
++ (int) getValue { return 1593; }
+@end
+
+int main(void) {
+ int val = [Base getValue];
+ CHECK_IF(val == 1593);
+ return 0;
+}
+
+#include "../objc-obj-c++-shared/Object1-implementation.h"