From 611ba3ea3300b71eb95dc4e45f20eee5dddd32e1 Mon Sep 17 00:00:00 2001 From: dim Date: Sun, 17 Jul 2011 15:40:56 +0000 Subject: Vendor import of clang trunk r135360: http://llvm.org/svn/llvm-project/cfe/trunk@135360 --- test/ARCMT/Common.h | 55 + test/ARCMT/Inputs/test.h | 15 + test/ARCMT/Inputs/test.h.result | 13 + test/ARCMT/Inputs/test1.m.in | 6 + test/ARCMT/Inputs/test1.m.in.result | 5 + test/ARCMT/Inputs/test2.m.in | 6 + test/ARCMT/Inputs/test2.m.in.result | 5 + test/ARCMT/assign-prop-no-arc-runtime.m | 15 + test/ARCMT/assign-prop-no-arc-runtime.m.result | 15 + test/ARCMT/assign-prop-with-arc-runtime.m | 40 + test/ARCMT/assign-prop-with-arc-runtime.m.result | 40 + test/ARCMT/atautorelease-2.m | 29 + test/ARCMT/atautorelease-2.m.result | 28 + test/ARCMT/atautorelease-3.m | 40 + test/ARCMT/atautorelease-3.m.result | 31 + test/ARCMT/atautorelease-check.m | 144 ++ test/ARCMT/atautorelease.m | 47 + test/ARCMT/atautorelease.m.result | 46 + test/ARCMT/autoreleases.m | 48 + test/ARCMT/autoreleases.m.result | 48 + test/ARCMT/checking.m | 295 ++++ test/ARCMT/cxx-checking.mm | 105 ++ test/ARCMT/cxx-rewrite.mm | 31 + test/ARCMT/cxx-rewrite.mm.result | 31 + test/ARCMT/dealloc.m | 24 + test/ARCMT/dealloc.m.result | 20 + test/ARCMT/driver-migrate.m | 3 + test/ARCMT/init.m | 37 + test/ARCMT/init.m.result | 37 + test/ARCMT/migrate.m | 4 + test/ARCMT/nonobjc-to-objc-cast-2.m | 14 + test/ARCMT/nonobjc-to-objc-cast.m | 38 + test/ARCMT/nonobjc-to-objc-cast.m.result | 38 + test/ARCMT/releases-driver.m | 68 + test/ARCMT/releases-driver.m.result | 61 + test/ARCMT/releases.m | 87 ++ test/ARCMT/releases.m.result | 79 + test/ARCMT/remove-dealloc-method.m | 26 + test/ARCMT/remove-dealloc-method.m.result | 20 + test/ARCMT/remove-dealloc-zerouts.m | 44 + test/ARCMT/remove-dealloc-zerouts.m.result | 39 + test/ARCMT/remove-statements.m | 45 + test/ARCMT/remove-statements.m.result | 38 + test/ARCMT/retains.m | 71 + test/ARCMT/retains.m.result | 65 + test/ARCMT/rewrite-block-var.m | 25 + test/ARCMT/rewrite-block-var.m.result | 25 + test/ARCMT/safe-arc-assign.m | 14 + test/ARCMT/safe-arc-assign.m.result | 14 + test/ARCMT/with-arc-mode-check.m | 9 + test/ARCMT/with-arc-mode-migrate.m | 12 + test/ARCMT/with-arc-mode-migrate.m.result | 11 + test/ARCMT/with-arc-mode-modify.m | 13 + test/ARCMT/with-arc-mode-modify.m.result | 12 + test/Analysis/bstring.c | 36 +- test/Analysis/misc-ps-eager-assume.m | 1 + test/Analysis/nullptr.cpp | 8 + test/Analysis/objc-arc.m | 149 ++ test/Analysis/pr4209.m | 6 +- test/Analysis/retain-release-gc-only.m | 1 + test/Analysis/retain-release-path-notes-gc.m | 74 + test/Analysis/retain-release-path-notes.m | 123 ++ test/Analysis/retain-release.m | 87 +- test/Analysis/retain-release.mm | 1 + test/Analysis/string-fail.c | 113 ++ test/Analysis/string.c | 402 +++-- test/Analysis/uninit-ps-rdar6145427.m | 5 +- test/Analysis/uninit-vals-ps-region.m | 9 + test/Analysis/uninit-vals.m | 9 + test/Analysis/variadic-method-types.m | 8 +- test/CMakeLists.txt | 6 +- .../basic/basic.lookup/basic.lookup.argdep/p4.cpp | 13 +- test/CXX/class/p6-0x.cpp | 15 + test/CXX/dcl.dcl/dcl.spec/dcl.stc/p1.cpp | 4 +- .../dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp | 2 +- .../dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp | 3 +- test/CXX/except/except.spec/canonical.cpp | 53 + test/CXX/except/except.spec/p14-ir.cpp | 13 +- test/CXX/special/class.copy/p33-0x.cpp | 32 + test/CXX/stmt.stmt/stmt.dcl/p3-0x.cpp | 8 +- test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp | 2 +- test/CXX/temp/p3.cpp | 20 + .../temp.deduct/temp.deduct.call/p3.cpp | 25 +- test/CXX/temp/temp.res/temp.local/p3.cpp | 8 +- test/CXX/temp/temp.spec/temp.explicit/p7.cpp | 4 +- test/CodeGen/annotate.c | 2 +- test/CodeGen/arm-arguments.c | 4 +- test/CodeGen/arm-asm-variable.c | 31 + test/CodeGen/asm-errors.c | 6 +- test/CodeGen/asm-inout.c | 3 +- test/CodeGen/asm.c | 26 +- test/CodeGen/attr-weak-import.c | 26 + test/CodeGen/attributes.c | 2 +- test/CodeGen/bitfield-2.c | 8 +- test/CodeGen/blocksignature.c | 6 +- test/CodeGen/blockstret.c | 2 +- test/CodeGen/builtin-expect.c | 26 + test/CodeGen/byval-memcpy-elim.c | 33 + test/CodeGen/call-knr-indirect.c | 11 - test/CodeGen/call.c | 39 + test/CodeGen/complex-indirect.c | 10 + test/CodeGen/complex.c | 4 + test/CodeGen/compound-literal.c | 25 +- test/CodeGen/const-init.c | 20 +- test/CodeGen/darwin-thread-specifier.c | 3 + test/CodeGen/debug-info-iv.c | 35 + test/CodeGen/debug-info-member.c | 3 + test/CodeGen/debug-info.c | 5 + test/CodeGen/decl.c | 4 +- test/CodeGen/designated-initializers.c | 10 +- test/CodeGen/flexible-array-init.c | 4 +- test/CodeGen/functions.c | 6 + test/CodeGen/global-init.c | 4 +- test/CodeGen/init.c | 8 + test/CodeGen/libcalls.c | 23 + test/CodeGen/mmx-inline-asm.c | 2 +- test/CodeGen/ms-anonymous-struct.c | 4 +- test/CodeGen/packed-union.c | 1 - test/CodeGen/pragma-pack-3.c | 2 - test/CodeGen/private-extern-redef.c | 39 + test/CodeGen/struct-init.c | 10 +- test/CodeGen/struct.c | 13 + test/CodeGen/trapv.c | 20 +- test/CodeGen/union-init2.c | 4 +- test/CodeGen/vla.c | 63 +- test/CodeGen/volatile-1.c | 2 +- test/CodeGen/volatile-2.c | 12 +- test/CodeGen/x86_32-arguments-darwin.c | 7 +- test/CodeGen/x86_32-arguments-linux.c | 2 +- test/CodeGen/x86_32-arguments-nommx.c | 11 + test/CodeGen/x86_64-arguments.c | 55 +- .../anonymous-union-member-initializer.cpp | 18 +- test/CodeGenCXX/attr-used.cpp | 4 +- test/CodeGenCXX/block-byref-cxx-objc.cpp | 4 +- test/CodeGenCXX/blocks.cpp | 4 +- test/CodeGenCXX/class-layout.cpp | 2 +- test/CodeGenCXX/compound-literals.cpp | 27 + test/CodeGenCXX/const-init.cpp | 4 +- test/CodeGenCXX/constructor-init.cpp | 16 + test/CodeGenCXX/constructors.cpp | 15 +- test/CodeGenCXX/copy-constructor-elim-2.cpp | 14 +- test/CodeGenCXX/copy-constructor-synthesis-2.cpp | 2 +- test/CodeGenCXX/copy-initialization.cpp | 2 +- test/CodeGenCXX/cxx0x-defaulted-templates.cpp | 12 +- test/CodeGenCXX/cxx0x-delegating-ctors.cpp | 20 +- .../default-constructor-default-argument.cpp | 2 +- .../default-constructor-template-member.cpp | 6 +- test/CodeGenCXX/delete.cpp | 58 +- test/CodeGenCXX/destructors.cpp | 46 +- test/CodeGenCXX/eh.cpp | 14 +- test/CodeGenCXX/elide-call-reference.cpp | 4 +- test/CodeGenCXX/for-range.cpp | 8 +- test/CodeGenCXX/global-init.cpp | 31 +- test/CodeGenCXX/implicit-copy-constructor.cpp | 10 + test/CodeGenCXX/init-incomplete-type.cpp | 19 + test/CodeGenCXX/mangle-subst-std.cpp | 4 +- test/CodeGenCXX/mangle-template.cpp | 4 +- test/CodeGenCXX/mangle.cpp | 157 +- test/CodeGenCXX/member-function-pointers.cpp | 44 +- test/CodeGenCXX/member-init-assignment.cpp | 4 +- test/CodeGenCXX/member-init-ctor.cpp | 2 +- test/CodeGenCXX/new-overflow.cpp | 209 +++ test/CodeGenCXX/new.cpp | 36 +- test/CodeGenCXX/noinline-template.cpp | 16 + test/CodeGenCXX/nrvo.cpp | 42 +- test/CodeGenCXX/partial-destruction.cpp | 169 +++ test/CodeGenCXX/pointers-to-data-members.cpp | 6 +- test/CodeGenCXX/pr9965.cpp | 6 +- test/CodeGenCXX/references.cpp | 32 +- test/CodeGenCXX/static-init-3.cpp | 4 +- test/CodeGenCXX/static-init.cpp | 3 + test/CodeGenCXX/stmtexpr.cpp | 10 +- test/CodeGenCXX/template-anonymous-types.cpp | 4 +- test/CodeGenCXX/temporaries.cpp | 22 +- test/CodeGenCXX/value-init.cpp | 69 +- test/CodeGenCXX/variadic-templates.cpp | 11 + test/CodeGenCXX/virt-call-offsets.cpp | 2 +- test/CodeGenCXX/virtual-base-destructor-call.cpp | 30 +- test/CodeGenCXX/virtual-bases.cpp | 4 +- .../virtual-functions-incomplete-types.cpp | 2 +- test/CodeGenCXX/virtual-pseudo-destructor-call.cpp | 6 +- test/CodeGenCXX/visibility-inlines-hidden.cpp | 2 +- test/CodeGenCXX/visibility.cpp | 32 + test/CodeGenCXX/vla.cpp | 43 + test/CodeGenCXX/volatile-1.cpp | 2 +- test/CodeGenCXX/vtable-pointer-initialization.cpp | 6 +- test/CodeGenCXX/x86_32-arguments.cpp | 2 +- test/CodeGenCXX/x86_64-arguments.cpp | 34 + test/CodeGenObjC/arc-arm.m | 20 + test/CodeGenObjC/arc-block-ivar-layout.m | 60 + test/CodeGenObjC/arc-bridged-cast.m | 90 ++ test/CodeGenObjC/arc-compound-stmt.m | 29 + test/CodeGenObjC/arc-foreach.m | 72 + test/CodeGenObjC/arc-ivar-layout.m | 44 + test/CodeGenObjC/arc-no-runtime.m | 9 + test/CodeGenObjC/arc-related-result-type.m | 30 + test/CodeGenObjC/arc-unbridged-cast.m | 37 + test/CodeGenObjC/arc-unopt.m | 69 + test/CodeGenObjC/arc-weak-property.m | 55 + test/CodeGenObjC/arc.m | 1554 ++++++++++++++++++++ test/CodeGenObjC/autorelease.m | 30 + test/CodeGenObjC/block-6.m | 14 +- test/CodeGenObjC/blocks.m | 10 +- test/CodeGenObjC/debug-info-foreach.m | 20 - test/CodeGenObjC/encode-test.m | 4 + test/CodeGenObjC/exceptions-nonfragile.m | 16 +- test/CodeGenObjC/gc.m | 14 + test/CodeGenObjC/mrr-autorelease.m | 24 + test/CodeGenObjC/nonlazy-msgSend.m | 6 + test/CodeGenObjC/property-list-in-class.m | 4 +- test/CodeGenObjC/related-result-type.m | 54 + test/CodeGenObjC/terminate.m | 29 + test/CodeGenObjC/variadic-sends.m | 8 +- test/CodeGenObjCXX/arc-globals.mm | 27 + test/CodeGenObjCXX/arc-mangle.mm | 25 + test/CodeGenObjCXX/arc-move.mm | 75 + test/CodeGenObjCXX/arc-new-delete.mm | 95 ++ test/CodeGenObjCXX/arc-pseudo-destructors.mm | 21 + test/CodeGenObjCXX/arc-references.mm | 83 ++ test/CodeGenObjCXX/arc-special-member-functions.mm | 161 ++ test/CodeGenObjCXX/arc.mm | 166 +++ test/CodeGenObjCXX/catch-id-type.mm | 48 + test/CodeGenObjCXX/copy.mm | 26 + test/CodeGenObjCXX/encode.mm | 14 + test/CodeGenObjCXX/gc.mm | 20 + .../property-object-conditional-exp.mm | 7 +- test/CodeGenObjCXX/property-objects.mm | 2 +- test/CodeGenOpenCL/2011-04-15-vec-init-from-vec.cl | 7 +- test/CodeGenOpenCL/vector_literals_valid.cl | 22 + test/Driver/arc-exceptions.m | 5 + test/Driver/arc.c | 14 + test/Driver/darwin-ld.c | 20 +- test/Driver/darwin-objc-options.m | 2 + test/Driver/darwin-xarch.c | 6 + test/Driver/gnu-runtime.m | 5 + test/Driver/ios-simulator-arcruntime.c | 6 + test/Driver/mg.c | 5 + test/Driver/no-objc-arr.m | 8 + test/Driver/noexecstack.c | 1 + test/Driver/rewrite-objc.m | 2 +- test/Driver/sysroot.c | 6 +- test/Driver/x86_features.c | 4 +- test/FixIt/fixit-objc.m | 14 + test/FixIt/fixit.c | 5 + test/FixIt/typo-crash.cpp | 11 + test/FixIt/typo.cpp | 12 + test/Frontend/dependency-gen.c | 34 +- test/Index/annotate-tokens-pp.c | 14 +- test/Index/annotate-tokens.cpp | 8 +- test/Index/annotate-tokens.m | 28 +- test/Index/arc-annotate.m | 38 + test/Index/arc-complete.m | 16 + test/Index/c-index-api-loadTU-test.m | 11 + test/Index/c-index-getCursor-pp.c | 8 +- test/Index/c-index-getCursor-test.m | 2 +- test/Index/code-completion.cpp | 20 + test/Index/complete-exprs.m | 9 +- test/Index/complete-natural.m | 5 +- test/Index/complete-property-flags.m | 2 + test/Index/get-cursor.cpp | 7 + test/Index/nested-macro-instantiations.cpp | 10 +- test/Index/werror.c | 15 + test/Lexer/has_feature_objc_arc.m | 20 + test/Makefile | 2 +- test/Misc/caret-diags-macros.c | 107 +- test/Misc/diag-aka-types.cpp | 38 + test/Misc/include-stack-for-note-flag.cpp | 4 +- test/Misc/macro-backtrace-limit.c | 12 +- test/PCH/Inputs/arc.h | 20 + test/PCH/Inputs/typo.hpp | 8 + test/PCH/arc.m | 9 + test/PCH/typo.cpp | 17 + test/PCH/variables.c | 34 +- test/PCH/variables.h | 1 - test/Parser/MicrosoftExtensions.c | 2 +- test/Parser/parenthesis-balance.cpp | 15 + test/Parser/recovery.c | 14 + test/Parser/switch-recovery.cpp | 14 + test/Preprocessor/include-directive2.c | 2 +- test/Preprocessor/init.c | 2 +- test/Preprocessor/macro_paste_bad.c | 1 - test/Preprocessor/macro_paste_hashhash.c | 6 +- test/Preprocessor/macro_paste_simple.c | 13 +- test/Preprocessor/pragma_diagnostic_output.c | 26 + test/Preprocessor/warn-macro-unused.c | 5 + test/Preprocessor/warn-macro-unused.h | 1 + test/Sema/arm-neon-types.c | 7 + test/Sema/asm.c | 20 +- test/Sema/attr-deprecated.c | 2 + test/Sema/attr-naked.c | 4 + test/Sema/attr-unavailable-message.c | 10 + test/Sema/attr-weak.c | 4 + test/Sema/bitfield.c | 1 + test/Sema/compare.c | 15 + test/Sema/const-eval.c | 2 +- test/Sema/conversion-64-32.c | 10 + test/Sema/conversion.c | 8 + test/Sema/ext_vector_casts.c | 2 +- test/Sema/extern-redecl.c | 15 +- test/Sema/format-strings.c | 14 + test/Sema/i-c-e.c | 2 +- test/Sema/incomplete-decl.c | 2 +- test/Sema/inline-redef.c | 24 + test/Sema/inline.c | 18 +- test/Sema/no-format-y2k-turnsoff-format.c | 9 + test/Sema/nonnull.c | 21 + test/Sema/paren-list-expr-type.cpp | 17 + test/Sema/parentheses.c | 30 +- test/Sema/parentheses.cpp | 38 +- test/Sema/pointer-addition.c | 25 +- test/Sema/pointer-subtract-compat.c | 2 +- test/Sema/shift.c | 2 +- test/Sema/sign-conversion.c | 8 + test/Sema/struct-decl.c | 2 +- test/Sema/typecheck-binop.c | 6 +- test/Sema/typedef-variable-type.c | 2 +- test/Sema/uninit-variables.c | 15 + test/Sema/varargs.c | 15 + test/Sema/vla.c | 4 +- test/Sema/warn-sizeof-arrayarg.c | 30 + test/Sema/x86-builtin-palignr.c | 4 +- test/SemaCXX/PR10243.cpp | 23 + test/SemaCXX/PR7410.cpp | 13 + test/SemaCXX/PR9459.cpp | 2 +- test/SemaCXX/alignof-sizeof-reference.cpp | 6 + test/SemaCXX/attr-unavailable.cpp | 9 + test/SemaCXX/c99-variable-length-array.cpp | 9 + test/SemaCXX/condition.cpp | 5 +- test/SemaCXX/conversion-function.cpp | 14 + test/SemaCXX/copy-assignment.cpp | 18 +- test/SemaCXX/crashes.cpp | 9 + test/SemaCXX/decltype.cpp | 5 + test/SemaCXX/enum-scoped.cpp | 23 + test/SemaCXX/expressions.cpp | 22 + test/SemaCXX/for-range-unused.cpp | 21 + test/SemaCXX/function-overload-typo-crash.cpp | 12 + test/SemaCXX/generalized-initializers.cpp | 62 +- test/SemaCXX/i-c-e-cxx.cpp | 13 + test/SemaCXX/member-init.cpp | 4 + test/SemaCXX/member-pointer.cpp | 16 + ...issing-namespace-qualifier-typo-corrections.cpp | 72 + test/SemaCXX/nested-name-spec.cpp | 21 +- test/SemaCXX/new-delete.cpp | 8 + test/SemaCXX/null_in_arithmetic_ops.cpp | 93 ++ test/SemaCXX/nullptr_in_arithmetic_ops.cpp | 73 + test/SemaCXX/overloaded-name.cpp | 16 + test/SemaCXX/return.cpp | 11 + test/SemaCXX/vararg-non-pod.cpp | 18 + test/SemaCXX/vector.cpp | 8 +- test/SemaCXX/virtuals.cpp | 29 +- test/SemaCXX/warn-bad-memaccess.cpp | 42 + test/SemaCXX/warn-memset-bad-sizeof.cpp | 101 ++ .../warn-pure-virtual-call-from-ctor-dtor.cpp | 7 + test/SemaCXX/warn-unused-variables.cpp | 26 + test/SemaObjC/Inputs/arc-system-header.h | 52 + test/SemaObjC/arc-bridged-cast.m | 43 + test/SemaObjC/arc-decls.m | 64 + test/SemaObjC/arc-jump-block.m | 84 ++ test/SemaObjC/arc-no-runtime.m | 15 + test/SemaObjC/arc-non-pod-memaccess.m | 55 + test/SemaObjC/arc-peformselector.m | 38 + test/SemaObjC/arc-property-decl-attrs.m | 67 + test/SemaObjC/arc-property-lifetime.m | 112 ++ test/SemaObjC/arc-property.m | 48 + test/SemaObjC/arc-system-header.m | 50 + test/SemaObjC/arc-type-conversion.m | 77 + test/SemaObjC/arc-unavailable-for-weakref.m | 47 + test/SemaObjC/arc-unbridged-cast.m | 18 + test/SemaObjC/arc-unsafe-assigns.m | 41 + test/SemaObjC/arc-unsafe_unretained.m | 12 + test/SemaObjC/arc.m | 628 ++++++++ test/SemaObjC/autoreleasepool.m | 22 + test/SemaObjC/class-proto-1.m | 4 +- test/SemaObjC/class-unavail-warning.m | 2 +- test/SemaObjC/debugger-support.m | 14 + test/SemaObjC/error-property-gc-attr.m | 4 +- test/SemaObjC/forward-class-1.m | 15 +- test/SemaObjC/ivar-ref-misuse.m | 5 +- test/SemaObjC/method-lookup-3.m | 16 + test/SemaObjC/no-warning-unavail-unimp.m | 12 + test/SemaObjC/property-10.m | 17 +- test/SemaObjC/property-inherited.m | 4 +- .../property-ns-returns-not-retained-attr.m | 21 + test/SemaObjC/related-result-type-inference.m | 2 +- test/SemaObjC/selector-3.m | 25 + test/SemaObjC/self-declared-in-block.m | 15 +- test/SemaObjC/sizeof-interface.m | 2 +- test/SemaObjC/special-dep-unavail-warning.m | 10 +- test/SemaObjC/synthesized-ivar.m | 8 + test/SemaObjC/typedef-class.m | 2 +- test/SemaObjC/undef-superclass-1.m | 6 +- test/SemaObjC/warn-retain-cycle.m | 91 ++ test/SemaObjC/weak-property.m | 24 + test/SemaObjCXX/Inputs/arc-system-header.h | 14 + test/SemaObjCXX/arc-0x.mm | 32 + test/SemaObjCXX/arc-bool-conversion.mm | 7 + test/SemaObjCXX/arc-bridged-cast.mm | 36 + test/SemaObjCXX/arc-libcxx.mm | 11 + test/SemaObjCXX/arc-libstdcxx.mm | 10 + test/SemaObjCXX/arc-memfunc.mm | 15 + test/SemaObjCXX/arc-non-pod.mm | 116 ++ test/SemaObjCXX/arc-object-init-destroy.mm | 52 + test/SemaObjCXX/arc-overloading.mm | 175 +++ test/SemaObjCXX/arc-system-header.mm | 10 + test/SemaObjCXX/arc-templates.mm | 254 ++++ test/SemaObjCXX/arc-type-conversion.mm | 221 +++ test/SemaObjCXX/arc-type-traits.mm | 90 ++ test/SemaObjCXX/arc-unavailable-for-weakref.mm | 47 + test/SemaObjCXX/exceptions-fragile.mm | 2 +- test/SemaObjCXX/gc-attributes.mm | 4 +- test/SemaObjCXX/null_objc_pointer.mm | 13 + test/SemaObjCXX/nullptr.mm | 5 +- test/SemaObjCXX/property-type-mismatch.mm | 19 + test/SemaObjCXX/related-result-type-inference.mm | 2 +- test/SemaOpenCL/vector_literals_invalid.cl | 13 + test/SemaTemplate/class-template-decl.cpp | 2 +- test/SemaTemplate/deduction.cpp | 12 + test/SemaTemplate/default-arguments.cpp | 15 + test/SemaTemplate/dependent-names-no-std.cpp | 2 +- test/SemaTemplate/dependent-names.cpp | 42 +- test/SemaTemplate/ext-vector-type.cpp | 34 + test/SemaTemplate/instantiate-call.cpp | 2 +- test/SemaTemplate/instantiate-function-2.cpp | 33 + test/SemaTemplate/instantiate-member-class.cpp | 14 + test/SemaTemplate/instantiate-try-catch.cpp | 17 + .../member-inclass-init-value-dependent.cpp | 11 + test/SemaTemplate/unresolved-construct.cpp | 19 + test/Unit/lit.cfg | 18 +- 428 files changed, 12737 insertions(+), 800 deletions(-) create mode 100644 test/ARCMT/Common.h create mode 100644 test/ARCMT/Inputs/test.h create mode 100644 test/ARCMT/Inputs/test.h.result create mode 100644 test/ARCMT/Inputs/test1.m.in create mode 100644 test/ARCMT/Inputs/test1.m.in.result create mode 100644 test/ARCMT/Inputs/test2.m.in create mode 100644 test/ARCMT/Inputs/test2.m.in.result create mode 100644 test/ARCMT/assign-prop-no-arc-runtime.m create mode 100644 test/ARCMT/assign-prop-no-arc-runtime.m.result create mode 100644 test/ARCMT/assign-prop-with-arc-runtime.m create mode 100644 test/ARCMT/assign-prop-with-arc-runtime.m.result create mode 100644 test/ARCMT/atautorelease-2.m create mode 100644 test/ARCMT/atautorelease-2.m.result create mode 100644 test/ARCMT/atautorelease-3.m create mode 100644 test/ARCMT/atautorelease-3.m.result create mode 100644 test/ARCMT/atautorelease-check.m create mode 100644 test/ARCMT/atautorelease.m create mode 100644 test/ARCMT/atautorelease.m.result create mode 100644 test/ARCMT/autoreleases.m create mode 100644 test/ARCMT/autoreleases.m.result create mode 100644 test/ARCMT/checking.m create mode 100644 test/ARCMT/cxx-checking.mm create mode 100644 test/ARCMT/cxx-rewrite.mm create mode 100644 test/ARCMT/cxx-rewrite.mm.result create mode 100644 test/ARCMT/dealloc.m create mode 100644 test/ARCMT/dealloc.m.result create mode 100644 test/ARCMT/driver-migrate.m create mode 100644 test/ARCMT/init.m create mode 100644 test/ARCMT/init.m.result create mode 100644 test/ARCMT/migrate.m create mode 100644 test/ARCMT/nonobjc-to-objc-cast-2.m create mode 100644 test/ARCMT/nonobjc-to-objc-cast.m create mode 100644 test/ARCMT/nonobjc-to-objc-cast.m.result create mode 100644 test/ARCMT/releases-driver.m create mode 100644 test/ARCMT/releases-driver.m.result create mode 100644 test/ARCMT/releases.m create mode 100644 test/ARCMT/releases.m.result create mode 100644 test/ARCMT/remove-dealloc-method.m create mode 100644 test/ARCMT/remove-dealloc-method.m.result create mode 100644 test/ARCMT/remove-dealloc-zerouts.m create mode 100644 test/ARCMT/remove-dealloc-zerouts.m.result create mode 100644 test/ARCMT/remove-statements.m create mode 100644 test/ARCMT/remove-statements.m.result create mode 100644 test/ARCMT/retains.m create mode 100644 test/ARCMT/retains.m.result create mode 100644 test/ARCMT/rewrite-block-var.m create mode 100644 test/ARCMT/rewrite-block-var.m.result create mode 100644 test/ARCMT/safe-arc-assign.m create mode 100644 test/ARCMT/safe-arc-assign.m.result create mode 100644 test/ARCMT/with-arc-mode-check.m create mode 100644 test/ARCMT/with-arc-mode-migrate.m create mode 100644 test/ARCMT/with-arc-mode-migrate.m.result create mode 100644 test/ARCMT/with-arc-mode-modify.m create mode 100644 test/ARCMT/with-arc-mode-modify.m.result create mode 100644 test/Analysis/objc-arc.m create mode 100644 test/Analysis/retain-release-path-notes-gc.m create mode 100644 test/Analysis/retain-release-path-notes.m create mode 100644 test/Analysis/string-fail.c create mode 100644 test/CXX/class/p6-0x.cpp create mode 100644 test/CXX/except/except.spec/canonical.cpp create mode 100644 test/CXX/temp/p3.cpp create mode 100644 test/CodeGen/arm-asm-variable.c create mode 100644 test/CodeGen/attr-weak-import.c delete mode 100644 test/CodeGen/call-knr-indirect.c create mode 100644 test/CodeGen/call.c create mode 100644 test/CodeGen/complex-indirect.c create mode 100644 test/CodeGen/darwin-thread-specifier.c create mode 100644 test/CodeGen/debug-info-iv.c create mode 100644 test/CodeGen/debug-info-member.c create mode 100644 test/CodeGen/private-extern-redef.c create mode 100644 test/CodeGen/x86_32-arguments-nommx.c create mode 100644 test/CodeGenCXX/compound-literals.cpp create mode 100644 test/CodeGenCXX/new-overflow.cpp create mode 100644 test/CodeGenCXX/noinline-template.cpp create mode 100644 test/CodeGenCXX/partial-destruction.cpp create mode 100644 test/CodeGenCXX/vla.cpp create mode 100644 test/CodeGenObjC/arc-arm.m create mode 100644 test/CodeGenObjC/arc-block-ivar-layout.m create mode 100644 test/CodeGenObjC/arc-bridged-cast.m create mode 100644 test/CodeGenObjC/arc-compound-stmt.m create mode 100644 test/CodeGenObjC/arc-foreach.m create mode 100644 test/CodeGenObjC/arc-ivar-layout.m create mode 100644 test/CodeGenObjC/arc-no-runtime.m create mode 100644 test/CodeGenObjC/arc-related-result-type.m create mode 100644 test/CodeGenObjC/arc-unbridged-cast.m create mode 100644 test/CodeGenObjC/arc-unopt.m create mode 100644 test/CodeGenObjC/arc-weak-property.m create mode 100644 test/CodeGenObjC/arc.m create mode 100644 test/CodeGenObjC/autorelease.m delete mode 100644 test/CodeGenObjC/debug-info-foreach.m create mode 100644 test/CodeGenObjC/gc.m create mode 100644 test/CodeGenObjC/mrr-autorelease.m create mode 100644 test/CodeGenObjC/nonlazy-msgSend.m create mode 100644 test/CodeGenObjC/related-result-type.m create mode 100644 test/CodeGenObjC/terminate.m create mode 100644 test/CodeGenObjCXX/arc-globals.mm create mode 100644 test/CodeGenObjCXX/arc-mangle.mm create mode 100644 test/CodeGenObjCXX/arc-move.mm create mode 100644 test/CodeGenObjCXX/arc-new-delete.mm create mode 100644 test/CodeGenObjCXX/arc-pseudo-destructors.mm create mode 100644 test/CodeGenObjCXX/arc-references.mm create mode 100644 test/CodeGenObjCXX/arc-special-member-functions.mm create mode 100644 test/CodeGenObjCXX/arc.mm create mode 100644 test/CodeGenObjCXX/catch-id-type.mm create mode 100644 test/CodeGenObjCXX/copy.mm create mode 100644 test/CodeGenObjCXX/gc.mm create mode 100644 test/CodeGenOpenCL/vector_literals_valid.cl create mode 100644 test/Driver/arc-exceptions.m create mode 100644 test/Driver/arc.c create mode 100644 test/Driver/gnu-runtime.m create mode 100644 test/Driver/ios-simulator-arcruntime.c create mode 100644 test/Driver/mg.c create mode 100644 test/Driver/no-objc-arr.m create mode 100644 test/Driver/noexecstack.c create mode 100644 test/FixIt/typo-crash.cpp create mode 100644 test/Index/arc-annotate.m create mode 100644 test/Index/arc-complete.m create mode 100644 test/Index/werror.c create mode 100644 test/Lexer/has_feature_objc_arc.m create mode 100644 test/PCH/Inputs/arc.h create mode 100644 test/PCH/Inputs/typo.hpp create mode 100644 test/PCH/arc.m create mode 100644 test/PCH/typo.cpp create mode 100644 test/Parser/parenthesis-balance.cpp create mode 100644 test/Preprocessor/pragma_diagnostic_output.c create mode 100644 test/Preprocessor/warn-macro-unused.h create mode 100644 test/Sema/inline-redef.c create mode 100644 test/Sema/no-format-y2k-turnsoff-format.c create mode 100644 test/Sema/nonnull.c create mode 100644 test/Sema/paren-list-expr-type.cpp create mode 100644 test/Sema/sign-conversion.c create mode 100644 test/Sema/warn-sizeof-arrayarg.c create mode 100644 test/SemaCXX/PR10243.cpp create mode 100644 test/SemaCXX/PR7410.cpp create mode 100644 test/SemaCXX/for-range-unused.cpp create mode 100644 test/SemaCXX/function-overload-typo-crash.cpp create mode 100644 test/SemaCXX/missing-namespace-qualifier-typo-corrections.cpp create mode 100644 test/SemaCXX/null_in_arithmetic_ops.cpp create mode 100644 test/SemaCXX/nullptr_in_arithmetic_ops.cpp create mode 100644 test/SemaCXX/warn-memset-bad-sizeof.cpp create mode 100644 test/SemaObjC/Inputs/arc-system-header.h create mode 100644 test/SemaObjC/arc-bridged-cast.m create mode 100644 test/SemaObjC/arc-decls.m create mode 100644 test/SemaObjC/arc-jump-block.m create mode 100644 test/SemaObjC/arc-no-runtime.m create mode 100644 test/SemaObjC/arc-non-pod-memaccess.m create mode 100644 test/SemaObjC/arc-peformselector.m create mode 100644 test/SemaObjC/arc-property-decl-attrs.m create mode 100644 test/SemaObjC/arc-property-lifetime.m create mode 100644 test/SemaObjC/arc-property.m create mode 100644 test/SemaObjC/arc-system-header.m create mode 100644 test/SemaObjC/arc-type-conversion.m create mode 100644 test/SemaObjC/arc-unavailable-for-weakref.m create mode 100644 test/SemaObjC/arc-unbridged-cast.m create mode 100644 test/SemaObjC/arc-unsafe-assigns.m create mode 100644 test/SemaObjC/arc-unsafe_unretained.m create mode 100644 test/SemaObjC/arc.m create mode 100644 test/SemaObjC/autoreleasepool.m create mode 100644 test/SemaObjC/debugger-support.m create mode 100644 test/SemaObjC/no-warning-unavail-unimp.m create mode 100644 test/SemaObjC/property-ns-returns-not-retained-attr.m create mode 100644 test/SemaObjC/warn-retain-cycle.m create mode 100644 test/SemaObjC/weak-property.m create mode 100644 test/SemaObjCXX/Inputs/arc-system-header.h create mode 100644 test/SemaObjCXX/arc-0x.mm create mode 100644 test/SemaObjCXX/arc-bool-conversion.mm create mode 100644 test/SemaObjCXX/arc-bridged-cast.mm create mode 100644 test/SemaObjCXX/arc-libcxx.mm create mode 100644 test/SemaObjCXX/arc-libstdcxx.mm create mode 100644 test/SemaObjCXX/arc-memfunc.mm create mode 100644 test/SemaObjCXX/arc-non-pod.mm create mode 100644 test/SemaObjCXX/arc-object-init-destroy.mm create mode 100644 test/SemaObjCXX/arc-overloading.mm create mode 100644 test/SemaObjCXX/arc-system-header.mm create mode 100644 test/SemaObjCXX/arc-templates.mm create mode 100644 test/SemaObjCXX/arc-type-conversion.mm create mode 100644 test/SemaObjCXX/arc-type-traits.mm create mode 100644 test/SemaObjCXX/arc-unavailable-for-weakref.mm create mode 100644 test/SemaObjCXX/null_objc_pointer.mm create mode 100644 test/SemaObjCXX/property-type-mismatch.mm create mode 100644 test/SemaOpenCL/vector_literals_invalid.cl create mode 100644 test/SemaTemplate/member-inclass-init-value-dependent.cpp create mode 100644 test/SemaTemplate/unresolved-construct.cpp (limited to 'test') diff --git a/test/ARCMT/Common.h b/test/ARCMT/Common.h new file mode 100644 index 0000000..c57f3e7 --- /dev/null +++ b/test/ARCMT/Common.h @@ -0,0 +1,55 @@ +#if __has_feature(objc_arr) +#define NS_AUTOMATED_REFCOUNT_UNAVAILABLE __attribute__((unavailable("not available in automatic reference counting mode"))) +#else +#define NS_AUTOMATED_REFCOUNT_UNAVAILABLE +#endif + +typedef int BOOL; +typedef unsigned NSUInteger; +typedef int int32_t; +typedef unsigned char uint8_t; +typedef int32_t UChar32; +typedef unsigned char UChar; + +@protocol NSObject +- (BOOL)isEqual:(id)object; +- (id)retain NS_AUTOMATED_REFCOUNT_UNAVAILABLE; +- (NSUInteger)retainCount NS_AUTOMATED_REFCOUNT_UNAVAILABLE; +- (oneway void)release NS_AUTOMATED_REFCOUNT_UNAVAILABLE; +- (id)autorelease NS_AUTOMATED_REFCOUNT_UNAVAILABLE; +@end + +@interface NSObject {} +- (id)init; + ++ (id)new; ++ (id)alloc; +- (void)dealloc; + +- (void)finalize; + +- (id)copy; +- (id)mutableCopy; +@end + +NS_AUTOMATED_REFCOUNT_UNAVAILABLE +@interface NSAutoreleasePool : NSObject { +@private + void *_token; + void *_reserved3; + void *_reserved2; + void *_reserved; +} + ++ (void)addObject:(id)anObject; + +- (void)addObject:(id)anObject; + +- (void)drain; + +@end + +typedef const void* objc_objectptr_t; +extern __attribute__((ns_returns_retained)) id objc_retainedObject(objc_objectptr_t __attribute__((cf_consumed)) pointer); +extern __attribute__((ns_returns_not_retained)) id objc_unretainedObject(objc_objectptr_t pointer); +extern objc_objectptr_t objc_unretainedPointer(id object); diff --git a/test/ARCMT/Inputs/test.h b/test/ARCMT/Inputs/test.h new file mode 100644 index 0000000..756295f --- /dev/null +++ b/test/ARCMT/Inputs/test.h @@ -0,0 +1,15 @@ +@protocol NSObject +- (oneway void)release; +@end + +#ifdef PART1 +static inline void part1(id p) { + [p release]; +} +#endif + +#ifdef PART2 +static inline void part2(id p) { + [p release]; +} +#endif diff --git a/test/ARCMT/Inputs/test.h.result b/test/ARCMT/Inputs/test.h.result new file mode 100644 index 0000000..0638a33 --- /dev/null +++ b/test/ARCMT/Inputs/test.h.result @@ -0,0 +1,13 @@ +@protocol NSObject +- (oneway void)release; +@end + +#ifdef PART1 +static inline void part1(id p) { +} +#endif + +#ifdef PART2 +static inline void part2(id p) { +} +#endif diff --git a/test/ARCMT/Inputs/test1.m.in b/test/ARCMT/Inputs/test1.m.in new file mode 100644 index 0000000..8416a88 --- /dev/null +++ b/test/ARCMT/Inputs/test1.m.in @@ -0,0 +1,6 @@ +#define PART1 +#include "test.h" + +void test1(id p) { + [p release]; +} diff --git a/test/ARCMT/Inputs/test1.m.in.result b/test/ARCMT/Inputs/test1.m.in.result new file mode 100644 index 0000000..f351fe6 --- /dev/null +++ b/test/ARCMT/Inputs/test1.m.in.result @@ -0,0 +1,5 @@ +#define PART1 +#include "test.h" + +void test1(id p) { +} diff --git a/test/ARCMT/Inputs/test2.m.in b/test/ARCMT/Inputs/test2.m.in new file mode 100644 index 0000000..99f87b0 --- /dev/null +++ b/test/ARCMT/Inputs/test2.m.in @@ -0,0 +1,6 @@ +#define PART2 +#include "test.h" + +void test2(id p) { + [p release]; +} diff --git a/test/ARCMT/Inputs/test2.m.in.result b/test/ARCMT/Inputs/test2.m.in.result new file mode 100644 index 0000000..f8e918c --- /dev/null +++ b/test/ARCMT/Inputs/test2.m.in.result @@ -0,0 +1,5 @@ +#define PART2 +#include "test.h" + +void test2(id p) { +} diff --git a/test/ARCMT/assign-prop-no-arc-runtime.m b/test/ARCMT/assign-prop-no-arc-runtime.m new file mode 100644 index 0000000..0baa1d2 --- /dev/null +++ b/test/ARCMT/assign-prop-no-arc-runtime.m @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -triple x86_64-apple-macosx10.6 -fobjc-nonfragile-abi -fsyntax-only %s > %t +// RUN: diff %t %s.result + +#include "Common.h" + +@interface Foo : NSObject { + NSObject *x; +} +@property (readonly,assign) id x; +@end + +@implementation Foo +@synthesize x; +@end diff --git a/test/ARCMT/assign-prop-no-arc-runtime.m.result b/test/ARCMT/assign-prop-no-arc-runtime.m.result new file mode 100644 index 0000000..49e91d8 --- /dev/null +++ b/test/ARCMT/assign-prop-no-arc-runtime.m.result @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -triple x86_64-apple-macosx10.6 -fobjc-nonfragile-abi -fsyntax-only %s > %t +// RUN: diff %t %s.result + +#include "Common.h" + +@interface Foo : NSObject { + NSObject *__unsafe_unretained x; +} +@property (readonly,unsafe_unretained) id x; +@end + +@implementation Foo +@synthesize x; +@end diff --git a/test/ARCMT/assign-prop-with-arc-runtime.m b/test/ARCMT/assign-prop-with-arc-runtime.m new file mode 100644 index 0000000..4e4ae77 --- /dev/null +++ b/test/ARCMT/assign-prop-with-arc-runtime.m @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -fobjc-runtime-has-weak -x objective-c %s.result +// RUN: arcmt-test --args -triple x86_64-apple-macosx10.7 -fobjc-nonfragile-abi -fsyntax-only %s > %t +// RUN: diff %t %s.result + +#include "Common.h" + +__attribute__((objc_arc_weak_reference_unavailable)) +@interface WeakOptOut +@end + +@class _NSCachedAttributedString; +typedef _NSCachedAttributedString *BadClassForWeak; + +@class Forw; + +@interface Foo : NSObject { + Foo *x, *w, *q1, *q2; + WeakOptOut *oo; + BadClassForWeak bcw; + id not_safe1; + NSObject *not_safe2; + Forw *not_safe3; +} +@property (readonly,assign) Foo *x; +@property (assign) Foo *w; +@property Foo *q1, *q2; +@property (assign) WeakOptOut *oo; +@property (assign) BadClassForWeak bcw; +@property (assign) id not_safe1; +@property () NSObject *not_safe2; +@property Forw *not_safe3; + +@property (assign) Foo *no_user_ivar1; +@property (readonly) Foo *no_user_ivar2; +@end + +@implementation Foo +@synthesize x,w,q1,q2,oo,bcw,not_safe1,not_safe2,not_safe3; +@synthesize no_user_ivar1, no_user_ivar2; +@end diff --git a/test/ARCMT/assign-prop-with-arc-runtime.m.result b/test/ARCMT/assign-prop-with-arc-runtime.m.result new file mode 100644 index 0000000..eb34c16 --- /dev/null +++ b/test/ARCMT/assign-prop-with-arc-runtime.m.result @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -fobjc-runtime-has-weak -x objective-c %s.result +// RUN: arcmt-test --args -triple x86_64-apple-macosx10.7 -fobjc-nonfragile-abi -fsyntax-only %s > %t +// RUN: diff %t %s.result + +#include "Common.h" + +__attribute__((objc_arc_weak_reference_unavailable)) +@interface WeakOptOut +@end + +@class _NSCachedAttributedString; +typedef _NSCachedAttributedString *BadClassForWeak; + +@class Forw; + +@interface Foo : NSObject { + Foo *__weak x, *__weak w, *__weak q1, *__weak q2; + WeakOptOut *__unsafe_unretained oo; + BadClassForWeak __unsafe_unretained bcw; + id __unsafe_unretained not_safe1; + NSObject *__unsafe_unretained not_safe2; + Forw *__unsafe_unretained not_safe3; +} +@property (readonly,weak) Foo *x; +@property (weak) Foo *w; +@property (weak) Foo *q1, *q2; +@property (unsafe_unretained) WeakOptOut *oo; +@property (unsafe_unretained) BadClassForWeak bcw; +@property (unsafe_unretained) id not_safe1; +@property (unsafe_unretained) NSObject *not_safe2; +@property (unsafe_unretained) Forw *not_safe3; + +@property (weak) Foo *no_user_ivar1; +@property (weak, readonly) Foo *no_user_ivar2; +@end + +@implementation Foo +@synthesize x,w,q1,q2,oo,bcw,not_safe1,not_safe2,not_safe3; +@synthesize no_user_ivar1, no_user_ivar2; +@end diff --git a/test/ARCMT/atautorelease-2.m b/test/ARCMT/atautorelease-2.m new file mode 100644 index 0000000..5d29772 --- /dev/null +++ b/test/ARCMT/atautorelease-2.m @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -x objective-c %s > %t +// RUN: diff %t %s.result + +@interface NSAutoreleasePool +- drain; ++new; ++alloc; +-init; +-autorelease; +-release; +@end + +void NSLog(id, ...); + +int main (int argc, const char * argv[]) { + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + NSAutoreleasePool *chunkPool = [[NSAutoreleasePool alloc] init]; + + while (argc) { + [chunkPool release]; + return 0; + } + + [chunkPool drain]; + [pool drain]; + + return 0; +} diff --git a/test/ARCMT/atautorelease-2.m.result b/test/ARCMT/atautorelease-2.m.result new file mode 100644 index 0000000..7bb1647 --- /dev/null +++ b/test/ARCMT/atautorelease-2.m.result @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -x objective-c %s > %t +// RUN: diff %t %s.result + +@interface NSAutoreleasePool +- drain; ++new; ++alloc; +-init; +-autorelease; +-release; +@end + +void NSLog(id, ...); + +int main (int argc, const char * argv[]) { + @autoreleasepool { + @autoreleasepool { + + while (argc) { + return 0; + } + + } + } + + return 0; +} diff --git a/test/ARCMT/atautorelease-3.m b/test/ARCMT/atautorelease-3.m new file mode 100644 index 0000000..5d71c33 --- /dev/null +++ b/test/ARCMT/atautorelease-3.m @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -x objective-c %s > %t +// RUN: diff %t %s.result + +@interface NSAutoreleasePool +- drain; ++new; ++alloc; +-init; +-autorelease; +- release; +@end + +void NSLog(id, ...); + +void test1(int x) { + // All this stuff get removed since nothing is happening inside. + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + NSAutoreleasePool *chunkPool = [[NSAutoreleasePool alloc] init]; + while (x) { + chunkPool = [[NSAutoreleasePool alloc] init]; + [chunkPool release]; + } + + [chunkPool drain]; + [pool drain]; +} + +void test2(int x) { + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + NSAutoreleasePool *chunkPool = [[NSAutoreleasePool alloc] init]; + while (x) { + chunkPool = [[NSAutoreleasePool alloc] init]; + ++x; + [chunkPool release]; + } + + [chunkPool drain]; + [pool drain]; +} diff --git a/test/ARCMT/atautorelease-3.m.result b/test/ARCMT/atautorelease-3.m.result new file mode 100644 index 0000000..682118e --- /dev/null +++ b/test/ARCMT/atautorelease-3.m.result @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -x objective-c %s > %t +// RUN: diff %t %s.result + +@interface NSAutoreleasePool +- drain; ++new; ++alloc; +-init; +-autorelease; +- release; +@end + +void NSLog(id, ...); + +void test1(int x) { + // All this stuff get removed since nothing is happening inside. +} + +void test2(int x) { + @autoreleasepool { + @autoreleasepool { + while (x) { + @autoreleasepool { + ++x; + } + } + + } + } +} diff --git a/test/ARCMT/atautorelease-check.m b/test/ARCMT/atautorelease-check.m new file mode 100644 index 0000000..6528f3e --- /dev/null +++ b/test/ARCMT/atautorelease-check.m @@ -0,0 +1,144 @@ +// RUN: %clang_cc1 -arcmt-check -verify -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi %s + +#if __has_feature(objc_arr) +#define NS_AUTOMATED_REFCOUNT_UNAVAILABLE __attribute__((unavailable("not available in automatic reference counting mode"))) +#else +#define NS_AUTOMATED_REFCOUNT_UNAVAILABLE +#endif + +typedef struct _NSZone NSZone; +typedef int BOOL; +typedef unsigned NSUInteger; + +@protocol NSObject +- (BOOL)isEqual:(id)object; +- (id)retain NS_AUTOMATED_REFCOUNT_UNAVAILABLE; +- (NSUInteger)retainCount NS_AUTOMATED_REFCOUNT_UNAVAILABLE; +- (oneway void)release NS_AUTOMATED_REFCOUNT_UNAVAILABLE; +- (id)autorelease NS_AUTOMATED_REFCOUNT_UNAVAILABLE; + +- (NSZone *)zone NS_AUTOMATED_REFCOUNT_UNAVAILABLE; +@end + +@protocol NSCopying +- (id)copyWithZone:(NSZone *)zone; +@end + +@protocol NSMutableCopying +- (id)mutableCopyWithZone:(NSZone *)zone; +@end + +@interface NSObject {} +- (id)init; + ++ (id)new; ++ (id)allocWithZone:(NSZone *)zone NS_AUTOMATED_REFCOUNT_UNAVAILABLE; ++ (id)alloc; +- (void)dealloc; + +- (void)finalize; + +- (id)copy; +- (id)mutableCopy; + ++ (id)copyWithZone:(NSZone *)zone NS_AUTOMATED_REFCOUNT_UNAVAILABLE; ++ (id)mutableCopyWithZone:(NSZone *)zone NS_AUTOMATED_REFCOUNT_UNAVAILABLE; +@end + +extern void NSRecycleZone(NSZone *zone); + +NS_AUTOMATED_REFCOUNT_UNAVAILABLE +@interface NSAutoreleasePool : NSObject { // expected-note 13 {{marked unavailable here}} +@private + void *_token; + void *_reserved3; + void *_reserved2; + void *_reserved; +} + ++ (void)addObject:(id)anObject; + +- (void)addObject:(id)anObject; + +- (void)drain; + +@end + + +void NSLog(id, ...); + +int main (int argc, const char * argv[]) { + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + NSAutoreleasePool *chunkPool = [[NSAutoreleasePool alloc] init]; // expected-error 2 {{'NSAutoreleasePool' is unavailable}} + + while (argc) { + [chunkPool release]; + // the following pool was not released in this scope, don't touch it. + chunkPool = [[NSAutoreleasePool alloc] init]; // expected-error {{'NSAutoreleasePool' is unavailable}} + } + + [chunkPool drain]; + [pool drain]; + + return 0; +} + +void f(void) { + NSAutoreleasePool * pool; // expected-error {{'NSAutoreleasePool' is unavailable}} + + for (int i=0; i != 10; ++i) { + id x = pool; // We won't touch a NSAutoreleasePool if we can't safely + // remove all the references to it. + } + + pool = [[NSAutoreleasePool alloc] init]; // expected-error {{'NSAutoreleasePool' is unavailable}} + NSLog(@"%s", "YES"); + [pool release]; +} + +void f2(void) { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // expected-error 2 {{'NSAutoreleasePool' is unavailable}} \ + // expected-note {{scope begins here}} + + // 'x' is declared inside the "pool scope" but used outside it, if we create + // a @autorelease scope it will be undefined outside it so don't touch the pool. + int x = 0; // expected-note {{declared here}} + + [pool release]; // expected-note {{scope ends here}} + + ++x; // expected-error {{a name is referenced outside the NSAutoreleasePool scope that it was declared in}} +} + +void f3(void) { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // expected-error 2 {{'NSAutoreleasePool' is unavailable}} \ + // expected-note {{scope begins here}} + + struct S { int x; }; // expected-note {{declared here}} + + [pool release]; // expected-note {{scope ends here}} + + struct S *var; // expected-error {{a name is referenced outside the NSAutoreleasePool scope that it was declared in}} + var->x = 0; +} + +void f4(void) { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // expected-error 2 {{'NSAutoreleasePool' is unavailable}} \ + // expected-note {{scope begins here}} + + enum { Bar }; // expected-note {{declared here}} + + [pool release]; // expected-note {{scope ends here}} + + int x = Bar; // expected-error {{a name is referenced outside the NSAutoreleasePool scope that it was declared in}} +} + +void f5(void) { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // expected-error 2 {{'NSAutoreleasePool' is unavailable}} \ + // expected-note {{scope begins here}} + + typedef int Bar; // expected-note {{declared here}} + + [pool release]; // expected-note {{scope ends here}} + + Bar x; // expected-error {{a name is referenced outside the NSAutoreleasePool scope that it was declared in}} +} diff --git a/test/ARCMT/atautorelease.m b/test/ARCMT/atautorelease.m new file mode 100644 index 0000000..bdf7719 --- /dev/null +++ b/test/ARCMT/atautorelease.m @@ -0,0 +1,47 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -x objective-c %s > %t +// RUN: diff %t %s.result + +#include "Common.h" + +void NSLog(id, ...); + +int main (int argc, const char * argv[]) { + + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + + if (argc) { + NSAutoreleasePool * pool = [NSAutoreleasePool new]; + NSLog(@"%s", "YES"); + [pool drain]; + } + [pool drain]; + + NSAutoreleasePool * pool1 = [[NSAutoreleasePool alloc] init]; + NSLog(@"%s", "YES"); + [pool1 release]; + + return 0; +} + +void f(void) { + NSAutoreleasePool *pool1; + + pool1 = [NSAutoreleasePool new]; + int x = 4; + + NSAutoreleasePool *pool2 = [[NSAutoreleasePool alloc] init]; + ++x; + [pool2 drain]; + + [pool1 release]; +} + +int UIApplicationMain(int argc, char *argv[]); + +int main2(int argc, char *argv[]) { + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int result = UIApplicationMain(argc, argv); + [pool release]; + return result; +} diff --git a/test/ARCMT/atautorelease.m.result b/test/ARCMT/atautorelease.m.result new file mode 100644 index 0000000..ccce1bd --- /dev/null +++ b/test/ARCMT/atautorelease.m.result @@ -0,0 +1,46 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -x objective-c %s > %t +// RUN: diff %t %s.result + +#include "Common.h" + +void NSLog(id, ...); + +int main (int argc, const char * argv[]) { + + @autoreleasepool { + + if (argc) { + @autoreleasepool { + NSLog(@"%s", "YES"); + } + } + } + + @autoreleasepool { + NSLog(@"%s", "YES"); + } + + return 0; +} + +void f(void) { + + @autoreleasepool { + int x = 4; + + @autoreleasepool { + ++x; + } + + } +} + +int UIApplicationMain(int argc, char *argv[]); + +int main2(int argc, char *argv[]) { + @autoreleasepool { + int result = UIApplicationMain(argc, argv); + return result; + } +} diff --git a/test/ARCMT/autoreleases.m b/test/ARCMT/autoreleases.m new file mode 100644 index 0000000..a12db81 --- /dev/null +++ b/test/ARCMT/autoreleases.m @@ -0,0 +1,48 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -x objective-c %s > %t +// RUN: diff %t %s.result + +typedef unsigned char BOOL; + +@interface NSObject { + id isa; +} ++new; ++alloc; +-init; +-autorelease; +@end + +@interface NSAutoreleasePool : NSObject +- drain; +@end + +@interface A : NSObject { +@package + id object; +} +@end + +@interface B : NSObject +- (BOOL)containsSelf:(A*)a; +@end + +@implementation A +@end + +@implementation B +- (BOOL)containsSelf:(A*)a { + return a->object == self; +} +@end + +void NSLog(id, ...); + +int main (int argc, const char * argv[]) { + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + A *a = [[A new] autorelease]; + B *b = [[B new] autorelease]; + NSLog(@"%s", [b containsSelf:a] ? "YES" : "NO"); + [pool drain]; + return 0; +} diff --git a/test/ARCMT/autoreleases.m.result b/test/ARCMT/autoreleases.m.result new file mode 100644 index 0000000..796bfbb --- /dev/null +++ b/test/ARCMT/autoreleases.m.result @@ -0,0 +1,48 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -x objective-c %s > %t +// RUN: diff %t %s.result + +typedef unsigned char BOOL; + +@interface NSObject { + id isa; +} ++new; ++alloc; +-init; +-autorelease; +@end + +@interface NSAutoreleasePool : NSObject +- drain; +@end + +@interface A : NSObject { +@package + id object; +} +@end + +@interface B : NSObject +- (BOOL)containsSelf:(A*)a; +@end + +@implementation A +@end + +@implementation B +- (BOOL)containsSelf:(A*)a { + return a->object == self; +} +@end + +void NSLog(id, ...); + +int main (int argc, const char * argv[]) { + @autoreleasepool { + A *a = [A new]; + B *b = [B new]; + NSLog(@"%s", [b containsSelf:a] ? "YES" : "NO"); + } + return 0; +} diff --git a/test/ARCMT/checking.m b/test/ARCMT/checking.m new file mode 100644 index 0000000..eea7a9f --- /dev/null +++ b/test/ARCMT/checking.m @@ -0,0 +1,295 @@ +// RUN: %clang_cc1 -arcmt-check -verify -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi %s + +#include "Common.h" + +typedef const struct __CFString * CFStringRef; +extern const CFStringRef kUTTypePlainText; +extern const CFStringRef kUTTypeRTF; +@class NSString; +@class A; + +struct UnsafeS { + A *__unsafe_unretained unsafeObj; +}; + +@interface A : NSObject +- (id)retain; +- (id)retainCount; +- (id)autorelease; +- (id)init; +- (oneway void)release; +- (void)dealloc; +-(void)test; +-(id)delegate; +@end + +@implementation A +-(void)test { + [super dealloc]; +} +-(void)dealloc { + [super dealloc]; +} + +- (id)retain { return self; } // expected-error {{ARC forbids implementation}} +- (id)retainCount { return self; } // expected-error {{ARC forbids implementation}} +- (id)autorelease { return self; } // expected-error {{ARC forbids implementation}} +- (oneway void)release { } // expected-error {{ARC forbids implementation}} + +-(id)delegate { return self; } +@end + +id global_foo; + +void test1(A *a, BOOL b, struct UnsafeS *unsafeS) { + [[a delegate] release]; // expected-error {{it is not safe to remove 'retain' message on the result of a 'delegate' message; the object that was passed to 'setDelegate:' may not be properly retained}} \ + // expected-error {{ARC forbids explicit message send}} + [a.delegate release]; // expected-error {{it is not safe to remove 'retain' message on the result of a 'delegate' message; the object that was passed to 'setDelegate:' may not be properly retained}} \ + // expected-error {{ARC forbids explicit message send}} + [unsafeS->unsafeObj retain]; // expected-error {{it is not safe to remove 'retain' message on an __unsafe_unretained type}} \ + // expected-error {{ARC forbids explicit message send}} + id foo = [unsafeS->unsafeObj retain]; // no warning. + [global_foo retain]; // expected-error {{it is not safe to remove 'retain' message on a global variable}} \ + // expected-error {{ARC forbids explicit message send}} + [global_foo release]; // expected-error {{it is not safe to remove 'release' message on a global variable}} \ + // expected-error {{ARC forbids explicit message send}} + [a dealloc]; + [a retain]; + [a retainCount]; // expected-error {{ARC forbids explicit message send of 'retainCount'}} + [a release]; + [a autorelease]; // expected-error {{it is not safe to remove an unused 'autorelease' message; its receiver may be destroyed immediately}} \ + // expected-error {{ARC forbids explicit message send}} + + CFStringRef cfstr; + NSString *str = (NSString *)cfstr; // expected-error {{cast of C pointer type 'CFStringRef' (aka 'const struct __CFString *') to Objective-C pointer type 'NSString *' requires a bridged cast}} \ + // expected-note{{use __bridge to convert directly (no change in ownership)}} \ + // expected-note{{use __bridge_transfer to transfer ownership of a +1 'CFStringRef' (aka 'const struct __CFString *') into ARC}} + str = (NSString *)kUTTypePlainText; + str = b ? kUTTypeRTF : kUTTypePlainText; + str = (NSString *)(b ? kUTTypeRTF : kUTTypePlainText); + str = (NSString *)a; // no change. + + SEL s = @selector(retain); // expected-error {{ARC forbids use of 'retain' in a @selector}} + s = @selector(release); // expected-error {{ARC forbids use of 'release' in a @selector}} + s = @selector(autorelease); // expected-error {{ARC forbids use of 'autorelease' in a @selector}} + s = @selector(dealloc); // expected-error {{ARC forbids use of 'dealloc' in a @selector}} + + static id __autoreleasing X1; // expected-error {{global variables cannot have __autoreleasing ownership}} +} + +struct S { + A* a; // expected-error {{ARC forbids Objective-C objects in structs or unions}} +}; + +@interface B +-(id)alloc; +- (id)initWithInt: (int) i; +@end + +void rdar8861761() { + B *o1 = [[B alloc] initWithInt:0]; + B *o2 = [B alloc]; + [o2 initWithInt:0]; +} + +@interface Test13 +- (id) init0; +- (void) noninit; +@end +@implementation Test13 +- (id) init0 { + self = 0; +} +- (void) noninit { + self = 0; // expected-error {{cannot assign to 'self' outside of a method in the init family}} + + for (id x in collection) { // expected-error {{use of undeclared identifier 'collection'}} + x = 0; + } +} +@end + +void * cvt(id arg) +{ + void* voidp_val; + (void)(int*)arg; // expected-error {{disallowed}} + (void)(id)arg; + (void)(__autoreleasing id*)arg; // expected-error {{disallowed}} + (void)(id*)arg; // expected-error {{disallowed}} + + (void)(__autoreleasing id**)voidp_val; + (void)(void*)voidp_val; + (void)(void**)arg; // expected-error {{disallowed}} + cvt((void*)arg); // expected-error {{requires a bridged cast}} expected-error {{disallowed}} \ + // expected-note {{use __bridge}} expected-note {{use __bridge_retained}} + cvt(0); + (void)(__strong id**)(0); + return arg; // expected-error {{disallowed}} +} + + +void test12(id collection) { + for (id x in collection) { + x = 0; + } + + for (__strong id x in collection) { + x = 0; + } +} + +void test6(unsigned cond) { + // FIXME: Fix this automatically ? + switch (cond) { + case 0: + ; + id x; // expected-note {{jump bypasses initialization of retaining variable}} + + case 1: // expected-error {{switch case is in protected scope}} + break; + } +} + +@class Test8_incomplete; +@interface Test8_complete @end; +@interface Test8_super @end; +@interface Test8 : Test8_super +- (id) init00; +- (id) init01; // expected-note {{declaration in interface}} +- (id) init02; +- (id) init03; // covariance +- (id) init04; // covariance +- (id) init05; + +- (void) init10; // expected-note {{declaration in interface is not in the 'init' family because its result type is not an object pointer}} +- (void) init11; +- (void) init12; +- (void) init13; // expected-note {{declaration in interface is not in the 'init' family because its result type is not an object pointer}} +- (void) init14; // expected-note {{declaration in interface is not in the 'init' family because its result type is not an object pointer}} +- (void) init15; + +// These should be invalid to actually call. +- (Test8_incomplete*) init20; +- (Test8_incomplete*) init21; // expected-note {{declaration in interface}} +- (Test8_incomplete*) init22; +- (Test8_incomplete*) init23; +- (Test8_incomplete*) init24; +- (Test8_incomplete*) init25; + +- (Test8_super*) init30; // id exception to covariance +- (Test8_super*) init31; // expected-note {{declaration in interface}} +- (Test8_super*) init32; +- (Test8_super*) init33; +- (Test8_super*) init34; // covariance +- (Test8_super*) init35; + +- (Test8*) init40; // id exception to covariance +- (Test8*) init41; // expected-note {{declaration in interface}} +- (Test8*) init42; +- (Test8*) init43; // this should be a warning, but that's a general language thing, not an ARC thing +- (Test8*) init44; +- (Test8*) init45; + +- (Test8_complete*) init50; // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_complete*) init51; // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_complete*) init52; // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_complete*) init53; // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_complete*) init54; // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_complete*) init55; // expected-error {{init methods must return a type related to the receiver type}} +@end +@implementation Test8 +- (id) init00 { return 0; } +- (id) init10 { return 0; } // expected-error {{method implementation does not match its declaration}} +- (id) init20 { return 0; } +- (id) init30 { return 0; } +- (id) init40 { return 0; } +- (id) init50 { return 0; } + +- (void) init01 {} // expected-error {{method was declared as an 'init' method, but its implementation doesn't match because its result type is not an object pointer}} +- (void) init11 {} +- (void) init21 {} // expected-error {{method was declared as an 'init' method, but its implementation doesn't match because its result type is not an object pointer}} +- (void) init31 {} // expected-error {{method was declared as an 'init' method, but its implementation doesn't match because its result type is not an object pointer}} +- (void) init41 {} // expected-error {{method was declared as an 'init' method, but its implementation doesn't match because its result type is not an object pointer}} +- (void) init51 {} + +- (Test8_incomplete*) init02 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_incomplete*) init12 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_incomplete*) init22 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_incomplete*) init32 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_incomplete*) init42 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_incomplete*) init52 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} + +- (Test8_super*) init03 { return 0; } +- (Test8_super*) init13 { return 0; } // expected-error {{method implementation does not match its declaration}} +- (Test8_super*) init23 { return 0; } +- (Test8_super*) init33 { return 0; } +- (Test8_super*) init43 { return 0; } +- (Test8_super*) init53 { return 0; } + +- (Test8*) init04 { return 0; } +- (Test8*) init14 { return 0; } // expected-error {{method implementation does not match its declaration}} +- (Test8*) init24 { return 0; } +- (Test8*) init34 { return 0; } +- (Test8*) init44 { return 0; } +- (Test8*) init54 { return 0; } + +- (Test8_complete*) init05 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_complete*) init15 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_complete*) init25 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_complete*) init35 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_complete*) init45 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_complete*) init55 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} +@end + +@class Test9_incomplete; +@interface Test9 +- (Test9_incomplete*) init1; // expected-error {{init methods must return a type related to the receiver type}} +- (Test9_incomplete*) init2; +@end +id test9(Test9 *v) { + return [v init1]; +} + +// rdar://9491791 +void rdar9491791(int p) { + switch (p) { + case 3:; + NSObject *o = [[NSObject alloc] init]; // expected-note {{jump bypasses initialization of retaining variable}} + [o release]; + break; + default: // expected-error {{switch case is in protected scope}} + break; + } +} + +#define RELEASE_MACRO(x) do { [x release]; } while(1) + +// rdar://9504750 +void rdar9504750(id p) { + RELEASE_MACRO(p); // expected-error {{ARC forbids explicit message send of 'release'}} +} + +// rdar://8939557 +@interface TestReadonlyProperty : NSObject +@property(assign,readonly) NSObject *value; +@end + +@implementation TestReadonlyProperty +@synthesize value; +- (void)viewDidLoad { + value = [NSObject new]; // expected-error {{assigning retained object}} +} +@end + +// rdar://9601437 +@interface I9601437 { + __unsafe_unretained id x; +} +-(void)Meth; +@end + +@implementation I9601437 +-(void)Meth { + self->x = [NSObject new]; // expected-error {{assigning retained object}} +} +@end diff --git a/test/ARCMT/cxx-checking.mm b/test/ARCMT/cxx-checking.mm new file mode 100644 index 0000000..27e0ea3 --- /dev/null +++ b/test/ARCMT/cxx-checking.mm @@ -0,0 +1,105 @@ +// RUN: %clang_cc1 -arcmt-check -verify -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fblocks -Warc-abi %s + +// Classes that have an Objective-C object pointer. +struct HasObjectMember0 { // expected-warning{{'HasObjectMember0' cannot be shared between ARC and non-ARC code; add a copy constructor, a copy assignment operator, and a destructor to make it ABI-compatible}} + id x; +}; + +struct HasObjectMember1 { // expected-warning{{'HasObjectMember1' cannot be shared between ARC and non-ARC code; add a copy constructor, a copy assignment operator, and a destructor to make it ABI-compatible}} + id x[3]; +}; + +struct HasObjectMember2 { // expected-warning{{'HasObjectMember2' cannot be shared between ARC and non-ARC code; add a copy constructor, a copy assignment operator, and a destructor to make it ABI-compatible}} + id x[3][2]; +}; + +// Don't complain if the type has non-external linkage +namespace { + struct HasObjectMember3 { + id x[3][2]; + }; +} + +// Don't complain if the Objective-C pointer type was explicitly given +// no lifetime. +struct HasObjectMember3 { + __unsafe_unretained id x[3][2]; +}; + +struct HasBlockPointerMember0 { // expected-warning{{'HasBlockPointerMember0' cannot be shared between ARC and non-ARC code; add a copy constructor, a copy assignment operator, and a destructor to make it ABI-compatible}} + int (^bp)(int); +}; + +struct HasBlockPointerMember1 { // expected-warning{{'HasBlockPointerMember1' cannot be shared between ARC and non-ARC code; add a copy constructor, a copy assignment operator, and a destructor to make it ABI-compatible}} + int (^bp[2][3])(int); +}; + +struct NonPOD { + NonPOD(const NonPOD&); +}; + +struct HasObjectMemberAndNonPOD0 { // expected-warning{{'HasObjectMemberAndNonPOD0' cannot be shared between ARC and non-ARC code; add a non-trivial copy assignment operator to make it ABI-compatible}} \ + // expected-warning{{'HasObjectMemberAndNonPOD0' cannot be shared between ARC and non-ARC code; add a non-trivial destructor to make it ABI-compatible}} + id x; + NonPOD np; +}; + +struct HasObjectMemberAndNonPOD1 { // expected-warning{{'HasObjectMemberAndNonPOD1' cannot be shared between ARC and non-ARC code; add a non-trivial copy assignment operator to make it ABI-compatible}} \ + // expected-warning{{'HasObjectMemberAndNonPOD1' cannot be shared between ARC and non-ARC code; add a non-trivial destructor to make it ABI-compatible}} + NonPOD np; + id x[3]; +}; + +struct HasObjectMemberAndNonPOD2 { // expected-warning{{'HasObjectMemberAndNonPOD2' cannot be shared between ARC and non-ARC code; add a non-trivial copy assignment operator to make it ABI-compatible}} \ + // expected-warning{{'HasObjectMemberAndNonPOD2' cannot be shared between ARC and non-ARC code; add a non-trivial destructor to make it ABI-compatible}} + NonPOD np; + id x[3][2]; +}; + +struct HasObjectMemberAndNonPOD3 { + HasObjectMemberAndNonPOD3 &operator=(const HasObjectMemberAndNonPOD3&); + ~HasObjectMemberAndNonPOD3(); + NonPOD np; + id x[3][2]; +}; + +struct HasBlockPointerMemberAndNonPOD0 { // expected-warning{{'HasBlockPointerMemberAndNonPOD0' cannot be shared between ARC and non-ARC code; add a non-trivial copy assignment operator to make it ABI-compatible}} \ +// expected-warning{{'HasBlockPointerMemberAndNonPOD0' cannot be shared between ARC and non-ARC code; add a non-trivial destructor to make it ABI-compatible}} + NonPOD np; + int (^bp)(int); +}; + +struct HasBlockPointerMemberAndNonPOD1 { // expected-warning{{'HasBlockPointerMemberAndNonPOD1' cannot be shared between ARC and non-ARC code; add a non-trivial copy assignment operator to make it ABI-compatible}} \ +// expected-warning{{'HasBlockPointerMemberAndNonPOD1' cannot be shared between ARC and non-ARC code; add a non-trivial destructor to make it ABI-compatible}} + NonPOD np; + int (^bp[2][3])(int); +}; + +int check_non_pod_objc_pointer0[__is_pod(id)? 1 : -1]; +int check_non_pod_objc_pointer1[__is_pod(__strong id)? -1 : 1]; +int check_non_pod_objc_pointer2[__is_pod(__unsafe_unretained id)? 1 : -1]; +int check_non_pod_objc_pointer3[__is_pod(id[2][3])? 1 : -1]; +int check_non_pod_objc_pointer4[__is_pod(__unsafe_unretained id[2][3])? 1 : -1]; +int check_non_pod_block0[__is_pod(int (^)(int))? 1 : -1]; +int check_non_pod_block1[__is_pod(int (^ __unsafe_unretained)(int))? 1 : -1]; + +struct FlexibleArrayMember0 { + int length; + id array[]; // expected-error{{flexible array member 'array' of non-POD element type 'id __strong[]'}} +}; + +struct FlexibleArrayMember1 { + int length; + __unsafe_unretained id array[]; +}; + +// It's okay to pass a retainable type through an ellipsis. +void variadic(...); +void test_variadic() { + variadic(1, 17, @"Foo"); +} + +// It's okay to create a VLA of retainable types. +void vla(int n) { + id vla[n]; +} diff --git a/test/ARCMT/cxx-rewrite.mm b/test/ARCMT/cxx-rewrite.mm new file mode 100644 index 0000000..aba3f75 --- /dev/null +++ b/test/ARCMT/cxx-rewrite.mm @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c++ %s.result +// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -x objective-c++ %s > %t +// RUN: diff %t %s.result + +#include "Common.h" + +@interface NSString : NSObject ++(id)string; +@end + +struct foo { + NSString *s; + foo(NSString *s): s([s retain]){ + NSAutoreleasePool *pool = [NSAutoreleasePool new]; + [[[NSString string] retain] release]; + [pool drain]; + } + ~foo(){ [s release]; } +private: + foo(foo const &); + foo &operator=(foo const &); +}; + +int main(){ + NSAutoreleasePool *pool = [NSAutoreleasePool new]; + + foo f([[NSString string] autorelease]); + + [pool drain]; + return 0; +} diff --git a/test/ARCMT/cxx-rewrite.mm.result b/test/ARCMT/cxx-rewrite.mm.result new file mode 100644 index 0000000..145ccd3 --- /dev/null +++ b/test/ARCMT/cxx-rewrite.mm.result @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c++ %s.result +// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -x objective-c++ %s > %t +// RUN: diff %t %s.result + +#include "Common.h" + +@interface NSString : NSObject ++(id)string; +@end + +struct foo { + NSString *s; + foo(NSString *s): s(s){ + @autoreleasepool { + [NSString string]; + } + } + ~foo(){ s; } +private: + foo(foo const &); + foo &operator=(foo const &); +}; + +int main(){ + @autoreleasepool { + + foo f([NSString string]); + + } + return 0; +} diff --git a/test/ARCMT/dealloc.m b/test/ARCMT/dealloc.m new file mode 100644 index 0000000..dac9644 --- /dev/null +++ b/test/ARCMT/dealloc.m @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -x objective-c %s > %t +// RUN: diff %t %s.result + +@interface A +- (id)retain; +- (id)autorelease; +- (oneway void)release; +- (void)dealloc; +@end + +void test1(A *a) { + [a dealloc]; +} + +@interface Test2 : A +- (void) dealloc; +@end + +@implementation Test2 +- (void) dealloc { + [super dealloc]; +} +@end diff --git a/test/ARCMT/dealloc.m.result b/test/ARCMT/dealloc.m.result new file mode 100644 index 0000000..24756d2 --- /dev/null +++ b/test/ARCMT/dealloc.m.result @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -x objective-c %s > %t +// RUN: diff %t %s.result + +@interface A +- (id)retain; +- (id)autorelease; +- (oneway void)release; +- (void)dealloc; +@end + +void test1(A *a) { +} + +@interface Test2 : A +- (void) dealloc; +@end + +@implementation Test2 +@end diff --git a/test/ARCMT/driver-migrate.m b/test/ARCMT/driver-migrate.m new file mode 100644 index 0000000..e283857 --- /dev/null +++ b/test/ARCMT/driver-migrate.m @@ -0,0 +1,3 @@ +// RUN: %clang -### -ccc-arcmt-migrate /foo/bar -fsyntax-only %s 2>&1 | FileCheck %s + +// CHECK: "-arcmt-migrate" "-arcmt-migrate-directory" "{{[^"]*}}/foo/bar" diff --git a/test/ARCMT/init.m b/test/ARCMT/init.m new file mode 100644 index 0000000..f0d24f6 --- /dev/null +++ b/test/ARCMT/init.m @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -x objective-c %s > %t +// RUN: diff %t %s.result + +@interface NSObject +-init; +@end + +@interface A : NSObject +-init; +-init2; +-foo; ++alloc; +@end + +@implementation A +-(id) init { + [self init]; + id a; + [a init]; + a = [[A alloc] init]; + + return self; +} + +-(id) init2 { + [super init]; + return self; +} + +-(id) foo { + [self init]; + [super init]; + + return self; +} +@end diff --git a/test/ARCMT/init.m.result b/test/ARCMT/init.m.result new file mode 100644 index 0000000..4f3b4e7 --- /dev/null +++ b/test/ARCMT/init.m.result @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -x objective-c %s > %t +// RUN: diff %t %s.result + +@interface NSObject +-init; +@end + +@interface A : NSObject +-init; +-init2; +-foo; ++alloc; +@end + +@implementation A +-(id) init { + self = [self init]; + id a; + [a init]; + a = [[A alloc] init]; + + return self; +} + +-(id) init2 { + self = [super init]; + return self; +} + +-(id) foo { + [self init]; + [super init]; + + return self; +} +@end diff --git a/test/ARCMT/migrate.m b/test/ARCMT/migrate.m new file mode 100644 index 0000000..51029c5 --- /dev/null +++ b/test/ARCMT/migrate.m @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 -arcmt-migrate -arcmt-migrate-directory %t %S/Inputs/test1.m.in -x objective-c -fobjc-nonfragile-abi +// RUN: %clang_cc1 -arcmt-migrate -arcmt-migrate-directory %t %S/Inputs/test2.m.in -x objective-c -fobjc-nonfragile-abi +// RUN: c-arcmt-test -arcmt-migrate-directory %t | arcmt-test -verify-transformed-files %S/Inputs/test1.m.in.result %S/Inputs/test2.m.in.result %S/Inputs/test.h.result +// RUN: rm -rf %t diff --git a/test/ARCMT/nonobjc-to-objc-cast-2.m b/test/ARCMT/nonobjc-to-objc-cast-2.m new file mode 100644 index 0000000..46ef024 --- /dev/null +++ b/test/ARCMT/nonobjc-to-objc-cast-2.m @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -arcmt-check -verify -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi %s + +typedef int BOOL; +typedef const struct __CFString * CFStringRef; + +@class NSString; + +void f(BOOL b) { + CFStringRef cfstr; + NSString *str = (NSString *)cfstr; // expected-error {{cast of C pointer type 'CFStringRef' (aka 'const struct __CFString *') to Objective-C pointer type 'NSString *' requires a bridged cast}} \ + // expected-note{{use __bridge to convert directly (no change in ownership)}} \ + // expected-note{{use __bridge_transfer to transfer ownership of a +1 'CFStringRef' (aka 'const struct __CFString *') into ARC}} + void *vp = str; // expected-error {{disallowed}} +} diff --git a/test/ARCMT/nonobjc-to-objc-cast.m b/test/ARCMT/nonobjc-to-objc-cast.m new file mode 100644 index 0000000..4e1e293 --- /dev/null +++ b/test/ARCMT/nonobjc-to-objc-cast.m @@ -0,0 +1,38 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -x objective-c %s > %t +// RUN: diff %t %s.result + +#include "Common.h" + +@interface NSString : NSObject +@end + +typedef const struct __CFString * CFStringRef; +extern const CFStringRef kUTTypePlainText; +extern const CFStringRef kUTTypeRTF; + +typedef const struct __CFAllocator * CFAllocatorRef; +typedef const struct __CFUUID * CFUUIDRef; + +extern const CFAllocatorRef kCFAllocatorDefault; + +extern CFStringRef CFUUIDCreateString(CFAllocatorRef alloc, CFUUIDRef uuid); + +void f(BOOL b, id p) { + NSString *str = (NSString *)kUTTypePlainText; + str = b ? kUTTypeRTF : kUTTypePlainText; + str = (NSString *)(b ? kUTTypeRTF : kUTTypePlainText); + str = (NSString *)p; // no change. + + CFUUIDRef _uuid; + NSString *_uuidString = (NSString *)CFUUIDCreateString(kCFAllocatorDefault, _uuid); + _uuidString = [(NSString *)CFUUIDCreateString(kCFAllocatorDefault, _uuid) autorelease]; +} + +@implementation NSString (StrExt) +- (NSString *)stringEscapedAsURI { + CFStringRef str = (CFStringRef)self; + CFStringRef str2 = self; + return self; +} +@end diff --git a/test/ARCMT/nonobjc-to-objc-cast.m.result b/test/ARCMT/nonobjc-to-objc-cast.m.result new file mode 100644 index 0000000..53dde75 --- /dev/null +++ b/test/ARCMT/nonobjc-to-objc-cast.m.result @@ -0,0 +1,38 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -x objective-c %s > %t +// RUN: diff %t %s.result + +#include "Common.h" + +@interface NSString : NSObject +@end + +typedef const struct __CFString * CFStringRef; +extern const CFStringRef kUTTypePlainText; +extern const CFStringRef kUTTypeRTF; + +typedef const struct __CFAllocator * CFAllocatorRef; +typedef const struct __CFUUID * CFUUIDRef; + +extern const CFAllocatorRef kCFAllocatorDefault; + +extern CFStringRef CFUUIDCreateString(CFAllocatorRef alloc, CFUUIDRef uuid); + +void f(BOOL b, id p) { + NSString *str = (__bridge NSString *)kUTTypePlainText; + str = (__bridge NSString *)(b ? kUTTypeRTF : kUTTypePlainText); + str = (__bridge NSString *)(b ? kUTTypeRTF : kUTTypePlainText); + str = (NSString *)p; // no change. + + CFUUIDRef _uuid; + NSString *_uuidString = (__bridge_transfer NSString *)CFUUIDCreateString(kCFAllocatorDefault, _uuid); + _uuidString = (__bridge_transfer NSString *)CFUUIDCreateString(kCFAllocatorDefault, _uuid); +} + +@implementation NSString (StrExt) +- (NSString *)stringEscapedAsURI { + CFStringRef str = (__bridge CFStringRef)self; + CFStringRef str2 = (__bridge CFStringRef)(self); + return self; +} +@end diff --git a/test/ARCMT/releases-driver.m b/test/ARCMT/releases-driver.m new file mode 100644 index 0000000..a016b26 --- /dev/null +++ b/test/ARCMT/releases-driver.m @@ -0,0 +1,68 @@ +// RUN: %clang_cc1 -fobjc-nonfragile-abi -fblocks -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: cp %s %t +// RUN: %clang_cc1 -arcmt-modify -triple x86_64-apple-macosx10.6 -fobjc-nonfragile-abi -x objective-c %t +// RUN: diff %t %s.result +// RUN: rm %t + +typedef int BOOL; + +id IhaveSideEffect(); + +@protocol NSObject +- (BOOL)isEqual:(id)object; +- (id)retain; +- (oneway void)release; +@end + +@interface NSObject {} +@end + +@interface Foo : NSObject { + id bar; +} +@property (retain) id bar; +-(void)test:(id)obj; +@end + +@implementation Foo + +@synthesize bar; + +-(void)test:(id)obj { + id x = self.bar; + [x retain]; + self.bar = obj; + // do stuff with x; + [x release]; + + [IhaveSideEffect() release]; + + [x release], x = 0; +} + +@end + +void func(Foo *p) { + [p release]; + (([p release])); +} + +@interface Baz { + id _foo; +} +@end + +@implementation Baz +- dealloc { + [_foo release]; + return 0; +} +@end + +#define RELEASE_MACRO(x) [x release] +#define RELEASE_MACRO2(x) RELEASE_MACRO(x) + +void test2(id p) { + RELEASE_MACRO(p); + RELEASE_MACRO2(p); +} diff --git a/test/ARCMT/releases-driver.m.result b/test/ARCMT/releases-driver.m.result new file mode 100644 index 0000000..c5f527f --- /dev/null +++ b/test/ARCMT/releases-driver.m.result @@ -0,0 +1,61 @@ +// RUN: %clang_cc1 -fobjc-nonfragile-abi -fblocks -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: cp %s %t +// RUN: %clang_cc1 -arcmt-modify -triple x86_64-apple-macosx10.6 -fobjc-nonfragile-abi -x objective-c %t +// RUN: diff %t %s.result +// RUN: rm %t + +typedef int BOOL; + +id IhaveSideEffect(); + +@protocol NSObject +- (BOOL)isEqual:(id)object; +- (id)retain; +- (oneway void)release; +@end + +@interface NSObject {} +@end + +@interface Foo : NSObject { + id bar; +} +@property (strong) id bar; +-(void)test:(id)obj; +@end + +@implementation Foo + +@synthesize bar; + +-(void)test:(id)obj { + id x = self.bar; + self.bar = obj; + // do stuff with x; + + IhaveSideEffect(); + + x = 0; +} + +@end + +void func(Foo *p) { +} + +@interface Baz { + id _foo; +} +@end + +@implementation Baz +- dealloc { + return 0; +} +@end + +#define RELEASE_MACRO(x) [x release] +#define RELEASE_MACRO2(x) RELEASE_MACRO(x) + +void test2(id p) { +} diff --git a/test/ARCMT/releases.m b/test/ARCMT/releases.m new file mode 100644 index 0000000..d5f21dc --- /dev/null +++ b/test/ARCMT/releases.m @@ -0,0 +1,87 @@ +// RUN: %clang_cc1 -fobjc-nonfragile-abi -fobjc-exceptions -fblocks -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fobjc-exceptions -fblocks -fobjc-nonfragile-abi -fsyntax-only -x objective-c %s > %t +// RUN: diff %t %s.result + +#define nil 0 + +typedef int BOOL; + +id IhaveSideEffect(); + +@protocol NSObject +- (BOOL)isEqual:(id)object; +- (id)retain; +- (oneway void)release; +@end + +@interface NSObject {} +@end + +@interface Foo : NSObject { + id bar; +} +@property (retain) id bar; +-(void)test:(id)obj; +@end + +@implementation Foo + +@synthesize bar; + +-(void)test:(id)obj { + id x = self.bar; + [x retain]; + self.bar = obj; + // do stuff with x; + [x release]; + + [IhaveSideEffect() release]; + + [x release], x = 0; + + @try { + } @finally { + [x release]; + } +} + +@end + +void func(Foo *p) { + [p release]; + (([p release])); +} + +@interface Baz { + id _foo; +} +@end + +@implementation Baz +- dealloc { + [_foo release]; + return 0; +} +@end + +void block_test(Foo *p) { + id (^B)() = ^() { + if (p) { + id (^IB)() = ^() { + id bar = [p retain]; + [p release]; + return bar; + }; + IB(); + } + return [p retain]; + }; +} + +#define RELEASE_MACRO(x) [x release] +#define RELEASE_MACRO2(x) RELEASE_MACRO(x) + +void test2(id p) { + RELEASE_MACRO(p); + RELEASE_MACRO2(p); +} diff --git a/test/ARCMT/releases.m.result b/test/ARCMT/releases.m.result new file mode 100644 index 0000000..1d36f3e --- /dev/null +++ b/test/ARCMT/releases.m.result @@ -0,0 +1,79 @@ +// RUN: %clang_cc1 -fobjc-nonfragile-abi -fobjc-exceptions -fblocks -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fobjc-exceptions -fblocks -fobjc-nonfragile-abi -fsyntax-only -x objective-c %s > %t +// RUN: diff %t %s.result + +#define nil 0 + +typedef int BOOL; + +id IhaveSideEffect(); + +@protocol NSObject +- (BOOL)isEqual:(id)object; +- (id)retain; +- (oneway void)release; +@end + +@interface NSObject {} +@end + +@interface Foo : NSObject { + id bar; +} +@property (strong) id bar; +-(void)test:(id)obj; +@end + +@implementation Foo + +@synthesize bar; + +-(void)test:(id)obj { + id x = self.bar; + self.bar = obj; + // do stuff with x; + + IhaveSideEffect(); + + x = 0; + + @try { + } @finally { + x = nil; + } +} + +@end + +void func(Foo *p) { +} + +@interface Baz { + id _foo; +} +@end + +@implementation Baz +- dealloc { + return 0; +} +@end + +void block_test(Foo *p) { + id (^B)() = ^() { + if (p) { + id (^IB)() = ^() { + id bar = p; + return bar; + }; + IB(); + } + return p; + }; +} + +#define RELEASE_MACRO(x) [x release] +#define RELEASE_MACRO2(x) RELEASE_MACRO(x) + +void test2(id p) { +} diff --git a/test/ARCMT/remove-dealloc-method.m b/test/ARCMT/remove-dealloc-method.m new file mode 100644 index 0000000..5c2d785 --- /dev/null +++ b/test/ARCMT/remove-dealloc-method.m @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -x objective-c %s > %t +// RUN: diff %t %s.result + +#define nil ((void*) 0) + +@interface Foo +@property (retain) id x; +@property (retain) id y; +@property (retain) id w; +@property (retain) id z; +@end + +@implementation Foo +@synthesize x; +@synthesize y; +@synthesize w; +@synthesize z; + +- (void) dealloc { + self.x = 0; + [self setY:nil]; + w = nil; + self.z = nil; +} +@end diff --git a/test/ARCMT/remove-dealloc-method.m.result b/test/ARCMT/remove-dealloc-method.m.result new file mode 100644 index 0000000..ecb752c --- /dev/null +++ b/test/ARCMT/remove-dealloc-method.m.result @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -x objective-c %s > %t +// RUN: diff %t %s.result + +#define nil ((void*) 0) + +@interface Foo +@property (strong) id x; +@property (strong) id y; +@property (strong) id w; +@property (strong) id z; +@end + +@implementation Foo +@synthesize x; +@synthesize y; +@synthesize w; +@synthesize z; + +@end diff --git a/test/ARCMT/remove-dealloc-zerouts.m b/test/ARCMT/remove-dealloc-zerouts.m new file mode 100644 index 0000000..3ba85f1 --- /dev/null +++ b/test/ARCMT/remove-dealloc-zerouts.m @@ -0,0 +1,44 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -x objective-c %s > %t +// RUN: diff %t %s.result + +@interface Foo +@property (retain) id x; +@property (retain) id y; +@property (retain) id w; +@property (retain) id z; +@property (strong) id q; +@end + +@implementation Foo +@synthesize x; +@synthesize y; +@synthesize w; +@synthesize q; +@dynamic z; + +- (void) dealloc { + self.x = self.y = self.w = 0; + self.x = 0, w = 0, y = 0; + [self setY:0]; + w = 0; + q = 0; + self.z = 0; +} +@end + +@interface Bar +@property (retain) Foo *a; +- (void) setA:(Foo*) val; +- (id) a; +@end + +@implementation Bar +- (void) dealloc { + [self setA:0]; // This is user-defined setter overriding synthesize, don't touch it. + self.a.x = 0; // every dealloc must zero out its own ivar. This patter is not recognized. +} +@synthesize a; +- (void) setA:(Foo*) val { } +- (id) a {return 0;} +@end diff --git a/test/ARCMT/remove-dealloc-zerouts.m.result b/test/ARCMT/remove-dealloc-zerouts.m.result new file mode 100644 index 0000000..dc6ffd3 --- /dev/null +++ b/test/ARCMT/remove-dealloc-zerouts.m.result @@ -0,0 +1,39 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -x objective-c %s > %t +// RUN: diff %t %s.result + +@interface Foo +@property (strong) id x; +@property (strong) id y; +@property (strong) id w; +@property (strong) id z; +@property (strong) id q; +@end + +@implementation Foo +@synthesize x; +@synthesize y; +@synthesize w; +@synthesize q; +@dynamic z; + +- (void) dealloc { + self.z = 0; +} +@end + +@interface Bar +@property (strong) Foo *a; +- (void) setA:(Foo*) val; +- (id) a; +@end + +@implementation Bar +- (void) dealloc { + [self setA:0]; // This is user-defined setter overriding synthesize, don't touch it. + self.a.x = 0; // every dealloc must zero out its own ivar. This patter is not recognized. +} +@synthesize a; +- (void) setA:(Foo*) val { } +- (id) a {return 0;} +@end diff --git a/test/ARCMT/remove-statements.m b/test/ARCMT/remove-statements.m new file mode 100644 index 0000000..7e10296 --- /dev/null +++ b/test/ARCMT/remove-statements.m @@ -0,0 +1,45 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -x objective-c %s > %t +// RUN: diff %t %s.result + +#include "Common.h" + +@interface myController : NSObject +-(id)test:(id)x; +@end + +#define MY_MACRO1(x) +#define MY_MACRO2(x) (void)x + +@implementation myController +-(id) test:(id) x { + [[x retain] release]; + return [[x retain] autorelease]; +} + +-(void)dealloc +{ + id array, array_already_empty; + for (id element in array_already_empty) { + } + + [array release]; + ; + + int b, b_array_already_empty; + if (b) + [array release]; + if (b_array_already_empty) ; + + if (b) { + [array release]; + } + if (b_array_already_empty) { + } + + if (b) + MY_MACRO1(array); + if (b) + MY_MACRO2(array); +} +@end diff --git a/test/ARCMT/remove-statements.m.result b/test/ARCMT/remove-statements.m.result new file mode 100644 index 0000000..9a1153e --- /dev/null +++ b/test/ARCMT/remove-statements.m.result @@ -0,0 +1,38 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -x objective-c %s > %t +// RUN: diff %t %s.result + +#include "Common.h" + +@interface myController : NSObject +-(id)test:(id)x; +@end + +#define MY_MACRO1(x) +#define MY_MACRO2(x) (void)x + +@implementation myController +-(id) test:(id) x { + return x; +} + +-(void)dealloc +{ + id array, array_already_empty; + for (id element in array_already_empty) { + } + + ; + + int b, b_array_already_empty; + if (b_array_already_empty) ; + + if (b_array_already_empty) { + } + + if (b) + MY_MACRO1(array); + if (b) + MY_MACRO2(array); +} +@end diff --git a/test/ARCMT/retains.m b/test/ARCMT/retains.m new file mode 100644 index 0000000..fa90f21 --- /dev/null +++ b/test/ARCMT/retains.m @@ -0,0 +1,71 @@ +// RUN: %clang_cc1 -fobjc-nonfragile-abi -fblocks -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fblocks -fobjc-nonfragile-abi -fsyntax-only -x objective-c %s > %t +// RUN: diff %t %s.result + +#include "Common.h" + +id IhaveSideEffect(); + +@interface Foo : NSObject { + id bar; +} +@property (retain) id bar; +-(id)test:(id)obj; +-(id)something; +@end + +#define Something_Macro(key, comment) \ + [[Foo new] something] + +@implementation Foo + +@synthesize bar; + +-(id)something {} + +-(id)test:(id)obj { + id x = self.bar; + [x retain]; + self.bar = obj; + if (obj) + [obj retain]; + + [Something_Macro(@"foo", "@bar") retain]; + + [IhaveSideEffect() retain]; + + [[self something] retain]; + + [[self retain] something]; + + [[IhaveSideEffect() retain] release]; + [[x retain] release]; + // do stuff with x; + [x release]; + return [self retain]; +} + +- (id)test1 { + id x=0; + ([x retain]); + return ((([x retain]))); +} +@end + +id foo (Foo *p) { + p = [p retain]; + return ([p retain]); +} + +void block_tests(Foo *p) { + id (^B)() = ^() { + if (p) { + id (^IB)() = ^() { + id bar = [p retain]; + return bar; + }; + IB(); + } + return [p retain]; + }; +} diff --git a/test/ARCMT/retains.m.result b/test/ARCMT/retains.m.result new file mode 100644 index 0000000..54df864 --- /dev/null +++ b/test/ARCMT/retains.m.result @@ -0,0 +1,65 @@ +// RUN: %clang_cc1 -fobjc-nonfragile-abi -fblocks -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fblocks -fobjc-nonfragile-abi -fsyntax-only -x objective-c %s > %t +// RUN: diff %t %s.result + +#include "Common.h" + +id IhaveSideEffect(); + +@interface Foo : NSObject { + id bar; +} +@property (strong) id bar; +-(id)test:(id)obj; +-(id)something; +@end + +#define Something_Macro(key, comment) \ + [[Foo new] something] + +@implementation Foo + +@synthesize bar; + +-(id)something {} + +-(id)test:(id)obj { + id x = self.bar; + self.bar = obj; + + Something_Macro(@"foo", "@bar"); + + IhaveSideEffect(); + + [self something]; + + [self something]; + + IhaveSideEffect(); + // do stuff with x; + return self; +} + +- (id)test1 { + id x=0; + return (((x))); +} +@end + +id foo (Foo *p) { + p = p; + return (p); +} + +void block_tests(Foo *p) { + id (^B)() = ^() { + if (p) { + id (^IB)() = ^() { + id bar = p; + return bar; + }; + IB(); + } + return p; + }; +} diff --git a/test/ARCMT/rewrite-block-var.m b/test/ARCMT/rewrite-block-var.m new file mode 100644 index 0000000..81407f9 --- /dev/null +++ b/test/ARCMT/rewrite-block-var.m @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fblocks -fsyntax-only -fobjc-arc -x objective-c -fobjc-runtime-has-weak %s.result +// RUN: arcmt-test --args -triple x86_64-apple-macosx10.7 -fobjc-nonfragile-abi -fblocks -fsyntax-only %s > %t +// RUN: diff %t %s.result + +#include "Common.h" + +@interface Foo : NSObject +-(Foo *)something; +@end + +void bar(void (^block)()); + +void test1(Foo *p) { + __block Foo *x = p; // __block used just to break cycle. + bar(^{ + [x something]; + }); +} + +void test2(Foo *p) { + __block Foo *x; // __block used as output variable. + bar(^{ + x = [p something]; + }); +} diff --git a/test/ARCMT/rewrite-block-var.m.result b/test/ARCMT/rewrite-block-var.m.result new file mode 100644 index 0000000..85093ac --- /dev/null +++ b/test/ARCMT/rewrite-block-var.m.result @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fblocks -fsyntax-only -fobjc-arc -x objective-c -fobjc-runtime-has-weak %s.result +// RUN: arcmt-test --args -triple x86_64-apple-macosx10.7 -fobjc-nonfragile-abi -fblocks -fsyntax-only %s > %t +// RUN: diff %t %s.result + +#include "Common.h" + +@interface Foo : NSObject +-(Foo *)something; +@end + +void bar(void (^block)()); + +void test1(Foo *p) { + __weak Foo *x = p; // __block used just to break cycle. + bar(^{ + [x something]; + }); +} + +void test2(Foo *p) { + __block Foo *x; // __block used as output variable. + bar(^{ + x = [p something]; + }); +} diff --git a/test/ARCMT/safe-arc-assign.m b/test/ARCMT/safe-arc-assign.m new file mode 100644 index 0000000..368c2b6 --- /dev/null +++ b/test/ARCMT/safe-arc-assign.m @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -x objective-c %s > %t +// RUN: diff %t %s.result + +void test12(id collection) { + for (id x in collection) { + x = 0; + x = 0; + } + + for (__strong id x in collection) { + x = 0; + } +} diff --git a/test/ARCMT/safe-arc-assign.m.result b/test/ARCMT/safe-arc-assign.m.result new file mode 100644 index 0000000..cacd109 --- /dev/null +++ b/test/ARCMT/safe-arc-assign.m.result @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -x objective-c %s > %t +// RUN: diff %t %s.result + +void test12(id collection) { + for (__strong id x in collection) { + x = 0; + x = 0; + } + + for (__strong id x in collection) { + x = 0; + } +} diff --git a/test/ARCMT/with-arc-mode-check.m b/test/ARCMT/with-arc-mode-check.m new file mode 100644 index 0000000..c3146ef --- /dev/null +++ b/test/ARCMT/with-arc-mode-check.m @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -arcmt-check -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s + +@protocol NSObject +- (oneway void)release; +@end + +void test1(id p) { + [p release]; +} diff --git a/test/ARCMT/with-arc-mode-migrate.m b/test/ARCMT/with-arc-mode-migrate.m new file mode 100644 index 0000000..3851bc7 --- /dev/null +++ b/test/ARCMT/with-arc-mode-migrate.m @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: %clang_cc1 -arcmt-migrate -arcmt-migrate-directory %t -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc %s +// RUN: c-arcmt-test -arcmt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result +// RUN: rm -rf %t + +@protocol NSObject +- (oneway void)release; +@end + +void test1(id p) { + [p release]; +} diff --git a/test/ARCMT/with-arc-mode-migrate.m.result b/test/ARCMT/with-arc-mode-migrate.m.result new file mode 100644 index 0000000..c2222ae --- /dev/null +++ b/test/ARCMT/with-arc-mode-migrate.m.result @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: %clang_cc1 -arcmt-migrate -arcmt-migrate-directory %t -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc %s +// RUN: c-arcmt-test -arcmt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result +// RUN: rm -rf %t + +@protocol NSObject +- (oneway void)release; +@end + +void test1(id p) { +} diff --git a/test/ARCMT/with-arc-mode-modify.m b/test/ARCMT/with-arc-mode-modify.m new file mode 100644 index 0000000..17a3980 --- /dev/null +++ b/test/ARCMT/with-arc-mode-modify.m @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: cp %s %t +// RUN: %clang_cc1 -arcmt-modify -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %t +// RUN: diff %t %s.result +// RUN: rm %t + +@protocol NSObject +- (oneway void)release; +@end + +void test1(id p) { + [p release]; +} diff --git a/test/ARCMT/with-arc-mode-modify.m.result b/test/ARCMT/with-arc-mode-modify.m.result new file mode 100644 index 0000000..97c5128 --- /dev/null +++ b/test/ARCMT/with-arc-mode-modify.m.result @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: cp %s %t +// RUN: %clang_cc1 -arcmt-modify -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %t +// RUN: diff %t %s.result +// RUN: rm %t + +@protocol NSObject +- (oneway void)release; +@end + +void test1(id p) { +} diff --git a/test/Analysis/bstring.c b/test/Analysis/bstring.c index 68bbb1a..cd43e36 100644 --- a/test/Analysis/bstring.c +++ b/test/Analysis/bstring.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.experimental.CString -analyzer-store=region -Wno-null-dereference -verify %s -// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -analyzer-checker=core,cplusplus.experimental.CString -analyzer-store=region -Wno-null-dereference -verify %s -// RUN: %clang_cc1 -analyze -DVARIANT -analyzer-checker=core,cplusplus.experimental.CString -analyzer-store=region -Wno-null-dereference -verify %s -// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -DVARIANT -analyzer-checker=core,cplusplus.experimental.CString -analyzer-store=region -Wno-null-dereference -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.experimental.CString -analyzer-store=region -Wno-null-dereference -verify %s +// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -analyzer-checker=core,unix.experimental.CString -analyzer-store=region -Wno-null-dereference -verify %s +// RUN: %clang_cc1 -analyze -DVARIANT -analyzer-checker=core,unix.experimental.CString -analyzer-store=region -Wno-null-dereference -verify %s +// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -DVARIANT -analyzer-checker=core,unix.experimental.CString -analyzer-store=region -Wno-null-dereference -verify %s //===----------------------------------------------------------------------=== // Declarations @@ -64,14 +64,14 @@ void memcpy1 () { char src[] = {1, 2, 3, 4}; char dst[10]; - memcpy(dst, src, 5); // expected-warning{{Byte string function accesses out-of-bound array element}} + memcpy(dst, src, 5); // expected-warning{{Memory copy function accesses out-of-bound array element}} } void memcpy2 () { char src[] = {1, 2, 3, 4}; char dst[1]; - memcpy(dst, src, 4); // expected-warning{{Byte string function overflows destination buffer}} + memcpy(dst, src, 4); // expected-warning{{Memory copy function overflows destination buffer}} } void memcpy3 () { @@ -85,14 +85,14 @@ void memcpy4 () { char src[] = {1, 2, 3, 4}; char dst[10]; - memcpy(dst+2, src+2, 3); // expected-warning{{Byte string function accesses out-of-bound array element}} + memcpy(dst+2, src+2, 3); // expected-warning{{Memory copy function accesses out-of-bound array element}} } void memcpy5() { char src[] = {1, 2, 3, 4}; char dst[3]; - memcpy(dst+2, src+2, 2); // expected-warning{{Byte string function overflows destination buffer}} + memcpy(dst+2, src+2, 2); // expected-warning{{Memory copy function overflows destination buffer}} } void memcpy6() { @@ -118,12 +118,12 @@ void memcpy9() { void memcpy10() { char a[4] = {0}; - memcpy(0, a, 4); // expected-warning{{Null pointer argument in call to byte string function}} + memcpy(0, a, 4); // expected-warning{{Null pointer argument in call to memory copy function}} } void memcpy11() { char a[4] = {0}; - memcpy(a, 0, 4); // expected-warning{{Null pointer argument in call to byte string function}} + memcpy(a, 0, 4); // expected-warning{{Null pointer argument in call to memory copy function}} } void memcpy12() { @@ -144,7 +144,7 @@ void memcpy_unknown_size (size_t n) { void memcpy_unknown_size_warn (size_t n) { char a[4]; - if (memcpy(a, 0, n) != a) // expected-warning{{Null pointer argument in call to byte string function}} + if (memcpy(a, 0, n) != a) // expected-warning{{Null pointer argument in call to memory copy function}} (void)*(char*)0; // no-warning } @@ -186,14 +186,14 @@ void mempcpy1 () { char src[] = {1, 2, 3, 4}; char dst[10]; - mempcpy(dst, src, 5); // expected-warning{{Byte string function accesses out-of-bound array element}} + mempcpy(dst, src, 5); // expected-warning{{Memory copy function accesses out-of-bound array element}} } void mempcpy2 () { char src[] = {1, 2, 3, 4}; char dst[1]; - mempcpy(dst, src, 4); // expected-warning{{Byte string function overflows destination buffer}} + mempcpy(dst, src, 4); // expected-warning{{Memory copy function overflows destination buffer}} } void mempcpy3 () { @@ -207,14 +207,14 @@ void mempcpy4 () { char src[] = {1, 2, 3, 4}; char dst[10]; - mempcpy(dst+2, src+2, 3); // expected-warning{{Byte string function accesses out-of-bound array element}} + mempcpy(dst+2, src+2, 3); // expected-warning{{Memory copy function accesses out-of-bound array element}} } void mempcpy5() { char src[] = {1, 2, 3, 4}; char dst[3]; - mempcpy(dst+2, src+2, 2); // expected-warning{{Byte string function overflows destination buffer}} + mempcpy(dst+2, src+2, 2); // expected-warning{{Memory copy function overflows destination buffer}} } void mempcpy6() { @@ -240,12 +240,12 @@ void mempcpy9() { void mempcpy10() { char a[4] = {0}; - mempcpy(0, a, 4); // expected-warning{{Null pointer argument in call to byte string function}} + mempcpy(0, a, 4); // expected-warning{{Null pointer argument in call to memory copy function}} } void mempcpy11() { char a[4] = {0}; - mempcpy(a, 0, 4); // expected-warning{{Null pointer argument in call to byte string function}} + mempcpy(a, 0, 4); // expected-warning{{Null pointer argument in call to memory copy function}} } void mempcpy12() { @@ -260,7 +260,7 @@ void mempcpy13() { void mempcpy_unknown_size_warn (size_t n) { char a[4]; - if (mempcpy(a, 0, n) != a) // expected-warning{{Null pointer argument in call to byte string function}} + if (mempcpy(a, 0, n) != a) // expected-warning{{Null pointer argument in call to memory copy function}} (void)*(char*)0; // no-warning } diff --git a/test/Analysis/misc-ps-eager-assume.m b/test/Analysis/misc-ps-eager-assume.m index 649c4b0..4380a18 100644 --- a/test/Analysis/misc-ps-eager-assume.m +++ b/test/Analysis/misc-ps-eager-assume.m @@ -12,6 +12,7 @@ typedef struct _NSZone NSZone; @end @protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; @end @interface NSObject {} + (id)alloc; +- (id)init; @end typedef struct {} NSFastEnumerationState; @protocol NSFastEnumeration - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len; diff --git a/test/Analysis/nullptr.cpp b/test/Analysis/nullptr.cpp index b74a5ab..6f78bae 100644 --- a/test/Analysis/nullptr.cpp +++ b/test/Analysis/nullptr.cpp @@ -39,3 +39,11 @@ void foo4(void) { *np = 0; // no-warning } + +int pr10372(void *& x) { + // GNU null is a pointer-sized integer, not a pointer. + x = __null; + // This used to crash. + return __null; +} + diff --git a/test/Analysis/objc-arc.m b/test/Analysis/objc-arc.m new file mode 100644 index 0000000..6b22fd0 --- /dev/null +++ b/test/Analysis/objc-arc.m @@ -0,0 +1,149 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core -analyzer-checker=deadcode -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks -fobjc-nonfragile-abi -fobjc-arc %s + +typedef signed char BOOL; +typedef struct _NSZone NSZone; +@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator; + +@protocol NSObject +- (BOOL)isEqual:(id)object; +@end +@protocol NSCopying +- (id)copyWithZone:(NSZone *)zone; +@end +@protocol NSCoding +- (void)encodeWithCoder:(NSCoder *)aCoder; +@end +@interface NSObject {} ++ (id)alloc; +@end +typedef const struct __CFAllocator * CFAllocatorRef; +extern const CFAllocatorRef kCFAllocatorDefault; +typedef double CFTimeInterval; +typedef CFTimeInterval CFAbsoluteTime; +extern CFAbsoluteTime CFAbsoluteTimeGetCurrent(void); +typedef const struct __CFDate * CFDateRef; +extern CFDateRef CFDateCreate(CFAllocatorRef allocator, CFAbsoluteTime at); + +typedef const void* objc_objectptr_t; +__attribute__((ns_returns_retained)) id objc_retainedObject(objc_objectptr_t __attribute__((cf_consumed)) pointer); +__attribute__((ns_returns_not_retained)) id objc_unretainedObject(objc_objectptr_t pointer); + +// Test the analyzer is working at all. +void test_working() { + int *p = 0; + *p = 0xDEADBEEF; // expected-warning {{null}} +} + +// Test that in ARC mode that blocks are correctly automatically copied +// and not flagged as warnings by the analyzer. +typedef void (^Block)(void); +void testblock_bar(int x); + +Block testblock_foo(int x) { + Block b = ^{ testblock_bar(x); }; + return b; // no-warning +} + +Block testblock_baz(int x) { + return ^{ testblock_bar(x); }; // no-warning +} + +Block global_block; + +void testblock_qux(int x) { + global_block = ^{ testblock_bar(x); }; // no-warning +} + +// Test that Objective-C pointers are null initialized. +void test_nil_initialized() { + id x; + if (x == 0) + return; + int *p = 0; + *p = 0xDEADBEEF; // no-warning +} + +// Test that we don't flag leaks of Objective-C objects. +void test_alloc() { + [NSObject alloc]; // no-warning +} + +// Test that CF allocations are still caught as leaks. +void test_cf_leak() { + CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); + CFDateRef date = CFDateCreate(0, t); // expected-warning {{Potential leak}} + (void) date; +} + +// Test that 'init' methods do not try to claim ownerhip of an *unowned* allocated object +// in ARC mode. +@interface RDar9424890_A : NSObject +- (id)initWithCleaner:(int)pop mop:(NSString *)mop ; +- (RDar9424890_A *)rdar9424890:(NSString *)identifier; +@end +@interface RDar9424890_B : NSObject +@end +@implementation RDar9424890_B +- (RDar9424890_A *)obj:(RDar9424890_A *)obj { + static NSString *WhizFiz = @"WhizFiz"; + RDar9424890_A *cell = [obj rdar9424890:WhizFiz]; + if (cell == ((void*)0)) { + cell = [[RDar9424890_A alloc] initWithCleaner:0 mop:WhizFiz]; // no-warning + } + return cell; +} +@end + +// Test that dead store checking works in the prescence of "cleanups" in the AST. +void rdar9424882() { + id x = [NSObject alloc]; // expected-warning {{Value stored to 'x' during its initialization is never read}} +} + +// Test +typedef const void *CFTypeRef; +typedef const struct __CFString *CFStringRef; + +@interface NSString +- (id) self; +@end + +CFTypeRef CFCreateSomething(); +CFStringRef CFCreateString(); +CFTypeRef CFGetSomething(); +CFStringRef CFGetString(); + +id CreateSomething(); +NSString *CreateNSString(); + +void from_cf() { + id obj1 = (__bridge_transfer id)CFCreateSomething(); // expected-warning{{never read}} + id obj2 = (__bridge_transfer NSString*)CFCreateString(); + [obj2 self]; // Add a use, to show we can use the object after it has been transfered. + id obj3 = (__bridge id)CFGetSomething(); + [obj3 self]; // Add a use, to show we can use the object after it has been bridged. + id obj4 = (__bridge NSString*)CFGetString(); // expected-warning{{never read}} + id obj5 = (__bridge id)CFCreateSomething(); // expected-warning{{never read}} expected-warning{{leak}} + id obj6 = (__bridge NSString*)CFCreateString(); // expected-warning{{never read}} expected-warning{{leak}} +} + +void to_cf(id obj) { + CFTypeRef cf1 = (__bridge_retained CFTypeRef)CreateSomething(); // expected-warning{{never read}} + CFStringRef cf2 = (__bridge_retained CFStringRef)CreateNSString(); // expected-warning{{never read}} + CFTypeRef cf3 = (__bridge CFTypeRef)CreateSomething(); // expected-warning{{never read}} + CFStringRef cf4 = (__bridge CFStringRef)CreateNSString(); // expected-warning{{never read}} +} + +void test_objc_retainedObject() { + CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); + CFDateRef date = CFDateCreate(0, t); + id x = objc_retainedObject(date); + (void) x; +} + +void test_objc_unretainedObject() { + CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); + CFDateRef date = CFDateCreate(0, t); // expected-warning {{Potential leak}} + id x = objc_unretainedObject(date); + (void) x; +} + diff --git a/test/Analysis/pr4209.m b/test/Analysis/pr4209.m index 1e0fd32..e3bc5cc 100644 --- a/test/Analysis/pr4209.m +++ b/test/Analysis/pr4209.m @@ -49,17 +49,17 @@ CMProfileLocation; GSEbayCategory *rootCategory; } - (NSMutableDictionary*)categoryDictionaryForCategoryID:(int)inID inRootTreeCategories:(NSMutableArray*)inRootTreeCategories; // expected-note {{method definition for 'categoryDictionaryForCategoryID:inRootTreeCategories:' not found}} --(NSString*) categoryID; // expected-note {{method definition for 'categoryID' not found}} +-(NSString*) categoryID; // expected-note {{method definition for 'categoryID' not found}} expected-note {{using}} @end @interface GSEbayCategory : NSObject { } -- (int) categoryID; +- (int) categoryID; // expected-note {{also found}} - (GSEbayCategory *) parent; - (GSEbayCategory*) subcategoryWithID:(int) inID; @end @implementation GBCategoryChooserPanelController + (int) chooseCategoryIDFromCategories:(NSArray*) inCategories searchRequest:(GBSearchRequest*)inRequest parentWindow:(NSWindow*) inParent { // expected-warning {{incomplete implementation}} return 0; } - (void) addCategory:(EBayCategoryType*)inCategory toRootTreeCategory:(NSMutableArray*)inRootTreeCategories { - GSEbayCategory *category = [rootCategory subcategoryWithID:[[inCategory categoryID] intValue]]; + GSEbayCategory *category = [rootCategory subcategoryWithID:[[inCategory categoryID] intValue]]; // expected-warning {{multiple methods named 'categoryID' found}} if (rootCategory != category) { GSEbayCategory *parent = category; diff --git a/test/Analysis/retain-release-gc-only.m b/test/Analysis/retain-release-gc-only.m index cbf00a2..ee1a6b4 100644 --- a/test/Analysis/retain-release-gc-only.m +++ b/test/Analysis/retain-release-gc-only.m @@ -113,6 +113,7 @@ NSFastEnumerationState; @end @interface NSAutoreleasePool : NSObject { } - (void)drain; +- (id)init; @end extern NSString * const NSBundleDidLoadNotification; typedef double NSTimeInterval; @interface NSDate : NSObject - (NSTimeInterval)timeIntervalSinceReferenceDate; diff --git a/test/Analysis/retain-release-path-notes-gc.m b/test/Analysis/retain-release-path-notes-gc.m new file mode 100644 index 0000000..21d314f --- /dev/null +++ b/test/Analysis/retain-release-path-notes-gc.m @@ -0,0 +1,74 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease -analyzer-store=basic -analyzer-output=text -fobjc-gc-only -verify %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease -analyzer-store=region -analyzer-output=text -fobjc-gc-only -verify %s + +/*** +This file is for testing the path-sensitive notes for retain/release errors. +Its goal is to have simple branch coverage of any path-based diagnostics, +not to actually check all possible retain/release errors. + +This file is for notes that only appear in a GC-enabled analysis. +Non-specific and ref-count-only notes should go in retain-release-path-notes.m. +***/ + +@interface NSObject ++ (id)alloc; +- (id)init; +- (void)dealloc; + +- (Class)class; + +- (id)retain; +- (void)release; +- (void)autorelease; +@end + +@interface Foo : NSObject +- (id)methodWithValue; +@property(retain) id propertyValue; +@end + +typedef struct CFType *CFTypeRef; +CFTypeRef CFRetain(CFTypeRef); +void CFRelease(CFTypeRef); + +id NSMakeCollectable(CFTypeRef); +CFTypeRef CFMakeCollectable(CFTypeRef); + +CFTypeRef CFCreateSomething(); +CFTypeRef CFGetSomething(); + + +void creationViaCFCreate () { + CFTypeRef leaked = CFCreateSomething(); // expected-warning{{leak}} expected-note{{Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count. Core Foundation objects are not automatically garbage collected}} + return; // expected-note{{Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1}} +} + +void makeCollectable () { + CFTypeRef leaked = CFCreateSomething(); // expected-warning{{leak}} expected-note{{Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count. Core Foundation objects are not automatically garbage collected}} + CFRetain(leaked); // expected-note{{Reference count incremented. The object now has a +2 retain count}} + CFMakeCollectable(leaked); // expected-note{{In GC mode a call to 'CFMakeCollectable' decrements an object's retain count and registers the object with the garbage collector. An object must have a 0 retain count to be garbage collected. After this call its retain count is +1.}} + NSMakeCollectable(leaked); // expected-note{{In GC mode a call to 'NSMakeCollectable' decrements an object's retain count and registers the object with the garbage collector. Since it now has a 0 retain count the object can be automatically collected by the garbage collector}} + CFRetain(leaked); // expected-note{{Reference count incremented. The object now has a +1 retain count. The object is not eligible for garbage collection until the retain count reaches 0 again.}} + return; // expected-note{{Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1}} +} + +void retainReleaseIgnored () { + id object = [[NSObject alloc] init]; // expected-note{{Method returns an Objective-C object with a +0 retain count}} + [object retain]; // expected-note{{In GC mode the 'retain' message has no effect}} + [object release]; // expected-note{{In GC mode the 'release' message has no effect}} + [object autorelease]; // expected-note{{In GC mode an 'autorelease' has no effect}} + CFRelease((CFTypeRef)object); // expected-warning{{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} expected-note{{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} +} + +@implementation Foo (FundamentalRuleUnderGC) +- (id)getViolation { + id object = (id) CFCreateSomething(); // expected-warning{{leak}} expected-note{{Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count. Core Foundation objects are not automatically garbage collected.}} + return object; // expected-note{{Object returned to caller as an owning reference (single retain count transferred to caller)}} expected-note{{Object leaked: object allocated and stored into 'object' and returned from method 'getViolation' is potentially leaked when using garbage collection. Callers of this method do not expect a returned object with a +1 retain count since they expect the object to be managed by the garbage collector}} +} + +- (id)copyViolation { + id object = (id) CFCreateSomething(); // expected-warning{{leak}} expected-note{{Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count. Core Foundation objects are not automatically garbage collected.}} + return object; // expected-note{{Object returned to caller as an owning reference (single retain count transferred to caller)}} expected-note{{Object leaked: object allocated and stored into 'object' and returned from method 'copyViolation' is potentially leaked when using garbage collection. Callers of this method do not expect a returned object with a +1 retain count since they expect the object to be managed by the garbage collector}} +} +@end + diff --git a/test/Analysis/retain-release-path-notes.m b/test/Analysis/retain-release-path-notes.m new file mode 100644 index 0000000..bac0afb --- /dev/null +++ b/test/Analysis/retain-release-path-notes.m @@ -0,0 +1,123 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease -analyzer-store=basic -analyzer-output=text -verify %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease -analyzer-store=region -analyzer-output=text -verify %s + +/*** +This file is for testing the path-sensitive notes for retain/release errors. +Its goal is to have simple branch coverage of any path-based diagnostics, +not to actually check all possible retain/release errors. + +This file includes notes that only appear in a ref-counted analysis. +GC-specific notes should go in retain-release-path-notes-gc.m. +***/ + +@interface NSObject ++ (id)alloc; +- (id)init; +- (void)dealloc; + +- (Class)class; + +- (id)retain; +- (void)release; +- (void)autorelease; +@end + +@interface Foo : NSObject +- (id)methodWithValue; +@property(retain) id propertyValue; +@end + +typedef struct CFType *CFTypeRef; +CFTypeRef CFRetain(CFTypeRef); +void CFRelease(CFTypeRef); + +id NSMakeCollectable(CFTypeRef); +CFTypeRef CFMakeCollectable(CFTypeRef); + +CFTypeRef CFCreateSomething(); +CFTypeRef CFGetSomething(); + + +void creationViaAlloc () { + id leaked = [[NSObject alloc] init]; // expected-warning{{leak}} expected-note{{Method returns an Objective-C object with a +1 retain count}} + return; // expected-note{{Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1}} +} + +void creationViaCFCreate () { + CFTypeRef leaked = CFCreateSomething(); // expected-warning{{leak}} expected-note{{Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count}} + return; // expected-note{{Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1}} +} + +void acquisitionViaMethod (Foo *foo) { + id leaked = [foo methodWithValue]; // expected-warning{{leak}} expected-note{{Method returns an Objective-C object with a +0 retain count}} + [leaked retain]; // expected-note{{Reference count incremented. The object now has a +1 retain count}} + [leaked retain]; // expected-note{{Reference count incremented. The object now has a +2 retain count}} + [leaked release]; // expected-note{{Reference count decremented. The object now has a +1 retain count}} + return; // expected-note{{Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1}} +} + +void acquisitionViaProperty (Foo *foo) { + id leaked = foo.propertyValue; // expected-warning{{leak}} expected-note{{Property returns an Objective-C object with a +0 retain count}} + [leaked retain]; // expected-note{{Reference count incremented. The object now has a +1 retain count}} + return; // expected-note{{Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1}} +} + +void acquisitionViaCFFunction () { + CFTypeRef leaked = CFGetSomething(); // expected-warning{{leak}} expected-note{{Call to function 'CFGetSomething' returns a Core Foundation object with a +0 retain count}} + CFRetain(leaked); // expected-note{{Reference count incremented. The object now has a +1 retain count}} + return; // expected-note{{Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1}} +} + +void explicitDealloc () { + id object = [[NSObject alloc] init]; // expected-note{{Method returns an Objective-C object with a +1 retain count}} + [object dealloc]; // expected-note{{Object released by directly sending the '-dealloc' message}} + [object class]; // expected-warning{{Reference-counted object is used after it is released}} // expected-note{{Reference-counted object is used after it is released}} +} + +void implicitDealloc () { + id object = [[NSObject alloc] init]; // expected-note{{Method returns an Objective-C object with a +1 retain count}} + [object release]; // expected-note{{Object released}} + [object class]; // expected-warning{{Reference-counted object is used after it is released}} // expected-note{{Reference-counted object is used after it is released}} +} + +void overAutorelease () { + id object = [[NSObject alloc] init]; // expected-note{{Method returns an Objective-C object with a +1 retain count}} + [object autorelease]; // expected-note{{Object sent -autorelease message}} + [object autorelease]; // expected-note{{Object sent -autorelease message}} + return; // expected-warning{{Object sent -autorelease too many times}} expected-note{{Object over-autoreleased: object was sent -autorelease 2 times but the object has a +1 retain count}} +} + +void autoreleaseUnowned (Foo *foo) { + id object = foo.propertyValue; // expected-note{{Property returns an Objective-C object with a +0 retain count}} + [object autorelease]; // expected-note{{Object sent -autorelease message}} + return; // expected-warning{{Object sent -autorelease too many times}} expected-note{{Object over-autoreleased: object was sent -autorelease but the object has a +0 retain count}} +} + +void makeCollectableIgnored () { + CFTypeRef leaked = CFCreateSomething(); // expected-warning{{leak}} expected-note{{Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count}} + CFMakeCollectable(leaked); // expected-note{{When GC is not enabled a call to 'CFMakeCollectable' has no effect on its argument}} + NSMakeCollectable(leaked); // expected-note{{When GC is not enabled a call to 'NSMakeCollectable' has no effect on its argument}} + return; // expected-note{{Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1}} +} + +CFTypeRef CFCopyRuleViolation () { + CFTypeRef object = CFGetSomething(); // expected-note{{Call to function 'CFGetSomething' returns a Core Foundation object with a +0 retain counte}} + return object; // expected-warning{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}} expected-note{{Object returned to caller with a +0 retain count}} expected-note{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}} +} + +CFTypeRef CFGetRuleViolation () { + CFTypeRef object = CFCreateSomething(); // expected-warning{{leak}} expected-note{{Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain counte}} + return object; // expected-note{{Object returned to caller as an owning reference (single retain count transferred to caller)}} expected-note{{Object leaked: object allocated and stored into 'object' is return from a function whose name ('CFGetRuleViolation') does not contain 'Copy' or 'Create'. This violates the naming convention rules given the Memory Management Guide for Core Foundation}} +} + +@implementation Foo (FundamentalMemoryManagementRules) +- (id)copyViolation { + id result = self.propertyValue; // expected-note{{Property returns an Objective-C object with a +0 retain count}} + return result; // expected-warning{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}} expected-note{{Object returned to caller with a +0 retain count}} expected-note{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}} +} + +- (id)getViolation { + id result = [[Foo alloc] init]; // expected-warning{{leak}} expected-note{{Method returns an Objective-C object with a +1 retain count}} + return result; // expected-note{{Object returned to caller as an owning reference (single retain count transferred to caller)}} expected-note{{Object leaked: object allocated and stored into 'result' is returned from a method whose name ('getViolation') does not start with 'copy', 'mutableCopy', 'alloc' or 'new'. This violates the naming convention rules given in the Memory Management Guide for Cocoa}} +} +@end diff --git a/test/Analysis/retain-release.m b/test/Analysis/retain-release.m index 7af14f1..71ae756 100644 --- a/test/Analysis/retain-release.m +++ b/test/Analysis/retain-release.m @@ -116,6 +116,7 @@ typedef struct _NSZone NSZone; - (id)retain; - (oneway void)release; - (id)autorelease; +- (id)init; @end @protocol NSCopying - (id)copyWithZone:(NSZone *)zone; @end @protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone; @end @protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; @@ -517,7 +518,7 @@ void f17(int x, CFTypeRef p) { @implementation TestReturnNotOwnedWhenExpectedOwned - (NSString*)newString { NSString *s = [NSString stringWithUTF8String:"hello"]; - return s; // expected-warning{{Object with +0 retain counts returned to caller where a +1 (owning) retain count is expected}} + return s; // expected-warning{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}} } @end @@ -735,7 +736,7 @@ typedef CFTypeRef OtherRef; - (id)initReturningNewClassBad2 { [self release]; self = [[RDar6320065Subclass alloc] init]; - return [self autorelease]; // expected-warning{{Object with +0 retain counts returned to caller where a +1 (owning) retain count is expected}} + return [self autorelease]; // expected-warning{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}} } @end @@ -1302,7 +1303,7 @@ CFDateRef returnsRetainedCFDate() { } - (CFDateRef) newCFRetainedAsCFNoAttr { - return (CFDateRef)[(id)[self returnsCFRetainedAsCF] autorelease]; // expected-warning{{Object with +0 retain counts returned to caller where a +1 (owning) retain count is expected}} + return (CFDateRef)[(id)[self returnsCFRetainedAsCF] autorelease]; // expected-warning{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}} } - (NSDate*) alsoReturnsRetained { @@ -1445,7 +1446,7 @@ static void rdar_8724287(CFErrorRef error) while (error_to_dump != ((void*)0)) { CFDictionaryRef info; - info = CFErrorCopyUserInfo(error_to_dump); // expected-warning{{Potential leak of an object allocated on line 1448 and stored into 'info'}} + info = CFErrorCopyUserInfo(error_to_dump); // expected-warning{{Potential leak of an object allocated on line 1449 and stored into 'info'}} if (info != ((void*)0)) { } @@ -1461,3 +1462,81 @@ extern void rdar_9234108_helper(void *key, void * CF_CONSUMED value); void rdar_9234108() { rdar_9234108_helper(0, CFStringCreate()); } + +// - Make sure that objc_method_family works +// to override naming conventions. +struct TwoDoubles { + double one; + double two; +}; +typedef struct TwoDoubles TwoDoubles; + +@interface NSValue (Mine) +- (id)_prefix_initWithTwoDoubles:(TwoDoubles)twoDoubles __attribute__((objc_method_family(init))); +@end + +@implementation NSValue (Mine) +- (id)_prefix_initWithTwoDoubles:(TwoDoubles)twoDoubles +{ + return [self init]; +} +@end + +void rdar9726279() { + TwoDoubles twoDoubles = { 0.0, 0.0 }; + NSValue *value = [[NSValue alloc] _prefix_initWithTwoDoubles:twoDoubles]; + [value release]; +} + +// +// Test camelcase support for CF conventions. While Core Foundation APIs +// don't use camel casing, other code is allowed to use it. +CFArrayRef camelcase_create_1() { + return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning +} + +CFArrayRef camelcase_createno() { + return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning {{leak}} +} + +CFArrayRef camelcase_copy() { + return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning +} + +CFArrayRef camelcase_copying() { + return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning {{leak}} +} + +CFArrayRef copyCamelCase() { + return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning +} + +CFArrayRef __copyCamelCase() { + return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning +} + +CFArrayRef __createCamelCase() { + return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning +} + +CFArrayRef camel_create() { + return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning +} + + +CFArrayRef camel_creat() { + return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning {{leak}} +} + +CFArrayRef camel_copy() { + return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning +} + +CFArrayRef camel_copyMachine() { + return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning +} + +CFArrayRef camel_copymachine() { + return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning {{leak}} +} + diff --git a/test/Analysis/retain-release.mm b/test/Analysis/retain-release.mm index 0faeb1a..bdc3dc0 100644 --- a/test/Analysis/retain-release.mm +++ b/test/Analysis/retain-release.mm @@ -121,6 +121,7 @@ typedef struct _NSZone NSZone; + (id)allocWithZone:(NSZone *)zone; + (id)alloc; - (void)dealloc; +- (id)init; @end @interface NSObject (NSCoderMethods) - (id)awakeAfterUsingCoder:(NSCoder *)aDecoder; diff --git a/test/Analysis/string-fail.c b/test/Analysis/string-fail.c new file mode 100644 index 0000000..64ac504 --- /dev/null +++ b/test/Analysis/string-fail.c @@ -0,0 +1,113 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.experimental.CString,deadcode.experimental.UnreachableCode -analyzer-store=region -Wno-null-dereference -verify %s +// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -analyzer-checker=core,unix.experimental.CString,deadcode.experimental.UnreachableCode -analyzer-store=region -Wno-null-dereference -verify %s +// XFAIL: * + +// This file is for tests that may eventually go into string.c, or may be +// deleted outright. At one point these tests passed, but only because we +// weren't correctly modelling the behavior of the relevant string functions. +// The tests aren't incorrect, but require the analyzer to be smarter about +// conjured values than it currently is. + +//===----------------------------------------------------------------------=== +// Declarations +//===----------------------------------------------------------------------=== + +// Some functions are so similar to each other that they follow the same code +// path, such as memcpy and __memcpy_chk, or memcmp and bcmp. If VARIANT is +// defined, make sure to use the variants instead to make sure they are still +// checked by the analyzer. + +// Some functions are implemented as builtins. These should be #defined as +// BUILTIN(f), which will prepend "__builtin_" if USE_BUILTINS is defined. + +// Functions that have variants and are also available as builtins should be +// declared carefully! See memcpy() for an example. + +#ifdef USE_BUILTINS +# define BUILTIN(f) __builtin_ ## f +#else /* USE_BUILTINS */ +# define BUILTIN(f) f +#endif /* USE_BUILTINS */ + +#define NULL 0 +typedef typeof(sizeof(int)) size_t; + + +//===----------------------------------------------------------------------=== +// strnlen() +//===----------------------------------------------------------------------=== + +#define strnlen BUILTIN(strnlen) +size_t strnlen(const char *s, size_t maxlen); + +void strnlen_liveness(const char *x) { + if (strnlen(x, 10) < 5) + return; + if (strnlen(x, 10) < 5) + (void)*(char*)0; // no-warning +} + +void strnlen_subregion() { + struct two_stringsn { char a[2], b[2]; }; + extern void use_two_stringsn(struct two_stringsn *); + + struct two_stringsn z; + use_two_stringsn(&z); + + size_t a = strnlen(z.a, 10); + z.b[0] = 5; + size_t b = strnlen(z.a, 10); + if (a == 0 && b != 0) + (void)*(char*)0; // expected-warning{{never executed}} + + use_two_stringsn(&z); + + size_t c = strnlen(z.a, 10); + if (a == 0 && c != 0) + (void)*(char*)0; // expected-warning{{null}} +} + +extern void use_stringn(char *); +void strnlen_argument(char *x) { + size_t a = strnlen(x, 10); + size_t b = strnlen(x, 10); + if (a == 0 && b != 0) + (void)*(char*)0; // expected-warning{{never executed}} + + use_stringn(x); + + size_t c = strnlen(x, 10); + if (a == 0 && c != 0) + (void)*(char*)0; // expected-warning{{null}} +} + +extern char global_strn[]; +void strnlen_global() { + size_t a = strnlen(global_strn, 10); + size_t b = strnlen(global_strn, 10); + if (a == 0 && b != 0) + (void)*(char*)0; // expected-warning{{never executed}} + + // Call a function with unknown effects, which should invalidate globals. + use_stringn(0); + + size_t c = strnlen(global_strn, 10); + if (a == 0 && c != 0) + (void)*(char*)0; // expected-warning{{null}} +} + +void strnlen_indirect(char *x) { + size_t a = strnlen(x, 10); + char *p = x; + char **p2 = &p; + size_t b = strnlen(x, 10); + if (a == 0 && b != 0) + (void)*(char*)0; // expected-warning{{never executed}} + + extern void use_stringn_ptr(char*const*); + use_stringn_ptr(p2); + + size_t c = strnlen(x, 10); + if (a == 0 && c != 0) + (void)*(char*)0; // expected-warning{{null}} +} diff --git a/test/Analysis/string.c b/test/Analysis/string.c index e6baf51..dc97e1a 100644 --- a/test/Analysis/string.c +++ b/test/Analysis/string.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.experimental.CString,deadcode.experimental.UnreachableCode -analyzer-store=region -Wno-null-dereference -verify %s -// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -analyzer-checker=core,cplusplus.experimental.CString,deadcode.experimental.UnreachableCode -analyzer-store=region -Wno-null-dereference -verify %s -// RUN: %clang_cc1 -analyze -DVARIANT -analyzer-checker=core,cplusplus.experimental.CString,deadcode.experimental.UnreachableCode -analyzer-store=region -Wno-null-dereference -verify %s -// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -DVARIANT -analyzer-checker=core,cplusplus.experimental.CString,deadcode.experimental.UnreachableCode -analyzer-store=region -Wno-null-dereference -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.experimental.CString,deadcode.experimental.UnreachableCode -analyzer-store=region -Wno-null-dereference -verify %s +// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -analyzer-checker=core,unix.experimental.CString,deadcode.experimental.UnreachableCode -analyzer-store=region -Wno-null-dereference -verify %s +// RUN: %clang_cc1 -analyze -DVARIANT -analyzer-checker=core,unix.experimental.CString,deadcode.experimental.UnreachableCode -analyzer-store=region -Wno-null-dereference -verify %s +// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -DVARIANT -analyzer-checker=core,unix.experimental.CString,deadcode.experimental.UnreachableCode -analyzer-store=region -Wno-null-dereference -verify %s //===----------------------------------------------------------------------=== // Declarations @@ -55,16 +55,16 @@ void strlen_constant2(char x) { } size_t strlen_null() { - return strlen(0); // expected-warning{{Null pointer argument in call to byte string function}} + return strlen(0); // expected-warning{{Null pointer argument in call to string length function}} } size_t strlen_fn() { - return strlen((char*)&strlen_fn); // expected-warning{{Argument to byte string function is the address of the function 'strlen_fn', which is not a null-terminated string}} + return strlen((char*)&strlen_fn); // expected-warning{{Argument to string length function is the address of the function 'strlen_fn', which is not a null-terminated string}} } size_t strlen_nonloc() { label: - return strlen((char*)&&label); // expected-warning{{Argument to byte string function is the address of the label 'label', which is not a null-terminated string}} + return strlen((char*)&&label); // expected-warning{{Argument to string length function is the address of the label 'label', which is not a null-terminated string}} } void strlen_subregion() { @@ -143,24 +143,23 @@ void strlen_liveness(const char *x) { // strnlen() //===----------------------------------------------------------------------=== -#define strnlen BUILTIN(strnlen) size_t strnlen(const char *s, size_t maxlen); void strnlen_constant0() { if (strnlen("123", 10) != 3) - (void)*(char*)0; // no-warning + (void)*(char*)0; // expected-warning{{never executed}} } void strnlen_constant1() { const char *a = "123"; if (strnlen(a, 10) != 3) - (void)*(char*)0; // no-warning + (void)*(char*)0; // expected-warning{{never executed}} } void strnlen_constant2(char x) { char a[] = "123"; if (strnlen(a, 10) != 3) - (void)*(char*)0; // no-warning + (void)*(char*)0; // expected-warning{{never executed}} a[0] = x; if (strnlen(a, 10) != 3) (void)*(char*)0; // expected-warning{{null}} @@ -168,107 +167,90 @@ void strnlen_constant2(char x) { void strnlen_constant4() { if (strnlen("123456", 3) != 3) - (void)*(char*)0; // no-warning + (void)*(char*)0; // expected-warning{{never executed}} } void strnlen_constant5() { const char *a = "123456"; if (strnlen(a, 3) != 3) - (void)*(char*)0; // no-warning + (void)*(char*)0; // expected-warning{{never executed}} } void strnlen_constant6(char x) { char a[] = "123456"; if (strnlen(a, 3) != 3) - (void)*(char*)0; // no-warning + (void)*(char*)0; // expected-warning{{never executed}} a[0] = x; if (strnlen(a, 3) != 3) (void)*(char*)0; // expected-warning{{null}} } size_t strnlen_null() { - return strnlen(0, 3); // expected-warning{{Null pointer argument in call to byte string function}} + return strnlen(0, 3); // expected-warning{{Null pointer argument in call to string length function}} } size_t strnlen_fn() { - return strnlen((char*)&strlen_fn, 3); // expected-warning{{Argument to byte string function is the address of the function 'strlen_fn', which is not a null-terminated string}} + return strnlen((char*)&strlen_fn, 3); // expected-warning{{Argument to string length function is the address of the function 'strlen_fn', which is not a null-terminated string}} } size_t strnlen_nonloc() { label: - return strnlen((char*)&&label, 3); // expected-warning{{Argument to byte string function is the address of the label 'label', which is not a null-terminated string}} + return strnlen((char*)&&label, 3); // expected-warning{{Argument to string length function is the address of the label 'label', which is not a null-terminated string}} } -void strnlen_subregion() { - struct two_stringsn { char a[2], b[2]; }; - extern void use_two_stringsn(struct two_stringsn *); - - struct two_stringsn z; - use_two_stringsn(&z); - - size_t a = strnlen(z.a, 10); - z.b[0] = 5; - size_t b = strnlen(z.a, 10); - if (a == 0 && b != 0) +void strnlen_zero() { + if (strnlen("abc", 0) != 0) (void)*(char*)0; // expected-warning{{never executed}} + if (strnlen(NULL, 0) != 0) // no-warning + (void)*(char*)0; // no-warning +} + +size_t strnlen_compound_literal() { + // This used to crash because we don't model the string lengths of + // compound literals. + return strnlen((char[]) { 'a', 'b', 0 }, 1); +} - use_two_stringsn(&z); +size_t strnlen_unknown_limit(float f) { + // This used to crash because we don't model the integer values of floats. + return strnlen("abc", (int)f); +} - size_t c = strnlen(z.a, 10); - if (a == 0 && c != 0) +void strnlen_is_not_strlen(char *x) { + if (strnlen(x, 10) != strlen(x)) (void)*(char*)0; // expected-warning{{null}} } -extern void use_stringn(char *); -void strnlen_argument(char *x) { - size_t a = strnlen(x, 10); - size_t b = strnlen(x, 10); - if (a == 0 && b != 0) +void strnlen_at_limit(char *x) { + size_t len = strnlen(x, 10); + if (len > 10) (void)*(char*)0; // expected-warning{{never executed}} - - use_stringn(x); - - size_t c = strnlen(x, 10); - if (a == 0 && c != 0) - (void)*(char*)0; // expected-warning{{null}} + if (len == 10) + (void)*(char*)0; // expected-warning{{null}} } -extern char global_strn[]; -void strnlen_global() { - size_t a = strnlen(global_strn, 10); - size_t b = strnlen(global_strn, 10); - if (a == 0 && b != 0) +void strnlen_less_than_limit(char *x) { + size_t len = strnlen(x, 10); + if (len > 10) (void)*(char*)0; // expected-warning{{never executed}} - - // Call a function with unknown effects, which should invalidate globals. - use_stringn(0); - - size_t c = strnlen(global_str, 10); - if (a == 0 && c != 0) - (void)*(char*)0; // expected-warning{{null}} + if (len < 10) + (void)*(char*)0; // expected-warning{{null}} } -void strnlen_indirect(char *x) { - size_t a = strnlen(x, 10); - char *p = x; - char **p2 = &p; - size_t b = strnlen(x, 10); - if (a == 0 && b != 0) +void strnlen_at_actual(size_t limit) { + size_t len = strnlen("abc", limit); + if (len > 3) (void)*(char*)0; // expected-warning{{never executed}} - - extern void use_stringn_ptr(char*const*); - use_stringn_ptr(p2); - - size_t c = strnlen(x, 10); - if (a == 0 && c != 0) + if (len == 3) (void)*(char*)0; // expected-warning{{null}} } -void strnlen_liveness(const char *x) { - if (strnlen(x, 10) < 5) - return; - if (strnlen(x, 10) < 5) - (void)*(char*)0; // no-warning +void strnlen_less_than_actual(size_t limit) { + size_t len = strnlen("abc", limit); + if (len > 3) + (void)*(char*)0; // expected-warning{{never executed}} + if (len < 3) + (void)*(char*)0; // expected-warning{{null}} } //===----------------------------------------------------------------------=== @@ -291,15 +273,15 @@ char *strcpy(char *restrict s1, const char *restrict s2); void strcpy_null_dst(char *x) { - strcpy(NULL, x); // expected-warning{{Null pointer argument in call to byte string function}} + strcpy(NULL, x); // expected-warning{{Null pointer argument in call to string copy function}} } void strcpy_null_src(char *x) { - strcpy(x, NULL); // expected-warning{{Null pointer argument in call to byte string function}} + strcpy(x, NULL); // expected-warning{{Null pointer argument in call to string copy function}} } void strcpy_fn(char *x) { - strcpy(x, (char*)&strcpy_fn); // expected-warning{{Argument to byte string function is the address of the function 'strcpy_fn', which is not a null-terminated string}} + strcpy(x, (char*)&strcpy_fn); // expected-warning{{Argument to string copy function is the address of the function 'strcpy_fn', which is not a null-terminated string}} } void strcpy_effects(char *x, char *y) { @@ -318,7 +300,7 @@ void strcpy_effects(char *x, char *y) { void strcpy_overflow(char *y) { char x[4]; if (strlen(y) == 4) - strcpy(x, y); // expected-warning{{Byte string function overflows destination buffer}} + strcpy(x, y); // expected-warning{{String copy function overflows destination buffer}} } void strcpy_no_overflow(char *y) { @@ -362,7 +344,7 @@ void stpcpy_effect(char *x, char *y) { void stpcpy_overflow(char *y) { char x[4]; if (strlen(y) == 4) - stpcpy(x, y); // expected-warning{{Byte string function overflows destination buffer}} + stpcpy(x, y); // expected-warning{{String copy function overflows destination buffer}} } void stpcpy_no_overflow(char *y) { @@ -391,15 +373,15 @@ char *strcat(char *restrict s1, const char *restrict s2); void strcat_null_dst(char *x) { - strcat(NULL, x); // expected-warning{{Null pointer argument in call to byte string function}} + strcat(NULL, x); // expected-warning{{Null pointer argument in call to string copy function}} } void strcat_null_src(char *x) { - strcat(x, NULL); // expected-warning{{Null pointer argument in call to byte string function}} + strcat(x, NULL); // expected-warning{{Null pointer argument in call to string copy function}} } void strcat_fn(char *x) { - strcat(x, (char*)&strcat_fn); // expected-warning{{Argument to byte string function is the address of the function 'strcat_fn', which is not a null-terminated string}} + strcat(x, (char*)&strcat_fn); // expected-warning{{Argument to string copy function is the address of the function 'strcat_fn', which is not a null-terminated string}} } void strcat_effects(char *y) { @@ -415,27 +397,24 @@ void strcat_effects(char *y) { if ((int)strlen(x) != (orig_len + strlen(y))) (void)*(char*)0; // no-warning - - if (a != x[0]) - (void)*(char*)0; // expected-warning{{null}} } void strcat_overflow_0(char *y) { char x[4] = "12"; if (strlen(y) == 4) - strcat(x, y); // expected-warning{{Byte string function overflows destination buffer}} + strcat(x, y); // expected-warning{{String copy function overflows destination buffer}} } void strcat_overflow_1(char *y) { char x[4] = "12"; if (strlen(y) == 3) - strcat(x, y); // expected-warning{{Byte string function overflows destination buffer}} + strcat(x, y); // expected-warning{{String copy function overflows destination buffer}} } void strcat_overflow_2(char *y) { char x[4] = "12"; if (strlen(y) == 2) - strcat(x, y); // expected-warning{{Byte string function overflows destination buffer}} + strcat(x, y); // expected-warning{{String copy function overflows destination buffer}} } void strcat_no_overflow(char *y) { @@ -444,6 +423,136 @@ void strcat_no_overflow(char *y) { strcat(x, y); // no-warning } +void strcat_symbolic_dst_length(char *dst) { + strcat(dst, "1234"); + if (strlen(dst) < 4) + (void)*(char*)0; // no-warning +} + +void strcat_symbolic_src_length(char *src) { + char dst[8] = "1234"; + strcat(dst, src); + if (strlen(dst) < 4) + (void)*(char*)0; // no-warning +} + +void strcat_unknown_src_length(char *src, int offset) { + char dst[8] = "1234"; + strcat(dst, &src[offset]); + if (strlen(dst) < 4) + (void)*(char*)0; // no-warning +} + +// There is no strcat_unknown_dst_length because if we can't get a symbolic +// length for the "before" strlen, we won't be able to set one for "after". + +void strcat_too_big(char *dst, char *src) { + if (strlen(dst) != (((size_t)0) - 2)) + return; + if (strlen(src) != 2) + return; + strcat(dst, src); // expected-warning{{This expression will create a string whose length is too big to be represented as a size_t}} +} + + +//===----------------------------------------------------------------------=== +// strncpy() +//===----------------------------------------------------------------------=== + +#ifdef VARIANT + +#define __strncpy_chk BUILTIN(__strncpy_chk) +char *__strncpy_chk(char *restrict s1, const char *restrict s2, size_t n, size_t destlen); + +#define strncpy(a,b,n) __strncpy_chk(a,b,n,(size_t)-1) + +#else /* VARIANT */ + +#define strncpy BUILTIN(strncpy) +char *strncpy(char *restrict s1, const char *restrict s2, size_t n); + +#endif /* VARIANT */ + + +void strncpy_null_dst(char *x) { + strncpy(NULL, x, 5); // expected-warning{{Null pointer argument in call to string copy function}} +} + +void strncpy_null_src(char *x) { + strncpy(x, NULL, 5); // expected-warning{{Null pointer argument in call to string copy function}} +} + +void strncpy_fn(char *x) { + strncpy(x, (char*)&strcpy_fn, 5); // expected-warning{{Argument to string copy function is the address of the function 'strcpy_fn', which is not a null-terminated string}} +} + +void strncpy_effects(char *x, char *y) { + char a = x[0]; + + if (strncpy(x, y, 5) != x) + (void)*(char*)0; // no-warning + + if (strlen(x) != strlen(y)) + (void)*(char*)0; // expected-warning{{null}} + + if (a != x[0]) + (void)*(char*)0; // expected-warning{{null}} +} + +void strncpy_overflow(char *y) { + char x[4]; + if (strlen(y) == 4) + strncpy(x, y, 5); // expected-warning{{Size argument is greater than the length of the destination buffer}} +} + +void strncpy_no_overflow(char *y) { + char x[4]; + if (strlen(y) == 3) + strncpy(x, y, 5); // expected-warning{{Size argument is greater than the length of the destination buffer}} +} + +void strncpy_no_overflow2(char *y, int n) { + if (n <= 4) + return; + + char x[4]; + if (strlen(y) == 3) + strncpy(x, y, n); // expected-warning{{Size argument is greater than the length of the destination buffer}} +} + +void strncpy_truncate(char *y) { + char x[4]; + if (strlen(y) == 4) + strncpy(x, y, 3); // no-warning +} + +void strncpy_no_truncate(char *y) { + char x[4]; + if (strlen(y) == 3) + strncpy(x, y, 3); // no-warning +} + +void strncpy_exactly_matching_buffer(char *y) { + char x[4]; + strncpy(x, y, 4); // no-warning + + // strncpy does not null-terminate, so we have no idea what the strlen is + // after this. + if (strlen(x) > 4) + (void)*(int*)0; // expected-warning{{null}} +} + +void strncpy_exactly_matching_buffer2(char *y) { + if (strlen(y) >= 4) + return; + + char x[4]; + strncpy(x, y, 4); // no-warning + + // This time, we know that y fits in x anyway. + if (strlen(x) > 3) + (void)*(int*)0; // no-warning +} //===----------------------------------------------------------------------=== // strncat() @@ -465,15 +574,15 @@ char *strncat(char *restrict s1, const char *restrict s2, size_t n); void strncat_null_dst(char *x) { - strncat(NULL, x, 4); // expected-warning{{Null pointer argument in call to byte string function}} + strncat(NULL, x, 4); // expected-warning{{Null pointer argument in call to string copy function}} } void strncat_null_src(char *x) { - strncat(x, NULL, 4); // expected-warning{{Null pointer argument in call to byte string function}} + strncat(x, NULL, 4); // expected-warning{{Null pointer argument in call to string copy function}} } void strncat_fn(char *x) { - strncat(x, (char*)&strncat_fn, 4); // expected-warning{{Argument to byte string function is the address of the function 'strncat_fn', which is not a null-terminated string}} + strncat(x, (char*)&strncat_fn, 4); // expected-warning{{Argument to string copy function is the address of the function 'strncat_fn', which is not a null-terminated string}} } void strncat_effects(char *y) { @@ -489,33 +598,30 @@ void strncat_effects(char *y) { if (strlen(x) != orig_len + strlen(y)) (void)*(char*)0; // no-warning - - if (a != x[0]) - (void)*(char*)0; // expected-warning{{null}} } void strncat_overflow_0(char *y) { char x[4] = "12"; if (strlen(y) == 4) - strncat(x, y, strlen(y)); // expected-warning{{Byte string function overflows destination buffer}} + strncat(x, y, strlen(y)); // expected-warning{{Size argument is greater than the free space in the destination buffer}} } void strncat_overflow_1(char *y) { char x[4] = "12"; if (strlen(y) == 3) - strncat(x, y, strlen(y)); // expected-warning{{Byte string function overflows destination buffer}} + strncat(x, y, strlen(y)); // expected-warning{{Size argument is greater than the free space in the destination buffer}} } void strncat_overflow_2(char *y) { char x[4] = "12"; if (strlen(y) == 2) - strncat(x, y, strlen(y)); // expected-warning{{Byte string function overflows destination buffer}} + strncat(x, y, strlen(y)); // expected-warning{{Size argument is greater than the free space in the destination buffer}} } void strncat_overflow_3(char *y) { char x[4] = "12"; if (strlen(y) == 4) - strncat(x, y, 2); // expected-warning{{Byte string function overflows destination buffer}} + strncat(x, y, 2); // expected-warning{{Size argument is greater than the free space in the destination buffer}} } void strncat_no_overflow_1(char *y) { char x[5] = "12"; @@ -529,12 +635,69 @@ void strncat_no_overflow_2(char *y) { strncat(x, y, 1); // no-warning } +void strncat_symbolic_dst_length(char *dst) { + strncat(dst, "1234", 5); + if (strlen(dst) < 4) + (void)*(char*)0; // no-warning +} + +void strncat_symbolic_src_length(char *src) { + char dst[8] = "1234"; + strncat(dst, src, 3); + if (strlen(dst) < 4) + (void)*(char*)0; // no-warning + + char dst2[8] = "1234"; + strncat(dst2, src, 4); // expected-warning{{Size argument is greater than the free space in the destination buffer}} +} + +void strncat_unknown_src_length(char *src, int offset) { + char dst[8] = "1234"; + strncat(dst, &src[offset], 3); + if (strlen(dst) < 4) + (void)*(char*)0; // no-warning + + char dst2[8] = "1234"; + strncat(dst2, &src[offset], 4); // expected-warning{{Size argument is greater than the free space in the destination buffer}} +} + +// There is no strncat_unknown_dst_length because if we can't get a symbolic +// length for the "before" strlen, we won't be able to set one for "after". + +void strncat_symbolic_limit(unsigned limit) { + char dst[6] = "1234"; + char src[] = "567"; + strncat(dst, src, limit); // no-warning + if (strlen(dst) < 4) + (void)*(char*)0; // no-warning + if (strlen(dst) == 4) + (void)*(char*)0; // expected-warning{{null}} +} + +void strncat_unknown_limit(float limit) { + char dst[6] = "1234"; + char src[] = "567"; + strncat(dst, src, (size_t)limit); // no-warning + if (strlen(dst) < 4) + (void)*(char*)0; // no-warning + if (strlen(dst) == 4) + (void)*(char*)0; // expected-warning{{null}} +} + +void strncat_too_big(char *dst, char *src) { + if (strlen(dst) != (((size_t)0) - 2)) + return; + if (strlen(src) != 2) + return; + strncat(dst, src, 2); // expected-warning{{This expression will create a string whose length is too big to be represented as a size_t}} +} + //===----------------------------------------------------------------------=== // strcmp() //===----------------------------------------------------------------------=== #define strcmp BUILTIN(strcmp) -int strcmp(const char *restrict s1, const char *restrict s2); +int strcmp(const char * s1, const char * s2); void strcmp_constant0() { if (strcmp("123", "123") != 0) @@ -577,13 +740,13 @@ void strcmp_2() { void strcmp_null_0() { char *x = NULL; char *y = "123"; - strcmp(x, y); // expected-warning{{Null pointer argument in call to byte string function}} + strcmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}} } void strcmp_null_1() { char *x = "123"; char *y = NULL; - strcmp(x, y); // expected-warning{{Null pointer argument in call to byte string function}} + strcmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}} } void strcmp_diff_length_0() { @@ -614,12 +777,22 @@ void strcmp_diff_length_3() { (void)*(char*)0; // no-warning } +void strcmp_embedded_null () { + if (strcmp("\0z", "\0y") != 0) + (void)*(char*)0; // no-warning +} + +void strcmp_unknown_arg (char *unknown) { + if (strcmp(unknown, unknown) != 0) + (void)*(char*)0; // no-warning +} + //===----------------------------------------------------------------------=== // strncmp() //===----------------------------------------------------------------------=== #define strncmp BUILTIN(strncmp) -int strncmp(const char *restrict s1, const char *restrict s2, size_t n); +int strncmp(const char *s1, const char *s2, size_t n); void strncmp_constant0() { if (strncmp("123", "123", 3) != 0) @@ -662,13 +835,13 @@ void strncmp_2() { void strncmp_null_0() { char *x = NULL; char *y = "123"; - strncmp(x, y, 3); // expected-warning{{Null pointer argument in call to byte string function}} + strncmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}} } void strncmp_null_1() { char *x = "123"; char *y = NULL; - strncmp(x, y, 3); // expected-warning{{Null pointer argument in call to byte string function}} + strncmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}} } void strncmp_diff_length_0() { @@ -720,12 +893,17 @@ void strncmp_diff_length_6() { (void)*(char*)0; // no-warning } +void strncmp_embedded_null () { + if (strncmp("ab\0zz", "ab\0yy", 4) != 0) + (void)*(char*)0; // no-warning +} + //===----------------------------------------------------------------------=== // strcasecmp() //===----------------------------------------------------------------------=== #define strcasecmp BUILTIN(strcasecmp) -int strcasecmp(const char *restrict s1, const char *restrict s2); +int strcasecmp(const char *s1, const char *s2); void strcasecmp_constant0() { if (strcasecmp("abc", "Abc") != 0) @@ -768,13 +946,13 @@ void strcasecmp_2() { void strcasecmp_null_0() { char *x = NULL; char *y = "123"; - strcasecmp(x, y); // expected-warning{{Null pointer argument in call to byte string function}} + strcasecmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}} } void strcasecmp_null_1() { char *x = "123"; char *y = NULL; - strcasecmp(x, y); // expected-warning{{Null pointer argument in call to byte string function}} + strcasecmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}} } void strcasecmp_diff_length_0() { @@ -805,12 +983,17 @@ void strcasecmp_diff_length_3() { (void)*(char*)0; // no-warning } +void strcasecmp_embedded_null () { + if (strcasecmp("ab\0zz", "ab\0yy") != 0) + (void)*(char*)0; // no-warning +} + //===----------------------------------------------------------------------=== // strncasecmp() //===----------------------------------------------------------------------=== #define strncasecmp BUILTIN(strncasecmp) -int strncasecmp(const char *restrict s1, const char *restrict s2, size_t n); +int strncasecmp(const char *s1, const char *s2, size_t n); void strncasecmp_constant0() { if (strncasecmp("abc", "Abc", 3) != 0) @@ -853,13 +1036,13 @@ void strncasecmp_2() { void strncasecmp_null_0() { char *x = NULL; char *y = "123"; - strncasecmp(x, y, 3); // expected-warning{{Null pointer argument in call to byte string function}} + strncasecmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}} } void strncasecmp_null_1() { char *x = "123"; char *y = NULL; - strncasecmp(x, y, 3); // expected-warning{{Null pointer argument in call to byte string function}} + strncasecmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}} } void strncasecmp_diff_length_0() { @@ -910,3 +1093,8 @@ void strncasecmp_diff_length_6() { if (strncasecmp(x, y, 3) != 1) (void)*(char*)0; // no-warning } + +void strncasecmp_embedded_null () { + if (strncasecmp("ab\0zz", "ab\0yy", 4) != 0) + (void)*(char*)0; // no-warning +} diff --git a/test/Analysis/uninit-ps-rdar6145427.m b/test/Analysis/uninit-ps-rdar6145427.m index f179406..f4df913 100644 --- a/test/Analysis/uninit-ps-rdar6145427.m +++ b/test/Analysis/uninit-ps-rdar6145427.m @@ -11,7 +11,10 @@ typedef struct _NSZone NSZone; @protocol NSObject - (BOOL)isEqual:(id)object; @end @protocol NSCopying - (id)copyWithZone:(NSZone *)zone; @end @protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; @end -@interface NSObject {} + (id)alloc; @end +@interface NSObject {} ++ (id)alloc; +- (id)init; +@end extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone); @interface NSValue : NSObject - (void)getValue:(void *)value; @end @class NSString, NSData; diff --git a/test/Analysis/uninit-vals-ps-region.m b/test/Analysis/uninit-vals-ps-region.m index 1700f54..c62818a 100644 --- a/test/Analysis/uninit-vals-ps-region.m +++ b/test/Analysis/uninit-vals-ps-region.m @@ -67,3 +67,12 @@ void rdar_7780304() { b.x |= 1; // expected-warning{{The left expression of the compound assignment is an uninitialized value. The computed value will also be garbage}} } + +// The flip side of PR10163 -- float arrays that are actually uninitialized +// (The main test is in uninit-vals.m) +void test_PR10163(float); +void PR10163 (void) { + float x[2]; + test_PR10163(x[1]); // expected-warning{{uninitialized value}} +} + diff --git a/test/Analysis/uninit-vals.m b/test/Analysis/uninit-vals.m index 2cd5e0c..4b7e6f4 100644 --- a/test/Analysis/uninit-vals.m +++ b/test/Analysis/uninit-vals.m @@ -23,3 +23,12 @@ NSUInteger f8(A* x){ return n; } + + +// PR10163 -- don't warn for default-initialized float arrays. +// (An additional test is in uninit-vals-ps-region.m) +void test_PR10163(float); +void PR10163 (void) { + float x[2] = {0}; + test_PR10163(x[1]); // no-warning +} diff --git a/test/Analysis/variadic-method-types.m b/test/Analysis/variadic-method-types.m index 018956a..03c309a 100644 --- a/test/Analysis/variadic-method-types.m +++ b/test/Analysis/variadic-method-types.m @@ -73,13 +73,13 @@ void f(id a, id

b, C* c, C

*d, FooType fooType, BarType barType) { [NSDictionary dictionaryWithObjectsAndKeys:@"Foo", "Bar", nil]; // expected-warning {{Argument to 'NSDictionary' method 'dictionaryWithObjectsAndKeys:' should be an Objective-C pointer type, not 'char *'}} [NSSet setWithObjects:@"Foo", "Bar", nil]; // expected-warning {{Argument to 'NSSet' method 'setWithObjects:' should be an Objective-C pointer type, not 'char *'}} - [[[NSArray alloc] initWithObjects:@"Foo", "Bar", nil] autorelease]; // expected-warning {{Argument to method 'initWithObjects:' should be an Objective-C pointer type, not 'char *'}} - [[[NSDictionary alloc] initWithObjectsAndKeys:@"Foo", "Bar", nil] autorelease]; // expected-warning {{Argument to method 'initWithObjectsAndKeys:' should be an Objective-C pointer type, not 'char *'}} + [[[NSArray alloc] initWithObjects:@"Foo", "Bar", nil] autorelease]; // expected-warning {{Argument to 'NSArray' method 'initWithObjects:' should be an Objective-C pointer type, not 'char *'}} + [[[NSDictionary alloc] initWithObjectsAndKeys:@"Foo", "Bar", nil] autorelease]; // expected-warning {{Argument to 'NSDictionary' method 'initWithObjectsAndKeys:' should be an Objective-C pointer type, not 'char *'}} [[[NSDictionary alloc] initWithObjectsAndKeys:@"Foo", (void*) 0, nil] autorelease]; // no-warning [[[NSDictionary alloc] initWithObjectsAndKeys:@"Foo", kCGImageSourceShouldCache, nil] autorelease]; // no-warning [[[NSDictionary alloc] initWithObjectsAndKeys:@"Foo", fooType, nil] autorelease]; // no-warning - [[[NSDictionary alloc] initWithObjectsAndKeys:@"Foo", barType, nil] autorelease]; // expected-warning {{Argument to method 'initWithObjectsAndKeys:' should be an Objective-C pointer type, not 'BarType'}} - [[[NSSet alloc] initWithObjects:@"Foo", "Bar", nil] autorelease]; // expected-warning {{Argument to method 'initWithObjects:' should be an Objective-C pointer type, not 'char *'}} + [[[NSDictionary alloc] initWithObjectsAndKeys:@"Foo", barType, nil] autorelease]; // expected-warning {{Argument to 'NSDictionary' method 'initWithObjectsAndKeys:' should be an Objective-C pointer type, not 'BarType'}} + [[[NSSet alloc] initWithObjects:@"Foo", "Bar", nil] autorelease]; // expected-warning {{Argument to 'NSSet' method 'initWithObjects:' should be an Objective-C pointer type, not 'char *'}} } // This previously crashed the variadic argument checker. diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index e35413a..0f00e50 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -99,10 +99,10 @@ if(PYTHONINTERP_FOUND) COMMENT "Running Clang and LLVM regression tests") add_dependencies(check-all clang-test.deps) if ( LLVM_INCLUDE_TESTS ) - add_dependencies(check-all check.deps ClangUnitTests) + add_dependencies(clang-test.deps check.deps ClangUnitTests) endif ( LLVM_INCLUDE_TESTS ) add_dependencies(clang-test.deps - llvm-dis opt + llvm-dis llc opt FileCheck count not ) set_target_properties(check-all PROPERTIES FOLDER "Clang tests") @@ -110,7 +110,7 @@ if(PYTHONINTERP_FOUND) add_dependencies(clang-test clang-test.deps) add_dependencies(clang-test.deps - clang clang-headers c-index-test + clang clang-headers c-index-test arcmt-test c-arcmt-test ) endif() diff --git a/test/CXX/basic/basic.lookup/basic.lookup.argdep/p4.cpp b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p4.cpp index ccadf41..15d86b7 100644 --- a/test/CXX/basic/basic.lookup/basic.lookup.argdep/p4.cpp +++ b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p4.cpp @@ -19,8 +19,9 @@ namespace D { } namespace C { - class C {}; - void func(C); + class C {}; // expected-note {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'B::B' to 'const C::C &' for 1st argument}} + void func(C); // expected-note {{'C::func' declared here}} \ + // expected-note {{passing argument to parameter here}} C operator+(C,C); D::D operator+(D::D,D::D); } @@ -32,7 +33,13 @@ namespace D { namespace Test { void test() { func(A::A()); - func(B::B()); // expected-error {{use of undeclared identifier 'func'}} + // FIXME: namespace-aware typo correction causes an extra, misleading + // message in this case; some form of backtracking, diagnostic message + // delaying, or argument checking before emitting diagnostics is needed to + // avoid accepting and printing out a typo correction that proves to be + // incorrect once argument-dependent lookup resolution has occurred. + func(B::B()); // expected-error {{use of undeclared identifier 'func'; did you mean 'C::func'?}} \ + // expected-error {{no viable conversion from 'B::B' to 'C::C'}} func(C::C()); A::A() + A::A(); B::B() + B::B(); diff --git a/test/CXX/class/p6-0x.cpp b/test/CXX/class/p6-0x.cpp new file mode 100644 index 0000000..fc83e06 --- /dev/null +++ b/test/CXX/class/p6-0x.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x + +class Trivial { int n; void f(); }; +class NonTrivial1 { NonTrivial1(const NonTrivial1 &); }; +class NonTrivial2 { NonTrivial2(NonTrivial2 &&); }; +class NonTrivial3 { NonTrivial3 operator=(const NonTrivial3 &); }; +class NonTrivial4 { NonTrivial4 operator=(NonTrivial4 &&); }; +class NonTrivial5 { ~NonTrivial5(); }; + +static_assert(__is_trivial(Trivial), "Trivial is not trivial"); +static_assert(!__is_trivial(NonTrivial1), "NonTrivial1 is trivial"); +static_assert(!__is_trivial(NonTrivial2), "NonTrivial2 is trivial"); +static_assert(!__is_trivial(NonTrivial3), "NonTrivial3 is trivial"); +static_assert(!__is_trivial(NonTrivial4), "NonTrivial4 is trivial"); +static_assert(!__is_trivial(NonTrivial5), "NonTrivial5 is trivial"); diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p1.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p1.cpp index 40917b8..cbb439e 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p1.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p1.cpp @@ -7,13 +7,13 @@ template void f(T) {} template static void g(T) {} -template<> static void f(int); // expected-error{{explicit specialization cannot have a storage class}} +template<> static void f(int); // expected-error{{explicit specialization has extraneous, inconsistent storage class 'static'}} template static void f(float); // expected-error{{explicit instantiation cannot have a storage class}} template<> void f(double); template void f(long); -template<> static void g(int); // expected-error{{explicit specialization cannot have a storage class}} +template<> static void g(int); // expected-warning{{explicit specialization cannot have a storage class}} template static void g(float); // expected-error{{explicit instantiation cannot have a storage class}} template<> void g(double); diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp index fabfb53..54da854 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp @@ -46,7 +46,7 @@ void j() { U v; // expected-error{{'auto' not allowed in template argument}} int n; - (void)dynamic_cast(S()); // expected-error{{'auto' not allowed here}} + (void)dynamic_cast(n); // expected-error{{'auto' not allowed here}} (void)static_cast(&n); // expected-error{{'auto' not allowed here}} (void)reinterpret_cast(&n); // expected-error{{'auto' not allowed here}} (void)const_cast(n); // expected-error{{'auto' not allowed here}} diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp index 06aeaa6..8b4b703 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp @@ -54,8 +54,7 @@ void f() { auto *fail1 = 0; // expected-error {{variable 'fail1' with type 'auto *' has incompatible initializer of type 'int'}} int **p; - // FIXME: due to PR9233, we get the wrong diagnostic here. - const auto **fail2(p); // desired-error {{variable 'fail2' with type 'auto const **' has incompatible initializer of type 'int **'}} expected-error {{cannot initialize}} + const auto **fail2(p); // expected-error {{variable 'fail2' with type 'auto const **' has incompatible initializer of type 'int **'}} } struct S { diff --git a/test/CXX/except/except.spec/canonical.cpp b/test/CXX/except/except.spec/canonical.cpp new file mode 100644 index 0000000..9bc26de --- /dev/null +++ b/test/CXX/except/except.spec/canonical.cpp @@ -0,0 +1,53 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s + +// PR10087: Make sure that we don't conflate exception specifications +// from different functions in the canonical type system. +namespace std +{ + +template _Tp&& declval() noexcept; + +template +struct __is_nothrow_constructible +{ + static const bool value = noexcept(_Tp(declval<_Args>()...)); +}; + +template +class basic_string +{ +public: + typedef typename _Traits::char_type value_type; + typedef _Allocator allocator_type; + + basic_string() + noexcept(__is_nothrow_constructible::value); +}; + +template +struct __map_value_compare +{ +public: + __map_value_compare() + noexcept(__is_nothrow_constructible<_Compare>::value); +}; + +struct less +{ +}; + +struct map +{ + typedef __map_value_compare __vc; + __vc vc_; +}; + + +template +basic_string::basic_string() noexcept(__is_nothrow_constructible::value) {} + +template +__map_value_compare::__map_value_compare() + noexcept(__is_nothrow_constructible<_Compare>::value) {} + +} // std diff --git a/test/CXX/except/except.spec/p14-ir.cpp b/test/CXX/except/except.spec/p14-ir.cpp index c681727..81fbf7d 100644 --- a/test/CXX/except/except.spec/p14-ir.cpp +++ b/test/CXX/except/except.spec/p14-ir.cpp @@ -26,12 +26,12 @@ struct X4 { struct X5 : X0, X4 { }; void test(X2 x2, X3 x3, X5 x5) { - // CHECK: define linkonce_odr void @_ZN2X2C1ERKS_(%struct.X0* %this, %struct.X0*) unnamed_addr + // CHECK: define linkonce_odr void @_ZN2X2C1ERKS_(%struct.X2* %this, %struct.X2*) unnamed_addr // CHECK: call void @_ZN2X2C2ERKS_({{.*}}) nounwind // CHECK-NEXT: ret void // CHECK-NEXT: } X2 x2a(x2); - // CHECK: define linkonce_odr void @_ZN2X3C1ERKS_(%struct.X0* %this, %struct.X0*) unnamed_addr + // CHECK: define linkonce_odr void @_ZN2X3C1ERKS_(%struct.X3* %this, %struct.X3*) unnamed_addr // CHECK: call void @_ZN2X3C2ERKS_({{.*}}) nounwind // CHECK-NEXT: ret void // CHECK-NEXT: } @@ -55,24 +55,25 @@ struct X8 : X6 { }; struct X9 : X6, X7 { }; void test() { - // CHECK: define linkonce_odr void @_ZN2X8C1Ev(%struct.X0* %this) unnamed_addr + // CHECK: define linkonce_odr void @_ZN2X8C1Ev(%struct.X8* %this) unnamed_addr // CHECK: call void @_ZN2X8C2Ev({{.*}}) nounwind // CHECK-NEXT: ret void X8(); - // CHECK: define linkonce_odr void @_ZN2X9C1Ev(%struct.X0* %this) unnamed_addr + // CHECK: define linkonce_odr void @_ZN2X9C1Ev(%struct.X9* %this) unnamed_addr // FIXME: check that this is the end of the line here: // CHECK: call void @_ZN2X9C2Ev({{.*}}) // CHECK-NEXT: ret void X9(); - // CHECK: define linkonce_odr void @_ZN2X9C2Ev(%struct.X0* %this) unnamed_addr + // CHECK: define linkonce_odr void @_ZN2X9C2Ev(%struct.X9* %this) unnamed_addr // CHECK: call void @_ZN2X6C2Ev({{.*}}) nounwind // FIXME: and here: + // CHECK-NEXT: bitcast // CHECK-NEXT: call void @_ZN2X7C2Ev({{.*}}) // CHECK: ret void - // CHECK: define linkonce_odr void @_ZN2X8C2Ev(%struct.X0* %this) unnamed_addr + // CHECK: define linkonce_odr void @_ZN2X8C2Ev(%struct.X8* %this) unnamed_addr // CHECK: call void @_ZN2X6C2Ev({{.*}}) nounwind // CHECK-NEXT: ret void } diff --git a/test/CXX/special/class.copy/p33-0x.cpp b/test/CXX/special/class.copy/p33-0x.cpp index 1e6a025..b196865 100644 --- a/test/CXX/special/class.copy/p33-0x.cpp +++ b/test/CXX/special/class.copy/p33-0x.cpp @@ -23,3 +23,35 @@ void throw_move_only(X x) { throw x2; } +namespace PR10142 { + struct X { + X(); + X(X&&); + X(const X&) = delete; // expected-note 2{{function has been explicitly marked deleted here}} + }; + + void f(int i) { + X x; + try { + X x2; + if (i) + throw x2; // okay + throw x; // expected-error{{call to deleted constructor of 'PR10142::X'}} + } catch (...) { + } + } + + template + void f2(int i) { + T x; + try { + T x2; + if (i) + throw x2; // okay + throw x; // expected-error{{call to deleted constructor of 'PR10142::X'}} + } catch (...) { + } + } + + template void f2(int); // expected-note{{in instantiation of function template specialization 'PR10142::f2' requested here}} +} diff --git a/test/CXX/stmt.stmt/stmt.dcl/p3-0x.cpp b/test/CXX/stmt.stmt/stmt.dcl/p3-0x.cpp index b415044..40b4c23 100644 --- a/test/CXX/stmt.stmt/stmt.dcl/p3-0x.cpp +++ b/test/CXX/stmt.stmt/stmt.dcl/p3-0x.cpp @@ -30,13 +30,13 @@ struct Y { void f(); void test_Y() { - goto end; - Y y; + goto end; // expected-error{{goto into protected scope}} + Y y; // expected-note{{jump bypasses variable with a non-trivial destructor}} end: f(); - goto inner; + goto inner; // expected-error{{goto into protected scope}} { - Y y2; + Y y2; // expected-note{{jump bypasses variable with a non-trivial destructor}} inner: f(); } diff --git a/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp b/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp index 7bfa6fe..0c92f62 100644 --- a/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp +++ b/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp @@ -129,7 +129,7 @@ void g() { void *begin(); // expected-note {{selected 'begin' function with iterator type 'void *'}} void *end(); }; - for (auto u : NoIncr()) { // expected-error {{arithmetic on pointer to void type}} + for (auto u : NoIncr()) { // expected-error {{arithmetic on a pointer to void type}} } struct NoNotEq { diff --git a/test/CXX/temp/p3.cpp b/test/CXX/temp/p3.cpp new file mode 100644 index 0000000..16ebb38 --- /dev/null +++ b/test/CXX/temp/p3.cpp @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -verify %s + +template struct S { + static int a, b; +}; + +template int S::a, S::b; // expected-error {{can only declare a single entity}} + +// FIXME: the last two diagnostics here are terrible. +template struct A { static A a; } A::a; // expected-error {{expected ';' after struct}} \ + expected-error {{use of undeclared identifier 'T'}} \ + expected-error {{cannot name the global scope}} \ + expected-error {{no member named 'a' in the global namespace}} + +template struct B { } f(); // expected-error {{expected ';' after struct}} \ + expected-error {{requires a type specifier}} + +template struct C { } // expected-error {{expected ';' after struct}} + +A c; diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3.cpp index 3c22cf3..295f080 100644 --- a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3.cpp +++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3.cpp @@ -71,7 +71,21 @@ void test_f3(int ***ip, volatile int ***vip) { A a0 = f3(ip); A a1 = f3(vip); } - + +// Also accept conversions for pointer types which require removing +// [[noreturn]]. +namespace noreturn_stripping { + template + void f(R (*function)()); + + void g() __attribute__ ((__noreturn__)); + void h(); + void test() { + f(g); + f(h); + } +} + // - If P is a class, and P has the form template-id, then A can be a // derived class of the deduced A. Likewise, if P is a pointer to a class // of the form template-id, A can be a pointer to a derived class pointed @@ -123,3 +137,12 @@ namespace N { N::F(d); // OK } } + +namespace PR9233 { + template void f(const T **q); // expected-note{{candidate template ignored: substitution failure [with T = int]}} + + void g(int **p) { + f(p); // expected-error{{no matching function for call to 'f'}} + } + +} diff --git a/test/CXX/temp/temp.res/temp.local/p3.cpp b/test/CXX/temp/temp.res/temp.local/p3.cpp index 88f8963..54da885 100644 --- a/test/CXX/temp/temp.res/temp.local/p3.cpp +++ b/test/CXX/temp/temp.res/temp.local/p3.cpp @@ -22,11 +22,11 @@ template struct Derived: Base, Base { namespace PR6717 { template class WebVector { - } + } // expected-error {{expected ';' after class}} - WebVector(const WebVector& other) { } + WebVector(const WebVector& other) { } // expected-error{{undeclared identifier 'T'}} \ + expected-error{{requires a type specifier}} template - WebVector& operator=(const C& other) { } // expected-error{{unknown type name 'WebVector'}} \ - // expected-error{{unqualified-id}} + WebVector& operator=(const C& other) { } // expected-error{{undeclared identifier 'T'}} } diff --git a/test/CXX/temp/temp.spec/temp.explicit/p7.cpp b/test/CXX/temp/temp.spec/temp.explicit/p7.cpp index b62e0cb..7398dca 100644 --- a/test/CXX/temp/temp.spec/temp.explicit/p7.cpp +++ b/test/CXX/temp/temp.spec/temp.explicit/p7.cpp @@ -7,14 +7,14 @@ struct X0 { }; T* f0(T* ptr) { - return ptr + 1; // expected-error{{pointer to function}} + return ptr + 1; // expected-error{{pointer to the function}} } static T* static_member; }; template -T* X0::static_member = ((T*)0) + 1; // expected-error{{pointer to function}} +T* X0::static_member = ((T*)0) + 1; // expected-error{{pointer to the function}} template class X0; // okay diff --git a/test/CodeGen/annotate.c b/test/CodeGen/annotate.c index ffaeebb..9ed187d 100644 --- a/test/CodeGen/annotate.c +++ b/test/CodeGen/annotate.c @@ -7,4 +7,4 @@ void a(char *a) { // CHECK: private unnamed_addr global // CHECK: private unnamed_addr global -// CHECK: @llvm.global.annotations = appending global [2 x %0] +// CHECK: @llvm.global.annotations = appending global [2 x { i8*, i8*, i8*, i32 }] diff --git a/test/CodeGen/arm-arguments.c b/test/CodeGen/arm-arguments.c index 73bc03d..081bc89 100644 --- a/test/CodeGen/arm-arguments.c +++ b/test/CodeGen/arm-arguments.c @@ -61,7 +61,7 @@ struct s10 { int f0; int : 0; int : 0; }; struct s10 f10(void) {} // APCS-GNU: define void @f11( -// APCS-GNU: struct.s10* sret +// APCS-GNU: struct.s11* sret // AAPCS: define arm_aapcscc i32 @f11() struct s11 { int : 0; int f0; }; struct s11 f11(void) {} @@ -80,7 +80,7 @@ struct s13 { float f0; }; struct s13 f13(void) {} // APCS-GNU: define void @f14( -// APCS-GNU: struct.s13* sret +// APCS-GNU: union.u14* sret // AAPCS: define arm_aapcscc i32 @f14() union u14 { float f0; }; union u14 f14(void) {} diff --git a/test/CodeGen/arm-asm-variable.c b/test/CodeGen/arm-asm-variable.c new file mode 100644 index 0000000..865d197 --- /dev/null +++ b/test/CodeGen/arm-asm-variable.c @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 -triple armv7-apple-darwin9 -emit-llvm -w -o - %s | FileCheck %s + +typedef long long int64_t; +typedef unsigned int uint32_t; + +int64_t foo(int64_t v, volatile int64_t *p) +{ + register uint32_t rl asm("r1"); + register uint32_t rh asm("r2"); + + int64_t r; + uint32_t t; + + __asm__ __volatile__( \ + "ldrexd%[_rl], %[_rh], [%[_p]]" \ + : [_rl] "=&r" (rl), [_rh] "=&r" (rh) \ + : [_p] "p" (p) : "memory"); + + // CHECK: call { i32, i32 } asm sideeffect "ldrexd$0, $1, [$2]", "={r1},={r2},r,~{memory}"(i64* + + return r; +} + +// Make sure we translate register names properly. +void bar (void) { + register unsigned int rn asm("r14"); + register unsigned int d asm("r2"); + + // CHECK: call i32 asm sideeffect "sub $1, $1, #32", "={r2},{lr}" + asm volatile ("sub %1, %1, #32" : "=r"(d) : "r"(rn)); +} diff --git a/test/CodeGen/asm-errors.c b/test/CodeGen/asm-errors.c index cd4d1ff..438c82b 100644 --- a/test/CodeGen/asm-errors.c +++ b/test/CodeGen/asm-errors.c @@ -1,6 +1,8 @@ // REQUIRES: x86-registered-target -// RUN: not %clang_cc1 -triple i386-apple-darwin10 -emit-obj %s -o /dev/null > %t 2>&1 -// RUN: FileCheck %s < %t + +// RUN: true +// UN: not %clang_cc1 -triple i386-apple-darwin10 -emit-obj %s -o /dev/null > %t 2>&1 +// UN: FileCheck %s < %t int test1(int X) { // CHECK: error: invalid instruction mnemonic 'abc' diff --git a/test/CodeGen/asm-inout.c b/test/CodeGen/asm-inout.c index 29142f7..ce524fe 100644 --- a/test/CodeGen/asm-inout.c +++ b/test/CodeGen/asm-inout.c @@ -21,7 +21,7 @@ void test2() { // PR7338 void test3(int *vout, int vin) { - // CHECK: call void asm "opr $0,$1", "=*r|m|r,r|m|r,~{di},~{dirflag},~{fpsr},~{flags}" + // CHECK: call void asm "opr $0,$1", "=*r|m|r,r|m|r,~{edi},~{dirflag},~{fpsr},~{flags}" asm( "opr %[vout],%[vin]" : [vout] "=r,=m,=r" (*vout) @@ -37,4 +37,3 @@ int test4(volatile int *addr) { return (int)oldval; // CHECK: call i8 asm "frob $0", "=r,0{{.*}}"(i8 -1) } - diff --git a/test/CodeGen/asm.c b/test/CodeGen/asm.c index eb11285..7199f09 100644 --- a/test/CodeGen/asm.c +++ b/test/CodeGen/asm.c @@ -49,10 +49,10 @@ unsigned t9(unsigned int a) { // PR3908 void t10(int r) { __asm__("PR3908 %[lf] %[xx] %[li] %[r]" : [r] "+r" (r) : [lf] "mx" (0), [li] "mr" (0), [xx] "x" ((double)(0))); - + // CHECK: @t10( // CHECK:PR3908 $1 $3 $2 $0 -} +} // PR3373 @@ -119,7 +119,7 @@ int t16() { void t17() { int i; __asm__ ( "nop": "=m"(i)); - + // CHECK: @t17() // CHECK: call void asm "nop", "=*m, } @@ -127,7 +127,7 @@ void t17() { // int t18(unsigned data) { int a, b; - + asm("xyz" :"=a"(a), "=d"(b) : "a"(data)); return a + b; // CHECK: t18(i32 @@ -140,7 +140,7 @@ int t18(unsigned data) { // PR6780 int t19(unsigned data) { int a, b; - + asm("x{abc|def|ghi}z" :"=r"(a): "r"(data)); return a + b; // CHECK: t19(i32 @@ -153,7 +153,7 @@ double t20(double x) { register long double result; __asm __volatile ("frndint" : "=t" (result) : "0" (x)); return result; - + // CHECK: @t20 // CHECK: fpext double {{.*}} to x86_fp80 // CHECK-NEXT: call x86_fp80 asm sideeffect "frndint" @@ -190,3 +190,17 @@ unsigned char t23(unsigned char a, unsigned char b) { "edx", "cc"); return res; } + + +// PR10299 - fpsr, fpcr +void test(void) +{ + __asm__ __volatile__( \ + "finit" \ + : \ + : \ + :"st","st(1)","st(2)","st(3)", \ + "st(4)","st(5)","st(6)","st(7)", \ + "fpsr","fpcr" \ + ); +} diff --git a/test/CodeGen/attr-weak-import.c b/test/CodeGen/attr-weak-import.c new file mode 100644 index 0000000..0707f59 --- /dev/null +++ b/test/CodeGen/attr-weak-import.c @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -triple x86_64-darwin-apple -emit-llvm -o - %s | FileCheck %s +// rdar://9538608 + +extern int A __attribute__((weak_import)); +int A; + +extern int B __attribute__((weak_import)); +extern int B; + +int C; +extern int C __attribute__((weak_import)); + +extern int D __attribute__((weak_import)); +extern int D __attribute__((weak_import)); +int D; + +extern int E __attribute__((weak_import)); +int E; +extern int E __attribute__((weak_import)); + +// CHECK: @A = global i32 +// CHECK-NOT: @B = +// CHECK: @C = common global i32 +// CHECK: @D = global i32 +// CHECK: @E = global i32 + diff --git a/test/CodeGen/attributes.c b/test/CodeGen/attributes.c index 770ce76..4e73af6 100644 --- a/test/CodeGen/attributes.c +++ b/test/CodeGen/attributes.c @@ -4,7 +4,7 @@ // CHECK: @t5 = weak global i32 2 int t5 __attribute__((weak)) = 2; -// CHECK: @t13 = global %0 zeroinitializer, section "SECT" +// CHECK: @t13 = global %struct.s0 zeroinitializer, section "SECT" struct s0 { int x; }; struct s0 t13 __attribute__((section("SECT"))) = { 0 }; diff --git a/test/CodeGen/bitfield-2.c b/test/CodeGen/bitfield-2.c index 8de432f..69ed5b1 100644 --- a/test/CodeGen/bitfield-2.c +++ b/test/CodeGen/bitfield-2.c @@ -11,7 +11,7 @@ // CHECK-RECORD: *** Dumping IRgen Record Layout // CHECK-RECORD: Record: struct s0 // CHECK-RECORD: Layout: +// CHECK-RECORD: LLVMType:%struct.s0 = type <{ [3 x i8] }> // CHECK-RECORD: IsZeroInitializable:1 // CHECK-RECORD: BitFields:[ // CHECK-RECORD: +// CHECK-RECORD: LLVMType:%struct.s1 = type <{ [2 x i8], i8 }> // CHECK-RECORD: IsZeroInitializable:1 // CHECK-RECORD: BitFields:[ // CHECK-RECORD: +// CHECK-RECORD: LLVMType:%union.u2 = type <{ i8 }> // CHECK-RECORD: IsZeroInitializable:1 // CHECK-RECORD: BitFields:[ // CHECK-RECORD: f0.f0) - 0); -// CHECK: @g1x = global {{%.}} { double 1.000000e+00{{[0]*}}, double 0.000000e+00{{[0]*}} } +// CHECK: @g1x = global { double, double } { double 1.000000e+00{{[0]*}}, double 0.000000e+00{{[0]*}} } _Complex double g1x = 1.0f; -// CHECK: @g1y = global {{%.}} { double 0.000000e+00{{[0]*}}, double 1.000000e+00{{[0]*}} } +// CHECK: @g1y = global { double, double } { double 0.000000e+00{{[0]*}}, double 1.000000e+00{{[0]*}} } _Complex double g1y = 1.0fi; -// CHECK: @g1 = global {{%.}} { i8 1, i8 10 } +// CHECK: @g1 = global { i8, i8 } { i8 1, i8 10 } _Complex char g1 = (char) 1 + (char) 10 * 1i; -// CHECK: @g2 = global %2 { i32 1, i32 10 } +// CHECK: @g2 = global { i32, i32 } { i32 1, i32 10 } _Complex int g2 = 1 + 10i; -// CHECK: @g3 = global {{%.}} { float 1.000000e+00{{[0]*}}, float 1.000000e+0{{[0]*}}1 } +// CHECK: @g3 = global { float, float } { float 1.000000e+00{{[0]*}}, float 1.000000e+0{{[0]*}}1 } _Complex float g3 = 1.0 + 10.0i; -// CHECK: @g4 = global {{%.}} { double 1.000000e+00{{[0]*}}, double 1.000000e+0{{[0]*}}1 } +// CHECK: @g4 = global { double, double } { double 1.000000e+00{{[0]*}}, double 1.000000e+0{{[0]*}}1 } _Complex double g4 = 1.0 + 10.0i; -// CHECK: @g5 = global %2 zeroinitializer +// CHECK: @g5 = global { i32, i32 } zeroinitializer _Complex int g5 = (2 + 3i) == (5 + 7i); -// CHECK: @g6 = global {{%.}} { double -1.100000e+0{{[0]*}}1, double 2.900000e+0{{[0]*}}1 } +// CHECK: @g6 = global { double, double } { double -1.100000e+0{{[0]*}}1, double 2.900000e+0{{[0]*}}1 } _Complex double g6 = (2.0 + 3.0i) * (5.0 + 7.0i); // CHECK: @g7 = global i32 1 int g7 = (2 + 3i) * (5 + 7i) == (-11 + 29i); @@ -52,14 +52,14 @@ int g9 = (2 + 3i) * (5 + 7i) != (-11 + 29i); int g10 = (2.0 + 3.0i) * (5.0 + 7.0i) != (-11.0 + 29.0i); // PR5108 -// CHECK: @gv1 = global %4 <{ i32 0, i8 7 }>, align 1 +// CHECK: @gv1 = global %struct.anon <{ i32 0, i8 7 }>, align 1 struct { unsigned long a; unsigned long b:3; } __attribute__((__packed__)) gv1 = { .a = 0x0, .b = 7, }; // PR5118 -// CHECK: @gv2 = global %5 <{ i8 1, i8* null }>, align 1 +// CHECK: @gv2 = global %struct.anon.0 <{ i8 1, i8* null }>, align 1 struct { unsigned char a; char *b; diff --git a/test/CodeGen/darwin-thread-specifier.c b/test/CodeGen/darwin-thread-specifier.c new file mode 100644 index 0000000..605d461 --- /dev/null +++ b/test/CodeGen/darwin-thread-specifier.c @@ -0,0 +1,3 @@ +// RUN: %clang_cc1 -triple x86_64-apple-macosx10.7.0 -emit-llvm -o - %s | FileCheck %s +// CHECK: @b = thread_local global i32 5, align 4 +__thread int b = 5; diff --git a/test/CodeGen/debug-info-iv.c b/test/CodeGen/debug-info-iv.c new file mode 100644 index 0000000..9265473 --- /dev/null +++ b/test/CodeGen/debug-info-iv.c @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -triple x86_64-darwin-apple -Os -S -g -o - %s | FileCheck %s + +int calculate(int); +static void test_indvars(int *Array1, int Array2[100][200]) { + unsigned i, j; + Array1[1] = Array2[3][6] = 12345; + + for (i = 0; i < 100; i+=2) + Array1[i] = i; /* Step by non unit amount */ + + for (i = 3; i < 103; i++) + Array1[i] = i+4; /* Step with an offset */ + + for (i = 13; i < 100; i++) + for (j = 0; j < 100; j+=3) /* 2d array access */ + Array2[i][j/3] = Array2[i][i]; +} + + +int main() { + int Array[100][200], i, j; + double sum = 0.0; + + for (i=0; i < 100; i+=2) + for (j=0; j < 200; j++) + Array[i][j] = 0; + test_indvars(Array[0], Array); + +//CHECK: .loc 2 30 3 + for (i=0; i < 100; i+=2) + for (j=0; j < 200; j++) + sum += Array[i][j]; + + return calculate(sum); +} diff --git a/test/CodeGen/debug-info-member.c b/test/CodeGen/debug-info-member.c new file mode 100644 index 0000000..54066fa --- /dev/null +++ b/test/CodeGen/debug-info-member.c @@ -0,0 +1,3 @@ +// RUN: %clang_cc1 -emit-llvm -g < %s | grep DW_TAG_member | grep \!3 + +struct A { int x; } a; diff --git a/test/CodeGen/debug-info.c b/test/CodeGen/debug-info.c index 876c6c2..af2ce96 100644 --- a/test/CodeGen/debug-info.c +++ b/test/CodeGen/debug-info.c @@ -54,3 +54,8 @@ __uint128_t foo128 () __uint128_t int128 = 44; return int128; } + +// CHECK: uint64x2_t +typedef unsigned long long uint64_t; +typedef uint64_t uint64x2_t __attribute__((ext_vector_type(2))); +uint64x2_t extvectbar[4]; diff --git a/test/CodeGen/decl.c b/test/CodeGen/decl.c index 29520d7..21b7579 100644 --- a/test/CodeGen/decl.c +++ b/test/CodeGen/decl.c @@ -2,8 +2,8 @@ // CHECK: @test1.x = internal constant [12 x i32] [i32 1 // CHECK: @test2.x = internal unnamed_addr constant [13 x i32] [i32 1, -// CHECK: @test5w = global %0 { i32 2, [4 x i8] undef } -// CHECK: @test5y = global %union.test5u { double 7.300000e+0{{[0]*}}1 } +// CHECK: @test5w = global { i32, [4 x i8] } { i32 2, [4 x i8] undef } +// CHECK: @test5y = global { double } { double 7.300000e+0{{[0]*}}1 } // CHECK: @test6.x = internal unnamed_addr constant %struct.SelectDest { i8 1, i8 2, i32 3, i32 0 } diff --git a/test/CodeGen/designated-initializers.c b/test/CodeGen/designated-initializers.c index d928296..6561ce5 100644 --- a/test/CodeGen/designated-initializers.c +++ b/test/CodeGen/designated-initializers.c @@ -8,10 +8,10 @@ struct foo { // CHECK: @u = global %union.anon zeroinitializer union { int i; float f; } u = { }; -// CHECK: @u2 = global %1 { i32 0, [4 x i8] undef } +// CHECK: @u2 = global { i32, [4 x i8] } { i32 0, [4 x i8] undef } union { int i; double f; } u2 = { }; -// CHECK: @u3 = global %2 zeroinitializer +// CHECK: @u3 = global %union.anon.1 zeroinitializer union { double f; int i; } u3 = { }; // CHECK: @b = global [2 x i32] [i32 0, i32 22] @@ -39,11 +39,11 @@ struct ds ds0 = { { { .a = 0 } } }; struct ds ds1 = { { .a = 1 } }; struct ds ds2 = { { .b = 1 } }; struct ds ds3 = { .a = 0 }; -// CHECK: @ds4 = global %3 { %4 { %struct.anon zeroinitializer, i16 0, %struct.anon { i16 1 } } } +// CHECK: @ds4 = global %struct.ds { %struct.anon.3 { %struct.anon zeroinitializer, i16 0, %struct.anon.2 { i16 1 } } } struct ds ds4 = { .c = 1 }; struct ds ds5 = { { { .a = 0 } }, .b = 1 }; struct ds ds6 = { { .a = 0, .b = 1 } }; -// CHECK: @ds7 = global %3 { %4 { %struct.anon { i16 2 }, i16 3, %struct.anon zeroinitializer } } +// CHECK: @ds7 = global %struct.ds { %struct.anon.3 { %struct.anon { i16 2 }, i16 3, %struct.anon.2 zeroinitializer } } struct ds ds7 = { { { .a = 1 @@ -59,7 +59,7 @@ void test1(int argc, char **argv) .b = 1024, }; - // CHECK: bitcast %union.anon* %u2 + // CHECK: bitcast %union.anon.4* %u2 // CHECK: call void @llvm.memset union { int i; float f; } u2 = { }; diff --git a/test/CodeGen/flexible-array-init.c b/test/CodeGen/flexible-array-init.c index 3632350..d3079dc 100644 --- a/test/CodeGen/flexible-array-init.c +++ b/test/CodeGen/flexible-array-init.c @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -o - %s | FileCheck %s struct { int x; int y[]; } a = { 1, 7, 11 }; -// CHECK: @a = global %0 { i32 1, [2 x i32] [i32 7, i32 11] } +// CHECK: @a = global { i32, [2 x i32] } { i32 1, [2 x i32] [i32 7, i32 11] } struct { int x; int y[]; } b = { 1, { 13, 15 } }; -// CHECK: @b = global %0 { i32 1, [2 x i32] [i32 13, i32 15] } +// CHECK: @b = global { i32, [2 x i32] } { i32 1, [2 x i32] [i32 13, i32 15] } diff --git a/test/CodeGen/functions.c b/test/CodeGen/functions.c index a2c692d..e51f93e 100644 --- a/test/CodeGen/functions.c +++ b/test/CodeGen/functions.c @@ -59,3 +59,9 @@ void f8_test() { // CHECK: declare void @f8_user({{.*}}*) // CHECK: declare void @f8_callback() } + +// PR10204: don't crash +static void test9_helper(void) {} +void test9() { + (void) test9_helper; +} diff --git a/test/CodeGen/global-init.c b/test/CodeGen/global-init.c index 351ca9e..074c2a0 100644 --- a/test/CodeGen/global-init.c +++ b/test/CodeGen/global-init.c @@ -27,12 +27,12 @@ struct ManyFields { int f; }; -// CHECK: global %0 { i32 1, i32 2, i32 0, i8 0, i32 0, i32 0 } +// CHECK: global %struct.ManyFields { i32 1, i32 2, i32 0, i8 0, i32 0, i32 0 } struct ManyFields FewInits = {1, 2}; // PR6766 -// CHECK: @l = global %1 { [24 x i8] c"f\00\00\00o\00\00\00o\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00", i32 1 } +// CHECK: @l = global { [24 x i8], i32 } { [24 x i8] c"f\00\00\00o\00\00\00o\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00", i32 1 } typedef __WCHAR_TYPE__ wchar_t; struct K { wchar_t L[6]; diff --git a/test/CodeGen/init.c b/test/CodeGen/init.c index 0f94729..599b4f2 100644 --- a/test/CodeGen/init.c +++ b/test/CodeGen/init.c @@ -115,3 +115,11 @@ void test11(struct test11S *P) { // CHECK: store i32 4 // CHECK: ret void } + + +// Verify that we can convert a recursive struct with a memory that returns +// an instance of the struct we're converting. +struct test12 { + struct test12 (*p)(void); +} test12g; + diff --git a/test/CodeGen/libcalls.c b/test/CodeGen/libcalls.c index 828d7de..5ff684f 100644 --- a/test/CodeGen/libcalls.c +++ b/test/CodeGen/libcalls.c @@ -50,3 +50,26 @@ void test_pow(float a0, double a1, long double a2) { // CHECK-NO: declare float @llvm.pow.f32(float, float) nounwind readonly // CHECK-NO: declare double @llvm.pow.f64(double, double) nounwind readonly // CHECK-NO: declare x86_fp80 @llvm.pow.f80(x86_fp80, x86_fp80) nounwind readonly + +// CHECK-YES: define void @test_fma +// CHECK-NO: define void @test_fma +void test_fma(float a0, double a1, long double a2) { + // CHECK-YES: call float @llvm.fma.f32 + // CHECK-NO: call float @llvm.fma.f32 + float l0 = fmaf(a0, a0, a0); + + // CHECK-YES: call double @llvm.fma.f64 + // CHECK-NO: call double @llvm.fma.f64 + double l1 = fma(a1, a1, a1); + + // CHECK-YES: call x86_fp80 @llvm.fma.f80 + // CHECK-NO: call x86_fp80 @llvm.fma.f80 + long double l2 = fmal(a2, a2, a2); +} + +// CHECK-YES: declare float @llvm.fma.f32(float, float, float) nounwind readnone +// CHECK-YES: declare double @llvm.fma.f64(double, double, double) nounwind readnone +// CHECK-YES: declare x86_fp80 @llvm.fma.f80(x86_fp80, x86_fp80, x86_fp80) nounwind readnone +// CHECK-NO: declare float @llvm.fma.f32(float, float, float) nounwind readnone +// CHECK-NO: declare double @llvm.fma.f64(double, double, double) nounwind readnone +// CHECK-NO: declare x86_fp80 @llvm.fma.f80(x86_fp80, x86_fp80, x86_fp80) nounwind readnone diff --git a/test/CodeGen/mmx-inline-asm.c b/test/CodeGen/mmx-inline-asm.c index c473a93..5d1371e 100644 --- a/test/CodeGen/mmx-inline-asm.c +++ b/test/CodeGen/mmx-inline-asm.c @@ -2,7 +2,7 @@ // #include -// CHECK: type { x86_mmx, x86_mmx, x86_mmx, x86_mmx, x86_mmx, x86_mmx, x86_mmx } +// CHECK: { x86_mmx, x86_mmx, x86_mmx, x86_mmx, x86_mmx, x86_mmx, x86_mmx } void foo(long long fill) { __m64 vfill = _mm_cvtsi64_m64(fill); diff --git a/test/CodeGen/ms-anonymous-struct.c b/test/CodeGen/ms-anonymous-struct.c index 3afe440..b41caab 100644 --- a/test/CodeGen/ms-anonymous-struct.c +++ b/test/CodeGen/ms-anonymous-struct.c @@ -1,19 +1,19 @@ // RUN: %clang_cc1 -fms-extensions -emit-llvm -o - %s | FileCheck %s +// CHECK: %struct.test = type { i32, %struct.nested2, i32 } +// CHECK: %struct.nested2 = type { i32, %struct.nested1, i32 } // CHECK: %struct.nested1 = type { i32, i32 } typedef struct nested1 { int a1; int b1; } NESTED1; -// CHECK: %struct.nested2 = type { i32, %struct.nested1, i32 } struct nested2 { int a; NESTED1; int b; }; -// CHECK: %struct.test = type { i32, %struct.nested2, i32 } struct test { int x; struct nested2; diff --git a/test/CodeGen/packed-union.c b/test/CodeGen/packed-union.c index 0aeed00..31ce614 100644 --- a/test/CodeGen/packed-union.c +++ b/test/CodeGen/packed-union.c @@ -1,6 +1,5 @@ // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm %s -o %t -// RUN: grep "struct._attrs = type <{ i32, i8 }>" %t typedef struct _attrs { unsigned file_attributes; unsigned char filename_length; diff --git a/test/CodeGen/pragma-pack-3.c b/test/CodeGen/pragma-pack-3.c index 676f0d7..04b636e 100644 --- a/test/CodeGen/pragma-pack-3.c +++ b/test/CodeGen/pragma-pack-3.c @@ -1,9 +1,7 @@ // RUN: %clang_cc1 -triple i386-apple-darwin9 %s -emit-llvm -o - | FileCheck -check-prefix X32 %s -// CHECK-X32: %struct.menu = type <{ i8*, i8, i8 }> // CHECK-X32: %union.command = type <{ i8*, [2 x i8] }> // RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -emit-llvm -o - | FileCheck -check-prefix X64 %s -// CHECK-X64: %struct.menu = type <{ i8*, i8, i8 }> // CHECK-X64: %union.command = type <{ i8*, [2 x i8] }> // diff --git a/test/CodeGen/private-extern-redef.c b/test/CodeGen/private-extern-redef.c new file mode 100644 index 0000000..580ce9b --- /dev/null +++ b/test/CodeGen/private-extern-redef.c @@ -0,0 +1,39 @@ +// RUN: %clang_cc1 -triple x86_64-darwin-apple -emit-llvm -o - %s | FileCheck %s +// rdar://9609649 + +__private_extern__ const int I; +__private_extern__ const int J = 927; + +__private_extern__ const int K; +const int K = 37; + +const int L = 10; +__private_extern__ const int L; + +__private_extern__ int M; +int M = 20; + +__private_extern__ int N; +int N; + +__private_extern__ int O; +int O=1; + +__private_extern__ int P; +extern int P; + +void bar(int); + +void foo() { + bar(I); +} + +// CHECK: @J = hidden constant +// CHECK: @K = hidden constant +// CHECK: @L = constant +// CHECK: @M = hidden global +// CHECK: @O = hidden global +// CHECK: @I = external hidden +// CHECK: @N = common hidden global +// CHECK-NOT: @P + diff --git a/test/CodeGen/struct-init.c b/test/CodeGen/struct-init.c index 861c41e..8a605c1 100644 --- a/test/CodeGen/struct-init.c +++ b/test/CodeGen/struct-init.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -emit-llvm-only +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s typedef struct _zend_ini_entry zend_ini_entry; struct _zend_ini_entry { @@ -29,3 +29,11 @@ typedef struct __simd64_uint32_t { void foo() { const uint32x2_t signBit = { (uint2) 0x80000000 }; } + +// CHECK: %struct.fp_struct_foo = type { void (i32)* } +struct fp_struct_bar { int a; }; + +struct fp_struct_foo { + void (*FP)(struct fp_struct_bar); +} G; + diff --git a/test/CodeGen/struct.c b/test/CodeGen/struct.c index 25477a0..e173931 100644 --- a/test/CodeGen/struct.c +++ b/test/CodeGen/struct.c @@ -181,3 +181,16 @@ range f18() { rangepair rp; return (rp = f18_ext()).range1; } + + + +// Complex forward reference of struct. +struct f19S; +extern struct f19T { + struct f19S (*p)(void); +} t; +struct f19S { int i; }; +void f19(void) { + t.p(); +} + diff --git a/test/CodeGen/trapv.c b/test/CodeGen/trapv.c index 7f192c6..f52dad5 100644 --- a/test/CodeGen/trapv.c +++ b/test/CodeGen/trapv.c @@ -1,7 +1,5 @@ // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -ftrapv %s -emit-llvm -o - | FileCheck %s -// CHECK: [[I32O:%.*]] = type { i32, i1 } - unsigned int ui, uj, uk; int i, j, k; @@ -16,9 +14,9 @@ void test0() { // CHECK: [[T1:%.*]] = load i32* @j // CHECK-NEXT: [[T2:%.*]] = load i32* @k - // CHECK-NEXT: [[T3:%.*]] = call [[I32O]] @llvm.sadd.with.overflow.i32(i32 [[T1]], i32 [[T2]]) - // CHECK-NEXT: [[T4:%.*]] = extractvalue [[I32O]] [[T3]], 0 - // CHECK-NEXT: [[T5:%.*]] = extractvalue [[I32O]] [[T3]], 1 + // CHECK-NEXT: [[T3:%.*]] = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[T1]], i32 [[T2]]) + // CHECK-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T3]], 0 + // CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T3]], 1 // CHECK-NEXT: br i1 [[T5]] // CHECK: call void @llvm.trap() i = j + k; @@ -30,9 +28,9 @@ void test1() { opaque(i++); // CHECK: [[T1:%.*]] = load i32* @i - // CHECK-NEXT: [[T2:%.*]] = call [[I32O]] @llvm.sadd.with.overflow.i32(i32 [[T1]], i32 1) - // CHECK-NEXT: [[T3:%.*]] = extractvalue [[I32O]] [[T2]], 0 - // CHECK-NEXT: [[T4:%.*]] = extractvalue [[I32O]] [[T2]], 1 + // CHECK-NEXT: [[T2:%.*]] = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[T1]], i32 1) + // CHECK-NEXT: [[T3:%.*]] = extractvalue { i32, i1 } [[T2]], 0 + // CHECK-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T2]], 1 // CHECK-NEXT: br i1 [[T4]] // CHECK: call void @llvm.trap() } @@ -43,9 +41,9 @@ void test2() { opaque(++i); // CHECK: [[T1:%.*]] = load i32* @i - // CHECK-NEXT: [[T2:%.*]] = call [[I32O]] @llvm.sadd.with.overflow.i32(i32 [[T1]], i32 1) - // CHECK-NEXT: [[T3:%.*]] = extractvalue [[I32O]] [[T2]], 0 - // CHECK-NEXT: [[T4:%.*]] = extractvalue [[I32O]] [[T2]], 1 + // CHECK-NEXT: [[T2:%.*]] = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[T1]], i32 1) + // CHECK-NEXT: [[T3:%.*]] = extractvalue { i32, i1 } [[T2]], 0 + // CHECK-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T2]], 1 // CHECK-NEXT: br i1 [[T4]] // CHECK: call void @llvm.trap() } diff --git a/test/CodeGen/union-init2.c b/test/CodeGen/union-init2.c index 1386c27..bf20696 100644 --- a/test/CodeGen/union-init2.c +++ b/test/CodeGen/union-init2.c @@ -1,11 +1,11 @@ // RUN: %clang_cc1 -emit-llvm %s -o - -triple i686-pc-linux-gnu | FileCheck %s // Make sure we generate something sane instead of a ptrtoint -// CHECK: bitcast (%0* @r to %union.x*), [4 x i8] undef +// CHECK: bitcast ({ %union.x*, [4 x i8] }* @r to %union.x*), [4 x i8] undef union x {long long b;union x* a;} r = {.a = &r}; -// CHECK: global %1 { [3 x i8] zeroinitializer, [5 x i8] undef } +// CHECK: global { [3 x i8], [5 x i8] } { [3 x i8] zeroinitializer, [5 x i8] undef } union z { char a[3]; long long b; diff --git a/test/CodeGen/vla.c b/test/CodeGen/vla.c index e5114a5..c9612bc 100644 --- a/test/CodeGen/vla.c +++ b/test/CodeGen/vla.c @@ -88,13 +88,60 @@ int test2(int n) // http://llvm.org/PR8567 // CHECK: define double @test_PR8567 double test_PR8567(int n, double (*p)[n][5]) { - // CHECK: store [[vla_type:.*]] %p, - // CHECK: load i32* - // CHECK-NEXT: mul i32 40 - // CHECK-NEXT: [[byte_idx:%.*]] = mul i32 1 - // CHECK-NEXT: [[tmp_1:%.*]] = load [[vla_type]]* - // CHECK-NEXT: [[tmp_2:%.*]] = bitcast [[vla_type]] [[tmp_1]] to i8* - // CHECK-NEXT: [[idx:%.*]] = getelementptr inbounds i8* [[tmp_2]], i32 [[byte_idx]] - // CHECK-NEXT: bitcast i8* [[idx]] to [[vla_type]] + // CHECK: [[NV:%.*]] = alloca i32, align 4 + // CHECK-NEXT: [[PV:%.*]] = alloca [5 x double]*, align 4 + // CHECK-NEXT: store + // CHECK-NEXT: store + // CHECK-NEXT: [[N:%.*]] = load i32* [[NV]], align 4 + // CHECK-NEXT: [[P:%.*]] = load [5 x double]** [[PV]], align 4 + // CHECK-NEXT: [[T0:%.*]] = mul nsw i32 1, [[N]] + // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [5 x double]* [[P]], i32 [[T0]] + // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [5 x double]* [[T1]], i32 2 + // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds [5 x double]* [[T2]], i32 0, i32 3 + // CHECK-NEXT: [[T4:%.*]] = load double* [[T3]] + // CHECK-NEXT: ret double [[T4]] return p[1][2][3]; } + +int test4(unsigned n, char (*p)[n][n+1][6]) { + // CHECK: define i32 @test4( + // CHECK: [[N:%.*]] = alloca i32, align 4 + // CHECK-NEXT: [[P:%.*]] = alloca [6 x i8]*, align 4 + // CHECK-NEXT: [[P2:%.*]] = alloca [6 x i8]*, align 4 + // CHECK-NEXT: store i32 + // CHECK-NEXT: store [6 x i8]* + + // VLA captures. + // CHECK-NEXT: [[DIM0:%.*]] = load i32* [[N]], align 4 + // CHECK-NEXT: [[T0:%.*]] = load i32* [[N]], align 4 + // CHECK-NEXT: [[DIM1:%.*]] = add i32 [[T0]], 1 + + // __typeof. FIXME: does this really need to be loaded? + // CHECK-NEXT: load [6 x i8]** [[P]] + + // CHECK-NEXT: [[T0:%.*]] = load [6 x i8]** [[P]], align 4 + // CHECK-NEXT: [[T1:%.*]] = load i32* [[N]], align 4 + // CHECK-NEXT: [[T2:%.*]] = udiv i32 [[T1]], 2 + // CHECK-NEXT: [[T3:%.*]] = mul nuw i32 [[DIM0]], [[DIM1]] + // CHECK-NEXT: [[T4:%.*]] = mul nsw i32 [[T2]], [[T3]] + // CHECK-NEXT: [[T5:%.*]] = getelementptr inbounds [6 x i8]* [[T0]], i32 [[T4]] + // CHECK-NEXT: [[T6:%.*]] = load i32* [[N]], align 4 + // CHECK-NEXT: [[T7:%.*]] = udiv i32 [[T6]], 4 + // CHECK-NEXT: [[T8:%.*]] = sub i32 0, [[T7]] + // CHECK-NEXT: [[T9:%.*]] = mul nuw i32 [[DIM0]], [[DIM1]] + // CHECK-NEXT: [[T10:%.*]] = mul nsw i32 [[T8]], [[T9]] + // CHECK-NEXT: [[T11:%.*]] = getelementptr inbounds [6 x i8]* [[T5]], i32 [[T10]] + // CHECK-NEXT: store [6 x i8]* [[T11]], [6 x i8]** [[P2]], align 4 + __typeof(p) p2 = (p + n/2) - n/4; + + // CHECK-NEXT: [[T0:%.*]] = load [6 x i8]** [[P2]], align 4 + // CHECK-NEXT: [[T1:%.*]] = load [6 x i8]** [[P]], align 4 + // CHECK-NEXT: [[T2:%.*]] = ptrtoint [6 x i8]* [[T0]] to i32 + // CHECK-NEXT: [[T3:%.*]] = ptrtoint [6 x i8]* [[T1]] to i32 + // CHECK-NEXT: [[T4:%.*]] = sub i32 [[T2]], [[T3]] + // CHECK-NEXT: [[T5:%.*]] = mul nuw i32 [[DIM0]], [[DIM1]] + // CHECK-NEXT: [[T6:%.*]] = mul nuw i32 6, [[T5]] + // CHECK-NEXT: [[T7:%.*]] = sdiv exact i32 [[T4]], [[T6]] + // CHECK-NEXT: ret i32 [[T7]] + return p2 - p; +} diff --git a/test/CodeGen/volatile-1.c b/test/CodeGen/volatile-1.c index f54afff..7c7a822 100644 --- a/test/CodeGen/volatile-1.c +++ b/test/CodeGen/volatile-1.c @@ -4,7 +4,7 @@ volatile int i, j, k; volatile int ar[5]; volatile char c; -// CHECK: @ci = common global [[CINT:%.*]] zeroinitializer +// CHECK: @ci = common global [[CINT:.*]] zeroinitializer volatile _Complex int ci; volatile struct S { #ifdef __cplusplus diff --git a/test/CodeGen/volatile-2.c b/test/CodeGen/volatile-2.c index 1ceaf17..490b7d7 100644 --- a/test/CodeGen/volatile-2.c +++ b/test/CodeGen/volatile-2.c @@ -3,8 +3,8 @@ void test0() { // CHECK: define void @test0() // CHECK: [[F:%.*]] = alloca float - // CHECK-NEXT: [[REAL:%.*]] = volatile load float* getelementptr inbounds ({{%.*}} @test0_v, i32 0, i32 0) - // CHECK-NEXT: volatile load float* getelementptr inbounds ({{%.*}} @test0_v, i32 0, i32 1) + // CHECK-NEXT: [[REAL:%.*]] = volatile load float* getelementptr inbounds ({ float, float }* @test0_v, i32 0, i32 0) + // CHECK-NEXT: volatile load float* getelementptr inbounds ({{.*}} @test0_v, i32 0, i32 1) // CHECK-NEXT: store float [[REAL]], float* [[F]], align 4 // CHECK-NEXT: ret void extern volatile _Complex float test0_v; @@ -13,10 +13,10 @@ void test0() { void test1() { // CHECK: define void @test1() - // CHECK: [[REAL:%.*]] = volatile load float* getelementptr inbounds ({{%.*}} @test1_v, i32 0, i32 0) - // CHECK-NEXT: [[IMAG:%.*]] = volatile load float* getelementptr inbounds ({{%.*}} @test1_v, i32 0, i32 1) - // CHECK-NEXT: volatile store float [[REAL]], float* getelementptr inbounds ({{%.*}} @test1_v, i32 0, i32 0) - // CHECK-NEXT: volatile store float [[IMAG]], float* getelementptr inbounds ({{%.*}} @test1_v, i32 0, i32 1) + // CHECK: [[REAL:%.*]] = volatile load float* getelementptr inbounds ({{.*}} @test1_v, i32 0, i32 0) + // CHECK-NEXT: [[IMAG:%.*]] = volatile load float* getelementptr inbounds ({{.*}} @test1_v, i32 0, i32 1) + // CHECK-NEXT: volatile store float [[REAL]], float* getelementptr inbounds ({{.*}} @test1_v, i32 0, i32 0) + // CHECK-NEXT: volatile store float [[IMAG]], float* getelementptr inbounds ({{.*}} @test1_v, i32 0, i32 1) // CHECK-NEXT: ret void extern volatile _Complex float test1_v; test1_v = test1_v; diff --git a/test/CodeGen/x86_32-arguments-darwin.c b/test/CodeGen/x86_32-arguments-darwin.c index f7e2a53..731d4f6 100644 --- a/test/CodeGen/x86_32-arguments-darwin.c +++ b/test/CodeGen/x86_32-arguments-darwin.c @@ -1,5 +1,4 @@ -// RUN: %clang_cc1 -w -fblocks -triple i386-apple-darwin9 -emit-llvm -o %t %s -// RUN: FileCheck < %t %s +// RUN: %clang_cc1 -w -fblocks -triple i386-apple-darwin9 -target-cpu yonah -emit-llvm -o - %s | FileCheck %s // CHECK: define signext i8 @f0() char f0(void) { @@ -232,7 +231,7 @@ v4i32 f55(v4i32 arg) { return arg+arg; } // CHECK: i8 signext %a0, %struct.s56_0* byval align 4 %a1, // CHECK: x86_mmx %a2.coerce, %struct.s56_1* byval align 4, // CHECK: i64 %a4.coerce, %struct.s56_2* byval align 4, -// CHECK: <4 x i32> %a6, %struct.s39* byval align 16 %a7, +// CHECK: <4 x i32> %a6, %struct.s56_3* byval align 16 %a7, // CHECK: <2 x double> %a8, %struct.s56_4* byval align 16 %a9, // CHECK: <8 x i32> %a10, %struct.s56_5* byval align 4, // CHECK: <4 x double> %a12, %struct.s56_6* byval align 4) @@ -241,7 +240,7 @@ v4i32 f55(v4i32 arg) { return arg+arg; } // CHECK: i32 %{{[^ ]*}}, %struct.s56_0* byval align 4 %{{[^ ]*}}, // CHECK: x86_mmx %{{[^ ]*}}, %struct.s56_1* byval align 4 %{{[^ ]*}}, // CHECK: i64 %{{[^ ]*}}, %struct.s56_2* byval align 4 %{{[^ ]*}}, -// CHECK: <4 x i32> %{{[^ ]*}}, %struct.s39* byval align 16 %{{[^ ]*}}, +// CHECK: <4 x i32> %{{[^ ]*}}, %struct.s56_3* byval align 16 %{{[^ ]*}}, // CHECK: <2 x double> %{{[^ ]*}}, %struct.s56_4* byval align 16 %{{[^ ]*}}, // CHECK: <8 x i32> {{[^ ]*}}, %struct.s56_5* byval align 4 %{{[^ ]*}}, // CHECK: <4 x double> {{[^ ]*}}, %struct.s56_6* byval align 4 %{{[^ ]*}}) diff --git a/test/CodeGen/x86_32-arguments-linux.c b/test/CodeGen/x86_32-arguments-linux.c index 2f246f8..81dcaf6 100644 --- a/test/CodeGen/x86_32-arguments-linux.c +++ b/test/CodeGen/x86_32-arguments-linux.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -w -fblocks -triple i386-pc-linux-gnu -emit-llvm -o %t %s +// RUN: %clang_cc1 -w -fblocks -triple i386-pc-linux-gnu -target-cpu pentium4 -emit-llvm -o %t %s // RUN: FileCheck < %t %s // CHECK: define void @f56( diff --git a/test/CodeGen/x86_32-arguments-nommx.c b/test/CodeGen/x86_32-arguments-nommx.c new file mode 100644 index 0000000..40362f7 --- /dev/null +++ b/test/CodeGen/x86_32-arguments-nommx.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -target-feature -mmx -target-feature +sse2 -triple i686-pc-linux-gnu -emit-llvm -o - %s | FileCheck %s + +// no-mmx should put mmx into memory +typedef int __attribute__((vector_size (8))) i32v2; +int a(i32v2 x) { return x[0]; } +// CHECK: define i32 @a(i64 %x.coerce) + +// but SSE2 vectors should still go into an SSE2 register +typedef int __attribute__((vector_size (16))) i32v4; +int b(i32v4 x) { return x[0]; } +// CHECK: define i32 @b(<4 x i32> %x) diff --git a/test/CodeGen/x86_64-arguments.c b/test/CodeGen/x86_64-arguments.c index 75c4788..221c7d3 100644 --- a/test/CodeGen/x86_64-arguments.c +++ b/test/CodeGen/x86_64-arguments.c @@ -42,8 +42,8 @@ void f7(e7 a0) { // Test merging/passing of upper eightbyte with X87 class. // -// CHECK: define void @f8_1(%struct.s19* sret %agg.result) -// CHECK: define void @f8_2(%struct.s19* byval align 16 %a0) +// CHECK: define void @f8_1(%union.u8* sret %agg.result) +// CHECK: define void @f8_2(%union.u8* byval align 16 %a0) union u8 { long double a; int b; @@ -58,7 +58,7 @@ struct s9 { int a; int b; int : 0; } f9(void) { while (1) {} } struct s10 { int a; int b; int : 0; }; void f10(struct s10 a0) {} -// CHECK: define void @f11(%struct.s19* sret %agg.result) +// CHECK: define void @f11(%union.anon* sret %agg.result) union { long double a; float b; } f11() { while (1) {} } // CHECK: define i32 @f12_0() @@ -147,7 +147,7 @@ struct f24s { long a; int b; }; struct f23S f24(struct f23S *X, struct f24s *P2) { return *X; - // CHECK: define %struct.f24s @f24(%struct.f23S* %X, %struct.f24s* %P2) + // CHECK: define { i64, i32 } @f24(%struct.f23S* %X, %struct.f24s* %P2) } // rdar://8248065 @@ -169,7 +169,7 @@ struct foo26 { }; struct foo26 f26(struct foo26 *P) { - // CHECK: define %struct.foo26 @f26(%struct.foo26* %P) + // CHECK: define { i32*, float* } @f26(%struct.foo26* %P) return *P; } @@ -259,3 +259,48 @@ void f9122143() func(ss); } +// CHECK: define double @f36(double %arg.coerce) +typedef unsigned v2i32 __attribute((__vector_size__(8))); +v2i32 f36(v2i32 arg) { return arg; } + +// CHECK: declare void @f38(<8 x float>) +// CHECK: declare void @f37(<8 x float>) +typedef float __m256 __attribute__ ((__vector_size__ (32))); +typedef struct { + __m256 m; +} s256; + +s256 x38; +__m256 x37; + +void f38(s256 x); +void f37(__m256 x); +void f39() { f38(x38); f37(x37); } + +// The two next tests make sure that the struct below is passed +// in the same way regardless of avx being used + +// CHECK: declare void @func40(%struct.t128* byval align 16) +typedef float __m128 __attribute__ ((__vector_size__ (16))); +typedef struct t128 { + __m128 m; + __m128 n; +} two128; + +extern void func40(two128 s); +void func41(two128 s) { + func40(s); +} + +// CHECK: declare void @func42(%struct.t128_2* byval align 16) +typedef struct xxx { + __m128 array[2]; +} Atwo128; +typedef struct t128_2 { + Atwo128 x; +} SA; + +extern void func42(SA s); +void func43(SA s) { + func42(s); +} diff --git a/test/CodeGenCXX/anonymous-union-member-initializer.cpp b/test/CodeGenCXX/anonymous-union-member-initializer.cpp index 2ddafec..324ff4a 100644 --- a/test/CodeGenCXX/anonymous-union-member-initializer.cpp +++ b/test/CodeGenCXX/anonymous-union-member-initializer.cpp @@ -86,7 +86,7 @@ namespace test3 { // CHECK-NEXT: [[UNION:%.*]] = getelementptr inbounds {{.*}} [[THIS]], i32 0, i32 0 // CHECK-NEXT: [[STRUCT:%.*]] = bitcast {{.*}}* [[UNION]] to // CHECK-NEXT: [[CALLBACK:%.*]] = getelementptr inbounds {{.*}} [[STRUCT]], i32 0, i32 0 - // CHECK-NEXT: store void (i8*)* null, void (i8*)** [[CALLBACK]] + // CHECK: store // CHECK-NEXT: [[UNION:%.*]] = getelementptr inbounds {{.*}} [[THIS]], i32 0, i32 0 // CHECK-NEXT: [[STRUCT:%.*]] = bitcast {{.*}}* [[UNION]] to // CHECK-NEXT: [[CVALUE:%.*]] = getelementptr inbounds {{.*}} [[STRUCT]], i32 0, i32 1 @@ -114,3 +114,19 @@ template struct Foo { }; }; Foo f; + +namespace PR9683 { + struct QueueEntry { + union { + struct { + void* mPtr; + union { + unsigned mSubmissionTag; + }; + }; + unsigned mValue; + }; + QueueEntry() {} + }; + QueueEntry QE; +} diff --git a/test/CodeGenCXX/attr-used.cpp b/test/CodeGenCXX/attr-used.cpp index 26109e7..2c82184 100644 --- a/test/CodeGenCXX/attr-used.cpp +++ b/test/CodeGenCXX/attr-used.cpp @@ -2,8 +2,8 @@ // : clang++ not respecting __attribute__((used)) on destructors struct X0 { - // CHECK: define linkonce_odr void @_ZN2X0C1Ev + // CHECK: define linkonce_odr {{.*}} @_ZN2X0C1Ev __attribute__((used)) X0() {} - // CHECK: define linkonce_odr void @_ZN2X0D1Ev + // CHECK: define linkonce_odr {{.*}} @_ZN2X0D1Ev __attribute__((used)) ~X0() {} }; diff --git a/test/CodeGenCXX/block-byref-cxx-objc.cpp b/test/CodeGenCXX/block-byref-cxx-objc.cpp index a4fbd6c..135e0c7 100644 --- a/test/CodeGenCXX/block-byref-cxx-objc.cpp +++ b/test/CodeGenCXX/block-byref-cxx-objc.cpp @@ -16,9 +16,9 @@ int main() } // CHECK: define internal void @__Block_byref_object_copy_ -// CHECK: call void @_ZN1AC1ERKS_ +// CHECK: call {{.*}} @_ZN1AC1ERKS_ // CHECK: define internal void @__Block_byref_object_dispose_ -// CHECK: call void @_ZN1AD1Ev +// CHECK: call {{.*}} @_ZN1AD1Ev // CHECK: define internal void @__copy_helper_block_ // CHECK: call void @_Block_object_assign // CHECK: define internal void @__destroy_helper_block_ diff --git a/test/CodeGenCXX/blocks.cpp b/test/CodeGenCXX/blocks.cpp index a4d5b86..0e310bd 100644 --- a/test/CodeGenCXX/blocks.cpp +++ b/test/CodeGenCXX/blocks.cpp @@ -31,7 +31,7 @@ namespace test1 { // ...unless they have mutable fields... // CHECK: define void @_ZN5test15test3Ev() - // CHECK: [[BLOCK:%.*]] = alloca [[BLOCK_T:%.*]], + // CHECK: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]], // CHECK: [[T0:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to void ()* // CHECK: store void ()* [[T0]], void ()** @out struct mut { mutable int x; }; @@ -43,7 +43,7 @@ namespace test1 { // ...or non-trivial destructors... // CHECK: define void @_ZN5test15test4Ev() // CHECK: [[OBJ:%.*]] = alloca - // CHECK: [[BLOCK:%.*]] = alloca [[BLOCK_T:%.*]], + // CHECK: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]], // CHECK: [[T0:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to void ()* // CHECK: store void ()* [[T0]], void ()** @out struct scope { int x; ~scope(); }; diff --git a/test/CodeGenCXX/class-layout.cpp b/test/CodeGenCXX/class-layout.cpp index 96fbae8..9569f47 100644 --- a/test/CodeGenCXX/class-layout.cpp +++ b/test/CodeGenCXX/class-layout.cpp @@ -20,8 +20,8 @@ namespace Test3 { namespace Test4 { // Test from PR5589. - // CHECK: %"struct.Test4::A" = type { i32, i8, float } // CHECK: %"struct.Test4::B" = type { %"struct.Test4::A", i16, double } + // CHECK: %"struct.Test4::A" = type { i32, i8, float } struct A { int a; char c; diff --git a/test/CodeGenCXX/compound-literals.cpp b/test/CodeGenCXX/compound-literals.cpp new file mode 100644 index 0000000..cd44e97 --- /dev/null +++ b/test/CodeGenCXX/compound-literals.cpp @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s + +struct X { + X(); + X(const X&); + X(const char*); + ~X(); +}; + +struct Y { + int i; + X x; +}; + +// CHECK: define i32 @_Z1fv() +int f() { + // CHECK: [[LVALUE:%[a-z0-9.]+]] = alloca + // CHECK-NEXT: [[I:%[a-z0-9]+]] = getelementptr inbounds {{.*}}* [[LVALUE]], i32 0, i32 0 + // CHECK-NEXT: store i32 17, i32* [[I]] + // CHECK-NEXT: [[X:%[a-z0-9]+]] = getelementptr inbounds {{.*}} [[LVALUE]], i32 0, i32 1 + // CHECK-NEXT: call void @_ZN1XC1EPKc({{.*}}[[X]] + // CHECK-NEXT: [[I:%[a-z0-9]+]] = getelementptr inbounds {{.*}} [[LVALUE]], i32 0, i32 0 + // CHECK-NEXT: [[RESULT:%[a-z0-9]+]] = load i32* + // CHECK-NEXT: call void @_ZN1YD1Ev + // CHECK-NEXT: ret i32 [[RESULT]] + return ((Y){17, "seventeen"}).i; +} diff --git a/test/CodeGenCXX/const-init.cpp b/test/CodeGenCXX/const-init.cpp index a8c6f30..797d137 100644 --- a/test/CodeGenCXX/const-init.cpp +++ b/test/CodeGenCXX/const-init.cpp @@ -10,7 +10,7 @@ void f(); void (&fr)() = f; struct S { int& a; }; -// CHECK: @s = global %0 { i32* @a } +// CHECK: @s = global %struct.S { i32* @a } S s = { a }; // PR5581 @@ -21,7 +21,7 @@ public: unsigned f; }; -// CHECK: @_ZN6PR55812g0E = global %1 { i32 1 } +// CHECK: @_ZN6PR55812g0E = global %"class.PR5581::C" { i32 1 } C g0 = { C::e1 }; } diff --git a/test/CodeGenCXX/constructor-init.cpp b/test/CodeGenCXX/constructor-init.cpp index 47e3b7b..a195afe 100644 --- a/test/CodeGenCXX/constructor-init.cpp +++ b/test/CodeGenCXX/constructor-init.cpp @@ -113,6 +113,22 @@ namespace InitVTable { B::B(int x) : A(x + 5) {} } +namespace rdar9694300 { + struct X { + int x; + }; + + // CHECK: define void @_ZN11rdar96943001fEv + void f() { + // CHECK: alloca + X x; + // CHECK-NEXT: [[I:%.*]] = alloca i32 + // CHECK-NEXT: store i32 17, i32* [[I]] + int i = 17; + // CHECK-NEXT: ret void + } +} + template struct X { X(const X &); diff --git a/test/CodeGenCXX/constructors.cpp b/test/CodeGenCXX/constructors.cpp index 75588ce..ec7f06c 100644 --- a/test/CodeGenCXX/constructors.cpp +++ b/test/CodeGenCXX/constructors.cpp @@ -83,12 +83,12 @@ struct D : A { D::D(int x, ...) : A(ValueClass(x, x+1)), mem(x*x) {} -// CHECK: define void @_ZN1DC1Eiz(%struct.B* %this, i32 %x, ...) unnamed_addr +// CHECK: define void @_ZN1DC1Eiz(%struct.D* %this, i32 %x, ...) unnamed_addr // CHECK: call void @_ZN10ValueClassC1Eii( // CHECK: call void @_ZN1AC2E10ValueClass( // CHECK: call void @_ZN6MemberC1Ei( -// CHECK: define void @_ZN1DC2Eiz(%struct.B* %this, i32 %x, ...) unnamed_addr +// CHECK: define void @_ZN1DC2Eiz(%struct.D* %this, i32 %x, ...) unnamed_addr // CHECK: call void @_ZN10ValueClassC1Eii( // CHECK: call void @_ZN1AC2E10ValueClass( // CHECK: call void @_ZN6MemberC1Ei( @@ -104,3 +104,14 @@ namespace test0 { C tmp = in; } } + +namespace test1 { + struct A { A(); void *ptr; }; + struct B { B(); int x; A a[0]; }; + B::B() {} + // CHECK: define void @_ZN5test11BC2Ev( + // CHECK: [[THIS:%.*]] = load [[B:%.*]]** + // CHECK-NEXT: [[A:%.*]] = getelementptr inbounds [[B:%.*]]* [[THIS]], i32 0, i32 1 + // CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [0 x {{%.*}}]* [[A]], i32 0, i32 0 + // CHECK-NEXT: ret void +} diff --git a/test/CodeGenCXX/copy-constructor-elim-2.cpp b/test/CodeGenCXX/copy-constructor-elim-2.cpp index 4f4a8e9..a4a688f 100644 --- a/test/CodeGenCXX/copy-constructor-elim-2.cpp +++ b/test/CodeGenCXX/copy-constructor-elim-2.cpp @@ -3,7 +3,7 @@ struct A { int x; A(int); ~A(); }; A f() { return A(0); } // CHECK: define void @_Z1fv -// CHECK: call void @_ZN1AC1Ei +// CHECK: call {{.*}} @_ZN1AC1Ei // CHECK-NEXT: ret void // Verify that we do not elide copies when constructing a base class. @@ -21,14 +21,14 @@ namespace no_elide_base { Derived(const Other &O); }; - // CHECK: define void @_ZN13no_elide_base7DerivedC1ERKNS_5OtherE(%"struct.no_elide_base::Derived"* %this, %"struct.PR8683::A"* %O) unnamed_addr + // CHECK: define {{.*}} @_ZN13no_elide_base7DerivedC1ERKNS_5OtherE(%"struct.no_elide_base::Derived"* %this, %"struct.no_elide_base::Other"* %O) unnamed_addr Derived::Derived(const Other &O) - // CHECK: call void @_ZNK13no_elide_base5OthercvNS_4BaseEEv - // CHECK: call void @_ZN13no_elide_base4BaseC2ERKS0_ - // CHECK: call void @_ZN13no_elide_base4BaseD1Ev + // CHECK: call {{.*}} @_ZNK13no_elide_base5OthercvNS_4BaseEEv + // CHECK: call {{.*}} @_ZN13no_elide_base4BaseC2ERKS0_ + // CHECK: call {{.*}} @_ZN13no_elide_base4BaseD1Ev : Base(O) { - // CHECK: ret void + // CHECK: ret } } @@ -48,7 +48,7 @@ struct B { void f() { // Verify that we don't mark the copy constructor in this expression as elidable. - // CHECK: call void @_ZN6PR86831AC1ERKS0_ + // CHECK: call {{.*}} @_ZN6PR86831AC1ERKS0_ A a = (B().a); } diff --git a/test/CodeGenCXX/copy-constructor-synthesis-2.cpp b/test/CodeGenCXX/copy-constructor-synthesis-2.cpp index a556679..d028a28 100644 --- a/test/CodeGenCXX/copy-constructor-synthesis-2.cpp +++ b/test/CodeGenCXX/copy-constructor-synthesis-2.cpp @@ -3,5 +3,5 @@ struct A { virtual void a(); }; A x(A& y) { return y; } -// CHECK: define linkonce_odr void @_ZN1AC1ERKS_(%struct.A* %this, %struct.A*) unnamed_addr +// CHECK: define linkonce_odr {{.*}} @_ZN1AC1ERKS_(%struct.A* %this, %struct.A*) unnamed_addr // CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1A, i64 0, i64 2) diff --git a/test/CodeGenCXX/copy-initialization.cpp b/test/CodeGenCXX/copy-initialization.cpp index 62b9f26..aecd64e 100644 --- a/test/CodeGenCXX/copy-initialization.cpp +++ b/test/CodeGenCXX/copy-initialization.cpp @@ -12,7 +12,7 @@ struct Bar { void f(Foo); -// CHECK: define void @_Z1g3Foo(%struct.Bar* %foo) +// CHECK: define void @_Z1g3Foo(%struct.Foo* %foo) void g(Foo foo) { // CHECK: call void @_ZN3BarC1Ev // CHECK: @_ZNK3BarcvRK3FooEv diff --git a/test/CodeGenCXX/cxx0x-defaulted-templates.cpp b/test/CodeGenCXX/cxx0x-defaulted-templates.cpp index 3d4000e..09eb4fe 100644 --- a/test/CodeGenCXX/cxx0x-defaulted-templates.cpp +++ b/test/CodeGenCXX/cxx0x-defaulted-templates.cpp @@ -5,15 +5,15 @@ struct X { X(); }; -// CHECK: define void @_ZN1XIbEC1Ev -// CHECK: define void @_ZN1XIbEC2Ev +// CHECK: define {{.*}} @_ZN1XIbEC1Ev +// CHECK: define {{.*}} @_ZN1XIbEC2Ev template <> X::X() = default; -// CHECK: define weak_odr void @_ZN1XIiEC1Ev -// CHECK: define weak_odr void @_ZN1XIiEC2Ev +// CHECK: define weak_odr {{.*}} @_ZN1XIiEC1Ev +// CHECK: define weak_odr {{.*}} @_ZN1XIiEC2Ev template X::X() = default; template X::X(); -// CHECK: define linkonce_odr void @_ZN1XIcEC1Ev -// CHECK: define linkonce_odr void @_ZN1XIcEC2Ev +// CHECK: define linkonce_odr {{.*}} @_ZN1XIcEC1Ev +// CHECK: define linkonce_odr {{.*}} @_ZN1XIcEC2Ev X x; diff --git a/test/CodeGenCXX/cxx0x-delegating-ctors.cpp b/test/CodeGenCXX/cxx0x-delegating-ctors.cpp index 15c8e7f..0bac492 100644 --- a/test/CodeGenCXX/cxx0x-delegating-ctors.cpp +++ b/test/CodeGenCXX/cxx0x-delegating-ctors.cpp @@ -26,28 +26,28 @@ delegator::delegator() { delegator::delegator(bool) {} -// CHECK: define void @_ZN9delegatorC1Ec -// CHECK: void @_ZN9delegatorC1Eb +// CHECK: define {{.*}} @_ZN9delegatorC1Ec +// CHECK: {{.*}} @_ZN9delegatorC1Eb // CHECK: void @__cxa_throw // CHECK: void @_ZSt9terminatev -// CHECK: void @_ZN9delegatorD1Ev -// CHECK: define void @_ZN9delegatorC2Ec -// CHECK: void @_ZN9delegatorC2Eb +// CHECK: {{.*}} @_ZN9delegatorD1Ev +// CHECK: define {{.*}} @_ZN9delegatorC2Ec +// CHECK: {{.*}} @_ZN9delegatorC2Eb // CHECK: void @__cxa_throw // CHECK: void @_ZSt9terminatev -// CHECK: void @_ZN9delegatorD2Ev +// CHECK: {{.*}} @_ZN9delegatorD2Ev delegator::delegator(char) : delegator(true) { throw 0; } -// CHECK: define void @_ZN9delegatorC1Ei -// CHECK: void @_ZN9delegatorC1Ev +// CHECK: define {{.*}} @_ZN9delegatorC1Ei +// CHECK: {{.*}} @_ZN9delegatorC1Ev // CHECK-NOT: void @_ZSt9terminatev // CHECK: ret // CHECK-NOT: void @_ZSt9terminatev -// CHECK: define void @_ZN9delegatorC2Ei -// CHECK: void @_ZN9delegatorC2Ev +// CHECK: define {{.*}} @_ZN9delegatorC2Ei +// CHECK: {{.*}} @_ZN9delegatorC2Ev // CHECK-NOT: void @_ZSt9terminatev // CHECK: ret // CHECK-NOT: void @_ZSt9terminatev diff --git a/test/CodeGenCXX/default-constructor-default-argument.cpp b/test/CodeGenCXX/default-constructor-default-argument.cpp index f2c7f6d..374a967 100644 --- a/test/CodeGenCXX/default-constructor-default-argument.cpp +++ b/test/CodeGenCXX/default-constructor-default-argument.cpp @@ -5,4 +5,4 @@ struct A { A(int x = 2); }; struct B : public A {}; B x; -// CHECK: call void @_ZN1AC2Ei +// CHECK: call {{.*}} @_ZN1AC2Ei diff --git a/test/CodeGenCXX/default-constructor-template-member.cpp b/test/CodeGenCXX/default-constructor-template-member.cpp index 422cc09..0dd64df 100644 --- a/test/CodeGenCXX/default-constructor-template-member.cpp +++ b/test/CodeGenCXX/default-constructor-template-member.cpp @@ -5,6 +5,6 @@ struct B { A x; }; void a() { B b; } -// CHECK: call void @_ZN1BC1Ev -// CHECK: define linkonce_odr void @_ZN1BC1Ev(%struct.B* %this) unnamed_addr -// CHECK: call void @_ZN1AIiEC1Ev +// CHECK: call {{.*}} @_ZN1BC1Ev +// CHECK: define linkonce_odr {{.*}} @_ZN1BC1Ev(%struct.B* %this) unnamed_addr +// CHECK: call {{.*}} @_ZN1AIiEC1Ev diff --git a/test/CodeGenCXX/delete.cpp b/test/CodeGenCXX/delete.cpp index ddc7bb8..08ce0de 100644 --- a/test/CodeGenCXX/delete.cpp +++ b/test/CodeGenCXX/delete.cpp @@ -54,7 +54,7 @@ namespace test0 { delete a; } - // CHECK: define linkonce_odr void @_ZN5test01AD1Ev(%class.A* %this) unnamed_addr + // CHECK: define linkonce_odr void @_ZN5test01AD1Ev(%"struct.test0::A"* %this) unnamed_addr // CHECK: define linkonce_odr void @_ZN5test01AdlEPv } @@ -67,31 +67,22 @@ namespace test1 { // CHECK: define void @_ZN5test14testEPA10_A20_NS_1AE( void test(A (*arr)[10][20]) { delete [] arr; - // CHECK: icmp eq [10 x [20 x [[S:%.*]]]]* [[PTR:%.*]], null + // CHECK: icmp eq [10 x [20 x [[A:%.*]]]]* [[PTR:%.*]], null // CHECK-NEXT: br i1 - // CHECK: [[ARR:%.*]] = getelementptr inbounds [10 x [20 x [[S]]]]* [[PTR]], i32 0, i32 0, i32 0 - // CHECK-NEXT: bitcast {{.*}} to i8* - // CHECK-NEXT: [[ALLOC:%.*]] = getelementptr inbounds {{.*}}, i64 -8 - // CHECK-NEXT: bitcast i8* [[ALLOC]] to i64* - // CHECK-NEXT: load - // CHECK-NEXT: store i64 {{.*}}, i64* [[IDX:%.*]] - - // CHECK: load i64* [[IDX]] - // CHECK-NEXT: icmp ne {{.*}}, 0 - // CHECK-NEXT: br i1 - - // CHECK: load i64* [[IDX]] - // CHECK-NEXT: [[I:%.*]] = sub i64 {{.*}}, 1 - // CHECK-NEXT: getelementptr inbounds [[S]]* [[ARR]], i64 [[I]] - // CHECK-NEXT: call void @_ZN5test11AD1Ev( - // CHECK-NEXT: br label - - // CHECK: load i64* [[IDX]] - // CHECK-NEXT: sub - // CHECK-NEXT: store {{.*}}, i64* [[IDX]] - // CHECK-NEXT: br label - + // CHECK: [[BEGIN:%.*]] = getelementptr inbounds [10 x [20 x [[A]]]]* [[PTR]], i32 0, i32 0, i32 0 + // CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]* [[BEGIN]] to i8* + // CHECK-NEXT: [[ALLOC:%.*]] = getelementptr inbounds i8* [[T0]], i64 -8 + // CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[ALLOC]] to i64* + // CHECK-NEXT: [[COUNT:%.*]] = load i64* [[T1]] + // CHECK: [[END:%.*]] = getelementptr inbounds [[A]]* [[BEGIN]], i64 [[COUNT]] + // CHECK-NEXT: [[ISEMPTY:%.*]] = icmp eq [[A]]* [[BEGIN]], [[END]] + // CHECK-NEXT: br i1 [[ISEMPTY]], + // CHECK: [[PAST:%.*]] = phi [[A]]* [ [[END]], {{%.*}} ], [ [[CUR:%.*]], {{%.*}} ] + // CHECK-NEXT: [[CUR:%.*]] = getelementptr inbounds [[A]]* [[PAST]], i64 -1 + // CHECK-NEXT: call void @_ZN5test11AD1Ev([[A]]* [[CUR]]) + // CHECK-NEXT: [[ISDONE:%.*]] = icmp eq [[A]]* [[CUR]], [[BEGIN]] + // CHECK-NEXT: br i1 [[ISDONE]] // CHECK: call void @_ZdaPv(i8* [[ALLOC]]) } } @@ -112,3 +103,22 @@ namespace test3 { delete a; } } + +namespace test4 { + // PR10341: ::delete with a virtual destructor + struct X { + virtual ~X(); + void operator delete (void *); + }; + + // CHECK: define void @_ZN5test421global_delete_virtualEPNS_1XE + void global_delete_virtual(X *xp) { + // CHECK: [[VTABLE:%.*]] = load void ([[X:%.*]])*** + // CHECK-NEXT: [[VFN:%.*]] = getelementptr inbounds void ([[X]])** [[VTABLE]], i64 0 + // CHECK-NEXT: [[VFNPTR:%.*]] = load void ([[X]])** [[VFN]] + // CHECK-NEXT: call void [[VFNPTR]]([[X]] [[OBJ:%.*]]) + // CHECK-NEXT: [[OBJVOID:%.*]] = bitcast [[X]] [[OBJ]] to i8* + // CHECK-NEXT: call void @_ZdlPv(i8* [[OBJVOID]]) nounwind + ::delete xp; + } +} diff --git a/test/CodeGenCXX/destructors.cpp b/test/CodeGenCXX/destructors.cpp index 94d8833..3381985 100644 --- a/test/CodeGenCXX/destructors.cpp +++ b/test/CodeGenCXX/destructors.cpp @@ -40,11 +40,11 @@ namespace PR7526 { struct allocator_derived : allocator { }; - // CHECK: define void @_ZN6PR75269allocatorD2Ev(%"struct.PR5529::A"* %this) unnamed_addr + // CHECK: define void @_ZN6PR75269allocatorD2Ev(%"struct.PR7526::allocator"* %this) unnamed_addr // CHECK: call void @__cxa_call_unexpected allocator::~allocator() throw() { foo(); } - // CHECK: define linkonce_odr void @_ZN6PR752617allocator_derivedD1Ev(%"struct.PR5529::A"* %this) unnamed_addr + // CHECK: define linkonce_odr void @_ZN6PR752617allocator_derivedD1Ev(%"struct.PR7526::allocator_derived"* %this) unnamed_addr // CHECK-NOT: call void @__cxa_call_unexpected // CHECK: } void foo() { @@ -145,10 +145,10 @@ namespace test1 { P::~P() {} // CHECK: define void @_ZN5test11PD2Ev(%"struct.test1::P"* %this) unnamed_addr struct Q : A, B { ~Q(); }; - Q::~Q() {} // CHECK: define void @_ZN5test11QD2Ev(%"struct.test1::M"* %this) unnamed_addr + Q::~Q() {} // CHECK: define void @_ZN5test11QD2Ev(%"struct.test1::Q"* %this) unnamed_addr struct R : A { ~R(); }; - R::~R() { A a; } // CHECK: define void @_ZN5test11RD2Ev(%"struct.test1::M"* %this) unnamed_addr + R::~R() { A a; } // CHECK: define void @_ZN5test11RD2Ev(%"struct.test1::R"* %this) unnamed_addr struct S : A { ~S(); int x; }; S::~S() {} // alias tested above @@ -168,7 +168,7 @@ namespace test2 { struct B : A { ~B(); }; B::~B() {} - // CHECK: define void @_ZN5test21BD2Ev(%"struct.test1::M"* %this) unnamed_addr + // CHECK: define void @_ZN5test21BD2Ev(%"struct.test2::B"* %this) unnamed_addr // CHECK: call void @_ZN5test21AD2Ev } @@ -233,28 +233,28 @@ namespace test4 { namespace test5 { struct A { ~A(); }; - // This is really unnecessarily verbose; we should be using phis, - // even at -O0. - // CHECK: define void @_ZN5test53fooEv() // CHECK: [[ELEMS:%.*]] = alloca [5 x [[A:%.*]]], align - // CHECK-NEXT: [[IVAR:%.*]] = alloca i64 - // CHECK: [[ELEMSARRAY:%.*]] = bitcast [5 x [[A]]]* [[ELEMS]] to [[A]] - // CHECK-NEXT: store i64 5, i64* [[IVAR]] - // CHECK-NEXT: br label - // CHECK: [[I:%.*]] = load i64* [[IVAR]] - // CHECK-NEXT: icmp ne i64 [[I]], 0 - // CHECK-NEXT: br i1 - // CHECK: [[I:%.*]] = load i64* [[IVAR]] - // CHECK-NEXT: [[I2:%.*]] = sub i64 [[I]], 1 - // CHECK-NEXT: getelementptr inbounds [[A]]* [[ELEMSARRAY]], i64 [[I2]] - // CHECK-NEXT: call void @_ZN5test51AD1Ev( - // CHECK-NEXT: br label - // CHECK: [[I:%.*]] = load i64* [[IVAR]] - // CHECK-NEXT: [[I1:%.*]] = sub i64 [[I]], 1 - // CHECK-NEXT: store i64 [[I1]], i64* [[IVAR]] + // CHECK-NEXT: [[EXN:%.*]] = alloca i8* + // CHECK-NEXT: [[SEL:%.*]] = alloca i32 + // CHECK-NEXT: [[EHCLEANUP:%.*]] = alloca i32 + // CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [5 x [[A]]]* [[ELEMS]], i32 0, i32 0 + // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]]* [[BEGIN]], i64 5 // CHECK-NEXT: br label + // CHECK: [[POST:%.*]] = phi [[A]]* [ [[END]], {{%.*}} ], [ [[ELT:%.*]], {{%.*}} ] + // CHECK-NEXT: [[ELT]] = getelementptr inbounds [[A]]* [[POST]], i64 -1 + // CHECK-NEXT: invoke void @_ZN5test51AD1Ev([[A]]* [[ELT]]) + // CHECK: [[T0:%.*]] = icmp eq [[A]]* [[ELT]], [[BEGIN]] + // CHECK-NEXT: br i1 [[T0]], // CHECK: ret void + // lpad + // CHECK: [[EMPTY:%.*]] = icmp eq [[A]]* [[BEGIN]], [[ELT]] + // CHECK-NEXT: br i1 [[EMPTY]] + // CHECK: [[AFTER:%.*]] = phi [[A]]* [ [[ELT]], {{%.*}} ], [ [[CUR:%.*]], {{%.*}} ] + // CHECK-NEXT: [[CUR:%.*]] = getelementptr inbounds [[A]]* [[AFTER]], i64 -1 + // CHECK-NEXT: invoke void @_ZN5test51AD1Ev([[A]]* [[CUR]]) + // CHECK: [[DONE:%.*]] = icmp eq [[A]]* [[CUR]], [[BEGIN]] + // CHECK-NEXT: br i1 [[DONE]], void foo() { A elems[5]; } diff --git a/test/CodeGenCXX/eh.cpp b/test/CodeGenCXX/eh.cpp index 44219b4..58cb445 100644 --- a/test/CodeGenCXX/eh.cpp +++ b/test/CodeGenCXX/eh.cpp @@ -14,7 +14,7 @@ void test1() { // CHECK-NEXT: [[EXN:%.*]] = bitcast i8* [[EXNOBJ]] to [[DSTAR:%[^*]*\*]] // CHECK-NEXT: [[EXN2:%.*]] = bitcast [[DSTAR]] [[EXN]] to i8* // CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[EXN2]], i8* bitcast ([[DSTAR]] @d1 to i8*), i64 8, i32 8, i1 false) -// CHECK-NEXT: call void @__cxa_throw(i8* [[EXNOBJ]], i8* bitcast (%0* @_ZTI7test1_D to i8*), i8* null) noreturn +// CHECK-NEXT: call void @__cxa_throw(i8* [[EXNOBJ]], i8* bitcast ({ i8*, i8* }* @_ZTI7test1_D to i8*), i8* null) noreturn // CHECK-NEXT: unreachable @@ -38,7 +38,7 @@ void test2() { // CHECK-NEXT: invoke void @_ZN7test2_DC1ERKS_([[DSTAR]] [[EXN]], [[DSTAR]] @d2) // CHECK-NEXT: to label %[[CONT:.*]] unwind label %{{.*}} // : [[CONT]]: (can't check this in Release-Asserts builds) -// CHECK: call void @__cxa_throw(i8* [[EXNOBJ]], i8* bitcast (%{{.*}}* @_ZTI7test2_D to i8*), i8* null) noreturn +// CHECK: call void @__cxa_throw(i8* [[EXNOBJ]], i8* bitcast ({{.*}}* @_ZTI7test2_D to i8*), i8* null) noreturn // CHECK-NEXT: unreachable @@ -56,7 +56,7 @@ void test3() { // CHECK: [[EXNOBJ:%.*]] = call i8* @__cxa_allocate_exception(i64 8) // CHECK-NEXT: [[EXN:%.*]] = bitcast i8* [[EXNOBJ]] to [[D:%[^*]+]]** // CHECK-NEXT: store [[D]]* null, [[D]]** [[EXN]] -// CHECK-NEXT: call void @__cxa_throw(i8* [[EXNOBJ]], i8* bitcast (%1* @_ZTIPV7test3_D to i8*), i8* null) noreturn +// CHECK-NEXT: call void @__cxa_throw(i8* [[EXNOBJ]], i8* bitcast ({ i8*, i8*, i32, i8* }* @_ZTIPV7test3_D to i8*), i8* null) noreturn // CHECK-NEXT: unreachable @@ -84,10 +84,10 @@ namespace test5 { // CHECK: [[EXNOBJ:%.*]] = call i8* @__cxa_allocate_exception(i64 1) // CHECK: [[EXNCAST:%.*]] = bitcast i8* [[EXNOBJ]] to [[A:%[^*]*]]* // CHECK-NEXT: invoke void @_ZN5test51AC1Ev([[A]]* [[EXNCAST]]) -// CHECK: invoke void @__cxa_throw(i8* [[EXNOBJ]], i8* bitcast ({{%.*}}* @_ZTIN5test51AE to i8*), i8* bitcast (void ([[A]]*)* @_ZN5test51AD1Ev to i8*)) noreturn +// CHECK: invoke void @__cxa_throw(i8* [[EXNOBJ]], i8* bitcast ({{.*}}* @_ZTIN5test51AE to i8*), i8* bitcast (void ([[A]]*)* @_ZN5test51AD1Ev to i8*)) noreturn // CHECK-NEXT: to label {{%.*}} unwind label %[[HANDLER:[^ ]*]] // : [[HANDLER]]: (can't check this in Release-Asserts builds) -// CHECK: {{%.*}} = call i32 @llvm.eh.typeid.for(i8* bitcast ({{%.*}}* @_ZTIN5test51AE to i8*)) +// CHECK: {{%.*}} = call i32 @llvm.eh.typeid.for(i8* bitcast ({{.*}}* @_ZTIN5test51AE to i8*)) } namespace test6 { @@ -177,11 +177,11 @@ namespace test9 { struct A { A(); }; - // CHECK: define void @_ZN5test91AC1Ev(%"struct.test10::A"* %this) unnamed_addr + // CHECK: define void @_ZN5test91AC1Ev(%"struct.test9::A"* %this) unnamed_addr // CHECK: call void @_ZN5test91AC2Ev // CHECK-NEXT: ret void - // CHECK: define void @_ZN5test91AC2Ev(%"struct.test10::A"* %this) unnamed_addr + // CHECK: define void @_ZN5test91AC2Ev(%"struct.test9::A"* %this) unnamed_addr A::A() try { // CHECK: invoke void @_ZN5test96opaqueEv() opaque(); diff --git a/test/CodeGenCXX/elide-call-reference.cpp b/test/CodeGenCXX/elide-call-reference.cpp index c82eee7..55d30e2 100644 --- a/test/CodeGenCXX/elide-call-reference.cpp +++ b/test/CodeGenCXX/elide-call-reference.cpp @@ -7,5 +7,5 @@ void b() { A x = a(); } -// CHECK: call void @_ZN1AC1ERKS_ -// CHECK: call void @_ZN1AD1Ev +// CHECK: call {{.*}} @_ZN1AC1ERKS_ +// CHECK: call {{.*}} @_ZN1AD1Ev diff --git a/test/CodeGenCXX/for-range.cpp b/test/CodeGenCXX/for-range.cpp index af46644..ab1a231 100644 --- a/test/CodeGenCXX/for-range.cpp +++ b/test/CodeGenCXX/for-range.cpp @@ -69,8 +69,8 @@ void for_range() { A a; for (B b : C()) { // CHECK: call void @_ZN1CC1Ev( - // CHECK: = call %struct.A* @_ZSt5beginR1C( - // CHECK: = call %struct.A* @_ZSt3endR1C( + // CHECK: = call %struct.B* @_ZSt5beginR1C( + // CHECK: = call %struct.B* @_ZSt3endR1C( // CHECK: br label %[[COND:.*]] // CHECK: [[COND]]: @@ -101,8 +101,8 @@ void for_member_range() { A a; for (B b : D()) { // CHECK: call void @_ZN1DC1Ev( - // CHECK: = call %struct.A* @_ZN1D5beginEv( - // CHECK: = call %struct.A* @_ZN1D3endEv( + // CHECK: = call %struct.B* @_ZN1D5beginEv( + // CHECK: = call %struct.B* @_ZN1D3endEv( // CHECK: br label %[[COND:.*]] // CHECK: [[COND]]: diff --git a/test/CodeGenCXX/global-init.cpp b/test/CodeGenCXX/global-init.cpp index 9bd7390..053210b 100644 --- a/test/CodeGenCXX/global-init.cpp +++ b/test/CodeGenCXX/global-init.cpp @@ -21,21 +21,21 @@ struct D { ~D(); }; // PR6205: The casts should not require global initializers // CHECK: @_ZN6PR59741cE = external global %"struct.PR5974::C" // CHECK: @_ZN6PR59741aE = global %"struct.PR5974::A"* getelementptr inbounds (%"struct.PR5974::C"* @_ZN6PR59741cE, i32 0, i32 0) -// CHECK: @_ZN6PR59741bE = global %"struct.PR5974::A"* bitcast (i8* getelementptr (i8* bitcast (%"struct.PR5974::C"* @_ZN6PR59741cE to i8*), i64 4) to %"struct.PR5974::A"*), align 8 +// CHECK: @_ZN6PR59741bE = global %"struct.PR5974::B"* bitcast (i8* getelementptr (i8* bitcast (%"struct.PR5974::C"* @_ZN6PR59741cE to i8*), i64 4) to %"struct.PR5974::B"*), align 8 // CHECK: call void @_ZN1AC1Ev(%struct.A* @a) // CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.A*)* @_ZN1AD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.A* @a, i32 0, i32 0), i8* bitcast (i8** @__dso_handle to i8*)) A a; -// CHECK: call void @_ZN1BC1Ev(%struct.A* @b) -// CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.A*)* @_ZN1BD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.A* @b, i32 0, i32 0), i8* bitcast (i8** @__dso_handle to i8*)) +// CHECK: call void @_ZN1BC1Ev(%struct.B* @b) +// CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.B*)* @_ZN1BD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.B* @b, i32 0, i32 0), i8* bitcast (i8** @__dso_handle to i8*)) B b; // PR6205: this should not require a global initializer // CHECK-NOT: call void @_ZN1CC1Ev(%struct.C* @c) C c; -// CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.A*)* @_ZN1DD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.A* @d, i32 0, i32 0), i8* bitcast (i8** @__dso_handle to i8*)) +// CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.D*)* @_ZN1DD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.D* @d, i32 0, i32 0), i8* bitcast (i8** @__dso_handle to i8*)) D d; // @@ -70,6 +70,20 @@ namespace test3 { const char *test() { return var; } } +namespace test6 { + struct A { + A(); + }; + extern int foo(); + + // This needs an initialization function and guard variables. + // CHECK: load i8* bitcast (i64* @_ZGVN5test61xE + // CHECK: [[CALL:%.*]] = call i32 @_ZN5test63fooEv + // CHECK-NEXT: store i32 [[CALL]], i32* @_ZN5test61xE + // CHECK-NEXT: store i64 1, i64* @_ZGVN5test61xE + __attribute__((weak)) int x = foo(); +} + namespace PR5974 { struct A { int a; }; struct B { int b; }; @@ -97,15 +111,6 @@ namespace test5 { }; } -namespace test6 { - struct A { - A(); - }; - extern int foo(); - - // This needs an initialization function but not guard variables. - __attribute__((weak)) int x = foo(); -} // At the end of the file, we check that y is initialized before z. diff --git a/test/CodeGenCXX/implicit-copy-constructor.cpp b/test/CodeGenCXX/implicit-copy-constructor.cpp index 5008601..8bc84a5 100644 --- a/test/CodeGenCXX/implicit-copy-constructor.cpp +++ b/test/CodeGenCXX/implicit-copy-constructor.cpp @@ -70,3 +70,13 @@ void test_X2() pimpl pdata; pdata.f0( new impl(*i)); } + +// rdar://problem/9598341 +namespace test3 { + struct A { A(const A&); A&operator=(const A&); }; + struct B { A a; unsigned : 0; }; + void test(const B &x) { + B y = x; + y = x; + } +} diff --git a/test/CodeGenCXX/init-incomplete-type.cpp b/test/CodeGenCXX/init-incomplete-type.cpp index 3312d3e..1755dfb 100644 --- a/test/CodeGenCXX/init-incomplete-type.cpp +++ b/test/CodeGenCXX/init-incomplete-type.cpp @@ -10,3 +10,22 @@ static struct Bar bar[1] = { { 0 } }; + + +namespace incomplete_type_refs { + struct A; + extern A g[]; + void foo(A*); + void f(void) { + foo(g); // Reference to array with unknown element type. + } + + struct A { // define the element type. + int a,b,c; + }; + + A *f2() { + return &g[1]; + } + +} \ No newline at end of file diff --git a/test/CodeGenCXX/mangle-subst-std.cpp b/test/CodeGenCXX/mangle-subst-std.cpp index 837d4fa..30b579c 100644 --- a/test/CodeGenCXX/mangle-subst-std.cpp +++ b/test/CodeGenCXX/mangle-subst-std.cpp @@ -15,8 +15,8 @@ namespace std { struct A { A(); }; - // CHECK: define void @_ZNSt1AC1Ev(%"struct.N::std::A"* %this) unnamed_addr - // CHECK: define void @_ZNSt1AC2Ev(%"struct.N::std::A"* %this) unnamed_addr + // CHECK: define void @_ZNSt1AC1Ev(%"struct.std::A"* %this) unnamed_addr + // CHECK: define void @_ZNSt1AC2Ev(%"struct.std::A"* %this) unnamed_addr A::A() { } }; diff --git a/test/CodeGenCXX/mangle-template.cpp b/test/CodeGenCXX/mangle-template.cpp index 463f15d..f95e152 100644 --- a/test/CodeGenCXX/mangle-template.cpp +++ b/test/CodeGenCXX/mangle-template.cpp @@ -82,7 +82,7 @@ namespace test7 { X(U*, typename int_c<(meta::value + meta::value)>::type *) { } }; - // CHECK: define weak_odr void @_ZN5test71XIiEC1IdEEPT_PNS_5int_cIXplL_ZNS_4metaIiE5valueEEsrNS6_IS3_EE5valueEE4typeE(%"class.test1::T"* %this, double*, float*) unnamed_addr + // CHECK: define weak_odr {{.*}} @_ZN5test71XIiEC1IdEEPT_PNS_5int_cIXplL_ZNS_4metaIiE5valueEEsr4metaIS3_EE5valueEE4typeE(%"struct.test7::X"* %this, double*, float*) unnamed_addr template X::X(double*, float*); } @@ -101,7 +101,7 @@ namespace test8 { template void f(int_c::type::value>) { } - // CHECK: define weak_odr void @_ZN5test81fIiEEvNS_5int_cIXsrNS_4metaIT_E4typeE5valueEEE + // CHECK: define weak_odr void @_ZN5test81fIiEEvNS_5int_cIXsr4metaIT_E4typeE5valueEEE template void f(int_c); } diff --git a/test/CodeGenCXX/mangle.cpp b/test/CodeGenCXX/mangle.cpp index 01dcf8b..453b7b7 100644 --- a/test/CodeGenCXX/mangle.cpp +++ b/test/CodeGenCXX/mangle.cpp @@ -196,9 +196,9 @@ template struct __enable_if { // PR5063 template typename __enable_if<__is_scalar_type::__value, void>::__type ft7() { } -// CHECK: @_Z3ft7IiEN11__enable_ifIXsr16__is_scalar_typeIT_E7__valueEvE6__typeEv +// CHECK: @_Z3ft7IiEN11__enable_ifIXsr16__is_scalar_typeIT_EE7__valueEvE6__typeEv template void ft7(); -// CHECK: @_Z3ft7IPvEN11__enable_ifIXsr16__is_scalar_typeIT_E7__valueEvE6__typeEv +// CHECK: @_Z3ft7IPvEN11__enable_ifIXsr16__is_scalar_typeIT_EE7__valueEvE6__typeEv template void ft7(); // PR5144 @@ -226,9 +226,9 @@ S7::S7() {} // PR5063 template typename __enable_if<(__is_scalar_type::__value), void>::__type ft8() { } -// CHECK: @_Z3ft8IiEN11__enable_ifIXsr16__is_scalar_typeIT_E7__valueEvE6__typeEv +// CHECK: @_Z3ft8IiEN11__enable_ifIXsr16__is_scalar_typeIT_EE7__valueEvE6__typeEv template void ft8(); -// CHECK: @_Z3ft8IPvEN11__enable_ifIXsr16__is_scalar_typeIT_E7__valueEvE6__typeEv +// CHECK: @_Z3ft8IPvEN11__enable_ifIXsr16__is_scalar_typeIT_EE7__valueEvE6__typeEv template void ft8(); // PR5796 @@ -241,7 +241,7 @@ template struct __enable_if {}; template struct __enable_if { typedef T __type; }; template -// CHECK: define linkonce_odr void @_ZN6PR57968__fill_aIiEENS_11__enable_ifIXntsrNS_16__is_scalar_typeIT_EE7__valueEvE6__typeEv +// CHECK: define linkonce_odr void @_ZN6PR57968__fill_aIiEENS_11__enable_ifIXntsr16__is_scalar_typeIT_EE7__valueEvE6__typeEv typename __enable_if::__value, void>::__type __fill_a() { }; void f() { __fill_a(); } @@ -711,3 +711,150 @@ namespace test27 { b(f); } } + +// An injected class name type in a unresolved-name. +namespace test28 { + template struct A { + enum { bit }; + }; + + template void foo(decltype(A::A::bit) x); + + void test() { + foo(A::bit); + // CHECK: call void @_ZN6test283fooIcEEvDtsr1AIT_E1AE3bitE( + } +} + +// An enclosing template type parameter in an unresolved-name. +namespace test29 { + template struct A { + template static void foo(decltype(T::fn(U())) x); + }; + struct B { static int fn(int); static long fn(long); }; + + void test() { + A::foo(0); + // CHECK: call void @_ZN6test291AINS_1BEE3fooIiEEvDTclsrS1_2fncvT__EEE( + } +} + +// An enclosing template template parameter in an unresolved-name. +namespace test30 { + template