aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/ARCMT/check-with-serialized-diag.m12
-rw-r--r--test/ARCMT/migrate-plist-output.m6
-rw-r--r--test/ARCMT/objcmt-subscripting-literals.m1
-rw-r--r--test/ARCMT/objcmt-subscripting-literals.m.result1
-rw-r--r--test/ASTMerge/function.c8
-rw-r--r--test/Analysis/Inputs/system-header-simulator-cxx.h37
-rw-r--r--test/Analysis/Inputs/system-header-simulator.h11
-rw-r--r--test/Analysis/Malloc+MismatchedDeallocator+NewDelete.cpp105
-rw-r--r--test/Analysis/Malloc+MismatchedDeallocator_intersections.cpp28
-rw-r--r--test/Analysis/Malloc+NewDelete_intersections.cpp15
-rw-r--r--test/Analysis/MismatchedDeallocator-checker-test.mm221
-rw-r--r--test/Analysis/MismatchedDeallocator-path-notes.cpp159
-rw-r--r--test/Analysis/NSContainers.m200
-rw-r--r--test/Analysis/NewDelete+MismatchedDeallocator_intersections.cpp29
-rw-r--r--test/Analysis/NewDelete-checker-test.cpp208
-rw-r--r--test/Analysis/NewDelete-custom.cpp80
-rw-r--r--test/Analysis/NewDelete-intersections.mm74
-rw-r--r--test/Analysis/NewDelete-path-notes.cpp551
-rw-r--r--test/Analysis/NewDelete-variadic.cpp19
-rw-r--r--test/Analysis/PR3991.m17
-rw-r--r--test/Analysis/additive-folding-range-constraints.c132
-rw-r--r--test/Analysis/additive-folding.cpp12
-rw-r--r--test/Analysis/analyzer-config.c8
-rw-r--r--test/Analysis/analyzer-config.cpp10
-rw-r--r--test/Analysis/analyzer-stats.c2
-rw-r--r--test/Analysis/bool-assignment.c (renamed from test/Analysis/bool-assignment.cpp)23
-rw-r--r--test/Analysis/bool-assignment2.c35
-rw-r--r--test/Analysis/call-invalidation.cpp91
-rw-r--r--test/Analysis/casts.c38
-rw-r--r--test/Analysis/conditional-operator-path-notes.c16
-rw-r--r--test/Analysis/conditional-operator.cpp17
-rw-r--r--test/Analysis/coverage.c12
-rw-r--r--test/Analysis/cstring-syntax-cxx.cpp5
-rw-r--r--test/Analysis/ctor-inlining.mm283
-rw-r--r--test/Analysis/dead-stores.c22
-rw-r--r--test/Analysis/derived-to-base.cpp87
-rw-r--r--test/Analysis/diagnostics/deref-track-symbolic-region.c354
-rw-r--r--test/Analysis/diagnostics/deref-track-symbolic-region.cpp15
-rw-r--r--test/Analysis/diagnostics/explicit-suppression.cpp17
-rw-r--r--test/Analysis/diagnostics/shortest-path-suppression.c19
-rw-r--r--test/Analysis/diagnostics/undef-value-param.c90
-rw-r--r--test/Analysis/diagnostics/undef-value-param.m193
-rw-r--r--test/Analysis/dtor.cpp73
-rw-r--r--test/Analysis/enum.cpp26
-rw-r--r--test/Analysis/free.c2
-rw-r--r--test/Analysis/global-region-invalidation.c5
-rw-r--r--test/Analysis/global_region_invalidation.mm173
-rw-r--r--test/Analysis/inline-plist.c186
-rw-r--r--test/Analysis/inline-unique-reports.c454
-rw-r--r--test/Analysis/inline.cpp32
-rw-r--r--test/Analysis/inlining/containers.cpp241
-rw-r--r--test/Analysis/inlining/dyn-dispatch-bifurcate.cpp5
-rw-r--r--test/Analysis/inlining/eager-reclamation-path-notes.c144
-rw-r--r--test/Analysis/inlining/eager-reclamation-path-notes.cpp36
-rw-r--r--test/Analysis/inlining/false-positive-suppression.c97
-rw-r--r--test/Analysis/inlining/false-positive-suppression.cpp99
-rw-r--r--test/Analysis/inlining/false-positive-suppression.m38
-rw-r--r--test/Analysis/inlining/inline-defensive-checks.c13
-rw-r--r--test/Analysis/inlining/inline-defensive-checks.cpp43
-rw-r--r--test/Analysis/inlining/inline-defensive-checks.m85
-rw-r--r--test/Analysis/inlining/path-notes.c934
-rw-r--r--test/Analysis/inlining/path-notes.cpp1685
-rw-r--r--test/Analysis/inlining/path-notes.m438
-rw-r--r--test/Analysis/inlining/stl.cpp4
-rw-r--r--test/Analysis/malloc-annotations.c28
-rw-r--r--test/Analysis/malloc-interprocedural.c8
-rw-r--r--test/Analysis/malloc-plist.c630
-rw-r--r--test/Analysis/malloc.c115
-rw-r--r--test/Analysis/malloc.cpp43
-rw-r--r--test/Analysis/malloc.mm14
-rw-r--r--test/Analysis/method-arg-decay.m6
-rw-r--r--test/Analysis/misc-ps-region-store.cpp19
-rw-r--r--test/Analysis/misc-ps-region-store.m2
-rw-r--r--test/Analysis/misc-ps.c12
-rw-r--r--test/Analysis/new.cpp104
-rw-r--r--test/Analysis/null-deref-path-notes.m91
-rw-r--r--test/Analysis/objc-boxing.m2
-rw-r--r--test/Analysis/objc-for.m14
-rw-r--r--test/Analysis/objc-string.mm39
-rw-r--r--test/Analysis/objc-subscript.m4
-rw-r--r--test/Analysis/objc_invalidation.m41
-rw-r--r--test/Analysis/operator-calls.cpp36
-rw-r--r--test/Analysis/plist-output-alternate.m80
-rw-r--r--test/Analysis/plist-output.m886
-rw-r--r--test/Analysis/pointer-to-member.cpp37
-rw-r--r--test/Analysis/pr4209.m8
-rw-r--r--test/Analysis/properties.m4
-rw-r--r--test/Analysis/ptr-arith.c113
-rw-r--r--test/Analysis/reference.cpp12
-rw-r--r--test/Analysis/reference.mm17
-rw-r--r--test/Analysis/region-store.c36
-rw-r--r--test/Analysis/region-store.cpp28
-rw-r--r--test/Analysis/retain-release-inline.m32
-rw-r--r--test/Analysis/retain-release-path-notes-gc.m46
-rw-r--r--test/Analysis/retain-release-path-notes.m841
-rw-r--r--test/Analysis/retain-release.m116
-rw-r--r--test/Analysis/retain-release.mm78
-rw-r--r--test/Analysis/simple-stream-checks.c2
-rw-r--r--test/Analysis/stack-addr-ps.cpp41
-rw-r--r--test/Analysis/stackaddrleak.c28
-rw-r--r--test/Analysis/string.c99
-rw-r--r--test/Analysis/svalbuilder-logic.c8
-rw-r--r--test/Analysis/taint-generic.c11
-rw-r--r--test/Analysis/taint-tester.c15
-rw-r--r--test/Analysis/temporaries.cpp35
-rw-r--r--test/Analysis/uninit-vals-ps.c17
-rw-r--r--test/Analysis/uninit-vals.m188
-rw-r--r--test/Analysis/unix-fns.c80
-rw-r--r--test/CMakeLists.txt4
-rw-r--r--test/CXX/basic/basic.link/p6.cpp43
-rw-r--r--test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp92
-rw-r--r--test/CXX/basic/basic.lookup/basic.lookup.unqual/p14.cpp53
-rw-r--r--test/CXX/basic/basic.types/p10.cpp24
-rw-r--r--test/CXX/class.derived/class.abstract/p16.cpp26
-rw-r--r--test/CXX/class/class.friend/p6.cpp12
-rw-r--r--test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.memdef/p3.cpp101
-rw-r--r--test/CXX/dcl.dcl/dcl.link/p7-2.cpp7
-rw-r--r--test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp4
-rw-r--r--test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp202
-rw-r--r--test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp38
-rw-r--r--test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p5.cpp2
-rw-r--r--test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p6.cpp4
-rw-r--r--test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p8.cpp14
-rw-r--r--test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p2.cpp2
-rw-r--r--test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-1y.cpp74
-rw-r--r--test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp2
-rw-r--r--test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p6-1y.cpp97
-rw-r--r--test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p5-cxx0x.cpp6
-rw-r--r--test/CXX/dcl.dcl/p4-0x.cpp8
-rw-r--r--test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp4
-rw-r--r--test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1-0x.cpp13
-rw-r--r--test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p7.cpp23
-rw-r--r--test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp10
-rw-r--r--test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp42
-rw-r--r--test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp23
-rw-r--r--test/CXX/except/except.spec/p1.cpp2
-rw-r--r--test/CXX/except/except.spec/p14.cpp23
-rw-r--r--test/CXX/expr/expr.ass/p9-cxx11.cpp4
-rw-r--r--test/CXX/expr/expr.const/p2-0x.cpp8
-rw-r--r--test/CXX/expr/expr.const/p3-0x.cpp2
-rw-r--r--test/CXX/expr/expr.const/p5-0x.cpp12
-rw-r--r--test/CXX/expr/expr.post/expr.const.cast/p1-0x.cpp17
-rw-r--r--test/CXX/expr/expr.prim/expr.prim.general/p3-0x.cpp37
-rw-r--r--test/CXX/expr/expr.prim/expr.prim.lambda/default-arguments.cpp2
-rw-r--r--test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp8
-rw-r--r--test/CXX/expr/expr.unary/expr.sizeof/p1.cpp20
-rw-r--r--test/CXX/over/over.oper/over.literal/p2.cpp9
-rw-r--r--test/CXX/special/class.dtor/p5-0x.cpp5
-rw-r--r--test/CXX/special/class.inhctor/elsewhere.cpp27
-rw-r--r--test/CXX/special/class.inhctor/p1.cpp64
-rw-r--r--test/CXX/special/class.inhctor/p2.cpp121
-rw-r--r--test/CXX/special/class.inhctor/p3.cpp22
-rw-r--r--test/CXX/special/class.inhctor/p4.cpp72
-rw-r--r--test/CXX/special/class.inhctor/p7.cpp30
-rw-r--r--test/CXX/special/class.inhctor/p8.cpp30
-rw-r--r--test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp10
-rw-r--r--test/CXX/stmt.stmt/stmt.select/stmt.switch/p2-0x.cpp4
-rw-r--r--test/CXX/temp/temp.arg/temp.arg.nontype/p1-11.cpp11
-rw-r--r--test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp10
-rw-r--r--test/CXX/temp/temp.spec/temp.explicit/p1-0x.cpp2
-rw-r--r--test/CodeGen/2010-02-10-PointerName.c4
-rw-r--r--test/CodeGen/arm-asm-diag.c23
-rw-r--r--test/CodeGen/builtins-aarch64.c6
-rw-r--r--test/CodeGen/c-strings.c13
-rw-r--r--test/CodeGen/catch-undef-behavior.c64
-rw-r--r--test/CodeGen/code-coverage.c10
-rw-r--r--test/CodeGen/frame-pointer-elim.c40
-rw-r--r--test/CodeGen/global-blocks-lines.c45
-rw-r--r--test/CodeGen/le32-regparm.c41
-rw-r--r--test/CodeGen/lifetime2.c17
-rw-r--r--test/CodeGen/linetable-endscope.c17
-rw-r--r--test/CodeGen/linux-arm-atomic.c11
-rw-r--r--test/CodeGen/may-alias.c15
-rw-r--r--test/CodeGen/mips-inline-asm-modifiers.c35
-rw-r--r--test/CodeGen/mips16-attr.c17
-rw-r--r--test/CodeGen/ms-inline-asm-64.c34
-rw-r--r--test/CodeGen/ms-inline-asm.c280
-rw-r--r--test/CodeGen/ms-inline-asm.cpp105
-rw-r--r--test/CodeGen/mult-alt-generic.c2
-rw-r--r--test/CodeGen/nvptx-cpus.c11
-rw-r--r--test/CodeGen/pragma-pack-1.c63
-rw-r--r--test/CodeGen/prefetchw-builtins.c12
-rw-r--r--test/CodeGen/rdrand-builtins.c25
-rw-r--r--test/CodeGen/rtm-builtins.c5
-rw-r--r--test/CodeGen/sanitize-init-order.cpp24
-rw-r--r--test/CodeGen/sanitize-use-after-scope.c22
-rw-r--r--test/CodeGen/sparc-target-data.c5
-rw-r--r--test/CodeGen/systemz-inline-asm.c131
-rw-r--r--test/CodeGen/tbaa-class.cpp226
-rw-r--r--test/CodeGen/tbaa-struct.cpp59
-rw-r--r--test/CodeGen/tbaa.cpp255
-rw-r--r--test/CodeGen/thread-specifier.c3
-rw-r--r--test/CodeGen/x86_32-arguments-darwin.c4
-rw-r--r--test/CodeGen/x86_32-arguments-linux.c4
-rw-r--r--test/CodeGen/x86_32-arguments-win32.c6
-rw-r--r--test/CodeGen/x86_32-inline-asm.c2
-rw-r--r--test/CodeGenCUDA/ptx-kernels.cu10
-rw-r--r--test/CodeGenCXX/2010-07-23-DeclLoc.cpp4
-rw-r--r--test/CodeGenCXX/arm.cpp8
-rw-r--r--test/CodeGenCXX/blocks.cpp33
-rw-r--r--test/CodeGenCXX/constructor-alias.cpp12
-rw-r--r--test/CodeGenCXX/constructor-destructor-return-this.cpp60
-rw-r--r--test/CodeGenCXX/coverage.cpp7
-rw-r--r--test/CodeGenCXX/cp-blocks-linetables.cpp61
-rw-r--r--test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp25
-rw-r--r--test/CodeGenCXX/cxx11-thread-local-reference.cpp26
-rw-r--r--test/CodeGenCXX/cxx11-thread-local.cpp173
-rw-r--r--test/CodeGenCXX/cxx1y-initializer-aggregate.cpp74
-rw-r--r--test/CodeGenCXX/debug-info-artificial-arg.cpp11
-rw-r--r--test/CodeGenCXX/debug-info-byval.cpp2
-rw-r--r--test/CodeGenCXX/debug-info-char16.cpp2
-rw-r--r--test/CodeGenCXX/debug-info-dup-fwd-decl.cpp6
-rw-r--r--test/CodeGenCXX/debug-info-enum-class.cpp8
-rw-r--r--test/CodeGenCXX/debug-info-fwd-ref.cpp9
-rw-r--r--test/CodeGenCXX/debug-info-namespace.cpp39
-rw-r--r--test/CodeGenCXX/debug-info-nullptr.cpp2
-rw-r--r--test/CodeGenCXX/debug-info-same-line.cpp98
-rw-r--r--test/CodeGenCXX/debug-info-static-fns.cpp2
-rw-r--r--test/CodeGenCXX/debug-info-template-member.cpp6
-rw-r--r--test/CodeGenCXX/debug-info-template-quals.cpp17
-rw-r--r--test/CodeGenCXX/debug-info-union-template.cpp15
-rw-r--r--test/CodeGenCXX/debug-info-union.cpp8
-rw-r--r--test/CodeGenCXX/debug-info-use-after-free.cpp3
-rw-r--r--test/CodeGenCXX/debug-info-zero-length-arrays.cpp5
-rw-r--r--test/CodeGenCXX/debug-lambda-expressions.cpp50
-rw-r--r--test/CodeGenCXX/debug-lambda-this.cpp2
-rw-r--r--test/CodeGenCXX/extern-c.cpp27
-rw-r--r--test/CodeGenCXX/inheriting-constructor.cpp21
-rw-r--r--test/CodeGenCXX/linetable-cleanup.cpp24
-rw-r--r--test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp45
-rw-r--r--test/CodeGenCXX/mangle-ms-return-qualifiers.cpp9
-rw-r--r--test/CodeGenCXX/mangle-ms-templates.cpp41
-rw-r--r--test/CodeGenCXX/mangle-ms-vector-types.cpp33
-rw-r--r--test/CodeGenCXX/mangle-ms.cpp7
-rw-r--r--test/CodeGenCXX/microsoft-abi-member-pointers.cpp363
-rw-r--r--test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp169
-rw-r--r--test/CodeGenCXX/pr15753.cpp12
-rw-r--r--test/CodeGenCXX/scoped-enums-debug-info.cpp26
-rw-r--r--test/CodeGenCXX/scoped-enums.cpp8
-rw-r--r--test/CodeGenCXX/throw-expressions.cpp28
-rw-r--r--test/CodeGenCXX/tls-init-funcs.cpp10
-rw-r--r--test/CodeGenCXX/vtable-debug-info.cpp2
-rw-r--r--test/CodeGenObjC/arc-blocks.m64
-rw-r--r--test/CodeGenObjC/arc-foreach.m3
-rw-r--r--test/CodeGenObjC/arc-linetable.m101
-rw-r--r--test/CodeGenObjC/arc-literals.m91
-rw-r--r--test/CodeGenObjC/arc-precise-lifetime.m120
-rw-r--r--test/CodeGenObjC/arc-property.m45
-rw-r--r--test/CodeGenObjC/arc-ternary-op.m4
-rw-r--r--test/CodeGenObjC/arc.m111
-rw-r--r--test/CodeGenObjC/autorelease.m27
-rw-r--r--test/CodeGenObjC/blocks.m3
-rw-r--r--test/CodeGenObjC/debug-info-block-captured-self.m69
-rw-r--r--test/CodeGenObjC/debug-info-block-helper.m2
-rw-r--r--test/CodeGenObjC/debug-info-block-line.m11
-rw-r--r--test/CodeGenObjC/debug-info-blocks.m19
-rw-r--r--test/CodeGenObjC/debug-info-fwddecl.m2
-rw-r--r--test/CodeGenObjC/debug-info-impl.m2
-rw-r--r--test/CodeGenObjC/debug-info-ivars-extension.m8
-rw-r--r--test/CodeGenObjC/debug-info-ivars-indirect.m2
-rw-r--r--test/CodeGenObjC/debug-info-ivars-private.m4
-rw-r--r--test/CodeGenObjC/debug-info-ivars.m14
-rw-r--r--test/CodeGenObjC/debug-info-pubtypes.m2
-rw-r--r--test/CodeGenObjC/debug-info-synthesis.m4
-rw-r--r--test/CodeGenObjC/encode-test-3.m8
-rw-r--r--test/CodeGenObjC/exceptions.m4
-rw-r--r--test/CodeGenObjC/metadata-symbols-32.m54
-rw-r--r--test/CodeGenObjC/metadata-symbols-64.m69
-rw-r--r--test/CodeGenObjC/metadata_symbols.m8
-rw-r--r--test/CodeGenObjC/objc-align.m18
-rw-r--r--test/CodeGenObjC/objc-fixed-enum.m64
-rw-r--r--test/CodeGenObjC/synthesize_ivar-cont-class.m4
-rw-r--r--test/CodeGenObjC/tentative-cfconstantstring.m43
-rw-r--r--test/CodeGenObjCXX/arc.mm24
-rw-r--r--test/CodeGenObjCXX/exceptions-legacy.mm80
-rw-r--r--test/CodeGenObjCXX/lambda-expressions.mm22
-rw-r--r--test/CodeGenObjCXX/mangle.mm26
-rw-r--r--test/CodeGenOpenCL/kernel-arg-info.cl19
-rw-r--r--test/CodeGenOpenCL/ptx-calls.cl7
-rw-r--r--test/CodeGenOpenCL/ptx-kernels.cl5
-rw-r--r--test/Driver/Inputs/fedora_18_tree/lib/.keep0
-rw-r--r--test/Driver/Inputs/fedora_18_tree/usr/lib/crt1.o0
-rw-r--r--test/Driver/Inputs/fedora_18_tree/usr/lib/crti.o0
-rw-r--r--test/Driver/Inputs/fedora_18_tree/usr/lib/crtn.o0
-rw-r--r--test/Driver/Inputs/fedora_18_tree/usr/lib/gcc/armv7hl-redhat-linux-gnueabi/4.7.2/crtbegin.o0
-rw-r--r--test/Driver/Inputs/fedora_18_tree/usr/lib/gcc/armv7hl-redhat-linux-gnueabi/4.7.2/crtend.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/bin/.keep0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/64/crtbegin.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/64/crtend.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/crtbegin.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/crtend.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/el/64/crtbegin.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/el/64/crtend.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/el/crtbegin.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/el/crtend.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/64/.keep0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/el/64/.keep0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/micromips/el/.keep0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/micromips/soft-float/el/.keep0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/mips16/el/.keep0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/mips16/soft-float/el/.keep0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/soft-float/64/.keep0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/soft-float/el/64/.keep0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include/.keep0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/crtbegin.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/crtend.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/el/crtbegin.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/el/crtend.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/soft-float/crtbegin.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/soft-float/crtend.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/soft-float/el/crtbegin.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/soft-float/el/crtend.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/crtbegin.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/crtend.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/el/crtbegin.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/el/crtend.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/soft-float/crtbegin.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/soft-float/crtend.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/soft-float/el/crtbegin.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/soft-float/el/crtend.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/64/crtbegin.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/64/crtend.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/crtbegin.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/crtend.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/el/64/crtbegin.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/el/64/crtend.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/el/crtbegin.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/el/crtend.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/.keep0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib/el/.keep0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib/micromips/el/.keep0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib/micromips/soft-float/el/.keep0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib/mips16/el/.keep0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib/mips16/soft-float/el/.keep0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib/soft-float/el/.keep0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib64/el/.keep0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib64/soft-float/el/.keep0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/lib/.keep0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/lib64/.keep0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/usr/lib/crt1.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/usr/lib/crti.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/usr/lib/crtn.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/usr/lib64/crt1.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/usr/lib64/crti.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/usr/lib64/crtn.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/lib/.keep0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/lib64/.keep0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/el/lib/.keep0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/el/usr/lib/crt1.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/el/usr/lib/crti.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/el/usr/lib/crtn.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/lib/.keep0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/el/lib/.keep0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/el/usr/lib/crt1.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/el/usr/lib/crti.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/el/usr/lib/crtn.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/lib/.keep0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/usr/lib/crt1.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/usr/lib/crti.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/usr/lib/crtn.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/usr/lib/crt1.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/usr/lib/crti.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/usr/lib/crtn.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/el/lib/.keep0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/el/usr/lib/crt1.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/el/usr/lib/crti.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/el/usr/lib/crtn.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/lib/.keep0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/el/lib/.keep0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/el/usr/lib/crt1.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/el/usr/lib/crti.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/el/usr/lib/crtn.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/lib/.keep0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/usr/lib/crt1.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/usr/lib/crti.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/usr/lib/crtn.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/usr/lib/crt1.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/usr/lib/crti.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/usr/lib/crtn.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/lib/.keep0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/lib64/.keep0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/usr/lib/crt1.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/usr/lib/crti.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/usr/lib/crtn.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/usr/lib64/crt1.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/usr/lib64/crti.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/usr/lib64/crtn.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/lib/.keep0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/lib64/.keep0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/usr/lib/crt1.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/usr/lib/crti.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/usr/lib/crtn.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/usr/lib64/crt1.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/usr/lib64/crti.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/usr/lib64/crtn.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/usr/include/.keep0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/usr/lib/crt1.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/usr/lib/crti.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/usr/lib/crtn.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/usr/lib64/crt1.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/usr/lib64/crti.o0
-rw-r--r--test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/usr/lib64/crtn.o0
-rw-r--r--test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.asan-i386.a.syms0
-rw-r--r--test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.asan-x86_64.a.syms0
-rw-r--r--test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.msan-x86_64.a.syms0
-rw-r--r--test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.tsan-x86_64.a.syms0
-rw-r--r--test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.ubsan-i386.a.syms0
-rw-r--r--test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.ubsan-x86_64.a.syms0
-rw-r--r--test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.ubsan_cxx-i386.a.syms0
-rw-r--r--test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.ubsan_cxx-x86_64.a.syms0
-rw-r--r--test/Driver/Ofast.c39
-rw-r--r--test/Driver/autolink_integrated_as.c6
-rw-r--r--test/Driver/clang_cpp.c5
-rw-r--r--test/Driver/clang_f_opts.c14
-rw-r--r--test/Driver/color-diagnostics.c53
-rw-r--r--test/Driver/debug-comp-dir.S3
-rw-r--r--test/Driver/debug.c3
-rw-r--r--test/Driver/dragonfly.c6
-rw-r--r--test/Driver/flags.c34
-rw-r--r--test/Driver/fparse-all-comments.c5
-rw-r--r--test/Driver/frame-pointer-elim.c30
-rw-r--r--test/Driver/freebsd.c2
-rw-r--r--test/Driver/fsanitize.c27
-rw-r--r--test/Driver/hexagon-toolchain-elf.c564
-rw-r--r--test/Driver/hexagon-toolchain.c2
-rw-r--r--test/Driver/inhibit-downstream-commands.c1
-rw-r--r--test/Driver/linux-ld.c16
-rw-r--r--test/Driver/mips-abi.c36
-rw-r--r--test/Driver/mips-as.c46
-rw-r--r--test/Driver/mips-cs-header-search.cpp257
-rw-r--r--test/Driver/mips-cs-ld.c288
-rw-r--r--test/Driver/mips-eleb.c29
-rw-r--r--test/Driver/mips-features.c14
-rw-r--r--test/Driver/mips-float.c20
-rw-r--r--test/Driver/modules.m6
-rw-r--r--test/Driver/modules_integrated_as.c4
-rw-r--r--test/Driver/no-integrated-as-win.c3
-rw-r--r--test/Driver/objc++-cpp-output.mm4
-rw-r--r--test/Driver/objc-cpp-output.m2
-rw-r--r--test/Driver/output-file-is-dir.c7
-rw-r--r--test/Driver/pic.c4
-rw-r--r--test/Driver/ppc-features.cpp18
-rw-r--r--test/Driver/r600-mcpu.cl52
-rw-r--r--test/Driver/sanitizer-ld.c69
-rw-r--r--test/Driver/save-temps.c19
-rw-r--r--test/Driver/split-debug.s21
-rw-r--r--test/Driver/unknown-gcc-arch.c40
-rw-r--r--test/FixIt/auto-isa-fixit.m66
-rw-r--r--test/FixIt/bridge-in-non-arc.m8
-rw-r--r--test/FixIt/fixit-cxx1y-compat.cpp12
-rw-r--r--test/FixIt/fixit.cpp8
-rw-r--r--test/FixIt/format-darwin.m8
-rw-r--r--test/Format/basic.cpp6
-rw-r--r--test/Format/diagnostic.cpp4
-rw-r--r--test/Format/multiple-inputs-error.cpp6
-rw-r--r--test/Format/multiple-inputs-inplace.cpp8
-rw-r--r--test/Format/multiple-inputs.cpp7
-rw-r--r--test/Format/ranges.cpp11
-rw-r--r--test/Frontend/Inputs/rewrite-includes8.h5
-rw-r--r--test/Frontend/ast-main.cpp22
-rw-r--r--test/Frontend/dependency-gen-escaping.c17
-rw-r--r--test/Frontend/rewrite-includes-invalid-hasinclude.c17
-rw-r--r--test/Frontend/rewrite-includes-missing.c2
-rw-r--r--test/Frontend/rewrite-includes-modules.c20
-rw-r--r--test/Frontend/rewrite-includes.c19
-rw-r--r--test/Frontend/rewrite-macros.c14
-rw-r--r--test/Frontend/verify.c16
-rw-r--r--test/Headers/c11.c14
-rw-r--r--test/Headers/cxx11.cpp8
-rw-r--r--test/Headers/ms-wchar.c15
-rw-r--r--test/Index/annotate-deep-statements.cpp3
-rw-r--r--test/Index/annotate-module.m7
-rw-r--r--test/Index/annotate-tokens.cpp55
-rw-r--r--test/Index/annotate-tokens.m10
-rw-r--r--test/Index/c-index-api-loadTU-test.m2
-rw-r--r--test/Index/comment-cplus11-specific.cpp27
-rw-r--r--test/Index/comment-misc-tags.m110
-rw-r--r--test/Index/comment-to-html-xml-conversion.cpp1
-rw-r--r--test/Index/comment-unqualified-objc-pointer.m36
-rw-r--r--test/Index/comment-with-preamble.c13
-rw-r--r--test/Index/complete-declarators.m6
-rw-r--r--test/Index/complete-documentation-properties.m24
-rw-r--r--test/Index/crash-recovery-code-complete.c3
-rw-r--r--test/Index/get-cursor.cpp25
-rw-r--r--test/Index/index-refs.m9
-rw-r--r--test/Index/load-classes.cpp20
-rw-r--r--test/Index/modules-objc-categories.m10
-rw-r--r--test/Index/parse-all-comments.c62
-rw-r--r--test/Index/print-type-size.cpp428
-rw-r--r--test/Index/print-type.c6
-rw-r--r--test/Index/print-type.cpp10
-rw-r--r--test/Index/print-type.m7
-rw-r--r--test/Index/properties-class-extensions.m10
-rw-r--r--test/Index/subclass-comment.mm107
-rw-r--r--test/Index/targeted-annotation.c8
-rw-r--r--test/Index/usrs.m7
-rw-r--r--test/Lexer/cxx1y_binary_literal.cpp19
-rw-r--r--test/Lexer/has_extension_cxx.cpp6
-rw-r--r--test/Lexer/has_feature_c1x.c11
-rw-r--r--test/Lexer/has_feature_cxx0x.cpp194
-rw-r--r--test/Lexer/pragma-message.c16
-rw-r--r--test/Lexer/pragma-message2.c19
-rw-r--r--test/Misc/ast-dump-decl.c2
-rw-r--r--test/Misc/ast-dump-decl.cpp5
-rw-r--r--test/Misc/ast-dump-stmt.cpp14
-rw-r--r--test/Misc/diag-template-diffing-color.cpp14
-rw-r--r--test/Misc/diag-template-diffing-cxx98.cpp44
-rw-r--r--test/Misc/diag-template-diffing.cpp149
-rw-r--r--test/Misc/diagnostic-crash.cpp39
-rw-r--r--test/Misc/warn-in-system-header.c2
-rw-r--r--test/Misc/warning-flags.c3
-rw-r--r--test/Modules/Inputs/Conflicts/conflict_a.h1
-rw-r--r--test/Modules/Inputs/Conflicts/conflict_b.h1
-rw-r--r--test/Modules/Inputs/Conflicts/module.map10
-rw-r--r--test/Modules/Inputs/Modified/B.h3
-rw-r--r--test/Modules/Inputs/Modified/module.map7
-rw-r--r--test/Modules/Inputs/ModuleDiags/has_errors.h2
-rw-r--r--test/Modules/Inputs/ModuleDiags/has_warnings.h3
-rw-r--r--test/Modules/Inputs/ModuleDiags/module.map7
-rw-r--r--test/Modules/Inputs/StdDef/module.map11
-rw-r--r--test/Modules/Inputs/StdDef/other.h2
-rw-r--r--test/Modules/Inputs/StdDef/size_t.h4
-rw-r--r--test/Modules/Inputs/System/usr/include/dbl_max.h1
-rw-r--r--test/Modules/Inputs/System/usr/include/module.map11
-rw-r--r--test/Modules/Inputs/System/usr/include/uses_other_constants.h3
-rw-r--r--test/Modules/Inputs/builtin.h3
-rw-r--r--test/Modules/Inputs/builtin_sub.h4
-rw-r--r--test/Modules/Inputs/config.h7
-rw-r--r--test/Modules/Inputs/diag_pragma.h3
-rw-r--r--test/Modules/Inputs/linkage-merge-bar.h3
-rw-r--r--test/Modules/Inputs/linkage-merge-foo.h2
-rw-r--r--test/Modules/Inputs/macros_left.h2
-rw-r--r--test/Modules/Inputs/macros_right.h2
-rw-r--r--test/Modules/Inputs/macros_top.h4
-rw-r--r--test/Modules/Inputs/module.map26
-rw-r--r--test/Modules/Inputs/oldname/module.map4
-rw-r--r--test/Modules/Inputs/oldname/new_name.h1
-rw-r--r--test/Modules/auto-module-import.m4
-rw-r--r--test/Modules/autolink.m6
-rw-r--r--test/Modules/builtins.m16
-rw-r--r--test/Modules/compiler_builtins.m1
-rw-r--r--test/Modules/config_macros.m28
-rw-r--r--test/Modules/conflicts.m7
-rw-r--r--test/Modules/cstd.m7
-rw-r--r--test/Modules/cycles.c4
-rw-r--r--test/Modules/decldef.m3
-rw-r--r--test/Modules/decldef.mm3
-rw-r--r--test/Modules/diag-pragma.c13
-rw-r--r--test/Modules/diamond-pch.c25
-rw-r--r--test/Modules/diamond.c22
-rw-r--r--test/Modules/driver.c2
-rw-r--r--test/Modules/linkage-merge.cpp12
-rw-r--r--test/Modules/linkage-merge.m23
-rw-r--r--test/Modules/lookup.cpp2
-rw-r--r--test/Modules/lookup.m18
-rw-r--r--test/Modules/macros.c35
-rw-r--r--test/Modules/method_pool.m8
-rw-r--r--test/Modules/modify-module.m15
-rw-r--r--test/Modules/module-private.cpp2
-rw-r--r--test/Modules/module_file_info.m34
-rw-r--r--test/Modules/namespaces.cpp4
-rw-r--r--test/Modules/normal-module-map.cpp6
-rw-r--r--test/Modules/objc-categories.m9
-rw-r--r--test/Modules/on-demand-build.m2
-rw-r--r--test/Modules/prune.m46
-rw-r--r--test/Modules/redecl-merge.m18
-rw-r--r--test/Modules/redecls/a.h3
-rw-r--r--test/Modules/redecls/b.h1
-rw-r--r--test/Modules/redecls/main.m27
-rw-r--r--test/Modules/redecls/module.map2
-rw-r--r--test/Modules/renamed.m8
-rw-r--r--test/Modules/serialized-diags.m32
-rw-r--r--test/Modules/stddef.m7
-rw-r--r--test/Modules/subframeworks.m2
-rw-r--r--test/Modules/system_version.m32
-rw-r--r--test/OpenMP/no_option.c6
-rw-r--r--test/OpenMP/no_option_no_warn.c6
-rw-r--r--test/OpenMP/openmp_common.c9
-rw-r--r--test/OpenMP/option_warn.c5
-rw-r--r--test/OpenMP/predefined_macro.c17
-rw-r--r--test/OpenMP/threadprivate_ast_print.cpp43
-rw-r--r--test/OpenMP/threadprivate_messages.cpp119
-rw-r--r--test/PCH/captured-stmt.cpp42
-rw-r--r--test/PCH/chain-late-anonymous-namespace.cpp2
-rw-r--r--test/PCH/cxx-constexpr.cpp3
-rw-r--r--test/PCH/cxx-templates.cpp2
-rw-r--r--test/PCH/cxx-templates.h23
-rw-r--r--test/PCH/cxx-typeid.cpp6
-rw-r--r--test/PCH/cxx-typeid.h43
-rw-r--r--test/PCH/cxx-using.cpp7
-rw-r--r--test/PCH/cxx11-statement-attributes.cpp3
-rw-r--r--test/PCH/cxx1y-decltype-auto.cpp24
-rw-r--r--test/PCH/cxx1y-default-initializer.cpp30
-rw-r--r--test/PCH/functions.c6
-rw-r--r--test/PCH/headersearch.cpp6
-rw-r--r--test/PCH/method_pool.m12
-rw-r--r--test/PCH/nonvisible-external-defs.c2
-rw-r--r--test/PCH/reloc.c4
-rw-r--r--test/PCH/tentative-defs.c3
-rw-r--r--test/PCH/thread-local.cpp20
-rw-r--r--test/PCH/typo.cpp19
-rw-r--r--test/PCH/typo.m3
-rw-r--r--test/Parser/MicrosoftExtensions.c2
-rw-r--r--test/Parser/MicrosoftExtensions.cpp29
-rw-r--r--test/Parser/asm.c6
-rw-r--r--test/Parser/atomic.c35
-rw-r--r--test/Parser/attributes.mm25
-rw-r--r--test/Parser/c11-noreturn.c6
-rw-r--r--test/Parser/captured-statements.c14
-rw-r--r--test/Parser/crash-report.c9
-rw-r--r--test/Parser/cxx-class.cpp11
-rw-r--r--test/Parser/cxx0x-ambig.cpp22
-rw-r--r--test/Parser/cxx0x-decl.cpp7
-rw-r--r--test/Parser/missing-closing-rbrace.m3
-rw-r--r--test/Parser/objc-boxing.m8
-rw-r--r--test/Parser/objc-error-qualified-implementation.m21
-rw-r--r--test/Parser/objcxx11-initialized-temps.mm38
-rw-r--r--test/Parser/pragma-options.c12
-rw-r--r--test/Parser/pragma-pack.c14
-rw-r--r--test/Parser/prefix-attributes.m8
-rw-r--r--test/Preprocessor/aarch64-target-features.c36
-rw-r--r--test/Preprocessor/cxx_oper_spelling.cpp3
-rw-r--r--test/Preprocessor/dependencies-and-pp.c17
-rw-r--r--test/Preprocessor/has_include.c9
-rw-r--r--test/Preprocessor/init.c165
-rw-r--r--test/Preprocessor/line-directive.c10
-rw-r--r--test/Preprocessor/macro_misc.c14
-rw-r--r--test/Preprocessor/pp-modules.c15
-rw-r--r--test/Preprocessor/pp-modules.h1
-rw-r--r--test/Preprocessor/pragma-captured.c13
-rw-r--r--test/Preprocessor/pragma_sysheader.c2
-rw-r--r--test/Preprocessor/predefined-arch-macros.c46
-rw-r--r--test/Preprocessor/predefined-macros.c18
-rw-r--r--test/Preprocessor/stdint.c107
-rw-r--r--test/Rewriter/rewrite-byref-in-nested-blocks.mm2
-rw-r--r--test/Rewriter/rewrite-line-directive.m18
-rw-r--r--test/Rewriter/rewrite-modern-qualified-type.mm11
-rw-r--r--test/Sema/MicrosoftCompatibility.cpp4
-rw-r--r--test/Sema/anonymous-struct-union.c2
-rw-r--r--test/Sema/arm-neon-types.c12
-rw-r--r--test/Sema/array-init.c2
-rw-r--r--test/Sema/asm.c23
-rw-r--r--test/Sema/atomic-expr.c47
-rw-r--r--test/Sema/atomic-ops.c3
-rw-r--r--test/Sema/bitfield.c15
-rw-r--r--test/Sema/block-return.c11
-rw-r--r--test/Sema/builtins-aarch64.c16
-rw-r--r--test/Sema/captured-statements.c78
-rw-r--r--test/Sema/compare.c16
-rw-r--r--test/Sema/crash-invalid-array.c7
-rw-r--r--test/Sema/decl-invalid.c4
-rw-r--r--test/Sema/declspec.c2
-rw-r--r--test/Sema/expr-comma-c99.c2
-rw-r--r--test/Sema/expr-comma.c2
-rw-r--r--test/Sema/exprs.c2
-rw-r--r--test/Sema/extern-redecl.c40
-rw-r--r--test/Sema/function-redecl.c4
-rw-r--r--test/Sema/function.c11
-rw-r--r--test/Sema/inline.c10
-rw-r--r--test/Sema/no-documentation-warn-tagdecl-specifier.c85
-rw-r--r--test/Sema/parentheses.c89
-rw-r--r--test/Sema/parentheses.cpp78
-rw-r--r--test/Sema/pragma-arc-cf-code-audited.c2
-rw-r--r--test/Sema/private-extern.c1
-rw-r--r--test/Sema/return.c13
-rw-r--r--test/Sema/static-assert.c33
-rw-r--r--test/Sema/struct-decl.c2
-rw-r--r--test/Sema/switch-1.c4
-rw-r--r--test/Sema/thread-specifier.c108
-rw-r--r--test/Sema/var-redecl.c4
-rw-r--r--test/Sema/warn-documentation.cpp2
-rw-r--r--test/Sema/warn-documentation.m15
-rw-r--r--test/Sema/warn-duplicate-enum.c9
-rw-r--r--test/Sema/warn-sizeof-array-decay.c18
-rw-r--r--test/Sema/warn-unused-variables-werror.c6
-rw-r--r--test/SemaCXX/Inputs/warn-unused-variables.h11
-rw-r--r--test/SemaCXX/MicrosoftExtensions.cpp125
-rw-r--r--test/SemaCXX/access.cpp76
-rw-r--r--test/SemaCXX/alignof.cpp52
-rw-r--r--test/SemaCXX/anonymous-union.cpp2
-rw-r--r--test/SemaCXX/ast-print.cpp11
-rw-r--r--test/SemaCXX/atomic-type.cxx25
-rw-r--r--test/SemaCXX/attr-cxx0x.cpp4
-rw-r--r--test/SemaCXX/attr-noreturn.cpp83
-rw-r--r--test/SemaCXX/blocks.cpp20
-rw-r--r--test/SemaCXX/captured-statements.cpp166
-rw-r--r--test/SemaCXX/class-base-member-init.cpp8
-rw-r--r--test/SemaCXX/compare.cpp16
-rw-r--r--test/SemaCXX/compound-literal.cpp66
-rw-r--r--test/SemaCXX/condition.cpp8
-rw-r--r--test/SemaCXX/constant-expression-cxx11.cpp84
-rw-r--r--test/SemaCXX/constant-expression-cxx1y.cpp459
-rw-r--r--test/SemaCXX/constexpr-printing.cpp2
-rw-r--r--test/SemaCXX/constexpr-value-init.cpp2
-rw-r--r--test/SemaCXX/constructor-initializer.cpp6
-rw-r--r--test/SemaCXX/cxx0x-defaulted-functions.cpp15
-rw-r--r--test/SemaCXX/cxx11-ast-print.cpp2
-rw-r--r--test/SemaCXX/cxx11-crashes.cpp4
-rw-r--r--test/SemaCXX/cxx11-inheriting-ctors.cpp28
-rw-r--r--test/SemaCXX/cxx11-thread-local-print.cpp9
-rw-r--r--test/SemaCXX/cxx11-thread-local.cpp23
-rw-r--r--test/SemaCXX/cxx11-user-defined-literals-unused.cpp13
-rw-r--r--test/SemaCXX/cxx1y-array-runtime-bound.cpp68
-rw-r--r--test/SemaCXX/cxx1y-constexpr-not-const.cpp18
-rw-r--r--test/SemaCXX/cxx1y-deduced-return-type.cpp338
-rw-r--r--test/SemaCXX/cxx1y-initializer-aggregates.cpp63
-rw-r--r--test/SemaCXX/cxx98-compat-pedantic.cpp11
-rw-r--r--test/SemaCXX/enum-scoped.cpp14
-rw-r--r--test/SemaCXX/enum-unscoped-nonexistent.cpp8
-rw-r--r--test/SemaCXX/extern-c.cpp58
-rw-r--r--test/SemaCXX/for-range-unused.cpp4
-rw-r--r--test/SemaCXX/friend.cpp16
-rw-r--r--test/SemaCXX/function-extern-c.cpp37
-rw-r--r--test/SemaCXX/function-redecl.cpp29
-rw-r--r--test/SemaCXX/i-c-e-cxx.cpp2
-rw-r--r--test/SemaCXX/linkage-spec.cpp12
-rw-r--r--test/SemaCXX/linkage.cpp9
-rw-r--r--test/SemaCXX/linkage2.cpp39
-rw-r--r--test/SemaCXX/member-pointer-ms.cpp175
-rw-r--r--test/SemaCXX/pascal-strings.cpp2
-rw-r--r--test/SemaCXX/return.cpp24
-rw-r--r--test/SemaCXX/storage-class.cpp2
-rw-r--r--test/SemaCXX/switch-implicit-fallthrough.cpp18
-rw-r--r--test/SemaCXX/trailing-return-0x.cpp9
-rw-r--r--test/SemaCXX/type-traits.cpp119
-rw-r--r--test/SemaCXX/typo-correction.cpp10
-rw-r--r--test/SemaCXX/undefined-internal.cpp7
-rw-r--r--test/SemaCXX/uninitialized.cpp27
-rw-r--r--test/SemaCXX/warn-c++11-extensions.cpp2
-rw-r--r--test/SemaCXX/warn-enum-compare.cpp4
-rw-r--r--test/SemaCXX/warn-overloaded-virtual.cpp18
-rw-r--r--test/SemaCXX/warn-reinterpret-base-class.cpp323
-rw-r--r--test/SemaCXX/warn-thread-safety-analysis.cpp90
-rw-r--r--test/SemaCXX/warn-unused-filescoped.cpp21
-rw-r--r--test/SemaCXX/warn-unused-variables-error.cpp10
-rw-r--r--test/SemaCXX/warn-unused-variables.cpp11
-rw-r--r--test/SemaObjC/arc-repeated-weak.mm26
-rw-r--r--test/SemaObjC/arc-system-header.m13
-rw-r--r--test/SemaObjC/arc-unavailable-for-weakref.m30
-rw-r--r--test/SemaObjC/arc.m11
-rw-r--r--test/SemaObjC/attr-availability.m32
-rw-r--r--test/SemaObjC/attr-deprecated.m19
-rw-r--r--test/SemaObjC/blocks.m4
-rw-r--r--test/SemaObjC/category-1.m3
-rw-r--r--test/SemaObjC/compare-qualified-id.m3
-rw-r--r--test/SemaObjC/conditional-expr.m4
-rw-r--r--test/SemaObjC/default-synthesize-3.m72
-rw-r--r--test/SemaObjC/deprecated-objc-introspection.m (renamed from test/SemaObjC/warn-isa-ref.m)32
-rw-r--r--test/SemaObjC/enum-fixed-type.m8
-rw-r--r--test/SemaObjC/format-arg-attribute.m2
-rw-r--r--test/SemaObjC/format-strings-objc.m6
-rw-r--r--test/SemaObjC/forward-protocol-incomplete-impl-warn.m1
-rw-r--r--test/SemaObjC/gcc-cast-ext.m7
-rw-r--r--test/SemaObjC/illegal-nonarc-bridged-cast.m11
-rw-r--r--test/SemaObjC/incomplete-implementation.m5
-rw-r--r--test/SemaObjC/instancetype.m38
-rw-r--r--test/SemaObjC/message.m12
-rw-r--r--test/SemaObjC/method-conflict-2.m22
-rw-r--r--test/SemaObjC/method-undef-category-warn-1.m16
-rw-r--r--test/SemaObjC/method-undef-extension-warn-1.m6
-rw-r--r--test/SemaObjC/method-undefined-warn-1.m20
-rw-r--r--test/SemaObjC/no-protocol-option-tests.m4
-rw-r--r--test/SemaObjC/property-category-4.m105
-rw-r--r--test/SemaObjC/property-category-impl.m5
-rw-r--r--test/SemaObjC/property-deprecated-warning.m38
-rw-r--r--test/SemaObjC/property-in-class-extension.m7
-rw-r--r--test/SemaObjC/property-noninherited-availability-attr.m34
-rw-r--r--test/SemaObjC/property-user-setter.m2
-rw-r--r--test/SemaObjC/property.m5
-rw-r--r--test/SemaObjC/protocol-lookup-2.m23
-rw-r--r--test/SemaObjC/related-result-type-inference.m2
-rw-r--r--test/SemaObjC/typo-correction.m20
-rw-r--r--test/SemaObjC/undef-protocol-methods-1.m5
-rw-r--r--test/SemaObjC/warn-missing-super.m2
-rw-r--r--test/SemaObjC/warning-missing-selector-name.m4
-rw-r--r--test/SemaObjCXX/arc-system-header.mm3
-rw-r--r--test/SemaObjCXX/foreach.mm16
-rw-r--r--test/SemaObjCXX/instancetype.mm216
-rw-r--r--test/SemaObjCXX/instantiate-expr.mm4
-rw-r--r--test/SemaObjCXX/parameters.mm3
-rw-r--r--test/SemaObjCXX/property-reference.mm18
-rw-r--r--test/SemaObjCXX/references.mm19
-rw-r--r--test/SemaOpenCL/endian-attr.cl9
-rw-r--r--test/SemaOpenCL/event_t.cl2
-rw-r--r--test/SemaOpenCL/storageclass.cl2
-rw-r--r--test/SemaTemplate/attributes.cpp22
-rw-r--r--test/SemaTemplate/dependent-names.cpp21
-rw-r--r--test/SemaTemplate/derived.cpp18
-rw-r--r--test/SemaTemplate/example-dynarray.cpp177
-rw-r--r--test/SemaTemplate/friend-template.cpp20
-rw-r--r--test/SemaTemplate/fun-template-def.cpp8
-rw-r--r--test/SemaTemplate/local-member-templates.cpp76
-rw-r--r--test/SemaTemplate/ms-function-specialization-class-scope.cpp1
-rw-r--r--test/SemaTemplate/ms-lookup-template-base-classes.cpp26
-rw-r--r--test/SemaTemplate/overload-candidates.cpp17
-rw-r--r--test/SemaTemplate/temp_arg_nontype.cpp9
-rw-r--r--test/Tooling/auto-detect-from-source-parent-of-cwd.cpp2
-rw-r--r--test/Tooling/auto-detect-from-source-parent.cpp2
-rw-r--r--test/Tooling/auto-detect-from-source.cpp2
-rw-r--r--test/Tooling/clang-check-args.cpp3
-rw-r--r--test/Tooling/clang-check-autodetect-dir.cpp2
-rw-r--r--test/Tooling/clang-check-builtin-headers.cpp3
-rw-r--r--test/Tooling/clang-check-chdir.cpp3
-rw-r--r--test/Tooling/clang-check-pwd.cpp2
-rw-r--r--test/Tooling/clang-check.cpp3
-rw-r--r--test/Tooling/multi-jobs.cpp3
-rw-r--r--test/Tooling/pch.cpp12
-rw-r--r--test/Unit/lit.cfg5
-rw-r--r--test/lit.cfg31
-rw-r--r--test/lit.site.cfg.in1
810 files changed, 25540 insertions, 3049 deletions
diff --git a/test/ARCMT/check-with-serialized-diag.m b/test/ARCMT/check-with-serialized-diag.m
index d8073d0469..77bad96dcc 100644
--- a/test/ARCMT/check-with-serialized-diag.m
+++ b/test/ARCMT/check-with-serialized-diag.m
@@ -43,13 +43,13 @@ void test1(A *a, struct UnsafeS *unsafeS) {
// CHECK-NEXT: Number FIXITs = 0
// CHECK-NEXT: {{.*}}check-with-serialized-diag.m:34:4: error: [rewriter] it is not safe to remove 'retain' message on a global variable
// CHECK-NEXT: Number FIXITs = 0
-// CHECK-NEXT: {{.*}}check-with-serialized-diag.m:32:4: error: ARC forbids explicit message send of 'retain'
-// CHECK-NEXT: Range: {{.*}}check-with-serialized-diag.m:32:23 {{.*}}check-with-serialized-diag.m:32:29
+// CHECK-NEXT: {{.*}}check-with-serialized-diag.m:32:23: error: ARC forbids explicit message send of 'retain'
+// CHECK-NEXT: Range: {{.*}}check-with-serialized-diag.m:32:4 {{.*}}check-with-serialized-diag.m:32:22
// CHECK-NEXT: Number FIXITs = 0
-// CHECK-NEXT: {{.*}}check-with-serialized-diag.m:34:4: error: ARC forbids explicit message send of 'retain'
-// CHECK-NEXT: Range: {{.*}}check-with-serialized-diag.m:34:15 {{.*}}check-with-serialized-diag.m:34:21
+// CHECK-NEXT: {{.*}}check-with-serialized-diag.m:34:15: error: ARC forbids explicit message send of 'retain'
+// CHECK-NEXT: Range: {{.*}}check-with-serialized-diag.m:34:4 {{.*}}check-with-serialized-diag.m:34:14
// CHECK-NEXT: Number FIXITs = 0
-// CHECK-NEXT: {{.*}}check-with-serialized-diag.m:35:4: error: ARC forbids explicit message send of 'retainCount'
-// CHECK-NEXT: Range: {{.*}}check-with-serialized-diag.m:35:6 {{.*}}check-with-serialized-diag.m:35:17
+// CHECK-NEXT: {{.*}}check-with-serialized-diag.m:35:6: error: ARC forbids explicit message send of 'retainCount'
+// CHECK-NEXT: Range: {{.*}}check-with-serialized-diag.m:35:4 {{.*}}check-with-serialized-diag.m:35:5
// CHECK-NEXT: Number FIXITs = 0
diff --git a/test/ARCMT/migrate-plist-output.m b/test/ARCMT/migrate-plist-output.m
index 12efa93f07..377dce30ca 100644
--- a/test/ARCMT/migrate-plist-output.m
+++ b/test/ARCMT/migrate-plist-output.m
@@ -26,7 +26,7 @@ void test(id p) {
// CHECK: <key>location</key>
// CHECK: <dict>
// CHECK: <key>line</key><integer>10</integer>
-// CHECK: <key>col</key><integer>4</integer>
+// CHECK: <key>col</key><integer>6</integer>
// CHECK: <key>file</key><integer>0</integer>
// CHECK: </dict>
// CHECK: <key>ranges</key>
@@ -34,12 +34,12 @@ void test(id p) {
// CHECK: <array>
// CHECK: <dict>
// CHECK: <key>line</key><integer>10</integer>
-// CHECK: <key>col</key><integer>6</integer>
+// CHECK: <key>col</key><integer>4</integer>
// CHECK: <key>file</key><integer>0</integer>
// CHECK: </dict>
// CHECK: <dict>
// CHECK: <key>line</key><integer>10</integer>
-// CHECK: <key>col</key><integer>12</integer>
+// CHECK: <key>col</key><integer>4</integer>
// CHECK: <key>file</key><integer>0</integer>
// CHECK: </dict>
// CHECK: </array>
diff --git a/test/ARCMT/objcmt-subscripting-literals.m b/test/ARCMT/objcmt-subscripting-literals.m
index 8cef0919bb..014c109299 100644
--- a/test/ARCMT/objcmt-subscripting-literals.m
+++ b/test/ARCMT/objcmt-subscripting-literals.m
@@ -157,6 +157,7 @@ typedef const struct __CFString * CFStringRef;
dict = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"1", [NSArray array], nil] forKeys:[NSArray arrayWithObjects:@"A", [arr objectAtIndex:2], nil]];
dict = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"1", @"2", nil] forKeys:arr];
dict = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"1", @"2", nil] forKeys:@[@"A", @"B"]];
+ dict = [NSDictionary dictionaryWithObjectsAndKeys:[NSArray array], @"A", [NSArray array], @"B", nil];
}
@end
diff --git a/test/ARCMT/objcmt-subscripting-literals.m.result b/test/ARCMT/objcmt-subscripting-literals.m.result
index 0ca6dca1fe..e9ff8df34d 100644
--- a/test/ARCMT/objcmt-subscripting-literals.m.result
+++ b/test/ARCMT/objcmt-subscripting-literals.m.result
@@ -157,6 +157,7 @@ typedef const struct __CFString * CFStringRef;
dict = @{@"A": @"1", arr[2]: @[]};
dict = [NSDictionary dictionaryWithObjects:@[@"1", @"2"] forKeys:arr];
dict = @{@"A": @"1", @"B": @"2"};
+ dict = @{@"A": @[], @"B": @[]};
}
@end
diff --git a/test/ASTMerge/function.c b/test/ASTMerge/function.c
index 320bca2a36..8a8a030514 100644
--- a/test/ASTMerge/function.c
+++ b/test/ASTMerge/function.c
@@ -9,7 +9,7 @@
// CHECK: function1.c:4:6: note: declared here with type 'void (void)'
// CHECK: 2 errors generated
-// expected-error@3 {{external function 'f1' declared with incompatible types}}
-// expected-note@2 {{declared here}}
-// expected-error@5 {{external function 'f3' declared with incompatible types}}
-// expected-note@4 {{declared here}}
+// expected-error@Inputs/function2.c:3 {{external function 'f1' declared with incompatible types}}
+// expected-note@Inputs/function1.c:2 {{declared here}}
+// expected-error@Inputs/function2.c:5 {{external function 'f3' declared with incompatible types}}
+// expected-note@Inputs/function1.c:4 {{declared here}}
diff --git a/test/Analysis/Inputs/system-header-simulator-cxx.h b/test/Analysis/Inputs/system-header-simulator-cxx.h
index faca0b41aa..6e434a04b2 100644
--- a/test/Analysis/Inputs/system-header-simulator-cxx.h
+++ b/test/Analysis/Inputs/system-header-simulator-cxx.h
@@ -59,4 +59,41 @@ namespace std {
return 0;
}
};
+
+ class bad_alloc : public exception {
+ public:
+ bad_alloc() throw();
+ bad_alloc(const bad_alloc&) throw();
+ bad_alloc& operator=(const bad_alloc&) throw();
+ virtual const char* what() const throw() {
+ return 0;
+ }
+ };
+
+ struct nothrow_t {};
+
+ extern const nothrow_t nothrow;
+
+ template<class InputIter, class OutputIter>
+ OutputIter copy(InputIter II, InputIter IE, OutputIter OI) {
+ while (II != IE)
+ *OI++ = *II++;
+ return OI;
+ }
+
+ struct input_iterator_tag { };
+ struct output_iterator_tag { };
+ struct forward_iterator_tag : public input_iterator_tag { };
+ struct bidirectional_iterator_tag : public forward_iterator_tag { };
+ struct random_access_iterator_tag : public bidirectional_iterator_tag { };
}
+
+void* operator new(std::size_t, const std::nothrow_t&) throw();
+void* operator new[](std::size_t, const std::nothrow_t&) throw();
+void operator delete(void*, const std::nothrow_t&) throw();
+void operator delete[](void*, const std::nothrow_t&) throw();
+
+void* operator new (std::size_t size, void* ptr) throw() { return ptr; };
+void* operator new[] (std::size_t size, void* ptr) throw() { return ptr; };
+void operator delete (void* ptr, void*) throw() {};
+void operator delete[] (void* ptr, void*) throw() {};
diff --git a/test/Analysis/Inputs/system-header-simulator.h b/test/Analysis/Inputs/system-header-simulator.h
index 04688c782a..dd1cd4942f 100644
--- a/test/Analysis/Inputs/system-header-simulator.h
+++ b/test/Analysis/Inputs/system-header-simulator.h
@@ -5,6 +5,10 @@
// suppressed.
#pragma clang system_header
+#ifdef __cplusplus
+#define restrict /*restrict*/
+#endif
+
typedef struct _FILE FILE;
extern FILE *stdin;
extern FILE *stdout;
@@ -14,8 +18,11 @@ extern FILE *__stdinp;
extern FILE *__stdoutp;
extern FILE *__stderrp;
-
+int scanf(const char *restrict format, ...);
int fscanf(FILE *restrict, const char *restrict, ...);
+int printf(const char *restrict format, ...);
+int fprintf(FILE *restrict, const char *restrict, ...);
+int getchar(void);
// Note, on some platforms errno macro gets replaced with a function call.
extern int errno;
@@ -37,6 +44,8 @@ typedef __darwin_off_t fpos_t;
void setbuf(FILE * restrict, char * restrict);
int setvbuf(FILE * restrict, char * restrict, int, size_t);
+FILE *fopen(const char * restrict, const char * restrict);
+int fclose(FILE *);
FILE *funopen(const void *,
int (*)(void *, char *, int),
int (*)(void *, const char *, int),
diff --git a/test/Analysis/Malloc+MismatchedDeallocator+NewDelete.cpp b/test/Analysis/Malloc+MismatchedDeallocator+NewDelete.cpp
new file mode 100644
index 0000000000..5a596d47ec
--- /dev/null
+++ b/test/Analysis/Malloc+MismatchedDeallocator+NewDelete.cpp
@@ -0,0 +1,105 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,unix.MismatchedDeallocator,cplusplus.NewDelete -std=c++11 -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,unix.MismatchedDeallocator,cplusplus.NewDelete,alpha.cplusplus.NewDeleteLeaks -DLEAKS -std=c++11 -verify %s
+
+#include "Inputs/system-header-simulator-for-malloc.h"
+
+//--------------------------------------------------
+// Check that unix.Malloc catches all types of bugs.
+//--------------------------------------------------
+void testMallocDoubleFree() {
+ int *p = (int *)malloc(sizeof(int));
+ free(p);
+ free(p); // expected-warning{{Attempt to free released memory}}
+}
+
+void testMallocLeak() {
+ int *p = (int *)malloc(sizeof(int));
+} // expected-warning{{Potential leak of memory pointed to by 'p'}}
+
+void testMallocUseAfterFree() {
+ int *p = (int *)malloc(sizeof(int));
+ free(p);
+ int j = *p; // expected-warning{{Use of memory after it is freed}}
+}
+
+void testMallocBadFree() {
+ int i;
+ free(&i); // expected-warning{{Argument to free() is the address of the local variable 'i', which is not memory allocated by malloc()}}
+}
+
+void testMallocOffsetFree() {
+ int *p = (int *)malloc(sizeof(int));
+ free(++p); // expected-warning{{Argument to free() is offset by 4 bytes from the start of memory allocated by malloc()}}
+}
+
+//-----------------------------------------------------------------
+// Check that unix.MismatchedDeallocator catches all types of bugs.
+//-----------------------------------------------------------------
+void testMismatchedDeallocator() {
+ int *x = (int *)malloc(sizeof(int));
+ delete x; // expected-warning{{Memory allocated by malloc() should be deallocated by free(), not 'delete'}}
+}
+
+//----------------------------------------------------------------
+// Check that alpha.cplusplus.NewDelete catches all types of bugs.
+//----------------------------------------------------------------
+void testNewDoubleFree() {
+ int *p = new int;
+ delete p;
+ delete p; // expected-warning{{Attempt to free released memory}}
+}
+
+void testNewLeak() {
+ int *p = new int;
+}
+#ifdef LEAKS
+// expected-warning@-2 {{Potential leak of memory pointed to by 'p'}}
+#endif
+
+void testNewUseAfterFree() {
+ int *p = (int *)operator new(0);
+ delete p;
+ int j = *p; // expected-warning{{Use of memory after it is freed}}
+}
+
+void testNewBadFree() {
+ int i;
+ delete &i; // expected-warning{{Argument to 'delete' is the address of the local variable 'i', which is not memory allocated by 'new'}}
+}
+
+void testNewOffsetFree() {
+ int *p = new int;
+ operator delete(++p); // expected-warning{{Argument to operator delete is offset by 4 bytes from the start of memory allocated by 'new'}}
+}
+
+//----------------------------------------------------------------
+// Test that we check for free errors on escaped pointers.
+//----------------------------------------------------------------
+void changePtr(int **p);
+static int *globalPtr;
+void changePointee(int *p);
+
+void testMismatchedChangePtrThroughCall() {
+ int *p = (int*)malloc(sizeof(int)*4);
+ changePtr(&p);
+ delete p; // no-warning the value of the pointer might have changed
+}
+
+void testMismatchedChangePointeeThroughCall() {
+ int *p = (int*)malloc(sizeof(int)*4);
+ changePointee(p);
+ delete p; // expected-warning{{Memory allocated by malloc() should be deallocated by free(), not 'delete'}}
+}
+
+void testShouldReportDoubleFreeNotMismatched() {
+ int *p = (int*)malloc(sizeof(int)*4);
+ globalPtr = p;
+ free(p);
+ delete globalPtr; // expected-warning {{Attempt to free released memory}}
+}
+
+void testMismatchedChangePointeeThroughAssignment() {
+ int *arr = new int[4];
+ globalPtr = arr;
+ delete arr; // expected-warning{{Memory allocated by 'new[]' should be deallocated by 'delete[]', not 'delete'}}
+} \ No newline at end of file
diff --git a/test/Analysis/Malloc+MismatchedDeallocator_intersections.cpp b/test/Analysis/Malloc+MismatchedDeallocator_intersections.cpp
new file mode 100644
index 0000000000..639790d31a
--- /dev/null
+++ b/test/Analysis/Malloc+MismatchedDeallocator_intersections.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,unix.MismatchedDeallocator -analyzer-store region -std=c++11 -verify %s
+// expected-no-diagnostics
+
+typedef __typeof(sizeof(int)) size_t;
+void *malloc(size_t);
+void free(void *);
+
+//--------------------------------------------------------------------
+// Check that unix.Malloc + unix.MismatchedDeallocator does not enable
+// warnings produced by the alpha.cplusplus.NewDelete checker.
+//--------------------------------------------------------------------
+void testNewDeleteNoWarn() {
+ int i;
+ delete &i; // no-warning
+
+ int *p1 = new int;
+ delete ++p1; // no-warning
+
+ int *p2 = new int;
+ delete p2;
+ delete p2; // no-warning
+
+ int *p3 = new int; // no-warning
+
+ int *p4 = new int;
+ delete p4;
+ int j = *p4; // no-warning
+}
diff --git a/test/Analysis/Malloc+NewDelete_intersections.cpp b/test/Analysis/Malloc+NewDelete_intersections.cpp
new file mode 100644
index 0000000000..310663646a
--- /dev/null
+++ b/test/Analysis/Malloc+NewDelete_intersections.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,cplusplus.NewDelete -std=c++11 -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,cplusplus.NewDelete,alpha.cplusplus.NewDeleteLeaks -std=c++11 -verify %s
+
+typedef __typeof(sizeof(int)) size_t;
+void *malloc(size_t);
+void free(void *);
+
+//-------------------------------------------------------------------
+// Check that unix.Malloc + cplusplus.NewDelete does not enable
+// warnings produced by unix.MismatchedDeallocator.
+//-------------------------------------------------------------------
+void testMismatchedDeallocator() {
+ int *p = (int *)malloc(sizeof(int));
+ delete p;
+} // expected-warning{{Potential leak of memory pointed to by 'p'}}
diff --git a/test/Analysis/MismatchedDeallocator-checker-test.mm b/test/Analysis/MismatchedDeallocator-checker-test.mm
new file mode 100644
index 0000000000..56d46d99b0
--- /dev/null
+++ b/test/Analysis/MismatchedDeallocator-checker-test.mm
@@ -0,0 +1,221 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.MismatchedDeallocator -fblocks -verify %s
+
+#include "Inputs/system-header-simulator-objc.h"
+#include "Inputs/system-header-simulator-cxx.h"
+
+typedef __typeof__(sizeof(int)) size_t;
+void *malloc(size_t);
+void *realloc(void *ptr, size_t size);
+void *calloc(size_t nmemb, size_t size);
+char *strdup(const char *s);
+void __attribute((ownership_returns(malloc))) *my_malloc(size_t);
+
+void free(void *);
+void __attribute((ownership_takes(malloc, 1))) my_free(void *);
+
+//---------------------------------------------------------------
+// Test if an allocation function matches deallocation function
+//---------------------------------------------------------------
+
+//--------------- test malloc family
+void testMalloc1() {
+ int *p = (int *)malloc(sizeof(int));
+ delete p; // expected-warning{{Memory allocated by malloc() should be deallocated by free(), not 'delete'}}
+}
+
+void testMalloc2() {
+ int *p = (int *)malloc(8);
+ int *q = (int *)realloc(p, 16);
+ delete q; // expected-warning{{Memory allocated by realloc() should be deallocated by free(), not 'delete'}}
+}
+
+void testMalloc3() {
+ int *p = (int *)calloc(1, sizeof(int));
+ delete p; // expected-warning{{Memory allocated by calloc() should be deallocated by free(), not 'delete'}}
+}
+
+void testMalloc4(const char *s) {
+ char *p = strdup(s);
+ delete p; // expected-warning{{Memory allocated by strdup() should be deallocated by free(), not 'delete'}}
+}
+
+void testMalloc5() {
+ int *p = (int *)my_malloc(sizeof(int));
+ delete p; // expected-warning{{Memory allocated by my_malloc() should be deallocated by free(), not 'delete'}}
+}
+
+void testMalloc6() {
+ int *p = (int *)malloc(sizeof(int));
+ operator delete(p); // expected-warning{{Memory allocated by malloc() should be deallocated by free(), not operator delete}}
+}
+
+void testMalloc7() {
+ int *p = (int *)malloc(sizeof(int));
+ delete[] p; // expected-warning{{Memory allocated by malloc() should be deallocated by free(), not 'delete[]'}}
+}
+
+void testMalloc8() {
+ int *p = (int *)malloc(sizeof(int));
+ operator delete[](p); // expected-warning{{Memory allocated by malloc() should be deallocated by free(), not operator delete[]}}
+}
+
+//--------------- test new family
+void testNew1() {
+ int *p = new int;
+ free(p); // expected-warning{{Memory allocated by 'new' should be deallocated by 'delete', not free()}}
+}
+
+void testNew2() {
+ int *p = (int *)operator new(0);
+ free(p); // expected-warning{{Memory allocated by operator new should be deallocated by 'delete', not free()}}
+}
+
+void testNew3() {
+ int *p = new int[1];
+ free(p); // expected-warning{{Memory allocated by 'new[]' should be deallocated by 'delete[]', not free()}}
+}
+
+void testNew4() {
+ int *p = new int;
+ realloc(p, sizeof(long)); // expected-warning{{Memory allocated by 'new' should be deallocated by 'delete', not realloc()}}
+}
+
+void testNew5() {
+ int *p = (int *)operator new(0);
+ realloc(p, sizeof(long)); // expected-warning{{Memory allocated by operator new should be deallocated by 'delete', not realloc()}}
+}
+
+void testNew6() {
+ int *p = new int[1];
+ realloc(p, sizeof(long)); // expected-warning{{Memory allocated by 'new[]' should be deallocated by 'delete[]', not realloc()}}
+}
+
+void testNew7() {
+ int *p = new int;
+ delete[] p; // expected-warning{{Memory allocated by 'new' should be deallocated by 'delete', not 'delete[]'}}
+}
+
+void testNew8() {
+ int *p = (int *)operator new(0);
+ delete[] p; // expected-warning{{Memory allocated by operator new should be deallocated by 'delete', not 'delete[]'}}
+}
+
+void testNew9() {
+ int *p = new int[1];
+ delete p; // expected-warning{{Memory allocated by 'new[]' should be deallocated by 'delete[]', not 'delete'}}
+}
+
+void testNew10() {
+ int *p = (int *)operator new[](0);
+ delete p; // expected-warning{{Memory allocated by operator new[] should be deallocated by 'delete[]', not 'delete'}}
+}
+
+void testNew11(NSUInteger dataLength) {
+ int *p = new int;
+ NSData *d = [NSData dataWithBytesNoCopy:p length:sizeof(int) freeWhenDone:1]; // expected-warning{{Memory allocated by 'new' should be deallocated by 'delete', not +dataWithBytesNoCopy:length:freeWhenDone:}}
+ // FIXME: should be "+dataWithBytesNoCopy:length:freeWhenDone: cannot take ownership of memory allocated by 'new'."
+}
+
+//-------------------------------------------------------
+// Check for intersection with unix.Malloc bounded with
+// unix.MismatchedDeallocator
+//-------------------------------------------------------
+
+// new/delete oparators are subjects of cplusplus.NewDelete.
+void testNewDeleteNoWarn() {
+ int i;
+ delete &i; // no-warning
+
+ int *p1 = new int;
+ delete ++p1; // no-warning
+
+ int *p2 = new int;
+ delete p2;
+ delete p2; // no-warning
+
+ int *p3 = new int; // no-warning
+}
+
+void testDeleteOpAfterFree() {
+ int *p = (int *)malloc(sizeof(int));
+ free(p);
+ operator delete(p); // no-warning
+}
+
+void testDeleteAfterFree() {
+ int *p = (int *)malloc(sizeof(int));
+ free(p);
+ delete p; // no-warning
+}
+
+void testStandardPlacementNewAfterFree() {
+ int *p = (int *)malloc(sizeof(int));
+ free(p);
+ p = new(p) int; // no-warning
+}
+
+//---------------------------------------------------------------
+// Check for intersection with cplusplus.NewDelete bounded with
+// unix.MismatchedDeallocator
+//---------------------------------------------------------------
+
+// malloc()/free() are subjects of unix.Malloc and unix.MallocWithAnnotations
+void testMallocFreeNoWarn() {
+ int i;
+ free(&i); // no-warning
+
+ int *p1 = (int *)malloc(sizeof(int));
+ free(++p1); // no-warning
+
+ int *p2 = (int *)malloc(sizeof(int));
+ free(p2);
+ free(p2); // no-warning
+
+ int *p3 = (int *)malloc(sizeof(int)); // no-warning
+}
+
+void testFreeAfterDelete() {
+ int *p = new int;
+ delete p;
+ free(p); // no-warning
+}
+
+void testStandardPlacementNewAfterDelete() {
+ int *p = new int;
+ delete p;
+ p = new(p) int; // no-warning
+}
+
+
+// Smart pointer example
+template <typename T>
+struct SimpleSmartPointer {
+ T *ptr;
+
+ explicit SimpleSmartPointer(T *p = 0) : ptr(p) {}
+ ~SimpleSmartPointer() {
+ delete ptr;
+ // expected-warning@-1 {{Memory allocated by 'new[]' should be deallocated by 'delete[]', not 'delete'}}
+ // expected-warning@-2 {{Memory allocated by malloc() should be deallocated by free(), not 'delete'}}
+ }
+};
+
+void testSimpleSmartPointerArrayNew() {
+ {
+ SimpleSmartPointer<int> a(new int);
+ } // no-warning
+
+ {
+ SimpleSmartPointer<int> a(new int[4]);
+ }
+}
+
+void testSimpleSmartPointerMalloc() {
+ {
+ SimpleSmartPointer<int> a(new int);
+ } // no-warning
+
+ {
+ SimpleSmartPointer<int> a((int *)malloc(4));
+ }
+}
diff --git a/test/Analysis/MismatchedDeallocator-path-notes.cpp b/test/Analysis/MismatchedDeallocator-path-notes.cpp
new file mode 100644
index 0000000000..369d8f6975
--- /dev/null
+++ b/test/Analysis/MismatchedDeallocator-path-notes.cpp
@@ -0,0 +1,159 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.MismatchedDeallocator -analyzer-output=text -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.MismatchedDeallocator -analyzer-output=plist %s -o %t.plist
+// RUN: FileCheck --input-file=%t.plist %s
+
+void changePointee(int *p);
+void test() {
+ int *p = new int[1];
+ // expected-note@-1 {{Memory is allocated}}
+ changePointee(p);
+ delete p; // expected-warning {{Memory allocated by 'new[]' should be deallocated by 'delete[]', not 'delete'}}
+ // expected-note@-1 {{Memory allocated by 'new[]' should be deallocated by 'delete[]', not 'delete'}}
+}
+
+// CHECK: <key>diagnostics</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>path</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>7</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>7</integer>
+// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>7</integer>
+// CHECK-NEXT: <key>col</key><integer>12</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>7</integer>
+// CHECK-NEXT: <key>col</key><integer>14</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>7</integer>
+// CHECK-NEXT: <key>col</key><integer>12</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>7</integer>
+// CHECK-NEXT: <key>col</key><integer>12</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>7</integer>
+// CHECK-NEXT: <key>col</key><integer>21</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Memory is allocated</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Memory is allocated</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>7</integer>
+// CHECK-NEXT: <key>col</key><integer>12</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>7</integer>
+// CHECK-NEXT: <key>col</key><integer>14</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>10</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>10</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>10</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>10</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>10</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Memory allocated by &apos;new[]&apos; should be deallocated by &apos;delete[]&apos;, not &apos;delete&apos;</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Memory allocated by &apos;new[]&apos; should be deallocated by &apos;delete[]&apos;, not &apos;delete&apos;</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>description</key><string>Memory allocated by &apos;new[]&apos; should be deallocated by &apos;delete[]&apos;, not &apos;delete&apos;</string>
+// CHECK-NEXT: <key>category</key><string>Memory Error</string>
+// CHECK-NEXT: <key>type</key><string>Bad deallocator</string>
+// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT: <key>issue_context</key><string>test</string>
+// CHECK-NEXT: <key>issue_hash</key><string>4</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>10</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
diff --git a/test/Analysis/NSContainers.m b/test/Analysis/NSContainers.m
new file mode 100644
index 0000000000..540c7a4eab
--- /dev/null
+++ b/test/Analysis/NSContainers.m
@@ -0,0 +1,200 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.NilArg -verify -Wno-objc-root-class %s
+typedef unsigned long NSUInteger;
+typedef signed char BOOL;
+typedef struct _NSZone NSZone;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject
+@end
+@protocol NSCopying
+- (id)copyWithZone:(NSZone *)zone;
+@end
+@protocol NSMutableCopying
+- (id)mutableCopyWithZone:(NSZone *)zone;
+@end
+@protocol NSCoding
+- (void)encodeWithCoder:(NSCoder *)aCoder;
+@end
+@protocol NSFastEnumeration
+@end
+@protocol NSSecureCoding <NSCoding>
+@required
++ (BOOL)supportsSecureCoding;
+@end
+@interface NSObject <NSObject> {}
+- (id)init;
++ (id)alloc;
+@end
+@interface NSArray : NSObject <NSCopying, NSMutableCopying, NSSecureCoding, NSFastEnumeration>
+
+- (NSUInteger)count;
+- (id)objectAtIndex:(NSUInteger)index;
+
+@end
+
+@interface NSArray (NSExtendedArray)
+- (NSArray *)arrayByAddingObject:(id)anObject;
+- (void)setObject:(id)obj atIndexedSubscript:(NSUInteger)idx __attribute__((availability(macosx,introduced=10.8)));
+@end
+
+@interface NSMutableArray : NSArray
+
+- (void)addObject:(id)anObject;
+- (void)insertObject:(id)anObject atIndex:(NSUInteger)index;
+- (void)removeLastObject;
+- (void)removeObjectAtIndex:(NSUInteger)index;
+- (void)replaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject;
+
+@end
+
+@interface NSDictionary : NSObject <NSCopying, NSMutableCopying, NSSecureCoding, NSFastEnumeration>
+
+- (NSUInteger)count;
+- (id)objectForKey:(id)aKey;
+- (NSEnumerator *)keyEnumerator;
+
+@end
+
+@interface NSDictionary (NSDictionaryCreation)
+
++ (id)dictionary;
++ (id)dictionaryWithObject:(id)object forKey:(id <NSCopying>)key;
+@end
+
+@interface NSMutableDictionary : NSDictionary
+
+- (void)removeObjectForKey:(id)aKey;
+- (void)setObject:(id)anObject forKey:(id <NSCopying>)aKey;
+
+@end
+
+@interface NSMutableDictionary (NSExtendedMutableDictionary)
+
+- (void)addEntriesFromDictionary:(NSDictionary *)otherDictionary;
+- (void)removeAllObjects;
+- (void)removeObjectsForKeys:(NSArray *)keyArray;
+- (void)setDictionary:(NSDictionary *)otherDictionary;
+- (void)setObject:(id)obj forKeyedSubscript:(id <NSCopying>)key __attribute__((availability(macosx,introduced=10.8)));
+
+@end
+
+@interface NSString : NSObject <NSCopying, NSMutableCopying, NSSecureCoding>
+
+@end
+
+// NSMutableArray API
+void testNilArgNSMutableArray1() {
+ NSMutableArray *marray = [[NSMutableArray alloc] init];
+ [marray addObject:0]; // expected-warning {{Argument to 'NSMutableArray' method 'addObject:' cannot be nil}}
+}
+
+void testNilArgNSMutableArray2() {
+ NSMutableArray *marray = [[NSMutableArray alloc] init];
+ [marray insertObject:0 atIndex:1]; // expected-warning {{Argument to 'NSMutableArray' method 'insertObject:atIndex:' cannot be nil}}
+}
+
+void testNilArgNSMutableArray3() {
+ NSMutableArray *marray = [[NSMutableArray alloc] init];
+ [marray replaceObjectAtIndex:1 withObject:0]; // expected-warning {{Argument to 'NSMutableArray' method 'replaceObjectAtIndex:withObject:' cannot be nil}}
+}
+
+void testNilArgNSMutableArray4() {
+ NSMutableArray *marray = [[NSMutableArray alloc] init];
+ [marray setObject:0 atIndexedSubscript:1]; // expected-warning {{Argument to 'NSMutableArray' method 'setObject:atIndexedSubscript:' cannot be nil}}
+}
+
+void testNilArgNSMutableArray5() {
+ NSMutableArray *marray = [[NSMutableArray alloc] init];
+ marray[1] = 0; // expected-warning {{Array element cannot be nil}}
+}
+
+// NSArray API
+void testNilArgNSArray1() {
+ NSArray *array = [[NSArray alloc] init];
+ NSArray *copyArray = [array arrayByAddingObject:0]; // expected-warning {{Argument to 'NSArray' method 'arrayByAddingObject:' cannot be nil}}
+}
+
+// NSMutableDictionary and NSDictionary APIs.
+void testNilArgNSMutableDictionary1(NSMutableDictionary *d, NSString* key) {
+ [d setObject:0 forKey:key]; // expected-warning {{Value argument to 'setObject:forKey:' cannot be nil}}
+}
+
+void testNilArgNSMutableDictionary2(NSMutableDictionary *d, NSObject *obj) {
+ [d setObject:obj forKey:0]; // expected-warning {{Key argument to 'setObject:forKey:' cannot be nil}}
+}
+
+void testNilArgNSMutableDictionary3(NSMutableDictionary *d) {
+ [d removeObjectForKey:0]; // expected-warning {{Value argument to 'removeObjectForKey:' cannot be nil}}
+}
+
+void testNilArgNSMutableDictionary5(NSMutableDictionary *d, NSString* key) {
+ d[key] = 0; // expected-warning {{Value stored into 'NSMutableDictionary' cannot be nil}}
+}
+void testNilArgNSMutableDictionary6(NSMutableDictionary *d, NSString *key) {
+ if (key)
+ ;
+ d[key] = 0; // expected-warning {{'NSMutableDictionary' key cannot be nil}}
+ // expected-warning@-1 {{Value stored into 'NSMutableDictionary' cannot be nil}}
+}
+
+NSDictionary *testNilArgNSDictionary1(NSString* key) {
+ return [NSDictionary dictionaryWithObject:0 forKey:key]; // expected-warning {{Value argument to 'dictionaryWithObject:forKey:' cannot be nil}}
+}
+NSDictionary *testNilArgNSDictionary2(NSObject *obj) {
+ return [NSDictionary dictionaryWithObject:obj forKey:0]; // expected-warning {{Key argument to 'dictionaryWithObject:forKey:' cannot be nil}}
+}
+
+// Test inline defensive checks suppression.
+void idc(id x) {
+ if (x)
+ ;
+}
+void testIDC(NSMutableDictionary *d, NSString *key) {
+ idc(key);
+ d[key] = @"abc"; // no-warning
+}
+
+@interface Foo {
+@public
+ int x;
+}
+- (int *)getPtr;
+- (int)getInt;
+- (NSMutableDictionary *)getDictPtr;
+@property (retain, readonly, nonatomic) Foo* data;
+- (NSString*) stringForKeyFE: (id<NSCopying>)key;
+@end
+
+void idc2(id x) {
+ if (!x)
+ return;
+}
+Foo *retNil() {
+ return 0;
+}
+
+void testIDC2(Foo *obj) {
+ idc2(obj);
+ *[obj getPtr] = 1; // no-warning
+}
+
+int testIDC3(Foo *obj) {
+ idc2(obj);
+ return 1/[obj getInt];
+}
+
+void testNilReceiverIDC(Foo *obj, NSString *key) {
+ NSMutableDictionary *D = [obj getDictPtr];
+ idc(D);
+ D[key] = @"abc"; // no-warning
+}
+
+void testNilReceiverRetNil2(NSMutableDictionary *D, Foo *FooPtrIn, id value) {
+ NSString* const kKeyIdentifier = @"key";
+ Foo *FooPtr = retNil();
+ NSString *key = [[FooPtr data] stringForKeyFE: kKeyIdentifier];
+ // key is nil because FooPtr is nil. However, FooPtr is set to nil inside an
+ // inlined function, so this error report should be suppressed.
+ [D setObject: value forKey: key]; // no-warning
+}
+
+
diff --git a/test/Analysis/NewDelete+MismatchedDeallocator_intersections.cpp b/test/Analysis/NewDelete+MismatchedDeallocator_intersections.cpp
new file mode 100644
index 0000000000..b606f23ec8
--- /dev/null
+++ b/test/Analysis/NewDelete+MismatchedDeallocator_intersections.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.NewDelete,unix.MismatchedDeallocator -std=c++11 -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.NewDelete,alpha.cplusplus.NewDeleteLeaks,unix.MismatchedDeallocator -DLEAKS -std=c++11 -verify %s
+// expected-no-diagnostics
+
+typedef __typeof(sizeof(int)) size_t;
+void *malloc(size_t);
+void free(void *);
+
+//------------------------------------------------------------------
+// Check that alpha.cplusplus.NewDelete + unix.MismatchedDeallocator
+// does not enable warnings produced by the unix.Malloc checker.
+//------------------------------------------------------------------
+void testMallocFreeNoWarn() {
+ int i;
+ free(&i); // no warn
+
+ int *p1 = (int *)malloc(sizeof(int));
+ free(++p1); // no warn
+
+ int *p2 = (int *)malloc(sizeof(int));
+ free(p2);
+ free(p2); // no warn
+
+ int *p3 = (int *)malloc(sizeof(int)); // no warn
+
+ int *p4 = (int *)malloc(sizeof(int));
+ free(p4);
+ int j = *p4; // no warn
+}
diff --git a/test/Analysis/NewDelete-checker-test.cpp b/test/Analysis/NewDelete-checker-test.cpp
new file mode 100644
index 0000000000..5d134bc36e
--- /dev/null
+++ b/test/Analysis/NewDelete-checker-test.cpp
@@ -0,0 +1,208 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.NewDelete -std=c++11 -fblocks -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.cplusplus.NewDeleteLeaks -DLEAKS -std=c++11 -fblocks -verify %s
+#include "Inputs/system-header-simulator-cxx.h"
+
+typedef __typeof__(sizeof(int)) size_t;
+extern "C" void *malloc(size_t);
+int *global;
+
+//------------------
+// check for leaks
+//------------------
+
+//----- Standard non-placement operators
+void testGlobalOpNew() {
+ void *p = operator new(0);
+}
+#ifdef LEAKS
+// expected-warning@-2{{Potential leak of memory pointed to by 'p'}}
+#endif
+
+void testGlobalOpNewArray() {
+ void *p = operator new[](0);
+}
+#ifdef LEAKS
+// expected-warning@-2{{Potential leak of memory pointed to by 'p'}}
+#endif
+
+void testGlobalNewExpr() {
+ int *p = new int;
+}
+#ifdef LEAKS
+// expected-warning@-2{{Potential leak of memory pointed to by 'p'}}
+#endif
+
+void testGlobalNewExprArray() {
+ int *p = new int[0];
+}
+#ifdef LEAKS
+// expected-warning@-2{{Potential leak of memory pointed to by 'p'}}
+#endif
+
+//----- Standard nothrow placement operators
+void testGlobalNoThrowPlacementOpNewBeforeOverload() {
+ void *p = operator new(0, std::nothrow);
+}
+#ifdef LEAKS
+// expected-warning@-2{{Potential leak of memory pointed to by 'p'}}
+#endif
+
+void testGlobalNoThrowPlacementExprNewBeforeOverload() {
+ int *p = new(std::nothrow) int;
+}
+#ifdef LEAKS
+// expected-warning@-2{{Potential leak of memory pointed to by 'p'}}
+#endif
+
+//----- Standard pointer placement operators
+void testGlobalPointerPlacementNew() {
+ int i;
+
+ void *p1 = operator new(0, &i); // no warn
+
+ void *p2 = operator new[](0, &i); // no warn
+
+ int *p3 = new(&i) int; // no warn
+
+ int *p4 = new(&i) int[0]; // no warn
+}
+
+//----- Other cases
+void testNewMemoryIsInHeap() {
+ int *p = new int;
+ if (global != p) // condition is always true as 'p' wraps a heap region that
+ // is different from a region wrapped by 'global'
+ global = p; // pointer escapes
+}
+
+struct PtrWrapper {
+ int *x;
+
+ PtrWrapper(int *input) : x(input) {}
+};
+
+void testNewInvalidationPlacement(PtrWrapper *w) {
+ // Ensure that we don't consider this a leak.
+ new (w) PtrWrapper(new int); // no warn
+}
+
+//---------------
+// other checks
+//---------------
+
+class SomeClass {
+public:
+ void f(int *p);
+};
+
+void f(int *p1, int *p2 = 0, int *p3 = 0);
+void g(SomeClass &c, ...);
+
+void testUseFirstArgAfterDelete() {
+ int *p = new int;
+ delete p;
+ f(p); // expected-warning{{Use of memory after it is freed}}
+}
+
+void testUseMiddleArgAfterDelete(int *p) {
+ delete p;
+ f(0, p); // expected-warning{{Use of memory after it is freed}}
+}
+
+void testUseLastArgAfterDelete(int *p) {
+ delete p;
+ f(0, 0, p); // expected-warning{{Use of memory after it is freed}}
+}
+
+void testUseSeveralArgsAfterDelete(int *p) {
+ delete p;
+ f(p, p, p); // expected-warning{{Use of memory after it is freed}}
+}
+
+void testUseRefArgAfterDelete(SomeClass &c) {
+ delete &c;
+ g(c); // expected-warning{{Use of memory after it is freed}}
+}
+
+void testVariadicArgAfterDelete() {
+ SomeClass c;
+ int *p = new int;
+ delete p;
+ g(c, 0, p); // expected-warning{{Use of memory after it is freed}}
+}
+
+void testUseMethodArgAfterDelete(int *p) {
+ SomeClass *c = new SomeClass;
+ delete p;
+ c->f(p); // expected-warning{{Use of memory after it is freed}}
+}
+
+void testUseThisAfterDelete() {
+ SomeClass *c = new SomeClass;
+ delete c;
+ c->f(0); // expected-warning{{Use of memory after it is freed}}
+}
+
+void testDeleteAlloca() {
+ int *p = (int *)__builtin_alloca(sizeof(int));
+ delete p; // expected-warning{{Memory allocated by alloca() should not be deallocated}}
+}
+
+void testDoubleDelete() {
+ int *p = new int;
+ delete p;
+ delete p; // expected-warning{{Attempt to free released memory}}
+}
+
+void testExprDeleteArg() {
+ int i;
+ delete &i; // expected-warning{{Argument to 'delete' is the address of the local variable 'i', which is not memory allocated by 'new'}}
+}
+
+void testExprDeleteArrArg() {
+ int i;
+ delete[] &i; // expected-warning{{Argument to 'delete[]' is the address of the local variable 'i', which is not memory allocated by 'new[]'}}
+}
+
+void testAllocDeallocNames() {
+ int *p = new(std::nothrow) int[1];
+ delete[] (++p); // expected-warning{{Argument to 'delete[]' is offset by 4 bytes from the start of memory allocated by 'new[]'}}
+}
+
+//--------------------------------
+// Test escape of newed const pointer. Note, a const pointer can be deleted.
+//--------------------------------
+struct StWithConstPtr {
+ const int *memp;
+};
+void escape(const int &x);
+void escapeStruct(const StWithConstPtr &x);
+void escapePtr(const StWithConstPtr *x);
+void escapeVoidPtr(const void *x);
+
+void testConstEscape() {
+ int *p = new int(1);
+ escape(*p);
+} // no-warning
+
+void testConstEscapeStruct() {
+ StWithConstPtr *St = new StWithConstPtr();
+ escapeStruct(*St);
+} // no-warning
+
+void testConstEscapeStructPtr() {
+ StWithConstPtr *St = new StWithConstPtr();
+ escapePtr(St);
+} // no-warning
+
+void testConstEscapeMember() {
+ StWithConstPtr St;
+ St.memp = new int(2);
+ escapeVoidPtr(St.memp);
+} // no-warning
+
+void testConstEscapePlacementNew() {
+ int *x = (int *)malloc(sizeof(int));
+ void *y = new (x) int;
+ escapeVoidPtr(y);
+} // no-warning
diff --git a/test/Analysis/NewDelete-custom.cpp b/test/Analysis/NewDelete-custom.cpp
new file mode 100644
index 0000000000..c64bfce2de
--- /dev/null
+++ b/test/Analysis/NewDelete-custom.cpp
@@ -0,0 +1,80 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.NewDelete,unix.Malloc -std=c++11 -fblocks -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.NewDelete,alpha.cplusplus.NewDeleteLeaks,unix.Malloc -std=c++11 -DLEAKS -fblocks -verify %s
+#include "Inputs/system-header-simulator-cxx.h"
+
+#ifndef LEAKS
+// expected-no-diagnostics
+#endif
+
+
+void *allocator(std::size_t size);
+
+void *operator new[](std::size_t size) throw() { return allocator(size); }
+void *operator new(std::size_t size) throw() { return allocator(size); }
+void *operator new(std::size_t size, std::nothrow_t& nothrow) throw() { return allocator(size); }
+void *operator new(std::size_t, double d);
+
+class C {
+public:
+ void *operator new(std::size_t);
+};
+
+void testNewMethod() {
+ void *p1 = C::operator new(0); // no warn
+
+ C *p2 = new C; // no warn
+
+ C *c3 = ::new C;
+}
+#ifdef LEAKS
+// expected-warning@-2{{Potential leak of memory pointed to by 'c3'}}
+#endif
+
+void testOpNewArray() {
+ void *p = operator new[](0); // call is inlined, no warn
+}
+
+void testNewExprArray() {
+ int *p = new int[0];
+}
+#ifdef LEAKS
+// expected-warning@-2{{Potential leak of memory pointed to by 'p'}}
+#endif
+
+
+//----- Custom non-placement operators
+void testOpNew() {
+ void *p = operator new(0); // call is inlined, no warn
+}
+
+void testNewExpr() {
+ int *p = new int;
+}
+#ifdef LEAKS
+// expected-warning@-2{{Potential leak of memory pointed to by 'p'}}
+#endif
+
+
+//----- Custom NoThrow placement operators
+void testOpNewNoThrow() {
+ void *p = operator new(0, std::nothrow);
+}
+#ifdef LEAKS
+// expected-warning@-2{{Potential leak of memory pointed to by 'p'}}
+#endif
+
+void testNewExprNoThrow() {
+ int *p = new(std::nothrow) int;
+}
+#ifdef LEAKS
+// expected-warning@-2{{Potential leak of memory pointed to by 'p'}}
+#endif
+
+//----- Custom placement operators
+void testOpNewPlacement() {
+ void *p = operator new(0, 0.1); // no warn
+}
+
+void testNewExprPlacement() {
+ int *p = new(0.1) int; // no warn
+}
diff --git a/test/Analysis/NewDelete-intersections.mm b/test/Analysis/NewDelete-intersections.mm
new file mode 100644
index 0000000000..9024ed5766
--- /dev/null
+++ b/test/Analysis/NewDelete-intersections.mm
@@ -0,0 +1,74 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.NewDelete -std=c++11 -fblocks -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.NewDelete,alpha.cplusplus.NewDeleteLeaks -std=c++11 -DLEAKS -fblocks -verify %s
+#include "Inputs/system-header-simulator-cxx.h"
+#include "Inputs/system-header-simulator-objc.h"
+
+typedef __typeof__(sizeof(int)) size_t;
+extern "C" void *malloc(size_t);
+extern "C" void free(void *);
+
+//----------------------------------------------------------------------------
+// Check for intersections with unix.Malloc and unix.MallocWithAnnotations
+// checkers bounded with cplusplus.NewDelete.
+//----------------------------------------------------------------------------
+
+//----- malloc()/free() are subjects of unix.Malloc and unix.MallocWithAnnotations
+void testMallocFreeNoWarn() {
+ int i;
+ free(&i); // no warn
+
+ int *p1 = (int *)malloc(sizeof(int));
+ free(++p1); // no warn
+
+ int *p2 = (int *)malloc(sizeof(int));
+ free(p2);
+ free(p2); // no warn
+
+ int *p3 = (int *)malloc(sizeof(int)); // no warn
+
+ int *p4 = (int *)malloc(sizeof(int));
+ free(p4);
+ int j = *p4; // no warn
+}
+
+void testDeleteMalloced() {
+ int *p = (int *)malloc(sizeof(int));
+ delete p; // no warn
+}
+
+//----- Test free standard new
+void testFreeOpNew() {
+ void *p = operator new(0);
+ free(p);
+}
+#ifdef LEAKS
+// expected-warning@-2 {{Potential leak of memory pointed to by 'p'}}
+#endif
+
+void testFreeNewExpr() {
+ int *p = new int;
+ free(p);
+}
+#ifdef LEAKS
+// expected-warning@-2 {{Potential leak of memory pointed to by 'p'}}
+#endif
+
+void testObjcFreeNewed() {
+ int *p = new int;
+ NSData *nsdata = [NSData dataWithBytesNoCopy:p length:sizeof(int) freeWhenDone:1];
+#ifdef LEAKS
+ // expected-warning@-2 {{Potential leak of memory pointed to by 'p'}}
+#endif
+}
+
+void testFreeAfterDelete() {
+ int *p = new int;
+ delete p;
+ free(p); // expected-warning{{Use of memory after it is freed}}
+}
+
+void testStandardPlacementNewAfterDelete() {
+ int *p = new int;
+ delete p;
+ p = new(p) int; // expected-warning{{Use of memory after it is freed}}
+}
diff --git a/test/Analysis/NewDelete-path-notes.cpp b/test/Analysis/NewDelete-path-notes.cpp
new file mode 100644
index 0000000000..85b71be68c
--- /dev/null
+++ b/test/Analysis/NewDelete-path-notes.cpp
@@ -0,0 +1,551 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=cplusplus.NewDelete,unix.Malloc -analyzer-output=text -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=cplusplus.NewDelete,unix.Malloc -analyzer-output=plist %s -o %t.plist
+// RUN: FileCheck --input-file=%t.plist %s
+
+void test() {
+ int *p = new int;
+ // expected-note@-1 {{Memory is allocated}}
+ if (p)
+ // expected-note@-1 {{Assuming 'p' is non-null}}
+ // expected-note@-2 {{Taking true branch}}
+ delete p;
+ // expected-note@-1 {{Memory is released}}
+
+ delete p; // expected-warning {{Attempt to free released memory}}
+ // expected-note@-1 {{Attempt to free released memory}}
+}
+
+struct Odd {
+ void kill() {
+ delete this; // expected-note {{Memory is released}}
+ }
+};
+
+void test(Odd *odd) {
+ odd->kill(); // expected-note{{Calling 'Odd::kill'}}
+ // expected-note@-1 {{Returning; memory was released}}
+ delete odd; // expected-warning {{Attempt to free released memory}}
+ // expected-note@-1 {{Attempt to free released memory}}
+}
+
+// CHECK: <key>diagnostics</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>path</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>6</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>6</integer>
+// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>6</integer>
+// CHECK-NEXT: <key>col</key><integer>12</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>6</integer>
+// CHECK-NEXT: <key>col</key><integer>14</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>6</integer>
+// CHECK-NEXT: <key>col</key><integer>12</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>6</integer>
+// CHECK-NEXT: <key>col</key><integer>12</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>6</integer>
+// CHECK-NEXT: <key>col</key><integer>18</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Memory is allocated</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Memory is allocated</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>6</integer>
+// CHECK-NEXT: <key>col</key><integer>12</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>6</integer>
+// CHECK-NEXT: <key>col</key><integer>14</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>8</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>8</integer>
+// CHECK-NEXT: <key>col</key><integer>4</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>8</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>8</integer>
+// CHECK-NEXT: <key>col</key><integer>4</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>8</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>8</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>8</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>8</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>8</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Assuming &apos;p&apos; is non-null</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Assuming &apos;p&apos; is non-null</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>8</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>8</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>11</integer>
+// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>11</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>11</integer>
+// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>11</integer>
+// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>11</integer>
+// CHECK-NEXT: <key>col</key><integer>12</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Memory is released</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Memory is released</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>11</integer>
+// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>11</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>14</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>14</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>14</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>14</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>14</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Attempt to free released memory</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Attempt to free released memory</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>description</key><string>Attempt to free released memory</string>
+// CHECK-NEXT: <key>category</key><string>Memory Error</string>
+// CHECK-NEXT: <key>type</key><string>Double free</string>
+// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT: <key>issue_context</key><string>test</string>
+// CHECK-NEXT: <key>issue_hash</key><string>9</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>14</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>path</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>25</integer>
+// CHECK-NEXT: <key>col</key><integer>2</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>25</integer>
+// CHECK-NEXT: <key>col</key><integer>2</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>25</integer>
+// CHECK-NEXT: <key>col</key><integer>12</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Calling &apos;Odd::kill&apos;</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Calling &apos;Odd::kill&apos;</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>19</integer>
+// CHECK-NEXT: <key>col</key><integer>2</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>depth</key><integer>1</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Entered call from &apos;test&apos;</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Entered call from &apos;test&apos;</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>19</integer>
+// CHECK-NEXT: <key>col</key><integer>2</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>19</integer>
+// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>20</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>20</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>20</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>20</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>20</integer>
+// CHECK-NEXT: <key>col</key><integer>13</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>1</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Memory is released</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Memory is released</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>25</integer>
+// CHECK-NEXT: <key>col</key><integer>2</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>25</integer>
+// CHECK-NEXT: <key>col</key><integer>2</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>25</integer>
+// CHECK-NEXT: <key>col</key><integer>12</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Returning; memory was released</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Returning; memory was released</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>25</integer>
+// CHECK-NEXT: <key>col</key><integer>2</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>25</integer>
+// CHECK-NEXT: <key>col</key><integer>4</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>27</integer>
+// CHECK-NEXT: <key>col</key><integer>2</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>27</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>27</integer>
+// CHECK-NEXT: <key>col</key><integer>2</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>27</integer>
+// CHECK-NEXT: <key>col</key><integer>2</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>27</integer>
+// CHECK-NEXT: <key>col</key><integer>11</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Attempt to free released memory</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Attempt to free released memory</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>description</key><string>Attempt to free released memory</string>
+// CHECK-NEXT: <key>category</key><string>Memory Error</string>
+// CHECK-NEXT: <key>type</key><string>Double free</string>
+// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT: <key>issue_context</key><string>test</string>
+// CHECK-NEXT: <key>issue_hash</key><string>3</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>27</integer>
+// CHECK-NEXT: <key>col</key><integer>2</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
diff --git a/test/Analysis/NewDelete-variadic.cpp b/test/Analysis/NewDelete-variadic.cpp
new file mode 100644
index 0000000000..53dba463bb
--- /dev/null
+++ b/test/Analysis/NewDelete-variadic.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.NewDelete,alpha.cplusplus.NewDeleteLeaks,unix.Malloc -std=c++11 -fblocks -verify %s
+// expected-no-diagnostics
+
+namespace std {
+ typedef __typeof__(sizeof(int)) size_t;
+}
+
+void *operator new(std::size_t, ...);
+void *operator new[](std::size_t, ...);
+
+void testGlobalCustomVariadicNew() {
+ void *p1 = operator new(0); // no warn
+
+ void *p2 = operator new[](0); // no warn
+
+ int *p3 = new int; // no warn
+
+ int *p4 = new int[0]; // no warn
+}
diff --git a/test/Analysis/PR3991.m b/test/Analysis/PR3991.m
index 4d76fd347e..5f0919d6f0 100644
--- a/test/Analysis/PR3991.m
+++ b/test/Analysis/PR3991.m
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -analyzer-constraints=range -verify -triple x86_64-apple-darwin9 %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -analyzer-constraints=range -verify -triple x86_64-apple-darwin9 -Wno-incomplete-implementation %s
+// expected-no-diagnostics
//===----------------------------------------------------------------------===//
// Delta-debugging produced forward declarations.
@@ -32,16 +33,16 @@ typedef struct _NSZone NSZone;
@protocol IHGoogleDocsAdapterDelegate - (void)googleDocsAdapter:(IHGoogleDocsAdapter*)inGoogleDocsAdapter accountVerifyIsValid:(BOOL)inIsValid error:(NSError *)inError;
@end @interface IHGoogleDocsAdapter : NSObject {
}
-- (NSArray *)entries; // expected-note {{method definition for 'entries' not found}}
+- (NSArray *)entries;
@end extern Class const kGDataUseRegisteredClass ;
-@interface IHGoogleDocsAdapter () - (GDataFeedDocList *)feedDocList; // expected-note {{method definition for 'feedDocList' not found}}
-- (NSArray *)directoryPathComponents; // expected-note {{method definition for 'directoryPathComponents' not found}}
-- (unsigned int)currentPathComponentIndex; // expected-note {{method definition for 'currentPathComponentIndex' not found}}
-- (void)setCurrentPathComponentIndex:(unsigned int)aCurrentPathComponentIndex; // expected-note {{method definition for 'setCurrentPathComponentIndex:' not found}}
-- (NSURL *)folderFeedURL; // expected-note {{method definition for 'folderFeedURL' not found}}
+@interface IHGoogleDocsAdapter () - (GDataFeedDocList *)feedDocList;
+- (NSArray *)directoryPathComponents;
+- (unsigned int)currentPathComponentIndex;
+- (void)setCurrentPathComponentIndex:(unsigned int)aCurrentPathComponentIndex;
+- (NSURL *)folderFeedURL;
@end
-@implementation IHGoogleDocsAdapter - (id)initWithUsername:(NSString *)inUsername password:(NSString *)inPassword owner:(NSObject <IHGoogleDocsAdapterDelegate> *)owner { // expected-warning {{incomplete implementation}}
+@implementation IHGoogleDocsAdapter - (id)initWithUsername:(NSString *)inUsername password:(NSString *)inPassword owner:(NSObject <IHGoogleDocsAdapterDelegate> *)owner {
return 0;
}
diff --git a/test/Analysis/additive-folding-range-constraints.c b/test/Analysis/additive-folding-range-constraints.c
index 7eb55ab1e1..b22eb2a5b3 100644
--- a/test/Analysis/additive-folding-range-constraints.c
+++ b/test/Analysis/additive-folding-range-constraints.c
@@ -170,3 +170,135 @@ void mixedComparisons9(signed char a) {
clang_analyzer_eval(a == 0x7F); // expected-warning{{UNKNOWN}}
clang_analyzer_eval(a == -0x80); // expected-warning{{UNKNOWN}}
}
+
+
+void mixedSignedness1(int a) {
+ unsigned max = UINT_MAX;
+ clang_analyzer_eval(a < max); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval((a + 2) < max); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval((a + 2U) < max); // expected-warning{{UNKNOWN}}
+}
+
+void mixedSignedness2(int a) {
+ unsigned max = UINT_MAX;
+ clang_analyzer_eval(a <= max); // expected-warning{{TRUE}}
+ clang_analyzer_eval((a + 2) <= max); // expected-warning{{TRUE}}
+ clang_analyzer_eval((a + 2U) <= max); // expected-warning{{TRUE}}
+}
+
+void mixedSignedness3(unsigned a) {
+ int max = INT_MAX;
+ clang_analyzer_eval(a < max); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval((a + 2) < max); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval((a + 2U) < max); // expected-warning{{UNKNOWN}}
+}
+
+void mixedSignedness4(unsigned a) {
+ int max = INT_MAX;
+ clang_analyzer_eval(a <= max); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval((a + 2) <= max); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval((a + 2U) <= max); // expected-warning{{UNKNOWN}}
+}
+
+void mixedSignedness5(unsigned a) {
+ int min = INT_MIN;
+ clang_analyzer_eval(a < min); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval((a + 2) < min); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval((a + 2U) < min); // expected-warning{{UNKNOWN}}
+}
+
+void mixedSignedness6(unsigned a) {
+ int min = INT_MIN;
+ clang_analyzer_eval(a <= min); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval((a + 2) <= min); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval((a + 2U) <= min); // expected-warning{{UNKNOWN}}
+}
+
+void mixedSignedness7(unsigned a) {
+ unsigned min = 0;
+ clang_analyzer_eval(a < min); // expected-warning{{FALSE}}
+ clang_analyzer_eval((a + 2) < min); // expected-warning{{FALSE}}
+ clang_analyzer_eval((a + 2U) < min); // expected-warning{{FALSE}}
+}
+
+void mixedSignedness8(unsigned a) {
+ unsigned min = 0;
+ clang_analyzer_eval(a <= min); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval((a + 2) <= min); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval((a + 2U) <= min); // expected-warning{{UNKNOWN}}
+}
+
+void mixedSignedness9(unsigned a) {
+ int min = 0;
+ clang_analyzer_eval(a < min); // expected-warning{{FALSE}}
+ clang_analyzer_eval((a + 2) < min); // expected-warning{{FALSE}}
+ clang_analyzer_eval((a + 2U) < min); // expected-warning{{FALSE}}
+}
+
+void mixedSignedness10(unsigned a) {
+ int min = 0;
+ clang_analyzer_eval(a <= min); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval((a + 2) <= min); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval((a + 2U) <= min); // expected-warning{{UNKNOWN}}
+}
+
+void mixedSignedness11(int a) {
+ int min = 0;
+ clang_analyzer_eval(a < min); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval((a + 2) < min); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval((a + 2U) < min); // expected-warning{{FALSE}}
+}
+
+void mixedSignedness12(int a) {
+ int min = 0;
+ clang_analyzer_eval(a <= min); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval((a + 2) <= min); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval((a + 2U) <= min); // expected-warning{{UNKNOWN}}
+}
+
+void mixedSignedness13(int a) {
+ unsigned max = INT_MAX;
+ clang_analyzer_eval(a < max); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval((a + 2) < max); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval((a + 2U) < max); // expected-warning{{UNKNOWN}}
+}
+
+void mixedSignedness14(int a) {
+ unsigned max = INT_MAX;
+ clang_analyzer_eval(a <= max); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval((a + 2) <= max); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval((a + 2U) <= max); // expected-warning{{UNKNOWN}}
+}
+
+void mixedSignedness15(int a) {
+ unsigned min = INT_MIN;
+ clang_analyzer_eval(a < min); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval((a + 2) < min); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval((a + 2U) < min); // expected-warning{{UNKNOWN}}
+}
+
+void mixedSignedness16(int a) {
+ unsigned min = INT_MIN;
+ clang_analyzer_eval(a <= min); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval((a + 2) <= min); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval((a + 2U) <= min); // expected-warning{{UNKNOWN}}
+}
+
+void mixedSignedness17(int a) {
+ unsigned max = INT_MAX;
+ if (a < max)
+ return;
+
+ clang_analyzer_eval(a < 0); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(a == 0); // expected-warning{{FALSE}}
+ clang_analyzer_eval(a == INT_MAX); // expected-warning{{UNKNOWN}}
+}
+
+void mixedSignedness18(int a) {
+ if (a >= 0)
+ return;
+
+ clang_analyzer_eval(a < 0); // expected-warning{{TRUE}}
+ clang_analyzer_eval(a == (unsigned)INT_MIN); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(a == UINT_MAX); // expected-warning{{UNKNOWN}}
+}
diff --git a/test/Analysis/additive-folding.cpp b/test/Analysis/additive-folding.cpp
index 33f3b9b251..c2e502623e 100644
--- a/test/Analysis/additive-folding.cpp
+++ b/test/Analysis/additive-folding.cpp
@@ -184,6 +184,18 @@ void mixedSignedness(int a, unsigned b) {
clang_analyzer_eval(b == uMin && b != sMin); // expected-warning{{FALSE}}
}
+void mixedSignedness2(int a) {
+ if (a != -1)
+ return;
+ clang_analyzer_eval(a == UINT_MAX); // expected-warning{{TRUE}}
+}
+
+void mixedSignedness3(unsigned a) {
+ if (a != UINT_MAX)
+ return;
+ clang_analyzer_eval(a == -1); // expected-warning{{TRUE}}
+}
+
void multiplicativeSanityTest(int x) {
// At one point we were ignoring the *4 completely -- the constraint manager
diff --git a/test/Analysis/analyzer-config.c b/test/Analysis/analyzer-config.c
index 7fa299b786..55b1df9ca8 100644
--- a/test/Analysis/analyzer-config.c
+++ b/test/Analysis/analyzer-config.c
@@ -1,18 +1,22 @@
-// RUN: %clang --analyze %s -o /dev/null -Xclang -analyzer-checker=debug.ConfigDumper > %t 2>&1
+// RUN: %clang -target x86_64-apple-darwin10 --analyze %s -o /dev/null -Xclang -analyzer-checker=debug.ConfigDumper > %t 2>&1
// RUN: FileCheck --input-file=%t %s
void bar() {}
void foo() { bar(); }
// CHECK: [config]
+// CHECK-NEXT: cfg-conditional-static-initializers = true
// CHECK-NEXT: cfg-temporary-dtors = false
// CHECK-NEXT: faux-bodies = true
// CHECK-NEXT: graph-trim-interval = 1000
// CHECK-NEXT: ipa = dynamic-bifurcate
// CHECK-NEXT: ipa-always-inline-size = 3
+// CHECK-NEXT: leak-diagnostics-reference-allocation = false
// CHECK-NEXT: max-inlinable-size = 50
// CHECK-NEXT: max-nodes = 150000
// CHECK-NEXT: max-times-inline-large = 32
// CHECK-NEXT: mode = deep
+// CHECK-NEXT: region-store-small-struct-limit = 2
// CHECK-NEXT: [stats]
-// CHECK-NEXT: num-entries = 9
+// CHECK-NEXT: num-entries = 12
+
diff --git a/test/Analysis/analyzer-config.cpp b/test/Analysis/analyzer-config.cpp
index 59587f6e11..bf18a5eb3e 100644
--- a/test/Analysis/analyzer-config.cpp
+++ b/test/Analysis/analyzer-config.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang --analyze %s -o /dev/null -Xclang -analyzer-checker=debug.ConfigDumper > %t 2>&1
+// RUN: %clang -target x86_64-apple-darwin10 --analyze %s -o /dev/null -Xclang -analyzer-checker=debug.ConfigDumper > %t 2>&1
// RUN: FileCheck --input-file=%t %s
void bar() {}
@@ -11,17 +11,21 @@ public:
};
// CHECK: [config]
-// CHECK-NEXT: c++-inlining = constructors
+// CHECK-NEXT: c++-container-inlining = false
+// CHECK-NEXT: c++-inlining = destructors
// CHECK-NEXT: c++-stdlib-inlining = true
// CHECK-NEXT: c++-template-inlining = true
+// CHECK-NEXT: cfg-conditional-static-initializers = true
// CHECK-NEXT: cfg-temporary-dtors = false
// CHECK-NEXT: faux-bodies = true
// CHECK-NEXT: graph-trim-interval = 1000
// CHECK-NEXT: ipa = dynamic-bifurcate
// CHECK-NEXT: ipa-always-inline-size = 3
+// CHECK-NEXT: leak-diagnostics-reference-allocation = false
// CHECK-NEXT: max-inlinable-size = 50
// CHECK-NEXT: max-nodes = 150000
// CHECK-NEXT: max-times-inline-large = 32
// CHECK-NEXT: mode = deep
+// CHECK-NEXT: region-store-small-struct-limit = 2
// CHECK-NEXT: [stats]
-// CHECK-NEXT: num-entries = 12
+// CHECK-NEXT: num-entries = 16
diff --git a/test/Analysis/analyzer-stats.c b/test/Analysis/analyzer-stats.c
index 9eeaade793..63073b7e40 100644
--- a/test/Analysis/analyzer-stats.c
+++ b/test/Analysis/analyzer-stats.c
@@ -2,7 +2,7 @@
int foo();
-int test() { // expected-warning{{Total CFGBlocks}}
+int test() { // expected-warning-re{{test -> Total CFGBlocks: [0-9]+ \| Unreachable CFGBlocks: 0 \| Exhausted Block: no \| Empty WorkList: yes}}
int a = 1;
a = 34 / 12;
diff --git a/test/Analysis/bool-assignment.cpp b/test/Analysis/bool-assignment.c
index 9361d93aab..0f782fbfd9 100644
--- a/test/Analysis/bool-assignment.cpp
+++ b/test/Analysis/bool-assignment.c
@@ -1,27 +1,32 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core.BoolAssignment -analyzer-store=region -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core.BoolAssignment -analyzer-store=region -verify -std=c99 -Dbool=_Bool %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core.BoolAssignment -analyzer-store=region -verify -x c++ %s
-// Test C++'s bool
+// Test C++'s bool and C's _Bool.
+// FIXME: We stopped warning on these when SValBuilder got smarter about
+// casts to bool. Arguably, however, these conversions are okay; the result
+// is always 'true' or 'false'.
-void test_cppbool_initialization(int y) {
+void test_stdbool_initialization(int y) {
+ bool constant = 2; // no-warning
if (y < 0) {
- bool x = y; // expected-warning {{Assignment of a non-Boolean value}}
+ bool x = y; // no-warning
return;
}
if (y > 1) {
- bool x = y; // expected-warning {{Assignment of a non-Boolean value}}
+ bool x = y; // no-warning
return;
}
bool x = y; // no-warning
}
-void test_cppbool_assignment(int y) {
+void test_stdbool_assignment(int y) {
bool x = 0; // no-warning
if (y < 0) {
- x = y; // expected-warning {{Assignment of a non-Boolean value}}
+ x = y; // no-warning
return;
}
if (y > 1) {
- x = y; // expected-warning {{Assignment of a non-Boolean value}}
+ x = y; // no-warning
return;
}
x = y; // no-warning
@@ -32,6 +37,7 @@ void test_cppbool_assignment(int y) {
typedef signed char BOOL;
void test_BOOL_initialization(int y) {
+ BOOL constant = 2; // expected-warning {{Assignment of a non-Boolean value}}
if (y < 0) {
BOOL x = y; // expected-warning {{Assignment of a non-Boolean value}}
return;
@@ -62,6 +68,7 @@ void test_BOOL_assignment(int y) {
typedef unsigned char Boolean;
void test_Boolean_initialization(int y) {
+ Boolean constant = 2; // expected-warning {{Assignment of a non-Boolean value}}
if (y < 0) {
Boolean x = y; // expected-warning {{Assignment of a non-Boolean value}}
return;
diff --git a/test/Analysis/bool-assignment2.c b/test/Analysis/bool-assignment2.c
deleted file mode 100644
index 22f4237adf..0000000000
--- a/test/Analysis/bool-assignment2.c
+++ /dev/null
@@ -1,35 +0,0 @@
-// RUN: %clang_cc1 -std=c99 -analyze -analyzer-checker=core,alpha.core.BoolAssignment -analyzer-store=region -verify %s
-
-// Test stdbool.h's _Bool
-
-// Prior to C99, stdbool.h uses this typedef, but even in ANSI C mode, _Bool
-// appears to be defined.
-
-// #if __STDC_VERSION__ < 199901L
-// typedef int _Bool;
-// #endif
-
-void test_stdbool_initialization(int y) {
- if (y < 0) {
- _Bool x = y; // expected-warning {{Assignment of a non-Boolean value}}
- return;
- }
- if (y > 1) {
- _Bool x = y; // expected-warning {{Assignment of a non-Boolean value}}
- return;
- }
- _Bool x = y; // no-warning
-}
-
-void test_stdbool_assignment(int y) {
- _Bool x = 0; // no-warning
- if (y < 0) {
- x = y; // expected-warning {{Assignment of a non-Boolean value}}
- return;
- }
- if (y > 1) {
- x = y; // expected-warning {{Assignment of a non-Boolean value}}
- return;
- }
- x = y; // no-warning
-}
diff --git a/test/Analysis/call-invalidation.cpp b/test/Analysis/call-invalidation.cpp
new file mode 100644
index 0000000000..54281cc98a
--- /dev/null
+++ b/test/Analysis/call-invalidation.cpp
@@ -0,0 +1,91 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s
+
+void clang_analyzer_eval(bool);
+
+void usePointer(int * const *);
+void useReference(int * const &);
+
+void testPointer() {
+ int x;
+ int *p;
+
+ p = &x;
+ x = 42;
+ clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
+ usePointer(&p);
+ clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}}
+
+ p = &x;
+ x = 42;
+ clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
+ useReference(p);
+ clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}}
+
+ int * const cp1 = &x;
+ x = 42;
+ clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
+ usePointer(&cp1);
+ clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}}
+
+ int * const cp2 = &x;
+ x = 42;
+ clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
+ useReference(cp2);
+ clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}}
+}
+
+
+struct Wrapper {
+ int *ptr;
+};
+
+void useStruct(Wrapper &w);
+void useConstStruct(const Wrapper &w);
+
+void testPointerStruct() {
+ int x;
+ Wrapper w;
+
+ w.ptr = &x;
+ x = 42;
+ clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
+ useStruct(w);
+ clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}}
+
+ w.ptr = &x;
+ x = 42;
+ clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
+ useConstStruct(w);
+ clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}}
+}
+
+
+struct RefWrapper {
+ int &ref;
+};
+
+void useStruct(RefWrapper &w);
+void useConstStruct(const RefWrapper &w);
+
+void testReferenceStruct() {
+ int x;
+ RefWrapper w = { x };
+
+ x = 42;
+ clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
+ useStruct(w);
+ clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}}
+}
+
+// FIXME: This test is split into two functions because region invalidation
+// does not preserve reference bindings. <rdar://problem/13320347>
+void testConstReferenceStruct() {
+ int x;
+ RefWrapper w = { x };
+
+ x = 42;
+ clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
+ useConstStruct(w);
+ clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}}
+}
+
diff --git a/test/Analysis/casts.c b/test/Analysis/casts.c
index 087bd978e1..3e2f8077ed 100644
--- a/test/Analysis/casts.c
+++ b/test/Analysis/casts.c
@@ -1,6 +1,7 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -verify %s
-// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -verify %s
-// expected-no-diagnostics
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -verify %s
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -verify %s
+
+extern void clang_analyzer_eval(_Bool);
// Test if the 'storage' region gets properly initialized after it is cast to
// 'struct sockaddr *'.
@@ -85,3 +86,34 @@ int foo (int* p) {
}
return 0;
}
+
+void castsToBool() {
+ clang_analyzer_eval(0); // expected-warning{{FALSE}}
+ clang_analyzer_eval(0U); // expected-warning{{FALSE}}
+ clang_analyzer_eval((void *)0); // expected-warning{{FALSE}}
+
+ clang_analyzer_eval(1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(1U); // expected-warning{{TRUE}}
+ clang_analyzer_eval(-1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(0x100); // expected-warning{{TRUE}}
+ clang_analyzer_eval(0x100U); // expected-warning{{TRUE}}
+ clang_analyzer_eval((void *)0x100); // expected-warning{{TRUE}}
+
+ extern int symbolicInt;
+ clang_analyzer_eval(symbolicInt); // expected-warning{{UNKNOWN}}
+ if (symbolicInt)
+ clang_analyzer_eval(symbolicInt); // expected-warning{{TRUE}}
+
+ extern void *symbolicPointer;
+ clang_analyzer_eval(symbolicPointer); // expected-warning{{UNKNOWN}}
+ if (symbolicPointer)
+ clang_analyzer_eval(symbolicPointer); // expected-warning{{TRUE}}
+
+ int localInt;
+ clang_analyzer_eval(&localInt); // expected-warning{{TRUE}}
+ clang_analyzer_eval(&castsToBool); // expected-warning{{TRUE}}
+ clang_analyzer_eval("abc"); // expected-warning{{TRUE}}
+
+ extern float globalFloat;
+ clang_analyzer_eval(globalFloat); // expected-warning{{UNKNOWN}}
+}
diff --git a/test/Analysis/conditional-operator-path-notes.c b/test/Analysis/conditional-operator-path-notes.c
index c781ddf833..a8af394a26 100644
--- a/test/Analysis/conditional-operator-path-notes.c
+++ b/test/Analysis/conditional-operator-path-notes.c
@@ -242,12 +242,12 @@ void testBinaryLHSProblem(int *p) {
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>10</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>10</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
@@ -259,7 +259,7 @@ void testBinaryLHSProblem(int *p) {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>10</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -293,7 +293,7 @@ void testBinaryLHSProblem(int *p) {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>10</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -882,12 +882,12 @@ void testBinaryLHSProblem(int *p) {
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>44</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>44</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
@@ -899,7 +899,7 @@ void testBinaryLHSProblem(int *p) {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>44</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -933,7 +933,7 @@ void testBinaryLHSProblem(int *p) {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>44</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
diff --git a/test/Analysis/conditional-operator.cpp b/test/Analysis/conditional-operator.cpp
new file mode 100644
index 0000000000..5a3c325b91
--- /dev/null
+++ b/test/Analysis/conditional-operator.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang -cc1 -analyze -analyzer-checker=core,debug.ExprInspection %s -analyzer-output=text -verify
+
+void clang_analyzer_eval(bool);
+
+// Test that the analyzer does not crash on GNU extension operator "?:".
+void NoCrashTest(int x, int y) {
+ int w = x ?: y;
+}
+
+void OperatorEvaluationTest(int y) {
+ int x = 1;
+ int w = x ?: y; // expected-note {{'?' condition is true}}
+
+ // TODO: We are not precise when processing the "?:" operator in C++.
+ clang_analyzer_eval(w == 1); // expected-warning{{UNKNOWN}}
+ // expected-note@-1{{UNKNOWN}}
+} \ No newline at end of file
diff --git a/test/Analysis/coverage.c b/test/Analysis/coverage.c
index 38e84e17ce..9e437d2182 100644
--- a/test/Analysis/coverage.c
+++ b/test/Analysis/coverage.c
@@ -33,26 +33,26 @@ static void function_which_doesnt_give_up_nested(int *x, int *y) {
void coverage1(int *x) {
function_which_gives_up(x);
char *m = (char*)malloc(12);
-} // expected-warning {{potential leak}}
+} // expected-warning {{Potential leak of memory pointed to by 'm'}}
void coverage2(int *x) {
if (x) {
function_which_gives_up(x);
char *m = (char*)malloc(12);
}
-} // expected-warning {{potential leak}}
+} // expected-warning {{Potential leak of memory pointed to by 'm'}}
void coverage3(int *x) {
x++;
function_which_gives_up(x);
char *m = (char*)malloc(12);
-} // expected-warning {{potential leak}}
+} // expected-warning {{Potential leak of memory pointed to by 'm'}}
void coverage4(int *x) {
*x += another_function(x);
function_which_gives_up(x);
char *m = (char*)malloc(12);
-} // expected-warning {{potential leak}}
+} // expected-warning {{Potential leak of memory pointed to by 'm'}}
void coverage5(int *x) {
for (int i = 0; i<7; ++i)
@@ -66,7 +66,7 @@ void coverage6(int *x) {
function_which_gives_up(x);
}
char *m = (char*)malloc(12);
-} // expected-warning {{potential leak}}
+} // expected-warning {{Potential leak of memory pointed to by 'm'}}
int coverage7_inline(int *i) {
function_which_doesnt_give_up(&i);
@@ -78,7 +78,7 @@ void coverage8(int *x) {
function_which_doesnt_give_up_nested(x, &y);
y = (*x)/y; // expected-warning {{Division by zero}}
char *m = (char*)malloc(12);
-} // expected-warning {{potential leak}}
+} // expected-warning {{Potential leak of memory pointed to by 'm'}}
void function_which_gives_up_settonull(int **x) {
*x = 0;
diff --git a/test/Analysis/cstring-syntax-cxx.cpp b/test/Analysis/cstring-syntax-cxx.cpp
index bae3d0a164..39c978ab60 100644
--- a/test/Analysis/cstring-syntax-cxx.cpp
+++ b/test/Analysis/cstring-syntax-cxx.cpp
@@ -15,3 +15,8 @@ void test(X a, X b) {
X c = a + b;
}
+// Ensure we don't crash on custom-defined strncat.
+char strncat ();
+int main () {
+ return strncat ();
+} \ No newline at end of file
diff --git a/test/Analysis/ctor-inlining.mm b/test/Analysis/ctor-inlining.mm
index 1603ff3893..8cdb005968 100644
--- a/test/Analysis/ctor-inlining.mm
+++ b/test/Analysis/ctor-inlining.mm
@@ -149,6 +149,19 @@ namespace PODUninitialized {
: x(Other.x), y(Other.y) // expected-warning {{undefined}}
{
}
+
+ NonPOD &operator=(const NonPOD &Other)
+ {
+ x = Other.x;
+ y = Other.y; // expected-warning {{undefined}}
+ return *this;
+ }
+ NonPOD &operator=(NonPOD &&Other)
+ {
+ x = Other.x;
+ y = Other.y; // expected-warning {{undefined}}
+ return *this;
+ }
};
class NonPODWrapper {
@@ -166,6 +179,19 @@ namespace PODUninitialized {
: x(Other.x), y(Other.y) // expected-warning {{undefined}}
{
}
+
+ Inner &operator=(const Inner &Other)
+ {
+ x = Other.x; // expected-warning {{undefined}}
+ y = Other.y;
+ return *this;
+ }
+ Inner &operator=(Inner &&Other)
+ {
+ x = Other.x; // expected-warning {{undefined}}
+ y = Other.y;
+ return *this;
+ }
};
Inner p;
@@ -216,4 +242,261 @@ namespace PODUninitialized {
w.p.y = 1;
NonPODWrapper w2 = move(w);
}
+
+ // Not strictly about constructors, but trivial assignment operators should
+ // essentially work the same way.
+ namespace AssignmentOperator {
+ void testPOD() {
+ POD p;
+ p.x = 1;
+ POD p2;
+ p2 = p; // no-warning
+ clang_analyzer_eval(p2.x == 1); // expected-warning{{TRUE}}
+ POD p3;
+ p3 = move(p); // no-warning
+ clang_analyzer_eval(p3.x == 1); // expected-warning{{TRUE}}
+
+ PODWrapper w;
+ w.p.y = 1;
+ PODWrapper w2;
+ w2 = w; // no-warning
+ clang_analyzer_eval(w2.p.y == 1); // expected-warning{{TRUE}}
+ PODWrapper w3;
+ w3 = move(w); // no-warning
+ clang_analyzer_eval(w3.p.y == 1); // expected-warning{{TRUE}}
+ }
+
+ void testReturnValue() {
+ POD p;
+ p.x = 1;
+ POD p2;
+ clang_analyzer_eval(&(p2 = p) == &p2); // expected-warning{{TRUE}}
+
+ PODWrapper w;
+ w.p.y = 1;
+ PODWrapper w2;
+ clang_analyzer_eval(&(w2 = w) == &w2); // expected-warning{{TRUE}}
+ }
+
+ void testNonPOD() {
+ NonPOD p;
+ p.x = 1;
+ NonPOD p2;
+ p2 = p;
+ }
+
+ void testNonPODMove() {
+ NonPOD p;
+ p.x = 1;
+ NonPOD p2;
+ p2 = move(p);
+ }
+
+ void testNonPODWrapper() {
+ NonPODWrapper w;
+ w.p.y = 1;
+ NonPODWrapper w2;
+ w2 = w;
+ }
+
+ void testNonPODWrapperMove() {
+ NonPODWrapper w;
+ w.p.y = 1;
+ NonPODWrapper w2;
+ w2 = move(w);
+ }
+ }
}
+
+namespace ArrayMembers {
+ struct Primitive {
+ int values[3];
+ };
+
+ void testPrimitive() {
+ Primitive a = { { 1, 2, 3 } };
+
+ clang_analyzer_eval(a.values[0] == 1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(a.values[1] == 2); // expected-warning{{TRUE}}
+ clang_analyzer_eval(a.values[2] == 3); // expected-warning{{TRUE}}
+
+ Primitive b = a;
+
+ clang_analyzer_eval(b.values[0] == 1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(b.values[1] == 2); // expected-warning{{TRUE}}
+ clang_analyzer_eval(b.values[2] == 3); // expected-warning{{TRUE}}
+
+ Primitive c;
+ c = b;
+
+ clang_analyzer_eval(c.values[0] == 1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(c.values[1] == 2); // expected-warning{{TRUE}}
+ clang_analyzer_eval(c.values[2] == 3); // expected-warning{{TRUE}}
+ }
+
+ struct NestedPrimitive {
+ int values[2][3];
+ };
+
+ void testNestedPrimitive() {
+ NestedPrimitive a = { { { 0, 0, 0 }, { 1, 2, 3 } } };
+
+ clang_analyzer_eval(a.values[1][0] == 1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(a.values[1][1] == 2); // expected-warning{{TRUE}}
+ clang_analyzer_eval(a.values[1][2] == 3); // expected-warning{{TRUE}}
+
+ NestedPrimitive b = a;
+
+ clang_analyzer_eval(b.values[1][0] == 1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(b.values[1][1] == 2); // expected-warning{{TRUE}}
+ clang_analyzer_eval(b.values[1][2] == 3); // expected-warning{{TRUE}}
+
+ NestedPrimitive c;
+ c = b;
+
+ clang_analyzer_eval(c.values[1][0] == 1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(c.values[1][1] == 2); // expected-warning{{TRUE}}
+ clang_analyzer_eval(c.values[1][2] == 3); // expected-warning{{TRUE}}
+ }
+
+ struct POD {
+ IntWrapper values[3];
+ };
+
+ void testPOD() {
+ POD a = { { { 1 }, { 2 }, { 3 } } };
+
+ clang_analyzer_eval(a.values[0].x == 1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(a.values[1].x == 2); // expected-warning{{TRUE}}
+ clang_analyzer_eval(a.values[2].x == 3); // expected-warning{{TRUE}}
+
+ POD b = a;
+
+ clang_analyzer_eval(b.values[0].x == 1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(b.values[1].x == 2); // expected-warning{{TRUE}}
+ clang_analyzer_eval(b.values[2].x == 3); // expected-warning{{TRUE}}
+
+ POD c;
+ c = b;
+
+ clang_analyzer_eval(c.values[0].x == 1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(c.values[1].x == 2); // expected-warning{{TRUE}}
+ clang_analyzer_eval(c.values[2].x == 3); // expected-warning{{TRUE}}
+ }
+
+ struct NestedPOD {
+ IntWrapper values[2][3];
+ };
+
+ void testNestedPOD() {
+ NestedPOD a = { { { { 0 }, { 0 }, { 0 } }, { { 1 }, { 2 }, { 3 } } } };
+
+ clang_analyzer_eval(a.values[1][0].x == 1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(a.values[1][1].x == 2); // expected-warning{{TRUE}}
+ clang_analyzer_eval(a.values[1][2].x == 3); // expected-warning{{TRUE}}
+
+ NestedPOD b = a;
+
+ clang_analyzer_eval(b.values[1][0].x == 1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(b.values[1][1].x == 2); // expected-warning{{TRUE}}
+ clang_analyzer_eval(b.values[1][2].x == 3); // expected-warning{{TRUE}}
+
+ NestedPOD c;
+ c = b;
+
+ clang_analyzer_eval(c.values[1][0].x == 1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(c.values[1][1].x == 2); // expected-warning{{TRUE}}
+ clang_analyzer_eval(c.values[1][2].x == 3); // expected-warning{{TRUE}}
+ }
+
+ struct NonPOD {
+ NonPODIntWrapper values[3];
+ };
+
+ void testNonPOD() {
+ NonPOD a;
+ a.values[0].x = 1;
+ a.values[1].x = 2;
+ a.values[2].x = 3;
+
+ clang_analyzer_eval(a.values[0].x == 1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(a.values[1].x == 2); // expected-warning{{TRUE}}
+ clang_analyzer_eval(a.values[2].x == 3); // expected-warning{{TRUE}}
+
+ NonPOD b = a;
+
+ clang_analyzer_eval(b.values[0].x == 1); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(b.values[1].x == 2); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(b.values[2].x == 3); // expected-warning{{UNKNOWN}}
+
+ NonPOD c;
+ c = b;
+
+ clang_analyzer_eval(c.values[0].x == 1); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(c.values[1].x == 2); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(c.values[2].x == 3); // expected-warning{{UNKNOWN}}
+ }
+
+ struct NestedNonPOD {
+ NonPODIntWrapper values[2][3];
+ };
+
+ void testNestedNonPOD() {
+ NestedNonPOD a;
+ a.values[0][0].x = 0;
+ a.values[0][1].x = 0;
+ a.values[0][2].x = 0;
+ a.values[1][0].x = 1;
+ a.values[1][1].x = 2;
+ a.values[1][2].x = 3;
+
+ clang_analyzer_eval(a.values[1][0].x == 1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(a.values[1][1].x == 2); // expected-warning{{TRUE}}
+ clang_analyzer_eval(a.values[1][2].x == 3); // expected-warning{{TRUE}}
+
+ NestedNonPOD b = a;
+
+ clang_analyzer_eval(b.values[1][0].x == 1); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(b.values[1][1].x == 2); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(b.values[1][2].x == 3); // expected-warning{{UNKNOWN}}
+
+ NestedNonPOD c;
+ c = b;
+
+ clang_analyzer_eval(c.values[1][0].x == 1); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(c.values[1][1].x == 2); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(c.values[1][2].x == 3); // expected-warning{{UNKNOWN}}
+ }
+
+ struct NonPODDefaulted {
+ NonPODIntWrapper values[3];
+
+ NonPODDefaulted() = default;
+ NonPODDefaulted(const NonPODDefaulted &) = default;
+ NonPODDefaulted &operator=(const NonPODDefaulted &) = default;
+ };
+
+ void testNonPODDefaulted() {
+ NonPODDefaulted a;
+ a.values[0].x = 1;
+ a.values[1].x = 2;
+ a.values[2].x = 3;
+
+ clang_analyzer_eval(a.values[0].x == 1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(a.values[1].x == 2); // expected-warning{{TRUE}}
+ clang_analyzer_eval(a.values[2].x == 3); // expected-warning{{TRUE}}
+
+ NonPODDefaulted b = a;
+
+ clang_analyzer_eval(b.values[0].x == 1); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(b.values[1].x == 2); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(b.values[2].x == 3); // expected-warning{{UNKNOWN}}
+
+ NonPODDefaulted c;
+ c = b;
+
+ clang_analyzer_eval(c.values[0].x == 1); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(c.values[1].x == 2); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(c.values[2].x == 3); // expected-warning{{UNKNOWN}}
+ }
+};
diff --git a/test/Analysis/dead-stores.c b/test/Analysis/dead-stores.c
index 165a12b59b..067a0504f1 100644
--- a/test/Analysis/dead-stores.c
+++ b/test/Analysis/dead-stores.c
@@ -547,3 +547,25 @@ int *radar11185138_baz() {
return y;
}
+int getInt();
+int *getPtr();
+void testBOComma() {
+ int x0 = (getInt(), 0); // expected-warning{{unused variable 'x0'}}
+ int x1 = (getInt(), getInt()); // expected-warning {{Value stored to 'x1' during its initialization is never read}} // expected-warning{{unused variable 'x1'}}
+ int x2 = (getInt(), getInt(), getInt()); //expected-warning{{Value stored to 'x2' during its initialization is never read}} // expected-warning{{unused variable 'x2'}}
+ int x3;
+ x3 = (getInt(), getInt(), 0); // expected-warning{{Value stored to 'x3' is never read}}
+ int x4 = (getInt(), (getInt(), 0)); // expected-warning{{unused variable 'x4'}}
+ int y;
+ int x5 = (getInt(), (y = 0)); // expected-warning{{unused variable 'x5'}}
+ int x6 = (getInt(), (y = getInt())); //expected-warning {{Value stored to 'x6' during its initialization is never read}} // expected-warning{{unused variable 'x6'}}
+ int x7 = 0, x8 = getInt(); //expected-warning {{Value stored to 'x8' during its initialization is never read}} // expected-warning{{unused variable 'x8'}} // expected-warning{{unused variable 'x7'}}
+ int x9 = getInt(), x10 = 0; //expected-warning {{Value stored to 'x9' during its initialization is never read}} // expected-warning{{unused variable 'x9'}} // expected-warning{{unused variable 'x10'}}
+ int m = getInt(), mm, mmm; //expected-warning {{Value stored to 'm' during its initialization is never read}} // expected-warning{{unused variable 'm'}} // expected-warning{{unused variable 'mm'}} // expected-warning{{unused variable 'mmm'}}
+ int n, nn = getInt(); //expected-warning {{Value stored to 'nn' during its initialization is never read}} // expected-warning{{unused variable 'n'}} // expected-warning{{unused variable 'nn'}}
+
+ int *p;
+ p = (getPtr(), (int *)0); // no warning
+
+}
+
diff --git a/test/Analysis/derived-to-base.cpp b/test/Analysis/derived-to-base.cpp
index b846d2c28b..0664189a95 100644
--- a/test/Analysis/derived-to-base.cpp
+++ b/test/Analysis/derived-to-base.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -DCONSTRUCTORS=1 -analyzer-config c++-inlining=constructors -verify %s
void clang_analyzer_eval(bool);
+void clang_analyzer_checkInlined(bool);
class A {
protected:
@@ -363,3 +364,89 @@ namespace Redeclaration {
}
};
+namespace PR15394 {
+ namespace Original {
+ class Base {
+ public:
+ virtual int f() = 0;
+ int i;
+ };
+
+ class Derived1 : public Base {
+ public:
+ int j;
+ };
+
+ class Derived2 : public Derived1 {
+ public:
+ virtual int f() {
+ clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
+ return i + j;
+ }
+ };
+
+ void testXXX() {
+ Derived1 *d1p = reinterpret_cast<Derived1*>(new Derived2);
+ d1p->i = 1;
+ d1p->j = 2;
+ clang_analyzer_eval(d1p->f() == 3); // expected-warning{{TRUE}}
+ }
+ }
+
+ namespace VirtualInDerived {
+ class Base {
+ public:
+ int i;
+ };
+
+ class Derived1 : public Base {
+ public:
+ virtual int f() = 0;
+ int j;
+ };
+
+ class Derived2 : public Derived1 {
+ public:
+ virtual int f() {
+ clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
+ return i + j;
+ }
+ };
+
+ void test() {
+ Derived1 *d1p = reinterpret_cast<Derived1*>(new Derived2);
+ d1p->i = 1;
+ d1p->j = 2;
+ clang_analyzer_eval(d1p->f() == 3); // expected-warning{{TRUE}}
+ }
+ }
+
+ namespace NoCast {
+ class Base {
+ public:
+ int i;
+ };
+
+ class Derived1 : public Base {
+ public:
+ virtual int f() = 0;
+ int j;
+ };
+
+ class Derived2 : public Derived1 {
+ public:
+ virtual int f() {
+ clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
+ return i + j;
+ }
+ };
+
+ void test() {
+ Derived1 *d1p = new Derived2;
+ d1p->i = 1;
+ d1p->j = 2;
+ clang_analyzer_eval(d1p->f() == 3); // expected-warning{{TRUE}}
+ }
+ }
+};
+
diff --git a/test/Analysis/diagnostics/deref-track-symbolic-region.c b/test/Analysis/diagnostics/deref-track-symbolic-region.c
index 94774dd61d..03716de9ff 100644
--- a/test/Analysis/diagnostics/deref-track-symbolic-region.c
+++ b/test/Analysis/diagnostics/deref-track-symbolic-region.c
@@ -24,6 +24,21 @@ void test(struct S syz, int *pp) {
// expected-note@-1{{Dereference of null pointer (loaded from field 'x')}}
}
+void testTrackConstraintBRVisitorIsTrackingTurnedOn(struct S syz, int *pp) {
+ int m = 0;
+ syz.x = foo(); // expected-note{{Value assigned to 'syz.x'}}
+
+ struct S *ps = &syz;
+ if (ps->x)
+ //expected-note@-1{{Taking false branch}}
+ //expected-note@-2{{Assuming pointer value is null}}
+
+ m++;
+ int *p = syz.x; //expected-note {{'p' initialized to a null pointer value}}
+ m = *p; // expected-warning {{Dereference of null pointer (loaded from variable 'p')}}
+ // expected-note@-1 {{Dereference of null pointer (loaded from variable 'p')}}
+}
+
// CHECK: <key>diagnostics</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
@@ -300,6 +315,341 @@ void test(struct S syz, int *pp) {
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>path</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>28</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>28</integer>
+// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>29</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>29</integer>
+// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>29</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>29</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>29</integer>
+// CHECK-NEXT: <key>col</key><integer>15</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Value assigned to &apos;syz.x&apos;</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Value assigned to &apos;syz.x&apos;</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>29</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>29</integer>
+// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>32</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>32</integer>
+// CHECK-NEXT: <key>col</key><integer>4</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>32</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>32</integer>
+// CHECK-NEXT: <key>col</key><integer>4</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>32</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>32</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>32</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>32</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>32</integer>
+// CHECK-NEXT: <key>col</key><integer>11</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Assuming pointer value is null</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Assuming pointer value is null</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>32</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>32</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>37</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>37</integer>
+// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>37</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>37</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>37</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>&apos;p&apos; initialized to a null pointer value</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>&apos;p&apos; initialized to a null pointer value</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>37</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>37</integer>
+// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>38</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>38</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>38</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>38</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>38</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>38</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>38</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>38</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>38</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Dereference of null pointer (loaded from variable &apos;p&apos;)</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Dereference of null pointer (loaded from variable &apos;p&apos;)</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>description</key><string>Dereference of null pointer (loaded from variable &apos;p&apos;)</string>
+// CHECK-NEXT: <key>category</key><string>Logic error</string>
+// CHECK-NEXT: <key>type</key><string>Dereference of null pointer</string>
+// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT: <key>issue_context</key><string>testTrackConstraintBRVisitorIsTrackingTurnedOn</string>
+// CHECK-NEXT: <key>issue_hash</key><string>11</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>38</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </plist>
diff --git a/test/Analysis/diagnostics/deref-track-symbolic-region.cpp b/test/Analysis/diagnostics/deref-track-symbolic-region.cpp
index e166109ef8..6d348415aa 100644
--- a/test/Analysis/diagnostics/deref-track-symbolic-region.cpp
+++ b/test/Analysis/diagnostics/deref-track-symbolic-region.cpp
@@ -25,4 +25,19 @@ void testRefParam(int *ptr) {
extern void use(int &ref);
use(ref); // expected-warning{{Forming reference to null pointer}}
// expected-note@-1{{Forming reference to null pointer}}
+}
+
+int testRefToNullPtr() {
+ int *p = 0; // expected-note {{'p' initialized to a null pointer value}}
+ int *const &p2 = p; // expected-note{{'p2' initialized here}}
+ int *p3 = p2; // expected-note {{'p3' initialized to a null pointer value}}
+ return *p3; // expected-warning {{Dereference of null pointer}}
+ // expected-note@-1{{Dereference of null pointer}}
+}
+
+int testRefToNullPtr2() {
+ int *p = 0; // expected-note {{'p' initialized to a null pointer value}}
+ int *const &p2 = p;// expected-note{{'p2' initialized here}}
+ return *p2; //expected-warning {{Dereference of null pointer}}
+ // expected-note@-1{{Dereference of null pointer}}
} \ No newline at end of file
diff --git a/test/Analysis/diagnostics/explicit-suppression.cpp b/test/Analysis/diagnostics/explicit-suppression.cpp
new file mode 100644
index 0000000000..57d2d16f89
--- /dev/null
+++ b/test/Analysis/diagnostics/explicit-suppression.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-config suppress-c++-stdlib=false -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-config suppress-c++-stdlib=true -DSUPPRESSED=1 -verify %s
+
+#ifdef SUPPRESSED
+// expected-no-diagnostics
+#endif
+
+#include "../Inputs/system-header-simulator-cxx.h"
+
+void clang_analyzer_eval(bool);
+
+void testCopyNull(int *I, int *E) {
+ std::copy(I, E, (int *)0);
+#ifndef SUPPRESSED
+ // expected-warning@../Inputs/system-header-simulator-cxx.h:80 {{Dereference of null pointer}}
+#endif
+}
diff --git a/test/Analysis/diagnostics/shortest-path-suppression.c b/test/Analysis/diagnostics/shortest-path-suppression.c
new file mode 100644
index 0000000000..4f648b986b
--- /dev/null
+++ b/test/Analysis/diagnostics/shortest-path-suppression.c
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-config suppress-null-return-paths=true -analyzer-output=text -verify %s
+// expected-no-diagnostics
+
+int *returnNull() { return 0; }
+int coin();
+
+// Use a float parameter to ensure that the value is unknown. This will create
+// a cycle in the generated ExplodedGraph.
+void testCycle(float i) {
+ int *x = returnNull();
+ int y;
+ while (i > 0) {
+ x = returnNull();
+ y = 2;
+ i -= 1;
+ }
+ *x = 1; // no-warning
+ y += 1;
+}
diff --git a/test/Analysis/diagnostics/undef-value-param.c b/test/Analysis/diagnostics/undef-value-param.c
index 597bf91fa2..5855f507f9 100644
--- a/test/Analysis/diagnostics/undef-value-param.c
+++ b/test/Analysis/diagnostics/undef-value-param.c
@@ -328,7 +328,7 @@ double testPassingParentRegionStruct(int x) {
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>1</integer>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>Returning from &apos;foo&apos;</string>
// CHECK-NEXT: <key>message</key>
@@ -390,46 +390,12 @@ double testPassingParentRegionStruct(int x) {
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>26</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>26</integer>
-// CHECK-NEXT: <key>col</key><integer>10</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>control</string>
-// CHECK-NEXT: <key>edges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>start</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>26</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>26</integer>
-// CHECK-NEXT: <key>col</key><integer>10</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>end</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>26</integer>
-// CHECK-NEXT: <key>col</key><integer>12</integer>
+// CHECK-NEXT: <key>col</key><integer>14</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>26</integer>
-// CHECK-NEXT: <key>col</key><integer>13</integer>
+// CHECK-NEXT: <key>col</key><integer>14</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
@@ -441,7 +407,7 @@ double testPassingParentRegionStruct(int x) {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>26</integer>
-// CHECK-NEXT: <key>col</key><integer>12</integer>
+// CHECK-NEXT: <key>col</key><integer>14</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -475,7 +441,7 @@ double testPassingParentRegionStruct(int x) {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>26</integer>
-// CHECK-NEXT: <key>col</key><integer>12</integer>
+// CHECK-NEXT: <key>col</key><integer>14</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -713,7 +679,7 @@ double testPassingParentRegionStruct(int x) {
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>1</integer>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>Returning from &apos;initArray&apos;</string>
// CHECK-NEXT: <key>message</key>
@@ -741,46 +707,12 @@ double testPassingParentRegionStruct(int x) {
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>42</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>42</integer>
-// CHECK-NEXT: <key>col</key><integer>10</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>control</string>
-// CHECK-NEXT: <key>edges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>start</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>42</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>42</integer>
-// CHECK-NEXT: <key>col</key><integer>10</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>end</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>42</integer>
-// CHECK-NEXT: <key>col</key><integer>12</integer>
+// CHECK-NEXT: <key>col</key><integer>14</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>42</integer>
-// CHECK-NEXT: <key>col</key><integer>12</integer>
+// CHECK-NEXT: <key>col</key><integer>14</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
@@ -792,7 +724,7 @@ double testPassingParentRegionStruct(int x) {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>42</integer>
-// CHECK-NEXT: <key>col</key><integer>12</integer>
+// CHECK-NEXT: <key>col</key><integer>14</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -826,7 +758,7 @@ double testPassingParentRegionStruct(int x) {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>42</integer>
-// CHECK-NEXT: <key>col</key><integer>12</integer>
+// CHECK-NEXT: <key>col</key><integer>14</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -1127,7 +1059,7 @@ double testPassingParentRegionStruct(int x) {
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>1</integer>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>Returning from &apos;initStruct&apos;</string>
// CHECK-NEXT: <key>message</key>
diff --git a/test/Analysis/diagnostics/undef-value-param.m b/test/Analysis/diagnostics/undef-value-param.m
index d6c8a16795..4de83bfb9c 100644
--- a/test/Analysis/diagnostics/undef-value-param.m
+++ b/test/Analysis/diagnostics/undef-value-param.m
@@ -1,5 +1,6 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx -analyzer-output=text -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx -analyzer-output=plist-multi-file %s -o - | FileCheck %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx -analyzer-output=plist-multi-file %s -o %t.plist
+// RUN: FileCheck --input-file=%t.plist %s
typedef signed char BOOL;
@protocol NSObject - (BOOL)isEqual:(id)object; @end
@@ -86,12 +87,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>34</integer>
+// CHECK-NEXT: <key>line</key><integer>35</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>34</integer>
+// CHECK-NEXT: <key>line</key><integer>35</integer>
// CHECK-NEXT: <key>col</key><integer>21</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -99,12 +100,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>35</integer>
+// CHECK-NEXT: <key>line</key><integer>36</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>35</integer>
+// CHECK-NEXT: <key>line</key><integer>36</integer>
// CHECK-NEXT: <key>col</key><integer>13</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -116,7 +117,7 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>35</integer>
+// CHECK-NEXT: <key>line</key><integer>36</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -124,12 +125,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>35</integer>
+// CHECK-NEXT: <key>line</key><integer>36</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>35</integer>
+// CHECK-NEXT: <key>line</key><integer>36</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -145,7 +146,7 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>52</integer>
+// CHECK-NEXT: <key>line</key><integer>53</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -163,12 +164,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>52</integer>
+// CHECK-NEXT: <key>line</key><integer>53</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>52</integer>
+// CHECK-NEXT: <key>line</key><integer>53</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -176,12 +177,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>53</integer>
+// CHECK-NEXT: <key>line</key><integer>54</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>53</integer>
+// CHECK-NEXT: <key>line</key><integer>54</integer>
// CHECK-NEXT: <key>col</key><integer>12</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -197,12 +198,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>53</integer>
+// CHECK-NEXT: <key>line</key><integer>54</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>53</integer>
+// CHECK-NEXT: <key>line</key><integer>54</integer>
// CHECK-NEXT: <key>col</key><integer>12</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -210,12 +211,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>55</integer>
+// CHECK-NEXT: <key>line</key><integer>56</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>55</integer>
+// CHECK-NEXT: <key>line</key><integer>56</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -231,12 +232,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>55</integer>
+// CHECK-NEXT: <key>line</key><integer>56</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>55</integer>
+// CHECK-NEXT: <key>line</key><integer>56</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -244,12 +245,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>55</integer>
+// CHECK-NEXT: <key>line</key><integer>56</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>55</integer>
+// CHECK-NEXT: <key>line</key><integer>56</integer>
// CHECK-NEXT: <key>col</key><integer>11</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -261,7 +262,7 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>55</integer>
+// CHECK-NEXT: <key>line</key><integer>56</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -269,12 +270,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>55</integer>
+// CHECK-NEXT: <key>line</key><integer>56</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>55</integer>
+// CHECK-NEXT: <key>line</key><integer>56</integer>
// CHECK-NEXT: <key>col</key><integer>11</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -294,12 +295,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>55</integer>
+// CHECK-NEXT: <key>line</key><integer>56</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>55</integer>
+// CHECK-NEXT: <key>line</key><integer>56</integer>
// CHECK-NEXT: <key>col</key><integer>11</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -307,12 +308,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>58</integer>
+// CHECK-NEXT: <key>line</key><integer>59</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>58</integer>
+// CHECK-NEXT: <key>line</key><integer>59</integer>
// CHECK-NEXT: <key>col</key><integer>17</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -328,12 +329,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>58</integer>
+// CHECK-NEXT: <key>line</key><integer>59</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>58</integer>
+// CHECK-NEXT: <key>line</key><integer>59</integer>
// CHECK-NEXT: <key>col</key><integer>17</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -341,12 +342,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>59</integer>
+// CHECK-NEXT: <key>line</key><integer>60</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>59</integer>
+// CHECK-NEXT: <key>line</key><integer>60</integer>
// CHECK-NEXT: <key>col</key><integer>11</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -358,7 +359,7 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>59</integer>
+// CHECK-NEXT: <key>line</key><integer>60</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -366,12 +367,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>59</integer>
+// CHECK-NEXT: <key>line</key><integer>60</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>59</integer>
+// CHECK-NEXT: <key>line</key><integer>60</integer>
// CHECK-NEXT: <key>col</key><integer>15</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -391,12 +392,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>59</integer>
+// CHECK-NEXT: <key>line</key><integer>60</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>59</integer>
+// CHECK-NEXT: <key>line</key><integer>60</integer>
// CHECK-NEXT: <key>col</key><integer>11</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -404,12 +405,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>61</integer>
+// CHECK-NEXT: <key>line</key><integer>62</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>61</integer>
+// CHECK-NEXT: <key>line</key><integer>62</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -421,7 +422,7 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>61</integer>
+// CHECK-NEXT: <key>line</key><integer>62</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -429,12 +430,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>61</integer>
+// CHECK-NEXT: <key>line</key><integer>62</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>61</integer>
+// CHECK-NEXT: <key>line</key><integer>62</integer>
// CHECK-NEXT: <key>col</key><integer>19</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -450,7 +451,7 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>35</integer>
+// CHECK-NEXT: <key>line</key><integer>36</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -458,18 +459,18 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>35</integer>
+// CHECK-NEXT: <key>line</key><integer>36</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>35</integer>
+// CHECK-NEXT: <key>line</key><integer>36</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>1</integer>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>Returning from &apos;CreateRef&apos;</string>
// CHECK-NEXT: <key>message</key>
@@ -483,12 +484,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>35</integer>
+// CHECK-NEXT: <key>line</key><integer>36</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>35</integer>
+// CHECK-NEXT: <key>line</key><integer>36</integer>
// CHECK-NEXT: <key>col</key><integer>13</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -496,12 +497,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>38</integer>
+// CHECK-NEXT: <key>line</key><integer>39</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>38</integer>
+// CHECK-NEXT: <key>line</key><integer>39</integer>
// CHECK-NEXT: <key>col</key><integer>13</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -513,7 +514,7 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>38</integer>
+// CHECK-NEXT: <key>line</key><integer>39</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -521,12 +522,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>38</integer>
+// CHECK-NEXT: <key>line</key><integer>39</integer>
// CHECK-NEXT: <key>col</key><integer>15</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>38</integer>
+// CHECK-NEXT: <key>line</key><integer>39</integer>
// CHECK-NEXT: <key>col</key><integer>22</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -547,7 +548,7 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <key>issue_hash</key><string>5</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>38</integer>
+// CHECK-NEXT: <key>line</key><integer>39</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -559,7 +560,7 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>43</integer>
+// CHECK-NEXT: <key>line</key><integer>44</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -567,12 +568,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>43</integer>
+// CHECK-NEXT: <key>line</key><integer>44</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>43</integer>
+// CHECK-NEXT: <key>line</key><integer>44</integer>
// CHECK-NEXT: <key>col</key><integer>30</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -592,12 +593,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>43</integer>
+// CHECK-NEXT: <key>line</key><integer>44</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>43</integer>
+// CHECK-NEXT: <key>line</key><integer>44</integer>
// CHECK-NEXT: <key>col</key><integer>21</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -605,12 +606,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>44</integer>
+// CHECK-NEXT: <key>line</key><integer>45</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>44</integer>
+// CHECK-NEXT: <key>line</key><integer>45</integer>
// CHECK-NEXT: <key>col</key><integer>18</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -622,7 +623,7 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>44</integer>
+// CHECK-NEXT: <key>line</key><integer>45</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -630,12 +631,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>44</integer>
+// CHECK-NEXT: <key>line</key><integer>45</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>44</integer>
+// CHECK-NEXT: <key>line</key><integer>45</integer>
// CHECK-NEXT: <key>col</key><integer>32</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -651,7 +652,7 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>64</integer>
+// CHECK-NEXT: <key>line</key><integer>65</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -669,12 +670,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>64</integer>
+// CHECK-NEXT: <key>line</key><integer>65</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>64</integer>
+// CHECK-NEXT: <key>line</key><integer>65</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -682,12 +683,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>65</integer>
+// CHECK-NEXT: <key>line</key><integer>66</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>65</integer>
+// CHECK-NEXT: <key>line</key><integer>66</integer>
// CHECK-NEXT: <key>col</key><integer>10</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -703,12 +704,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>65</integer>
+// CHECK-NEXT: <key>line</key><integer>66</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>65</integer>
+// CHECK-NEXT: <key>line</key><integer>66</integer>
// CHECK-NEXT: <key>col</key><integer>10</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -716,12 +717,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>67</integer>
+// CHECK-NEXT: <key>line</key><integer>68</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>67</integer>
+// CHECK-NEXT: <key>line</key><integer>68</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -737,12 +738,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>67</integer>
+// CHECK-NEXT: <key>line</key><integer>68</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>67</integer>
+// CHECK-NEXT: <key>line</key><integer>68</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -750,12 +751,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>67</integer>
+// CHECK-NEXT: <key>line</key><integer>68</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>67</integer>
+// CHECK-NEXT: <key>line</key><integer>68</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -767,7 +768,7 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>67</integer>
+// CHECK-NEXT: <key>line</key><integer>68</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -775,12 +776,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>67</integer>
+// CHECK-NEXT: <key>line</key><integer>68</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>67</integer>
+// CHECK-NEXT: <key>line</key><integer>68</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -800,12 +801,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>67</integer>
+// CHECK-NEXT: <key>line</key><integer>68</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>67</integer>
+// CHECK-NEXT: <key>line</key><integer>68</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -813,12 +814,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>70</integer>
+// CHECK-NEXT: <key>line</key><integer>71</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>70</integer>
+// CHECK-NEXT: <key>line</key><integer>71</integer>
// CHECK-NEXT: <key>col</key><integer>13</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -830,7 +831,7 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>44</integer>
+// CHECK-NEXT: <key>line</key><integer>45</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -838,18 +839,18 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>44</integer>
+// CHECK-NEXT: <key>line</key><integer>45</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>44</integer>
+// CHECK-NEXT: <key>line</key><integer>45</integer>
// CHECK-NEXT: <key>col</key><integer>32</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>1</integer>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>Returning from &apos;CreateRefUndef&apos;</string>
// CHECK-NEXT: <key>message</key>
@@ -863,12 +864,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>44</integer>
+// CHECK-NEXT: <key>line</key><integer>45</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>44</integer>
+// CHECK-NEXT: <key>line</key><integer>45</integer>
// CHECK-NEXT: <key>col</key><integer>18</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -876,12 +877,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>47</integer>
+// CHECK-NEXT: <key>line</key><integer>48</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>47</integer>
+// CHECK-NEXT: <key>line</key><integer>48</integer>
// CHECK-NEXT: <key>col</key><integer>13</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -893,7 +894,7 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>47</integer>
+// CHECK-NEXT: <key>line</key><integer>48</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -901,12 +902,12 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>47</integer>
+// CHECK-NEXT: <key>line</key><integer>48</integer>
// CHECK-NEXT: <key>col</key><integer>15</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>47</integer>
+// CHECK-NEXT: <key>line</key><integer>48</integer>
// CHECK-NEXT: <key>col</key><integer>22</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -927,7 +928,7 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
// CHECK-NEXT: <key>issue_hash</key><string>5</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>47</integer>
+// CHECK-NEXT: <key>line</key><integer>48</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
diff --git a/test/Analysis/dtor.cpp b/test/Analysis/dtor.cpp
index a30823766e..18cd9853f6 100644
--- a/test/Analysis/dtor.cpp
+++ b/test/Analysis/dtor.cpp
@@ -328,3 +328,76 @@ namespace MultidimensionalArrays {
clang_analyzer_eval(j == 42); // expected-warning{{UNKNOWN}}
}
}
+
+namespace LifetimeExtension {
+ struct IntWrapper {
+ int x;
+ IntWrapper(int y) : x(y) {}
+ IntWrapper() {
+ extern void use(int);
+ use(x); // no-warning
+ }
+ };
+
+ struct DerivedWrapper : public IntWrapper {
+ DerivedWrapper(int y) : IntWrapper(y) {}
+ };
+
+ DerivedWrapper get() {
+ return DerivedWrapper(1);
+ }
+
+ void test() {
+ const DerivedWrapper &d = get(); // lifetime extended here
+ }
+
+
+ class SaveOnDestruct {
+ public:
+ static int lastOutput;
+ int value;
+
+ SaveOnDestruct();
+ ~SaveOnDestruct() {
+ lastOutput = value;
+ }
+ };
+
+ void testSimple() {
+ {
+ const SaveOnDestruct &obj = SaveOnDestruct();
+ if (obj.value != 42)
+ return;
+ // destructor called here
+ }
+
+ clang_analyzer_eval(SaveOnDestruct::lastOutput == 42); // expected-warning{{TRUE}}
+ }
+
+ class VirtualDtorBase {
+ public:
+ int value;
+ virtual ~VirtualDtorBase() {}
+ };
+
+ class SaveOnVirtualDestruct : public VirtualDtorBase {
+ public:
+ static int lastOutput;
+
+ SaveOnVirtualDestruct();
+ virtual ~SaveOnVirtualDestruct() {
+ lastOutput = value;
+ }
+ };
+
+ void testVirtual() {
+ {
+ const VirtualDtorBase &obj = SaveOnVirtualDestruct();
+ if (obj.value != 42)
+ return;
+ // destructor called here
+ }
+
+ clang_analyzer_eval(SaveOnVirtualDestruct::lastOutput == 42); // expected-warning{{TRUE}}
+ }
+}
diff --git a/test/Analysis/enum.cpp b/test/Analysis/enum.cpp
new file mode 100644
index 0000000000..571fa7ba22
--- /dev/null
+++ b/test/Analysis/enum.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -analyze -std=c++11 -analyzer-checker=debug.ExprInspection %s
+
+void clang_analyzer_eval(bool);
+
+enum class Foo {
+ Zero
+};
+
+bool pr15703(int x) {
+ return Foo::Zero == (Foo)x; // don't crash
+}
+
+void testCasting(int i) {
+ Foo f = static_cast<Foo>(i);
+ int j = static_cast<int>(f);
+ if (i == 0)
+ {
+ clang_analyzer_eval(f == Foo::Zero); // expected-warning{{TRUE}}
+ clang_analyzer_eval(j == 0); // expected-warning{{TRUE}}
+ }
+ else
+ {
+ clang_analyzer_eval(f == Foo::Zero); // expected-warning{{FALSE}}
+ clang_analyzer_eval(j == 0); // expected-warning{{FALSE}}
+ }
+}
diff --git a/test/Analysis/free.c b/test/Analysis/free.c
index 0b283ee5d4..1dfc1082c7 100644
--- a/test/Analysis/free.c
+++ b/test/Analysis/free.c
@@ -50,7 +50,7 @@ void t10 () {
void t11 () {
char *p = (char*)__builtin_alloca(2);
- free(p); // expected-warning {{Argument to free() was allocated by alloca(), not malloc()}}
+ free(p); // expected-warning {{Memory allocated by alloca() should not be deallocated}}
}
void t12 () {
diff --git a/test/Analysis/global-region-invalidation.c b/test/Analysis/global-region-invalidation.c
index 77de9dd326..bff22012c0 100644
--- a/test/Analysis/global-region-invalidation.c
+++ b/test/Analysis/global-region-invalidation.c
@@ -44,7 +44,10 @@ int testErrnoSystem() {
fscanf(stdin, "%d", &i); // errno gets invalidated here.
return 5 / errno; // no-warning
}
- return 0;
+
+ errno = 0;
+ fscanf(stdin, "%d", &i); // errno gets invalidated here.
+ return 5 / errno; // no-warning
}
// Test that errno gets invalidated by internal calls.
diff --git a/test/Analysis/global_region_invalidation.mm b/test/Analysis/global_region_invalidation.mm
index be337edab1..2369c09d22 100644
--- a/test/Analysis/global_region_invalidation.mm
+++ b/test/Analysis/global_region_invalidation.mm
@@ -2,6 +2,8 @@
void clang_analyzer_eval(int);
+#include "Inputs/system-header-simulator.h"
+
void use(int);
id foo(int x) {
if (x)
@@ -11,9 +13,176 @@ id foo(int x) {
return p;
}
-const int &globalInt = 42;
+const int &globalIntRef = 42;
-void testGlobal() {
+void testGlobalRef() {
// FIXME: Should be TRUE, but should at least not crash.
+ clang_analyzer_eval(globalIntRef == 42); // expected-warning{{UNKNOWN}}
+}
+
+extern int globalInt;
+struct IntWrapper {
+ int value;
+};
+extern struct IntWrapper globalStruct;
+extern void invalidateGlobals();
+
+void testGlobalInvalidation() {
+ clang_analyzer_eval(globalInt == 42); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(globalStruct.value == 43); // expected-warning{{UNKNOWN}}
+
+ if (globalInt != 42)
+ return;
+ if (globalStruct.value != 43)
+ return;
+ clang_analyzer_eval(globalInt == 42); // expected-warning{{TRUE}}
+ clang_analyzer_eval(globalStruct.value == 43); // expected-warning{{TRUE}}
+
+ invalidateGlobals();
+ clang_analyzer_eval(globalInt == 42); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(globalStruct.value == 43); // expected-warning{{UNKNOWN}}
+
+ // Repeat to make sure we don't get the /same/ new symbolic values.
+ if (globalInt != 42)
+ return;
+ if (globalStruct.value != 43)
+ return;
+ clang_analyzer_eval(globalInt == 42); // expected-warning{{TRUE}}
+ clang_analyzer_eval(globalStruct.value == 43); // expected-warning{{TRUE}}
+
+ invalidateGlobals();
clang_analyzer_eval(globalInt == 42); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(globalStruct.value == 43); // expected-warning{{UNKNOWN}}
+}
+
+void testGlobalInvalidationWithDirectBinding() {
+ clang_analyzer_eval(globalInt == 42); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(globalStruct.value == 43); // expected-warning{{UNKNOWN}}
+
+ globalInt = 42;
+ globalStruct.value = 43;
+ clang_analyzer_eval(globalInt == 42); // expected-warning{{TRUE}}
+ clang_analyzer_eval(globalStruct.value == 43); // expected-warning{{TRUE}}
+
+ invalidateGlobals();
+ clang_analyzer_eval(globalInt == 42); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(globalStruct.value == 43); // expected-warning{{UNKNOWN}}
+}
+
+void testStaticLocals(void) {
+ static int i;
+ int tmp;
+
+ extern int someSymbolicValue();
+ i = someSymbolicValue();
+
+ if (i == 5) {
+ clang_analyzer_eval(i == 5); // expected-warning{{TRUE}}
+ scanf("%d", &tmp);
+ clang_analyzer_eval(i == 5); // expected-warning{{TRUE}}
+ invalidateGlobals();
+ clang_analyzer_eval(i == 5); // expected-warning{{TRUE}}
+ }
+
+ i = 6;
+ clang_analyzer_eval(i == 6); // expected-warning{{TRUE}}
+ scanf("%d", &tmp);
+ clang_analyzer_eval(i == 6); // expected-warning{{TRUE}}
+ invalidateGlobals();
+ clang_analyzer_eval(i == 6); // expected-warning{{TRUE}}
+
+ i = someSymbolicValue();
+ if (i == 7) {
+ clang_analyzer_eval(i == 7); // expected-warning{{TRUE}}
+ scanf("%d", &i);
+ clang_analyzer_eval(i == 7); // expected-warning{{UNKNOWN}}
+ }
+
+ i = 8;
+ clang_analyzer_eval(i == 8); // expected-warning{{TRUE}}
+ scanf("%d", &i);
+ clang_analyzer_eval(i == 8); // expected-warning{{UNKNOWN}}
+}
+
+void testNonSystemGlobals(void) {
+ extern int i;
+ int tmp;
+
+ if (i == 5) {
+ clang_analyzer_eval(i == 5); // expected-warning{{TRUE}}
+ scanf("%d", &tmp);
+ clang_analyzer_eval(i == 5); // expected-warning{{TRUE}}
+ invalidateGlobals();
+ clang_analyzer_eval(i == 5); // expected-warning{{UNKNOWN}}
+ }
+
+ i = 6;
+ clang_analyzer_eval(i == 6); // expected-warning{{TRUE}}
+ scanf("%d", &tmp);
+ clang_analyzer_eval(i == 6); // expected-warning{{TRUE}}
+ invalidateGlobals();
+ clang_analyzer_eval(i == 6); // expected-warning{{UNKNOWN}}
+
+ if (i == 7) {
+ clang_analyzer_eval(i == 7); // expected-warning{{TRUE}}
+ scanf("%d", &i);
+ clang_analyzer_eval(i == 7); // expected-warning{{UNKNOWN}}
+ }
+
+ i = 8;
+ clang_analyzer_eval(i == 8); // expected-warning{{TRUE}}
+ scanf("%d", &i);
+ clang_analyzer_eval(i == 8); // expected-warning{{UNKNOWN}}
+}
+
+void testWrappedGlobals(void) {
+ extern char c;
+ SomeStruct s;
+
+ if (c == 'C') {
+ s.p = &c;
+ clang_analyzer_eval(c == 'C'); // expected-warning{{TRUE}}
+ fakeSystemHeaderCall(0);
+ clang_analyzer_eval(c == 'C'); // expected-warning{{TRUE}}
+ fakeSystemHeaderCall(&s);
+ clang_analyzer_eval(c == 'C'); // expected-warning{{UNKNOWN}}
+ }
+
+ c = 'c';
+ s.p = &c;
+ clang_analyzer_eval(c == 'c'); // expected-warning{{TRUE}}
+ fakeSystemHeaderCall(0);
+ clang_analyzer_eval(c == 'c'); // expected-warning{{TRUE}}
+ fakeSystemHeaderCall(&s);
+ clang_analyzer_eval(c == 'c'); // expected-warning{{UNKNOWN}}
+
+ if (c == 'C') {
+ s.p = &c;
+ clang_analyzer_eval(c == 'C'); // expected-warning{{TRUE}}
+ fakeSystemHeaderCall(0);
+ clang_analyzer_eval(c == 'C'); // expected-warning{{TRUE}}
+ fakeSystemHeaderCall(&s);
+ clang_analyzer_eval(c == 'C'); // expected-warning{{UNKNOWN}}
+ }
+}
+
+void testWrappedStaticsViaGlobal(void) {
+ static char c;
+ extern SomeStruct s;
+
+ extern char getSomeChar();
+ c = getSomeChar();
+
+ if (c == 'C') {
+ s.p = &c;
+ clang_analyzer_eval(c == 'C'); // expected-warning{{TRUE}}
+ invalidateGlobals();
+ clang_analyzer_eval(c == 'C'); // expected-warning{{UNKNOWN}}
+ }
+
+ c = 'c';
+ s.p = &c;
+ clang_analyzer_eval(c == 'c'); // expected-warning{{TRUE}}
+ invalidateGlobals();
+ clang_analyzer_eval(c == 'c'); // expected-warning{{UNKNOWN}}
}
diff --git a/test/Analysis/inline-plist.c b/test/Analysis/inline-plist.c
index a2dd98a6d0..dcdd23f74b 100644
--- a/test/Analysis/inline-plist.c
+++ b/test/Analysis/inline-plist.c
@@ -244,12 +244,12 @@ void test_block_arg() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>18</integer>
-// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>col</key><integer>11</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>18</integer>
-// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>col</key><integer>11</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
@@ -261,7 +261,7 @@ void test_block_arg() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>18</integer>
-// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>col</key><integer>11</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -295,7 +295,7 @@ void test_block_arg() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>18</integer>
-// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>col</key><integer>11</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -443,11 +443,45 @@ void test_block_arg() {
// CHECK-NEXT: </array>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>23</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>23</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>23</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>23</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>23</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -481,7 +515,7 @@ void test_block_arg() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>23</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -760,11 +794,45 @@ void test_block_arg() {
// CHECK-NEXT: </array>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>33</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>33</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>33</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>33</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>33</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -798,7 +866,7 @@ void test_block_arg() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>33</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -946,11 +1014,45 @@ void test_block_arg() {
// CHECK-NEXT: </array>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>60</integer>
+// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>60</integer>
+// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>60</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>60</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>60</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -981,7 +1083,7 @@ void test_block_arg() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>60</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -1214,7 +1316,7 @@ void test_block_arg() {
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>1</integer>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>Returning to caller</string>
// CHECK-NEXT: <key>message</key>
@@ -1229,40 +1331,6 @@ void test_block_arg() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>66</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>66</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>end</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>66</integer>
-// CHECK-NEXT: <key>col</key><integer>12</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>66</integer>
-// CHECK-NEXT: <key>col</key><integer>12</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>control</string>
-// CHECK-NEXT: <key>edges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>start</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>66</integer>
// CHECK-NEXT: <key>col</key><integer>12</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1339,12 +1407,12 @@ void test_block_arg() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>70</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>70</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
@@ -1356,7 +1424,7 @@ void test_block_arg() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>70</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -1390,7 +1458,7 @@ void test_block_arg() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>70</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -1560,7 +1628,7 @@ void test_block_arg() {
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>1</integer>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>Returning to caller</string>
// CHECK-NEXT: <key>message</key>
@@ -1588,12 +1656,12 @@ void test_block_arg() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>78</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>78</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
@@ -1605,7 +1673,7 @@ void test_block_arg() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>78</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -1639,7 +1707,7 @@ void test_block_arg() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>78</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -1809,7 +1877,7 @@ void test_block_arg() {
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>1</integer>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>Returning to caller</string>
// CHECK-NEXT: <key>message</key>
@@ -1837,12 +1905,12 @@ void test_block_arg() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>86</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>86</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
@@ -1854,7 +1922,7 @@ void test_block_arg() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>86</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -1888,7 +1956,7 @@ void test_block_arg() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>86</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
diff --git a/test/Analysis/inline-unique-reports.c b/test/Analysis/inline-unique-reports.c
index 9a8cd7f495..5c42135b04 100644
--- a/test/Analysis/inline-unique-reports.c
+++ b/test/Analysis/inline-unique-reports.c
@@ -15,172 +15,290 @@ void test_bug_2() {
bug(p);
}
-// CHECK: <?xml version="1.0" encoding="UTF-8"?>
-// CHECK: <plist version="1.0">
-// CHECK: <dict>
-// CHECK: <key>files</key>
-// CHECK: <array>
-// CHECK: </array>
-// CHECK: <key>diagnostics</key>
-// CHECK: <array>
-// CHECK: <dict>
-// CHECK: <key>path</key>
-// CHECK: <array>
-// CHECK: <dict>
-// CHECK: <key>kind</key><string>control</string>
-// CHECK: <key>edges</key>
-// CHECK: <array>
-// CHECK: <dict>
-// CHECK: <key>start</key>
-// CHECK: <array>
-// CHECK: <dict>
-// CHECK: <key>line</key><integer>14</integer>
-// CHECK: <key>col</key><integer>3</integer>
-// CHECK: <key>file</key><integer>0</integer>
-// CHECK: </dict>
-// CHECK: <dict>
-// CHECK: <key>line</key><integer>14</integer>
-// CHECK: <key>col</key><integer>5</integer>
-// CHECK: <key>file</key><integer>0</integer>
-// CHECK: </dict>
-// CHECK: </array>
-// CHECK: <key>end</key>
-// CHECK: <array>
-// CHECK: <dict>
-// CHECK: <key>line</key><integer>15</integer>
-// CHECK: <key>col</key><integer>3</integer>
-// CHECK: <key>file</key><integer>0</integer>
-// CHECK: </dict>
-// CHECK: <dict>
-// CHECK: <key>line</key><integer>15</integer>
-// CHECK: <key>col</key><integer>5</integer>
-// CHECK: <key>file</key><integer>0</integer>
-// CHECK: </dict>
-// CHECK: </array>
-// CHECK: </dict>
-// CHECK: </array>
-// CHECK: </dict>
-// CHECK: <dict>
-// CHECK: <key>kind</key><string>event</string>
-// CHECK: <key>location</key>
-// CHECK: <dict>
-// CHECK: <key>line</key><integer>15</integer>
-// CHECK: <key>col</key><integer>3</integer>
-// CHECK: <key>file</key><integer>0</integer>
-// CHECK: </dict>
-// CHECK: <key>ranges</key>
-// CHECK: <array>
-// CHECK: <array>
-// CHECK: <dict>
-// CHECK: <key>line</key><integer>15</integer>
-// CHECK: <key>col</key><integer>3</integer>
-// CHECK: <key>file</key><integer>0</integer>
-// CHECK: </dict>
-// CHECK: <dict>
-// CHECK: <key>line</key><integer>15</integer>
-// CHECK: <key>col</key><integer>8</integer>
-// CHECK: <key>file</key><integer>0</integer>
-// CHECK: </dict>
-// CHECK: </array>
-// CHECK: </array>
-// CHECK: <key>depth</key><integer>0</integer>
-// CHECK: <key>extended_message</key>
-// CHECK: <string>Calling &apos;bug&apos;</string>
-// CHECK: <key>message</key>
-// CHECK: <string>Calling &apos;bug&apos;</string>
-// CHECK: </dict>
-// CHECK: <dict>
-// CHECK: <key>kind</key><string>event</string>
-// CHECK: <key>location</key>
-// CHECK: <dict>
-// CHECK: <key>line</key><integer>4</integer>
-// CHECK: <key>col</key><integer>1</integer>
-// CHECK: <key>file</key><integer>0</integer>
-// CHECK: </dict>
-// CHECK: <key>depth</key><integer>1</integer>
-// CHECK: <key>extended_message</key>
-// CHECK: <string>Entered call from &apos;test_bug_2&apos;</string>
-// CHECK: <key>message</key>
-// CHECK: <string>Entered call from &apos;test_bug_2&apos;</string>
-// CHECK: </dict>
-// CHECK: <dict>
-// CHECK: <key>kind</key><string>control</string>
-// CHECK: <key>edges</key>
-// CHECK: <array>
-// CHECK: <dict>
-// CHECK: <key>start</key>
-// CHECK: <array>
-// CHECK: <dict>
-// CHECK: <key>line</key><integer>4</integer>
-// CHECK: <key>col</key><integer>1</integer>
-// CHECK: <key>file</key><integer>0</integer>
-// CHECK: </dict>
-// CHECK: <dict>
-// CHECK: <key>line</key><integer>4</integer>
-// CHECK: <key>col</key><integer>6</integer>
-// CHECK: <key>file</key><integer>0</integer>
-// CHECK: </dict>
-// CHECK: </array>
-// CHECK: <key>end</key>
-// CHECK: <array>
-// CHECK: <dict>
-// CHECK: <key>line</key><integer>5</integer>
-// CHECK: <key>col</key><integer>3</integer>
-// CHECK: <key>file</key><integer>0</integer>
-// CHECK: </dict>
-// CHECK: <dict>
-// CHECK: <key>line</key><integer>5</integer>
-// CHECK: <key>col</key><integer>3</integer>
-// CHECK: <key>file</key><integer>0</integer>
-// CHECK: </dict>
-// CHECK: </array>
-// CHECK: </dict>
-// CHECK: </array>
-// CHECK: </dict>
-// CHECK: <dict>
-// CHECK: <key>kind</key><string>event</string>
-// CHECK: <key>location</key>
-// CHECK: <dict>
-// CHECK: <key>line</key><integer>5</integer>
-// CHECK: <key>col</key><integer>3</integer>
-// CHECK: <key>file</key><integer>0</integer>
-// CHECK: </dict>
-// CHECK: <key>ranges</key>
-// CHECK: <array>
-// CHECK: <array>
-// CHECK: <dict>
-// CHECK: <key>line</key><integer>5</integer>
-// CHECK: <key>col</key><integer>4</integer>
-// CHECK: <key>file</key><integer>0</integer>
-// CHECK: </dict>
-// CHECK: <dict>
-// CHECK: <key>line</key><integer>5</integer>
-// CHECK: <key>col</key><integer>4</integer>
-// CHECK: <key>file</key><integer>0</integer>
-// CHECK: </dict>
-// CHECK: </array>
-// CHECK: </array>
-// CHECK: <key>depth</key><integer>1</integer>
-// CHECK: <key>extended_message</key>
-// CHECK: <string>Dereference of null pointer (loaded from variable &apos;p&apos;)</string>
-// CHECK: <key>message</key>
-// CHECK: <string>Dereference of null pointer (loaded from variable &apos;p&apos;)</string>
-// CHECK: </dict>
-// CHECK: </array>
-// CHECK: <key>description</key><string>Dereference of null pointer (loaded from variable &apos;p&apos;)</string>
-// CHECK: <key>category</key><string>Logic error</string>
-// CHECK: <key>type</key><string>Dereference of null pointer</string>
-// CHECK: <key>issue_context_kind</key><string>function</string>
-// CHECK: <key>issue_context</key><string>bug</string>
-// CHECK: <key>issue_hash</key><string>1</string>
-// CHECK: <key>location</key>
-// CHECK: <dict>
-// CHECK: <key>line</key><integer>5</integer>
-// CHECK: <key>col</key><integer>3</integer>
-// CHECK: <key>file</key><integer>0</integer>
-// CHECK: </dict>
-// CHECK: </dict>
-// CHECK: </array>
-// CHECK: </dict>
-// CHECK: </plist>
+// CHECK: <key>diagnostics</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>path</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>14</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>14</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>14</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>&apos;p&apos; initialized to a null pointer value</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>&apos;p&apos; initialized to a null pointer value</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>14</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>14</integer>
+// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>15</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>15</integer>
+// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>15</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>15</integer>
+// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>15</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>15</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>15</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>15</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>15</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Passing null pointer value via 1st parameter &apos;p&apos;</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Passing null pointer value via 1st parameter &apos;p&apos;</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>15</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>15</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>15</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Calling &apos;bug&apos;</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Calling &apos;bug&apos;</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>4</integer>
+// CHECK-NEXT: <key>col</key><integer>1</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>depth</key><integer>1</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Entered call from &apos;test_bug_2&apos;</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Entered call from &apos;test_bug_2&apos;</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>4</integer>
+// CHECK-NEXT: <key>col</key><integer>1</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>4</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>5</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>5</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>5</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>5</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>5</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>5</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>5</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>5</integer>
+// CHECK-NEXT: <key>col</key><integer>4</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>5</integer>
+// CHECK-NEXT: <key>col</key><integer>4</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>1</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Dereference of null pointer (loaded from variable &apos;p&apos;)</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Dereference of null pointer (loaded from variable &apos;p&apos;)</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>description</key><string>Dereference of null pointer (loaded from variable &apos;p&apos;)</string>
+// CHECK-NEXT: <key>category</key><string>Logic error</string>
+// CHECK-NEXT: <key>type</key><string>Dereference of null pointer</string>
+// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT: <key>issue_context</key><string>bug</string>
+// CHECK-NEXT: <key>issue_hash</key><string>1</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>5</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
diff --git a/test/Analysis/inline.cpp b/test/Analysis/inline.cpp
index 27853dc2aa..909e18017b 100644
--- a/test/Analysis/inline.cpp
+++ b/test/Analysis/inline.cpp
@@ -262,12 +262,33 @@ namespace DefaultArgs {
}
int defaultReference(const int &input = 42) {
- return input;
+ return -input;
+ }
+ int defaultReferenceZero(const int &input = 0) {
+ return -input;
}
void testReference() {
- clang_analyzer_eval(defaultReference(1) == 1); // expected-warning{{TRUE}}
- clang_analyzer_eval(defaultReference() == 42); // expected-warning{{TRUE}}
+ clang_analyzer_eval(defaultReference(1) == -1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(defaultReference() == -42); // expected-warning{{TRUE}}
+
+ clang_analyzer_eval(defaultReferenceZero(1) == -1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(defaultReferenceZero() == 0); // expected-warning{{TRUE}}
+}
+
+ double defaultFloatReference(const double &i = 42) {
+ return -i;
+ }
+ double defaultFloatReferenceZero(const double &i = 0) {
+ return -i;
+ }
+
+ void testFloatReference() {
+ clang_analyzer_eval(defaultFloatReference(1) == -1); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(defaultFloatReference() == -42); // expected-warning{{UNKNOWN}}
+
+ clang_analyzer_eval(defaultFloatReferenceZero(1) == -1); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(defaultFloatReferenceZero() == 0); // expected-warning{{UNKNOWN}}
}
}
@@ -288,6 +309,7 @@ namespace OperatorNew {
IntWrapper *obj = new IntWrapper(42);
// should be TRUE
clang_analyzer_eval(obj->value == 42); // expected-warning{{UNKNOWN}}
+ delete obj;
}
void testPlacement() {
@@ -350,9 +372,7 @@ namespace VirtualWithSisterCasts {
void testCastViaNew(B *b) {
Grandchild *g = new (b) Grandchild();
- // FIXME: We actually now have perfect type info because of 'new'.
- // This should be TRUE.
- clang_analyzer_eval(g->foo() == 42); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(g->foo() == 42); // expected-warning{{TRUE}}
g->x = 42;
clang_analyzer_eval(g->x == 42); // expected-warning{{TRUE}}
diff --git a/test/Analysis/inlining/containers.cpp b/test/Analysis/inlining/containers.cpp
new file mode 100644
index 0000000000..73b2957ad6
--- /dev/null
+++ b/test/Analysis/inlining/containers.cpp
@@ -0,0 +1,241 @@
+// RUN: %clang_cc1 -analyze -std=c++11 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-inlining=destructors -analyzer-config c++-container-inlining=false -verify %s
+// RUN: %clang_cc1 -analyze -std=c++11 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-inlining=destructors -analyzer-config c++-container-inlining=true -DINLINE=1 -verify %s
+
+#ifndef HEADER
+
+void clang_analyzer_eval(bool);
+void clang_analyzer_checkInlined(bool);
+
+#define HEADER
+#include "containers.cpp"
+#undef HEADER
+
+void test() {
+ MySet set(0);
+
+ clang_analyzer_eval(set.isEmpty());
+#if INLINE
+ // expected-warning@-2 {{TRUE}}
+#else
+ // expected-warning@-4 {{UNKNOWN}}
+#endif
+
+ clang_analyzer_eval(set.raw_begin() == set.raw_end());
+#if INLINE
+ // expected-warning@-2 {{TRUE}}
+#else
+ // expected-warning@-4 {{UNKNOWN}}
+#endif
+
+ clang_analyzer_eval(set.begin().impl == set.end().impl);
+#if INLINE
+ // expected-warning@-2 {{TRUE}}
+#else
+ // expected-warning@-4 {{UNKNOWN}}
+#endif
+}
+
+void testSubclass(MySetSubclass &sub) {
+ sub.useIterator(sub.begin());
+
+ MySetSubclass local;
+}
+
+void testWrappers(BeginOnlySet &w1, IteratorStructOnlySet &w2,
+ IteratorTypedefOnlySet &w3, IteratorUsingOnlySet &w4) {
+ BeginOnlySet local1;
+ IteratorStructOnlySet local2;
+ IteratorTypedefOnlySet local3;
+ IteratorUsingOnlySet local4;
+
+ clang_analyzer_eval(w1.begin().impl.impl == w1.begin().impl.impl);
+#if INLINE
+ // expected-warning@-2 {{TRUE}}
+#else
+ // expected-warning@-4 {{UNKNOWN}}
+#endif
+
+ clang_analyzer_eval(w2.start().impl == w2.start().impl);
+#if INLINE
+ // expected-warning@-2 {{TRUE}}
+#else
+ // expected-warning@-4 {{UNKNOWN}}
+#endif
+
+ clang_analyzer_eval(w3.start().impl == w3.start().impl);
+#if INLINE
+ // expected-warning@-2 {{TRUE}}
+#else
+ // expected-warning@-4 {{UNKNOWN}}
+#endif
+
+ clang_analyzer_eval(w4.start().impl == w4.start().impl);
+#if INLINE
+ // expected-warning@-2 {{TRUE}}
+#else
+ // expected-warning@-4 {{UNKNOWN}}
+#endif
+}
+
+
+#else // HEADER
+
+#include "../Inputs/system-header-simulator-cxx.h"
+
+class MySet {
+ int *storage;
+ unsigned size;
+public:
+ MySet() : storage(0), size(0) {
+ clang_analyzer_checkInlined(true);
+#if INLINE
+ // expected-warning@-2 {{TRUE}}
+#endif
+ }
+
+ MySet(unsigned n) : storage(new int[n]), size(n) {
+ clang_analyzer_checkInlined(true);
+#if INLINE
+ // expected-warning@-2 {{TRUE}}
+#endif
+ }
+
+ ~MySet() { delete[] storage; }
+
+ bool isEmpty() {
+ clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
+ return size == 0;
+ }
+
+ struct iterator {
+ int *impl;
+
+ iterator(int *p) : impl(p) {}
+ };
+
+ iterator begin() {
+ clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
+ return iterator(storage);
+ }
+
+ iterator end() {
+ clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
+ return iterator(storage+size);
+ }
+
+ typedef int *raw_iterator;
+
+ raw_iterator raw_begin() {
+ clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
+ return storage;
+ }
+ raw_iterator raw_end() {
+ clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
+ return storage + size;
+ }
+};
+
+class MySetSubclass : public MySet {
+public:
+ MySetSubclass() {
+ clang_analyzer_checkInlined(true);
+#if INLINE
+ // expected-warning@-2 {{TRUE}}
+#endif
+ }
+
+ void useIterator(iterator i) {
+ clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
+ }
+};
+
+class BeginOnlySet {
+ MySet impl;
+public:
+ struct IterImpl {
+ MySet::iterator impl;
+ typedef std::forward_iterator_tag iterator_category;
+
+ IterImpl(MySet::iterator i) : impl(i) {
+ clang_analyzer_checkInlined(true);
+#if INLINE
+ // expected-warning@-2 {{TRUE}}
+#endif
+ }
+ };
+
+ BeginOnlySet() {
+ clang_analyzer_checkInlined(true);
+#if INLINE
+ // expected-warning@-2 {{TRUE}}
+#endif
+ }
+
+ typedef IterImpl wrapped_iterator;
+
+ wrapped_iterator begin() {
+ clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
+ return IterImpl(impl.begin());
+ }
+};
+
+class IteratorTypedefOnlySet {
+ MySet impl;
+public:
+
+ IteratorTypedefOnlySet() {
+ clang_analyzer_checkInlined(true);
+#if INLINE
+ // expected-warning@-2 {{TRUE}}
+#endif
+ }
+
+ typedef MySet::iterator iterator;
+
+ iterator start() {
+ clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
+ return impl.begin();
+ }
+};
+
+class IteratorUsingOnlySet {
+ MySet impl;
+public:
+
+ IteratorUsingOnlySet() {
+ clang_analyzer_checkInlined(true);
+#if INLINE
+ // expected-warning@-2 {{TRUE}}
+#endif
+ }
+
+ using iterator = MySet::iterator;
+
+ iterator start() {
+ clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
+ return impl.begin();
+ }
+};
+
+class IteratorStructOnlySet {
+ MySet impl;
+public:
+
+ IteratorStructOnlySet() {
+ clang_analyzer_checkInlined(true);
+#if INLINE
+ // expected-warning@-2 {{TRUE}}
+#endif
+ }
+
+ struct iterator {
+ int *impl;
+ };
+
+ iterator start() {
+ clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
+ return iterator{impl.begin().impl};
+ }
+};
+
+#endif // HEADER
diff --git a/test/Analysis/inlining/dyn-dispatch-bifurcate.cpp b/test/Analysis/inlining/dyn-dispatch-bifurcate.cpp
index 890e5640ce..d219446fc9 100644
--- a/test/Analysis/inlining/dyn-dispatch-bifurcate.cpp
+++ b/test/Analysis/inlining/dyn-dispatch-bifurcate.cpp
@@ -16,6 +16,11 @@ void testKnown() {
clang_analyzer_eval(a.get() == 0); // expected-warning{{TRUE}}
}
+void testNew() {
+ A *a = new A();
+ clang_analyzer_eval(a->get() == 0); // expected-warning{{TRUE}}
+}
+
namespace ReinterpretDisruptsDynamicTypeInfo {
class Parent {};
diff --git a/test/Analysis/inlining/eager-reclamation-path-notes.c b/test/Analysis/inlining/eager-reclamation-path-notes.c
index f3e7376156..65613658fc 100644
--- a/test/Analysis/inlining/eager-reclamation-path-notes.c
+++ b/test/Analysis/inlining/eager-reclamation-path-notes.c
@@ -120,40 +120,6 @@ void testChainedCalls() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>21</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>21</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>end</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>21</integer>
-// CHECK-NEXT: <key>col</key><integer>10</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>21</integer>
-// CHECK-NEXT: <key>col</key><integer>16</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>control</string>
-// CHECK-NEXT: <key>edges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>start</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>21</integer>
// CHECK-NEXT: <key>col</key><integer>10</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -286,11 +252,45 @@ void testChainedCalls() {
// CHECK-NEXT: </array>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>6</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>6</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>6</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>6</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>6</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -324,7 +324,7 @@ void testChainedCalls() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>6</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -577,40 +577,6 @@ void testChainedCalls() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>33</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>33</integer>
-// CHECK-NEXT: <key>col</key><integer>6</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>end</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>33</integer>
-// CHECK-NEXT: <key>col</key><integer>11</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>33</integer>
-// CHECK-NEXT: <key>col</key><integer>17</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>control</string>
-// CHECK-NEXT: <key>edges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>start</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>33</integer>
// CHECK-NEXT: <key>col</key><integer>11</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -743,11 +709,45 @@ void testChainedCalls() {
// CHECK-NEXT: </array>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>28</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>28</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>28</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>28</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>28</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -781,7 +781,7 @@ void testChainedCalls() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>28</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
diff --git a/test/Analysis/inlining/eager-reclamation-path-notes.cpp b/test/Analysis/inlining/eager-reclamation-path-notes.cpp
index 3ee9d92b01..05411bbc77 100644
--- a/test/Analysis/inlining/eager-reclamation-path-notes.cpp
+++ b/test/Analysis/inlining/eager-reclamation-path-notes.cpp
@@ -202,7 +202,7 @@ int memberCallBaseDisappears() {
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>1</integer>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>Returning from &apos;getNullWrapper&apos;</string>
// CHECK-NEXT: <key>message</key>
@@ -217,40 +217,6 @@ int memberCallBaseDisappears() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>24</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>24</integer>
-// CHECK-NEXT: <key>col</key><integer>12</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>end</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>24</integer>
-// CHECK-NEXT: <key>col</key><integer>21</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>24</integer>
-// CHECK-NEXT: <key>col</key><integer>34</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>control</string>
-// CHECK-NEXT: <key>edges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>start</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>24</integer>
// CHECK-NEXT: <key>col</key><integer>21</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
diff --git a/test/Analysis/inlining/false-positive-suppression.c b/test/Analysis/inlining/false-positive-suppression.c
index bed64f1837..c5c6bb875e 100644
--- a/test/Analysis/inlining/false-positive-suppression.c
+++ b/test/Analysis/inlining/false-positive-suppression.c
@@ -9,6 +9,8 @@ int *getNull() {
return 0;
}
+int* getPtr();
+
int *dynCastToInt(void *ptr) {
if (opaquePropertyCheck(ptr))
return (int *)ptr;
@@ -141,6 +143,27 @@ void testTrackNullVariable() {
#endif
}
+void inlinedIsDifferent(int inlined) {
+ int i;
+
+ // We were erroneously picking up the inner stack frame's initialization,
+ // even though the error occurs in the outer stack frame!
+ int *p = inlined ? &i : getNull();
+
+ if (!inlined)
+ inlinedIsDifferent(1);
+
+ *p = 1;
+#ifndef SUPPRESSED
+ // expected-warning@-2 {{Dereference of null pointer}}
+#endif
+}
+
+void testInlinedIsDifferent() {
+ // <rdar://problem/13787723>
+ inlinedIsDifferent(0);
+}
+
// ---------------------------------------
// FALSE NEGATIVES (over-suppression)
@@ -191,3 +214,77 @@ void testAlwaysReturnNull(void *input) {
#endif
}
+int derefArg(int *p) {
+ return *p;
+#ifndef SUPPRESSED
+ // expected-warning@-2 {{Dereference of null pointer}}
+#endif
+}
+void ternaryArg(char cond) {
+ static int x;
+ derefArg(cond ? &x : getNull());
+}
+
+int derefArgCast(char *p) {
+ return *p;
+#ifndef SUPPRESSED
+ // expected-warning@-2 {{Dereference of null pointer}}
+#endif
+}
+void ternaryArgCast(char cond) {
+ static int x;
+ derefArgCast((char*)((unsigned)cond ? &x : getNull()));
+}
+
+int derefAssignment(int *p) {
+ return *p;
+#ifndef SUPPRESSED
+ // expected-warning@-2 {{Dereference of null pointer}}
+#endif
+}
+
+void ternaryAssignment(char cond) {
+ static int x;
+ int *p = cond ? getNull() : getPtr();
+ derefAssignment(p);
+}
+
+int *retNull(char cond) {
+ static int x;
+ return cond ? &x : getNull();
+}
+int ternaryRetNull(char cond) {
+ int *p = retNull(cond);
+ return *p;
+#ifndef SUPPRESSED
+ // expected-warning@-2 {{Dereference of null pointer}}
+#endif
+}
+
+// Test suppression of nested conditional operators.
+int testConditionalOperatorSuppress(int x) {
+ return *(x ? getNull() : getPtr());
+#ifndef SUPPRESSED
+ // expected-warning@-2 {{Dereference of null pointer}}
+#endif
+}
+int testNestedConditionalOperatorSuppress(int x) {
+ return *(x ? (x ? getNull() : getPtr()) : getPtr());
+#ifndef SUPPRESSED
+ // expected-warning@-2 {{Dereference of null pointer}}
+#endif
+}
+int testConditionalOperator(int x) {
+ return *(x ? 0 : getPtr()); // expected-warning {{Dereference of null pointer}}
+}
+int testNestedConditionalOperator(int x) {
+ return *(x ? (x ? 0 : getPtr()) : getPtr()); // expected-warning {{Dereference of null pointer}}
+}
+
+int testConditionalOperatorSuppressFloatCond(float x) {
+ return *(x ? getNull() : getPtr());
+#ifndef SUPPRESSED
+ // expected-warning@-2 {{Dereference of null pointer}}
+#endif
+}
+
diff --git a/test/Analysis/inlining/false-positive-suppression.cpp b/test/Analysis/inlining/false-positive-suppression.cpp
index f27c7cf364..bff6907809 100644
--- a/test/Analysis/inlining/false-positive-suppression.cpp
+++ b/test/Analysis/inlining/false-positive-suppression.cpp
@@ -40,6 +40,11 @@ inline void* operator new(__typeof__(sizeof(int)), void* __p) throw()
extern bool coin();
+class SomeClass {
+public:
+ void doSomething();
+};
+
namespace References {
class Map {
int *&getNewBox();
@@ -79,15 +84,10 @@ namespace References {
*box = 1; // no-warning
int *&box2 = m.getValue(i);
- box = 0;
- *box = 1; // expected-warning {{Dereference of null pointer}}
+ box2 = 0;
+ *box2 = 1; // expected-warning {{Dereference of null pointer}}
}
- class SomeClass {
- public:
- void doSomething();
- };
-
SomeClass *&getSomeClass() {
if (coin()) {
extern SomeClass *&opaqueClass();
@@ -125,3 +125,88 @@ namespace References {
#endif
}
}
+
+class X{
+public:
+ void get();
+};
+
+X *getNull() {
+ return 0;
+}
+
+void deref1(X *const &p) {
+ return p->get();
+ #ifndef SUPPRESSED
+ // expected-warning@-2 {{Called C++ object pointer is null}}
+ #endif
+}
+
+void test1() {
+ return deref1(getNull());
+}
+
+void deref2(X *p3) {
+ p3->get();
+ #ifndef SUPPRESSED
+ // expected-warning@-2 {{Called C++ object pointer is null}}
+ #endif
+}
+
+void pass2(X *const &p2) {
+ deref2(p2);
+}
+
+void test2() {
+ pass2(getNull());
+}
+
+void deref3(X *const &p2) {
+ X *p3 = p2;
+ p3->get();
+ #ifndef SUPPRESSED
+ // expected-warning@-2 {{Called C++ object pointer is null}}
+ #endif
+}
+
+void test3() {
+ deref3(getNull());
+}
+
+
+namespace Cleanups {
+ class NonTrivial {
+ public:
+ ~NonTrivial();
+
+ SomeClass *getNull() {
+ return 0;
+ }
+ };
+
+ void testImmediate() {
+ NonTrivial().getNull()->doSomething();
+#ifndef SUPPRESSED
+ // expected-warning@-2 {{Called C++ object pointer is null}}
+#endif
+ }
+
+ void testAssignment() {
+ SomeClass *ptr = NonTrivial().getNull();
+ ptr->doSomething();
+#ifndef SUPPRESSED
+ // expected-warning@-2 {{Called C++ object pointer is null}}
+#endif
+ }
+
+ void testArgumentHelper(SomeClass *arg) {
+ arg->doSomething();
+#ifndef SUPPRESSED
+ // expected-warning@-2 {{Called C++ object pointer is null}}
+#endif
+ }
+
+ void testArgument() {
+ testArgumentHelper(NonTrivial().getNull());
+ }
+}
diff --git a/test/Analysis/inlining/false-positive-suppression.m b/test/Analysis/inlining/false-positive-suppression.m
new file mode 100644
index 0000000000..53ec138367
--- /dev/null
+++ b/test/Analysis/inlining/false-positive-suppression.m
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-config suppress-null-return-paths=false -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify -DSUPPRESSED=1 %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-config avoid-suppressing-null-argument-paths=true -DSUPPRESSED=1 -DNULL_ARGS=1 -verify %s
+
+#ifdef SUPPRESSED
+// expected-no-diagnostics
+#endif
+
+@interface PointerWrapper
+- (int *)getPtr;
+- (id)getObject;
+@end
+
+id getNil() {
+ return 0;
+}
+
+void testNilReceiverHelperA(int *x) {
+ *x = 1;
+#ifndef SUPPRESSED
+ // expected-warning@-2 {{Dereference of null pointer}}
+#endif
+}
+
+void testNilReceiverHelperB(int *x) {
+ *x = 1;
+#ifndef SUPPRESSED
+ // expected-warning@-2 {{Dereference of null pointer}}
+#endif
+}
+
+void testNilReceiver(int coin) {
+ id x = getNil();
+ if (coin)
+ testNilReceiverHelperA([x getPtr]);
+ else
+ testNilReceiverHelperB([[x getObject] getPtr]);
+}
diff --git a/test/Analysis/inlining/inline-defensive-checks.c b/test/Analysis/inlining/inline-defensive-checks.c
index df3a8f2281..aa7f70030c 100644
--- a/test/Analysis/inlining/inline-defensive-checks.c
+++ b/test/Analysis/inlining/inline-defensive-checks.c
@@ -97,3 +97,16 @@ void test24(char *buffer) {
use(buffer);
buffer[1] = 'b';
}
+
+// Ensure idc works on pointers with constant offset.
+void idcchar(const char *s2) {
+ if(s2)
+ ;
+}
+void testConstantOffset(char *value) {
+ char *cursor = value + 5;
+ idcchar(cursor);
+ if (*cursor) {
+ cursor++;
+ }
+}
diff --git a/test/Analysis/inlining/inline-defensive-checks.cpp b/test/Analysis/inlining/inline-defensive-checks.cpp
index c77961d03c..b69c535657 100644
--- a/test/Analysis/inlining/inline-defensive-checks.cpp
+++ b/test/Analysis/inlining/inline-defensive-checks.cpp
@@ -1,6 +1,12 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify %s
// expected-no-diagnostics
+extern void __assert_fail (__const char *__assertion, __const char *__file,
+ unsigned int __line, __const char *__function)
+__attribute__ ((__noreturn__));
+#define assert(expr) \
+((expr) ? (void)(0) : __assert_fail (#expr, __FILE__, __LINE__, __func__))
+
class ButterFly {
private:
ButterFly() { }
@@ -29,4 +35,39 @@ class X{
subtest1();
return subtest2();
}
-}; \ No newline at end of file
+};
+
+typedef const int *Ty;
+extern
+Ty notNullArg(Ty cf) __attribute__((nonnull));
+typedef const void *CFTypeRef;
+extern Ty getTyVal();
+inline void radar13224271_callee(Ty def, Ty& result ) {
+ result = def;
+ // Clearly indicates that result cannot be 0 if def is not NULL.
+ assert( (result != 0) || (def == 0) );
+}
+void radar13224271_caller()
+{
+ Ty value;
+ radar13224271_callee(getTyVal(), value );
+ notNullArg(value); // no-warning
+}
+
+struct Foo {
+ int *ptr;
+ Foo(int *p) {
+ *p = 1; // no-warning
+ }
+};
+void idc(int *p3) {
+ if (p3)
+ ;
+}
+int *retNull() {
+ return 0;
+}
+void test(int *p1, int *p2) {
+ idc(p1);
+ Foo f(p1);
+} \ No newline at end of file
diff --git a/test/Analysis/inlining/inline-defensive-checks.m b/test/Analysis/inlining/inline-defensive-checks.m
index bafc812486..0404ee6df8 100644
--- a/test/Analysis/inlining/inline-defensive-checks.m
+++ b/test/Analysis/inlining/inline-defensive-checks.m
@@ -16,7 +16,6 @@ typedef struct objc_object {
-(id)retain;
@end
-// expected-no-diagnostics
// Check that inline defensive checks is triggered for null expressions
// within CompoundLiteralExpr.
typedef union {
@@ -44,3 +43,87 @@ dispatch_resume(dispatch_object_t object);
dispatch_resume(p); // no warning
}
@end
+
+// Test nil receiver suppression.
+// We only suppress on nil receiver if the nil value is directly causing the bug.
+@interface Foo {
+@public
+ int x;
+}
+- (Foo *)getFooPtr;
+@end
+
+Foo *retNil() {
+ return 0;
+}
+
+Foo *retInputOrNil(Foo *p) {
+ if (p)
+ return p;
+ return 0;
+}
+
+void idc(Foo *p) {
+ if (p)
+ ;
+}
+
+int testNilReceiver(Foo* fPtr) {
+ if (fPtr)
+ ;
+ // On a path where fPtr is nil, mem should be nil.
+ Foo *mem = [fPtr getFooPtr];
+ return mem->x; // expected-warning {{Access to instance variable 'x' results in a dereference of a null pointer}}
+}
+
+int suppressNilReceiverRetNullCond(Foo* fPtr) {
+ unsigned zero = 0;
+ fPtr = retInputOrNil(fPtr);
+ // On a path where fPtr is nzil, mem should be nil.
+ Foo *mem = [fPtr getFooPtr];
+ return mem->x;
+}
+
+int suppressNilReceiverRetNullCondCast(id fPtr) {
+ unsigned zero = 0;
+ fPtr = retInputOrNil(fPtr);
+ // On a path where fPtr is nzil, mem should be nil.
+ Foo *mem = ((id)([(Foo*)(fPtr) getFooPtr]));
+ return mem->x;
+}
+
+int dontSuppressNilReceiverRetNullCond(Foo* fPtr) {
+ unsigned zero = 0;
+ fPtr = retInputOrNil(fPtr);
+ // On a path where fPtr is nil, mem should be nil.
+ // The warning is not suppressed because the receiver being nil is not
+ // directly related to the value that triggers the warning.
+ Foo *mem = [fPtr getFooPtr];
+ if (!mem)
+ return 5/zero; // expected-warning {{Division by zero}}
+ return 0;
+}
+
+int dontSuppressNilReceiverRetNull(Foo* fPtr) {
+ unsigned zero = 0;
+ fPtr = retNil();
+ // On a path where fPtr is nil, mem should be nil.
+ // The warning is not suppressed because the receiver being nil is not
+ // directly related to the value that triggers the warning.
+ Foo *mem = [fPtr getFooPtr];
+ if (!mem)
+ return 5/zero; // expected-warning {{Division by zero}}
+ return 0;
+}
+
+int dontSuppressNilReceiverIDC(Foo* fPtr) {
+ unsigned zero = 0;
+ idc(fPtr);
+ // On a path where fPtr is nil, mem should be nil.
+ // The warning is not suppressed because the receiver being nil is not
+ // directly related to the value that triggers the warning.
+ Foo *mem = [fPtr getFooPtr];
+ if (!mem)
+ return 5/zero; // expected-warning {{Division by zero}}
+ return 0;
+}
diff --git a/test/Analysis/inlining/path-notes.c b/test/Analysis/inlining/path-notes.c
index b128aabf7e..660988535b 100644
--- a/test/Analysis/inlining/path-notes.c
+++ b/test/Analysis/inlining/path-notes.c
@@ -107,6 +107,39 @@ void testUseOfNullPointer() {
// expected-note@-4 {{Calling 'usePointer'}}
}
+struct X { char *p; };
+
+void setFieldToNull(struct X *x) {
+ x->p = 0; // expected-note {{Null pointer value stored to field 'p'}}
+}
+
+int testSetFieldToNull(struct X *x) {
+ setFieldToNull(x); // expected-note {{Calling 'setFieldToNull'}}
+ // expected-note@-1{{Returning from 'setFieldToNull'}}
+ return *x->p;
+ // expected-warning@-1 {{Dereference of null pointer (loaded from field 'p')}}
+ // expected-note@-2 {{Dereference of null pointer (loaded from field 'p')}}
+}
+
+struct Outer {
+ struct Inner {
+ int *p;
+ } inner;
+};
+
+void test(struct Outer *wrapperPtr) {
+ wrapperPtr->inner.p = 0; // expected-note {{Null pointer value stored to field 'p'}}
+ *wrapperPtr->inner.p = 1; //expected-warning {{Dereference of null pointer (loaded from field 'p')}}
+ // expected-note@-1 {{Dereference of null pointer (loaded from field 'p')}}
+}
+
+void test4(int **p) {
+ if (*p) return; // expected-note {{Taking false branch}}
+ // expected-note@-1 {{Assuming pointer value is null}}
+ **p = 1; // expected-warning {{Dereference of null pointer}}
+ // expected-note@-1 {{Dereference of null pointer}}
+}
+
// CHECK: <key>diagnostics</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
@@ -241,7 +274,7 @@ void testUseOfNullPointer() {
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>1</integer>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>Returning from &apos;zero&apos;</string>
// CHECK-NEXT: <key>message</key>
@@ -269,12 +302,12 @@ void testUseOfNullPointer() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>14</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>14</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
@@ -286,7 +319,7 @@ void testUseOfNullPointer() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>14</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -320,7 +353,7 @@ void testUseOfNullPointer() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>14</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -425,11 +458,45 @@ void testUseOfNullPointer() {
// CHECK-NEXT: </array>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>24</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>24</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>24</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>24</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>24</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -463,7 +530,7 @@ void testUseOfNullPointer() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>24</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -631,11 +698,45 @@ void testUseOfNullPointer() {
// CHECK-NEXT: </array>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>39</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>39</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>39</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>39</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>39</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -669,7 +770,7 @@ void testUseOfNullPointer() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>39</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -837,11 +938,45 @@ void testUseOfNullPointer() {
// CHECK-NEXT: </array>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>51</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>51</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>51</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>51</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>51</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -875,7 +1010,7 @@ void testUseOfNullPointer() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>51</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -1108,7 +1243,7 @@ void testUseOfNullPointer() {
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>1</integer>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>Returning from &apos;getZero&apos;</string>
// CHECK-NEXT: <key>message</key>
@@ -1123,40 +1258,6 @@ void testUseOfNullPointer() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>65</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>65</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>end</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>65</integer>
-// CHECK-NEXT: <key>col</key><integer>4</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>65</integer>
-// CHECK-NEXT: <key>col</key><integer>10</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>control</string>
-// CHECK-NEXT: <key>edges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>start</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>65</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1170,12 +1271,12 @@ void testUseOfNullPointer() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>65</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>14</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>65</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>14</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
@@ -1187,7 +1288,7 @@ void testUseOfNullPointer() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>65</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>14</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -1221,7 +1322,7 @@ void testUseOfNullPointer() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>65</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>14</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -1454,7 +1555,7 @@ void testUseOfNullPointer() {
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>1</integer>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>Returning from &apos;getZero&apos;</string>
// CHECK-NEXT: <key>message</key>
@@ -1469,40 +1570,6 @@ void testUseOfNullPointer() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>72</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>72</integer>
-// CHECK-NEXT: <key>col</key><integer>8</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>end</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>72</integer>
-// CHECK-NEXT: <key>col</key><integer>11</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>72</integer>
-// CHECK-NEXT: <key>col</key><integer>17</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>control</string>
-// CHECK-NEXT: <key>edges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>start</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>72</integer>
// CHECK-NEXT: <key>col</key><integer>11</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1800,7 +1867,7 @@ void testUseOfNullPointer() {
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>1</integer>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>Returning from &apos;getZero&apos;</string>
// CHECK-NEXT: <key>message</key>
@@ -1815,40 +1882,6 @@ void testUseOfNullPointer() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>79</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>79</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>end</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>79</integer>
-// CHECK-NEXT: <key>col</key><integer>12</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>79</integer>
-// CHECK-NEXT: <key>col</key><integer>18</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>control</string>
-// CHECK-NEXT: <key>edges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>start</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>79</integer>
// CHECK-NEXT: <key>col</key><integer>12</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1925,12 +1958,12 @@ void testUseOfNullPointer() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>83</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>83</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
@@ -1942,7 +1975,7 @@ void testUseOfNullPointer() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>83</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -1976,7 +2009,7 @@ void testUseOfNullPointer() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>83</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -2209,7 +2242,7 @@ void testUseOfNullPointer() {
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>1</integer>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>Returning from &apos;getZero&apos;</string>
// CHECK-NEXT: <key>message</key>
@@ -2224,40 +2257,6 @@ void testUseOfNullPointer() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>88</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>88</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>end</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>88</integer>
-// CHECK-NEXT: <key>col</key><integer>7</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>88</integer>
-// CHECK-NEXT: <key>col</key><integer>13</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>control</string>
-// CHECK-NEXT: <key>edges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>start</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>88</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2334,12 +2333,12 @@ void testUseOfNullPointer() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>92</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>92</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
@@ -2351,7 +2350,7 @@ void testUseOfNullPointer() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>92</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -2385,7 +2384,7 @@ void testUseOfNullPointer() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>92</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -2618,47 +2617,13 @@ void testUseOfNullPointer() {
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>1</integer>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>Returning from &apos;getZero&apos;</string>
// CHECK-NEXT: <key>message</key>
// CHECK-NEXT: <string>Returning from &apos;getZero&apos;</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>control</string>
-// CHECK-NEXT: <key>edges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>start</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>103</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>103</integer>
-// CHECK-NEXT: <key>col</key><integer>12</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>end</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>103</integer>
-// CHECK-NEXT: <key>col</key><integer>14</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>103</integer>
-// CHECK-NEXT: <key>col</key><integer>20</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
@@ -2765,11 +2730,45 @@ void testUseOfNullPointer() {
// CHECK-NEXT: </array>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>97</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>97</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>97</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>97</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>97</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -2803,7 +2802,542 @@ void testUseOfNullPointer() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>97</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>path</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>117</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>117</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>117</integer>
+// CHECK-NEXT: <key>col</key><integer>19</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Calling &apos;setFieldToNull&apos;</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Calling &apos;setFieldToNull&apos;</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>112</integer>
+// CHECK-NEXT: <key>col</key><integer>1</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>depth</key><integer>1</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Entered call from &apos;testSetFieldToNull&apos;</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Entered call from &apos;testSetFieldToNull&apos;</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>112</integer>
+// CHECK-NEXT: <key>col</key><integer>1</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>112</integer>
+// CHECK-NEXT: <key>col</key><integer>4</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>113</integer>
+// CHECK-NEXT: <key>col</key><integer>2</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>113</integer>
+// CHECK-NEXT: <key>col</key><integer>2</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>113</integer>
+// CHECK-NEXT: <key>col</key><integer>2</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>113</integer>
+// CHECK-NEXT: <key>col</key><integer>2</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>113</integer>
+// CHECK-NEXT: <key>col</key><integer>9</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>1</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Null pointer value stored to field &apos;p&apos;</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Null pointer value stored to field &apos;p&apos;</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>117</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>117</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>117</integer>
+// CHECK-NEXT: <key>col</key><integer>19</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Returning from &apos;setFieldToNull&apos;</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Returning from &apos;setFieldToNull&apos;</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>117</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>117</integer>
+// CHECK-NEXT: <key>col</key><integer>16</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>119</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>119</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>119</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>119</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>119</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>119</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>119</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>119</integer>
+// CHECK-NEXT: <key>col</key><integer>14</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>119</integer>
+// CHECK-NEXT: <key>col</key><integer>14</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Dereference of null pointer (loaded from field &apos;p&apos;)</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Dereference of null pointer (loaded from field &apos;p&apos;)</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>description</key><string>Dereference of null pointer (loaded from field &apos;p&apos;)</string>
+// CHECK-NEXT: <key>category</key><string>Logic error</string>
+// CHECK-NEXT: <key>type</key><string>Dereference of null pointer</string>
+// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT: <key>issue_context</key><string>testSetFieldToNull</string>
+// CHECK-NEXT: <key>issue_hash</key><string>3</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>119</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>path</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>131</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>131</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>131</integer>
+// CHECK-NEXT: <key>col</key><integer>25</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Null pointer value stored to field &apos;p&apos;</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Null pointer value stored to field &apos;p&apos;</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>131</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>131</integer>
+// CHECK-NEXT: <key>col</key><integer>12</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>132</integer>
+// CHECK-NEXT: <key>col</key><integer>24</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>132</integer>
+// CHECK-NEXT: <key>col</key><integer>24</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>132</integer>
+// CHECK-NEXT: <key>col</key><integer>24</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>132</integer>
+// CHECK-NEXT: <key>col</key><integer>22</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>132</integer>
+// CHECK-NEXT: <key>col</key><integer>22</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Dereference of null pointer (loaded from field &apos;p&apos;)</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Dereference of null pointer (loaded from field &apos;p&apos;)</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>description</key><string>Dereference of null pointer (loaded from field &apos;p&apos;)</string>
+// CHECK-NEXT: <key>category</key><string>Logic error</string>
+// CHECK-NEXT: <key>type</key><string>Dereference of null pointer</string>
+// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT: <key>issue_context</key><string>test</string>
+// CHECK-NEXT: <key>issue_hash</key><string>2</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>132</integer>
+// CHECK-NEXT: <key>col</key><integer>24</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>path</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>137</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>137</integer>
+// CHECK-NEXT: <key>col</key><integer>4</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>137</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>137</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>137</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>137</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>137</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Assuming pointer value is null</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Assuming pointer value is null</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>137</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>137</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>139</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>139</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>139</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>139</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>139</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>139</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>139</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>139</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>139</integer>
+// CHECK-NEXT: <key>col</key><integer>9</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Dereference of null pointer</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Dereference of null pointer</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>description</key><string>Dereference of null pointer</string>
+// CHECK-NEXT: <key>category</key><string>Logic error</string>
+// CHECK-NEXT: <key>type</key><string>Dereference of null pointer</string>
+// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT: <key>issue_context</key><string>test4</string>
+// CHECK-NEXT: <key>issue_hash</key><string>3</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>139</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
diff --git a/test/Analysis/inlining/path-notes.cpp b/test/Analysis/inlining/path-notes.cpp
index 6c63e1400c..e0c83cbe32 100644
--- a/test/Analysis/inlining/path-notes.cpp
+++ b/test/Analysis/inlining/path-notes.cpp
@@ -184,7 +184,6 @@ namespace ReturnZeroNote {
}
}
-
int &returnNullReference() {
int *x = 0;
// expected-note@-1 {{'x' initialized to a null pointer value}}
@@ -192,7 +191,79 @@ int &returnNullReference() {
// expected-note@-1 {{Returning null reference}}
}
+struct FooWithInitializer {
+ int *ptr;
+ FooWithInitializer(int *p) : ptr(p) { // expected-note {{Null pointer value stored to 'f.ptr'}}
+ *ptr = 1; // expected-note {{Dereference of null pointer (loaded from field 'ptr')}}
+ // expected-warning@-1 {{Dereference of null pointer (loaded from field 'ptr')}}
+ }
+};
+
+void testPathNoteOnInitializer() {
+ int *p = 0; // expected-note {{'p' initialized to a null pointer value}}
+
+ FooWithInitializer f(p); // expected-note {{Passing null pointer value via 1st parameter 'p'}}
+ // expected-note@-1 {{Calling constructor for 'FooWithInitializer'}}
+}
+
+int testNonPrintableAssignment(int **p) {
+ int *&y = *p; // expected-note {{'y' initialized here}}
+ y = 0; // expected-note {{Storing null pointer value}}
+ return *y; // expected-warning {{Dereference of null pointer (loaded from variable 'y')}}
+ // expected-note@-1 {{Dereference of null pointer (loaded from variable 'y')}}
+}
+
+struct Base { int *x; };
+struct Derived : public Base {};
+
+void test(Derived d) {
+ d.x = 0; //expected-note {{Null pointer value stored to 'd.x'}}
+ *d.x = 1; // expected-warning {{Dereference of null pointer (loaded from field 'x')}}
+ // expected-note@-1 {{Dereference of null pointer (loaded from field 'x')}}
+}
+
+struct Owner {
+ struct Wrapper {
+ int x;
+ };
+ Wrapper *arr;
+ void testGetDerefExprOnMemberExprWithADot();
+};
+
+void Owner::testGetDerefExprOnMemberExprWithADot() {
+ if (arr) // expected-note {{Assuming pointer value is null}}
+ // expected-note@-1 {{Taking false branch}}
+ ;
+ arr[1].x = 1; //expected-warning {{Dereference of null pointer}}
+ //expected-note@-1 {{Dereference of null pointer}}
+}
+
+void testGetDerefExprOnMemberExprWithADot() {
+ Owner::Wrapper *arr; // expected-note {{'arr' declared without an initial value}}
+ arr[2].x = 1; // expected-warning {{Dereference of undefined pointer value}}
+ // expected-note@-1 {{Dereference of undefined pointer value}}
+}
+
+
+class A {
+public:
+ void bar() const {}
+};
+const A& testDeclRefExprToReferenceInGetDerefExpr(const A *ptr) {
+ const A& val = *ptr; //expected-note {{'val' initialized here}}
+
+ // This is not valid C++; if 'ptr' were null, creating 'ref' would be illegal.
+ // However, this is not checked at runtime, so this branch is actually
+ // possible.
+ if (&val == 0) { //expected-note {{Assuming pointer value is null}}
+ // expected-note@-1 {{Taking true branch}}
+ val.bar(); // expected-warning {{Called C++ object pointer is null}}
+ // expected-note@-1 {{Called C++ object pointer is null}}
+ }
+
+ return val;
+}
// CHECK: <key>diagnostics</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
@@ -706,11 +777,45 @@ int &returnNullReference() {
// CHECK-NEXT: </array>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>8</integer>
+// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>8</integer>
+// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>8</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>8</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>8</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -744,7 +849,7 @@ int &returnNullReference() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>8</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -960,11 +1065,45 @@ int &returnNullReference() {
// CHECK-NEXT: </array>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>41</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>41</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>41</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>41</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>41</integer>
-// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -998,7 +1137,7 @@ int &returnNullReference() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>41</integer>
-// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -1175,11 +1314,45 @@ int &returnNullReference() {
// CHECK-NEXT: </array>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>63</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>63</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>63</integer>
+// CHECK-NEXT: <key>col</key><integer>18</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>63</integer>
+// CHECK-NEXT: <key>col</key><integer>18</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>63</integer>
-// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>col</key><integer>18</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -1211,7 +1384,7 @@ int &returnNullReference() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>63</integer>
-// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>col</key><integer>18</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -1388,11 +1561,45 @@ int &returnNullReference() {
// CHECK-NEXT: </array>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>68</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>68</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>68</integer>
+// CHECK-NEXT: <key>col</key><integer>18</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>68</integer>
+// CHECK-NEXT: <key>col</key><integer>18</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>68</integer>
-// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>col</key><integer>18</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -1424,7 +1631,7 @@ int &returnNullReference() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>68</integer>
-// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>col</key><integer>18</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -1635,11 +1842,45 @@ int &returnNullReference() {
// CHECK-NEXT: </array>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>73</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>73</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>73</integer>
+// CHECK-NEXT: <key>col</key><integer>18</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>73</integer>
+// CHECK-NEXT: <key>col</key><integer>18</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>73</integer>
-// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>col</key><integer>18</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -1671,7 +1912,7 @@ int &returnNullReference() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>73</integer>
-// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>col</key><integer>18</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -1916,11 +2157,45 @@ int &returnNullReference() {
// CHECK-NEXT: </array>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>78</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>78</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>78</integer>
+// CHECK-NEXT: <key>col</key><integer>18</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>78</integer>
+// CHECK-NEXT: <key>col</key><integer>18</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>78</integer>
-// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>col</key><integer>18</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -1954,7 +2229,7 @@ int &returnNullReference() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>78</integer>
-// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>col</key><integer>18</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -2093,40 +2368,6 @@ int &returnNullReference() {
// CHECK-NEXT: </array>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>control</string>
-// CHECK-NEXT: <key>edges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>start</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>145</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>145</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>end</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>145</integer>
-// CHECK-NEXT: <key>col</key><integer>9</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>145</integer>
-// CHECK-NEXT: <key>col</key><integer>12</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
@@ -2267,11 +2508,45 @@ int &returnNullReference() {
// CHECK-NEXT: </array>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>83</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>83</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>83</integer>
+// CHECK-NEXT: <key>col</key><integer>18</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>83</integer>
+// CHECK-NEXT: <key>col</key><integer>18</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>83</integer>
-// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>col</key><integer>18</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -2305,7 +2580,7 @@ int &returnNullReference() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>83</integer>
-// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>col</key><integer>18</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -2520,11 +2795,45 @@ int &returnNullReference() {
// CHECK-NEXT: </array>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>88</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>88</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>88</integer>
+// CHECK-NEXT: <key>col</key><integer>18</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>88</integer>
+// CHECK-NEXT: <key>col</key><integer>18</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>88</integer>
-// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>col</key><integer>18</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -2556,7 +2865,7 @@ int &returnNullReference() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>88</integer>
-// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>col</key><integer>18</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -2726,7 +3035,7 @@ int &returnNullReference() {
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>1</integer>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>Returning from &apos;getZero&apos;</string>
// CHECK-NEXT: <key>message</key>
@@ -2741,40 +3050,6 @@ int &returnNullReference() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>173</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>173</integer>
-// CHECK-NEXT: <key>col</key><integer>7</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>end</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>173</integer>
-// CHECK-NEXT: <key>col</key><integer>23</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>173</integer>
-// CHECK-NEXT: <key>col</key><integer>29</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>control</string>
-// CHECK-NEXT: <key>edges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>start</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>173</integer>
// CHECK-NEXT: <key>col</key><integer>23</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2788,12 +3063,12 @@ int &returnNullReference() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>173</integer>
-// CHECK-NEXT: <key>col</key><integer>19</integer>
+// CHECK-NEXT: <key>col</key><integer>21</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>173</integer>
-// CHECK-NEXT: <key>col</key><integer>19</integer>
+// CHECK-NEXT: <key>col</key><integer>21</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
@@ -2805,7 +3080,7 @@ int &returnNullReference() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>173</integer>
-// CHECK-NEXT: <key>col</key><integer>19</integer>
+// CHECK-NEXT: <key>col</key><integer>21</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -2839,7 +3114,7 @@ int &returnNullReference() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>173</integer>
-// CHECK-NEXT: <key>col</key><integer>19</integer>
+// CHECK-NEXT: <key>col</key><integer>21</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -3106,7 +3381,7 @@ int &returnNullReference() {
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>1</integer>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>Returning from &apos;getZeroByRef&apos;</string>
// CHECK-NEXT: <key>message</key>
@@ -3121,12 +3396,12 @@ int &returnNullReference() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>180</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>col</key><integer>23</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>180</integer>
-// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>col</key><integer>34</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
@@ -3134,12 +3409,12 @@ int &returnNullReference() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>180</integer>
-// CHECK-NEXT: <key>col</key><integer>23</integer>
+// CHECK-NEXT: <key>col</key><integer>21</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>180</integer>
-// CHECK-NEXT: <key>col</key><integer>34</integer>
+// CHECK-NEXT: <key>col</key><integer>21</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
@@ -3147,6 +3422,81 @@ int &returnNullReference() {
// CHECK-NEXT: </array>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>180</integer>
+// CHECK-NEXT: <key>col</key><integer>21</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>180</integer>
+// CHECK-NEXT: <key>col</key><integer>19</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>180</integer>
+// CHECK-NEXT: <key>col</key><integer>36</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Division by zero</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Division by zero</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>description</key><string>Division by zero</string>
+// CHECK-NEXT: <key>category</key><string>Logic error</string>
+// CHECK-NEXT: <key>type</key><string>Division by zero</string>
+// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT: <key>issue_context</key><string>testRef</string>
+// CHECK-NEXT: <key>issue_hash</key><string>1</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>180</integer>
+// CHECK-NEXT: <key>col</key><integer>21</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>path</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>188</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>188</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>188</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>&apos;x&apos; initialized to a null pointer value</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>&apos;x&apos; initialized to a null pointer value</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>control</string>
// CHECK-NEXT: <key>edges</key>
// CHECK-NEXT: <array>
@@ -3154,29 +3504,172 @@ int &returnNullReference() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>180</integer>
-// CHECK-NEXT: <key>col</key><integer>23</integer>
+// CHECK-NEXT: <key>line</key><integer>188</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>180</integer>
-// CHECK-NEXT: <key>col</key><integer>34</integer>
+// CHECK-NEXT: <key>line</key><integer>188</integer>
+// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>180</integer>
+// CHECK-NEXT: <key>line</key><integer>190</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>190</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>190</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>190</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>190</integer>
+// CHECK-NEXT: <key>col</key><integer>11</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Returning null reference</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Returning null reference</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>description</key><string>Returning null reference</string>
+// CHECK-NEXT: <key>category</key><string>Logic error</string>
+// CHECK-NEXT: <key>type</key><string>Returning null reference</string>
+// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT: <key>issue_context</key><string>returnNullReference</string>
+// CHECK-NEXT: <key>issue_hash</key><string>3</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>190</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>path</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>203</integer>
+// CHECK-NEXT: <key>col</key><integer>2</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>203</integer>
+// CHECK-NEXT: <key>col</key><integer>2</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>203</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>&apos;p&apos; initialized to a null pointer value</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>&apos;p&apos; initialized to a null pointer value</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>203</integer>
+// CHECK-NEXT: <key>col</key><integer>2</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>203</integer>
+// CHECK-NEXT: <key>col</key><integer>4</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>205</integer>
+// CHECK-NEXT: <key>col</key><integer>2</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>205</integer>
// CHECK-NEXT: <key>col</key><integer>19</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>205</integer>
+// CHECK-NEXT: <key>col</key><integer>2</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>180</integer>
+// CHECK-NEXT: <key>line</key><integer>205</integer>
// CHECK-NEXT: <key>col</key><integer>19</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>205</integer>
+// CHECK-NEXT: <key>col</key><integer>23</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>205</integer>
+// CHECK-NEXT: <key>col</key><integer>23</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
// CHECK-NEXT: </dict>
@@ -3184,42 +3677,262 @@ int &returnNullReference() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>180</integer>
-// CHECK-NEXT: <key>col</key><integer>19</integer>
+// CHECK-NEXT: <key>line</key><integer>205</integer>
+// CHECK-NEXT: <key>col</key><integer>23</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>180</integer>
-// CHECK-NEXT: <key>col</key><integer>19</integer>
+// CHECK-NEXT: <key>line</key><integer>205</integer>
+// CHECK-NEXT: <key>col</key><integer>23</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>180</integer>
-// CHECK-NEXT: <key>col</key><integer>36</integer>
+// CHECK-NEXT: <key>line</key><integer>205</integer>
+// CHECK-NEXT: <key>col</key><integer>23</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
// CHECK-NEXT: </array>
// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>Division by zero</string>
+// CHECK-NEXT: <string>Passing null pointer value via 1st parameter &apos;p&apos;</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Division by zero</string>
+// CHECK-NEXT: <string>Passing null pointer value via 1st parameter &apos;p&apos;</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>205</integer>
+// CHECK-NEXT: <key>col</key><integer>23</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>205</integer>
+// CHECK-NEXT: <key>col</key><integer>23</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>205</integer>
+// CHECK-NEXT: <key>col</key><integer>21</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>205</integer>
+// CHECK-NEXT: <key>col</key><integer>21</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>205</integer>
+// CHECK-NEXT: <key>col</key><integer>21</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>205</integer>
+// CHECK-NEXT: <key>col</key><integer>21</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>205</integer>
+// CHECK-NEXT: <key>col</key><integer>24</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Calling constructor for &apos;FooWithInitializer&apos;</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Calling constructor for &apos;FooWithInitializer&apos;</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>196</integer>
+// CHECK-NEXT: <key>col</key><integer>2</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>depth</key><integer>1</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Entered call from &apos;testPathNoteOnInitializer&apos;</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Entered call from &apos;testPathNoteOnInitializer&apos;</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>196</integer>
+// CHECK-NEXT: <key>col</key><integer>2</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>196</integer>
+// CHECK-NEXT: <key>col</key><integer>19</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>196</integer>
+// CHECK-NEXT: <key>col</key><integer>35</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>196</integer>
+// CHECK-NEXT: <key>col</key><integer>35</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>196</integer>
+// CHECK-NEXT: <key>col</key><integer>35</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>196</integer>
+// CHECK-NEXT: <key>col</key><integer>35</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>196</integer>
+// CHECK-NEXT: <key>col</key><integer>31</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>196</integer>
+// CHECK-NEXT: <key>col</key><integer>33</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>196</integer>
+// CHECK-NEXT: <key>col</key><integer>31</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>depth</key><integer>1</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Null pointer value stored to &apos;f.ptr&apos;</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Null pointer value stored to &apos;f.ptr&apos;</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>196</integer>
+// CHECK-NEXT: <key>col</key><integer>31</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>196</integer>
+// CHECK-NEXT: <key>col</key><integer>33</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>197</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>197</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>197</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>197</integer>
+// CHECK-NEXT: <key>col</key><integer>4</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>197</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>1</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Dereference of null pointer (loaded from field &apos;ptr&apos;)</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Dereference of null pointer (loaded from field &apos;ptr&apos;)</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>description</key><string>Division by zero</string>
+// CHECK-NEXT: <key>description</key><string>Dereference of null pointer (loaded from field &apos;ptr&apos;)</string>
// CHECK-NEXT: <key>category</key><string>Logic error</string>
-// CHECK-NEXT: <key>type</key><string>Division by zero</string>
-// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
-// CHECK-NEXT: <key>issue_context</key><string>testRef</string>
+// CHECK-NEXT: <key>type</key><string>Dereference of null pointer</string>
// CHECK-NEXT: <key>issue_hash</key><string>1</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>180</integer>
-// CHECK-NEXT: <key>col</key><integer>19</integer>
+// CHECK-NEXT: <key>line</key><integer>197</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -3230,7 +3943,7 @@ int &returnNullReference() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>189</integer>
+// CHECK-NEXT: <key>line</key><integer>210</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3238,22 +3951,22 @@ int &returnNullReference() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>189</integer>
+// CHECK-NEXT: <key>line</key><integer>210</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>189</integer>
-// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>line</key><integer>210</integer>
+// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
// CHECK-NEXT: </array>
// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>&apos;x&apos; initialized to a null pointer value</string>
+// CHECK-NEXT: <string>&apos;y&apos; initialized here</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>&apos;x&apos; initialized to a null pointer value</string>
+// CHECK-NEXT: <string>&apos;y&apos; initialized here</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>control</string>
@@ -3263,12 +3976,12 @@ int &returnNullReference() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>189</integer>
+// CHECK-NEXT: <key>line</key><integer>210</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>189</integer>
+// CHECK-NEXT: <key>line</key><integer>210</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3276,13 +3989,13 @@ int &returnNullReference() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>191</integer>
+// CHECK-NEXT: <key>line</key><integer>211</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>191</integer>
-// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>line</key><integer>211</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
@@ -3293,7 +4006,7 @@ int &returnNullReference() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>191</integer>
+// CHECK-NEXT: <key>line</key><integer>211</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3301,12 +4014,109 @@ int &returnNullReference() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>191</integer>
-// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>line</key><integer>211</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>211</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Storing null pointer value</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Storing null pointer value</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>211</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>211</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>212</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>212</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>212</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>212</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>212</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>212</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>212</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>212</integer>
+// CHECK-NEXT: <key>col</key><integer>11</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>191</integer>
+// CHECK-NEXT: <key>line</key><integer>212</integer>
// CHECK-NEXT: <key>col</key><integer>11</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3314,21 +4124,622 @@ int &returnNullReference() {
// CHECK-NEXT: </array>
// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>Returning null reference</string>
+// CHECK-NEXT: <string>Dereference of null pointer (loaded from variable &apos;y&apos;)</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Returning null reference</string>
+// CHECK-NEXT: <string>Dereference of null pointer (loaded from variable &apos;y&apos;)</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>description</key><string>Returning null reference</string>
+// CHECK-NEXT: <key>description</key><string>Dereference of null pointer (loaded from variable &apos;y&apos;)</string>
// CHECK-NEXT: <key>category</key><string>Logic error</string>
-// CHECK-NEXT: <key>type</key><string>Returning null reference</string>
+// CHECK-NEXT: <key>type</key><string>Dereference of null pointer</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
-// CHECK-NEXT: <key>issue_context</key><string>returnNullReference</string>
+// CHECK-NEXT: <key>issue_context</key><string>testNonPrintableAssignment</string>
// CHECK-NEXT: <key>issue_hash</key><string>3</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>191</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>line</key><integer>212</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>path</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>220</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>220</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>220</integer>
+// CHECK-NEXT: <key>col</key><integer>9</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Null pointer value stored to &apos;d.x&apos;</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Null pointer value stored to &apos;d.x&apos;</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>220</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>220</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>221</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>221</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>221</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>221</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>221</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Dereference of null pointer (loaded from field &apos;x&apos;)</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Dereference of null pointer (loaded from field &apos;x&apos;)</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>description</key><string>Dereference of null pointer (loaded from field &apos;x&apos;)</string>
+// CHECK-NEXT: <key>category</key><string>Logic error</string>
+// CHECK-NEXT: <key>type</key><string>Dereference of null pointer</string>
+// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT: <key>issue_context</key><string>test</string>
+// CHECK-NEXT: <key>issue_hash</key><string>2</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>221</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>path</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>234</integer>
+// CHECK-NEXT: <key>col</key><integer>2</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>234</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>234</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>234</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>234</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>234</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>234</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Assuming pointer value is null</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Assuming pointer value is null</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>234</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>234</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>237</integer>
+// CHECK-NEXT: <key>col</key><integer>2</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>237</integer>
+// CHECK-NEXT: <key>col</key><integer>4</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>237</integer>
+// CHECK-NEXT: <key>col</key><integer>2</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>237</integer>
+// CHECK-NEXT: <key>col</key><integer>4</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>237</integer>
+// CHECK-NEXT: <key>col</key><integer>11</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>237</integer>
+// CHECK-NEXT: <key>col</key><integer>11</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>237</integer>
+// CHECK-NEXT: <key>col</key><integer>11</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>237</integer>
+// CHECK-NEXT: <key>col</key><integer>2</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>237</integer>
+// CHECK-NEXT: <key>col</key><integer>13</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Dereference of null pointer</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Dereference of null pointer</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>description</key><string>Dereference of null pointer</string>
+// CHECK-NEXT: <key>category</key><string>Logic error</string>
+// CHECK-NEXT: <key>type</key><string>Dereference of null pointer</string>
+// CHECK-NEXT: <key>issue_context_kind</key><string>C++ method</string>
+// CHECK-NEXT: <key>issue_context</key><string>testGetDerefExprOnMemberExprWithADot</string>
+// CHECK-NEXT: <key>issue_hash</key><string>4</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>237</integer>
+// CHECK-NEXT: <key>col</key><integer>11</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>path</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>242</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>242</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>242</integer>
+// CHECK-NEXT: <key>col</key><integer>21</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>&apos;arr&apos; declared without an initial value</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>&apos;arr&apos; declared without an initial value</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>242</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>242</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>243</integer>
+// CHECK-NEXT: <key>col</key><integer>11</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>243</integer>
+// CHECK-NEXT: <key>col</key><integer>11</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>243</integer>
+// CHECK-NEXT: <key>col</key><integer>11</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>243</integer>
+// CHECK-NEXT: <key>col</key><integer>2</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>243</integer>
+// CHECK-NEXT: <key>col</key><integer>13</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Dereference of undefined pointer value</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Dereference of undefined pointer value</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>description</key><string>Dereference of undefined pointer value</string>
+// CHECK-NEXT: <key>category</key><string>Logic error</string>
+// CHECK-NEXT: <key>type</key><string>Dereference of undefined pointer value</string>
+// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT: <key>issue_context</key><string>testGetDerefExprOnMemberExprWithADot</string>
+// CHECK-NEXT: <key>issue_hash</key><string>2</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>243</integer>
+// CHECK-NEXT: <key>col</key><integer>11</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>path</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>254</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>254</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>254</integer>
+// CHECK-NEXT: <key>col</key><integer>14</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>&apos;val&apos; initialized here</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>&apos;val&apos; initialized here</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>254</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>254</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>259</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>259</integer>
+// CHECK-NEXT: <key>col</key><integer>4</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>259</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>259</integer>
+// CHECK-NEXT: <key>col</key><integer>4</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>259</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>259</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>259</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>259</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>259</integer>
+// CHECK-NEXT: <key>col</key><integer>15</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Assuming pointer value is null</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Assuming pointer value is null</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>259</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>259</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>261</integer>
+// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>261</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>261</integer>
+// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>261</integer>
+// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>261</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Called C++ object pointer is null</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Called C++ object pointer is null</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>description</key><string>Called C++ object pointer is null</string>
+// CHECK-NEXT: <key>category</key><string>Logic error</string>
+// CHECK-NEXT: <key>type</key><string>Called C++ object pointer is null</string>
+// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT: <key>issue_context</key><string>testDeclRefExprToReferenceInGetDerefExpr</string>
+// CHECK-NEXT: <key>issue_hash</key><string>8</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>261</integer>
+// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
diff --git a/test/Analysis/inlining/path-notes.m b/test/Analysis/inlining/path-notes.m
index f3a7b6cc0f..74f088a382 100644
--- a/test/Analysis/inlining/path-notes.m
+++ b/test/Analysis/inlining/path-notes.m
@@ -13,7 +13,7 @@ void dispatch_sync(dispatch_queue_t, dispatch_block_t);
int *getZeroIfNil(Test *x) {
return x.p;
- // expected-note@-1 {{No method is called because the receiver is nil}}
+ // expected-note@-1 {{'p' not called because the receiver is nil}}
// expected-note@-2 {{Returning null pointer}}
}
@@ -65,6 +65,31 @@ int testDispatchSyncInliningNoPruning(int coin) {
}
+@interface PointerWrapper
+- (int *)getPtr;
+@end
+
+id getNil() {
+ return 0;
+}
+
+void testNilReceiverHelper(int *x) {
+ *x = 1; // expected-warning {{Dereference of null pointer}}
+ // expected-note@-1 {{Dereference of null pointer (loaded from variable 'x')}}
+}
+
+void testNilReceiver(id *x) {
+ if (*x) {
+ // expected-note@-1 {{Taking false branch}}
+ return;
+ }
+ testNilReceiverHelper([*x getPtr]);
+ // expected-note@-1 {{'getPtr' not called because the receiver is nil}}
+ // expected-note@-2 {{Passing null pointer value via 1st parameter 'x'}}
+ // expected-note@-3 {{Calling 'testNilReceiverHelper'}}
+}
+
+
// CHECK: <key>diagnostics</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
@@ -303,9 +328,9 @@ int testDispatchSyncInliningNoPruning(int coin) {
// CHECK-NEXT: </array>
// CHECK-NEXT: <key>depth</key><integer>1</integer>
// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>No method is called because the receiver is nil</string>
+// CHECK-NEXT: <string>&apos;p&apos; not called because the receiver is nil</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>No method is called because the receiver is nil</string>
+// CHECK-NEXT: <string>&apos;p&apos; not called because the receiver is nil</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>control</string>
@@ -393,7 +418,7 @@ int testDispatchSyncInliningNoPruning(int coin) {
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>1</integer>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>Returning from &apos;getZeroIfNil&apos;</string>
// CHECK-NEXT: <key>message</key>
@@ -408,40 +433,6 @@ int testDispatchSyncInliningNoPruning(int coin) {
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>21</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>21</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>end</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>21</integer>
-// CHECK-NEXT: <key>col</key><integer>4</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>21</integer>
-// CHECK-NEXT: <key>col</key><integer>15</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>control</string>
-// CHECK-NEXT: <key>edges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>start</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>21</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -455,12 +446,12 @@ int testDispatchSyncInliningNoPruning(int coin) {
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>21</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>21</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
@@ -472,7 +463,7 @@ int testDispatchSyncInliningNoPruning(int coin) {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>21</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -506,7 +497,7 @@ int testDispatchSyncInliningNoPruning(int coin) {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>21</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -689,7 +680,7 @@ int testDispatchSyncInliningNoPruning(int coin) {
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
-// CHECK-NEXT: <key>depth</key><integer>2</integer>
+// CHECK-NEXT: <key>depth</key><integer>1</integer>
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>Returning to caller</string>
// CHECK-NEXT: <key>message</key>
@@ -718,7 +709,7 @@ int testDispatchSyncInliningNoPruning(int coin) {
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>1</integer>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>Returning from &apos;dispatch_sync&apos;</string>
// CHECK-NEXT: <key>message</key>
@@ -746,46 +737,12 @@ int testDispatchSyncInliningNoPruning(int coin) {
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>43</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>12</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>43</integer>
-// CHECK-NEXT: <key>col</key><integer>8</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>control</string>
-// CHECK-NEXT: <key>edges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>start</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>43</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>43</integer>
-// CHECK-NEXT: <key>col</key><integer>8</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>end</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>43</integer>
-// CHECK-NEXT: <key>col</key><integer>10</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>43</integer>
-// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>col</key><integer>12</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
@@ -797,7 +754,7 @@ int testDispatchSyncInliningNoPruning(int coin) {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>43</integer>
-// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>col</key><integer>12</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -831,7 +788,7 @@ int testDispatchSyncInliningNoPruning(int coin) {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>43</integer>
-// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>col</key><integer>12</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -1080,4 +1037,321 @@ int testDispatchSyncInliningNoPruning(int coin) {
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>path</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>82</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>82</integer>
+// CHECK-NEXT: <key>col</key><integer>4</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>86</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>86</integer>
+// CHECK-NEXT: <key>col</key><integer>23</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>86</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>86</integer>
+// CHECK-NEXT: <key>col</key><integer>23</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>86</integer>
+// CHECK-NEXT: <key>col</key><integer>26</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>86</integer>
+// CHECK-NEXT: <key>col</key><integer>26</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>86</integer>
+// CHECK-NEXT: <key>col</key><integer>26</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>86</integer>
+// CHECK-NEXT: <key>col</key><integer>26</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>86</integer>
+// CHECK-NEXT: <key>col</key><integer>27</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>&apos;getPtr&apos; not called because the receiver is nil</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>&apos;getPtr&apos; not called because the receiver is nil</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>86</integer>
+// CHECK-NEXT: <key>col</key><integer>26</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>86</integer>
+// CHECK-NEXT: <key>col</key><integer>26</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>86</integer>
+// CHECK-NEXT: <key>col</key><integer>25</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>86</integer>
+// CHECK-NEXT: <key>col</key><integer>25</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>86</integer>
+// CHECK-NEXT: <key>col</key><integer>25</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>86</integer>
+// CHECK-NEXT: <key>col</key><integer>25</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>86</integer>
+// CHECK-NEXT: <key>col</key><integer>35</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Passing null pointer value via 1st parameter &apos;x&apos;</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Passing null pointer value via 1st parameter &apos;x&apos;</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>86</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>86</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>86</integer>
+// CHECK-NEXT: <key>col</key><integer>36</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Calling &apos;testNilReceiverHelper&apos;</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Calling &apos;testNilReceiverHelper&apos;</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>76</integer>
+// CHECK-NEXT: <key>col</key><integer>1</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>depth</key><integer>1</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Entered call from &apos;testNilReceiver&apos;</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Entered call from &apos;testNilReceiver&apos;</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>76</integer>
+// CHECK-NEXT: <key>col</key><integer>1</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>76</integer>
+// CHECK-NEXT: <key>col</key><integer>4</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>77</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>77</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>77</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>77</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>77</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>77</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>77</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>77</integer>
+// CHECK-NEXT: <key>col</key><integer>4</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>77</integer>
+// CHECK-NEXT: <key>col</key><integer>4</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>1</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Dereference of null pointer (loaded from variable &apos;x&apos;)</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Dereference of null pointer (loaded from variable &apos;x&apos;)</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>description</key><string>Dereference of null pointer (loaded from variable &apos;x&apos;)</string>
+// CHECK-NEXT: <key>category</key><string>Logic error</string>
+// CHECK-NEXT: <key>type</key><string>Dereference of null pointer</string>
+// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT: <key>issue_context</key><string>testNilReceiverHelper</string>
+// CHECK-NEXT: <key>issue_hash</key><string>1</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>77</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
diff --git a/test/Analysis/inlining/stl.cpp b/test/Analysis/inlining/stl.cpp
index b09a5126bc..6053daaf3a 100644
--- a/test/Analysis/inlining/stl.cpp
+++ b/test/Analysis/inlining/stl.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-stdlib-inlining=false -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-stdlib-inlining=true -DINLINE=1 -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-container-inlining=true -analyzer-config c++-stdlib-inlining=false -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-container-inlining=true -analyzer-config c++-stdlib-inlining=true -DINLINE=1 -verify %s
#include "../Inputs/system-header-simulator-cxx.h"
diff --git a/test/Analysis/malloc-annotations.c b/test/Analysis/malloc-annotations.c
index bdd50c6be5..c197df4386 100644
--- a/test/Analysis/malloc-annotations.c
+++ b/test/Analysis/malloc-annotations.c
@@ -26,7 +26,7 @@ struct stuff myglobalstuff;
void f1() {
int *p = malloc(12);
- return; // expected-warning{{Memory is never released; potential leak}}
+ return; // expected-warning{{Potential leak of memory pointed to by}}
}
void f2() {
@@ -54,22 +54,27 @@ void naf1() {
void n2af1() {
int *p = my_malloc2(12);
- return; // expected-warning{{Memory is never released; potential leak}}
+ return; // expected-warning{{Potential leak of memory pointed to by}}
}
void af1() {
int *p = my_malloc(12);
- return; // expected-warning{{Memory is never released; potential leak}}
+ return; // expected-warning{{Potential leak of memory pointed to by}}
}
void af1_b() {
int *p = my_malloc(12);
-} // expected-warning{{Memory is never released; potential leak}}
+} // expected-warning{{Potential leak of memory pointed to by}}
void af1_c() {
myglobalpointer = my_malloc(12); // no-warning
}
+void af1_d() {
+ struct stuff mystuff;
+ mystuff.somefield = my_malloc(12);
+} // expected-warning{{Potential leak of memory pointed to by}}
+
// Test that we can pass out allocated memory via pointer-to-pointer.
void af1_e(void **pp) {
*pp = my_malloc(42); // no-warning
@@ -234,7 +239,7 @@ char mallocGarbage () {
// This tests that calloc() buffers need to be freed
void callocNoFree () {
char *buf = calloc(2,2);
- return; // expected-warning{{never released}}
+ return; // expected-warning{{Potential leak of memory pointed to by}}
}
// These test that calloc() buffers are zeroed by default
@@ -253,7 +258,7 @@ char callocZeroesBad () {
if (buf[1] != 0) {
free(buf); // expected-warning{{never executed}}
}
- return result; // expected-warning{{never released}}
+ return result; // expected-warning{{Potential leak of memory pointed to by}}
}
void testMultipleFreeAnnotations() {
@@ -262,14 +267,3 @@ void testMultipleFreeAnnotations() {
my_freeBoth(p, q);
}
-// ----------------------------------------------------------------------------
-
-// False negatives.
-
-// Pending on removal of the escaping on assignment to struct fields.
-void af1_d() {
- struct stuff mystuff;
- mystuff.somefield = my_malloc(12);
-} // missing warning
-
-
diff --git a/test/Analysis/malloc-interprocedural.c b/test/Analysis/malloc-interprocedural.c
index 3c7bab6717..c78cc6c6aa 100644
--- a/test/Analysis/malloc-interprocedural.c
+++ b/test/Analysis/malloc-interprocedural.c
@@ -32,7 +32,7 @@ static void my_free1(void *p) {
static void test1() {
void *data = 0;
my_malloc1(&data, 4);
-} // expected-warning {{Memory is never released; potential leak of memory pointed to by 'data'}}
+} // expected-warning {{Potential leak of memory pointed to by 'data'}}
static void test11() {
void *data = 0;
@@ -43,9 +43,9 @@ static void test11() {
static void testUniqueingByallocationSiteInTopLevelFunction() {
void *data = my_malloc2(1, 4);
data = 0;
- int x = 5;// expected-warning {{Memory is never released; potential leak of memory pointed to by 'data'}}
+ int x = 5;// expected-warning {{Potential leak of memory pointed to by 'data'}}
data = my_malloc2(1, 4);
-} // expected-warning {{Memory is never released; potential leak of memory pointed to by 'data'}}
+} // expected-warning {{Potential leak of memory pointed to by 'data'}}
static void test3() {
void *data = my_malloc2(1, 4);
@@ -81,7 +81,7 @@ static char *reshape(char *in) {
void testThatRemoveDeadBindingsRunBeforeEachCall() {
char *v = malloc(12);
v = reshape(v);
- v = reshape(v);// expected-warning {{Memory is never released; potential leak of memory pointed to by 'v'}}
+ v = reshape(v);// expected-warning {{Potential leak of memory pointed to by 'v'}}
}
// Test that we keep processing after 'return;'
diff --git a/test/Analysis/malloc-plist.c b/test/Analysis/malloc-plist.c
index ddd09db6ff..41bb8b5793 100644
--- a/test/Analysis/malloc-plist.c
+++ b/test/Analysis/malloc-plist.c
@@ -169,6 +169,28 @@ void use_function_with_leak7() {
function_with_leak7();
}
+// Test that we do not print the name of a variable not visible from where
+// the issue is reported.
+int *my_malloc() {
+ int *p = malloc(12);
+ return p;
+}
+void testOnlyRefferToVisibleVariables() {
+ my_malloc();
+} // expected-warning {{Potential leak of memory}}
+
+struct PointerWrapper{
+ int*p;
+};
+int *my_malloc_into_struct() {
+ struct PointerWrapper w;
+ w.p = malloc(12);
+ return w.p;
+}
+void testMyMalloc() {
+ my_malloc_into_struct(); // expected-warning {{Potential leak of memory}}
+}
+
// CHECK: <key>diagnostics</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
@@ -378,12 +400,12 @@ void use_function_with_leak7() {
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by &apos;p&apos;</string>
+// CHECK-NEXT: <string>Potential leak of memory pointed to by &apos;p&apos;</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by &apos;p&apos;</string>
+// CHECK-NEXT: <string>Potential leak of memory pointed to by &apos;p&apos;</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>description</key><string>Memory is never released; potential leak of memory pointed to by &apos;p&apos;</string>
+// CHECK-NEXT: <key>description</key><string>Potential leak of memory pointed to by &apos;p&apos;</string>
// CHECK-NEXT: <key>category</key><string>Memory Error</string>
// CHECK-NEXT: <key>type</key><string>Memory leak</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
@@ -540,12 +562,12 @@ void use_function_with_leak7() {
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by &apos;A&apos;</string>
+// CHECK-NEXT: <string>Potential leak of memory pointed to by &apos;A&apos;</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by &apos;A&apos;</string>
+// CHECK-NEXT: <string>Potential leak of memory pointed to by &apos;A&apos;</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>description</key><string>Memory is never released; potential leak of memory pointed to by &apos;A&apos;</string>
+// CHECK-NEXT: <key>description</key><string>Potential leak of memory pointed to by &apos;A&apos;</string>
// CHECK-NEXT: <key>category</key><string>Memory Error</string>
// CHECK-NEXT: <key>type</key><string>Memory leak</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
@@ -925,12 +947,12 @@ void use_function_with_leak7() {
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by &apos;buf&apos;</string>
+// CHECK-NEXT: <string>Potential leak of memory pointed to by &apos;buf&apos;</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by &apos;buf&apos;</string>
+// CHECK-NEXT: <string>Potential leak of memory pointed to by &apos;buf&apos;</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>description</key><string>Memory is never released; potential leak of memory pointed to by &apos;buf&apos;</string>
+// CHECK-NEXT: <key>description</key><string>Potential leak of memory pointed to by &apos;buf&apos;</string>
// CHECK-NEXT: <key>category</key><string>Memory Error</string>
// CHECK-NEXT: <key>type</key><string>Memory leak</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
@@ -1274,7 +1296,7 @@ void use_function_with_leak7() {
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>1</integer>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>Returned allocated memory</string>
// CHECK-NEXT: <key>message</key>
@@ -1324,12 +1346,12 @@ void use_function_with_leak7() {
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by &apos;buf&apos;</string>
+// CHECK-NEXT: <string>Potential leak of memory pointed to by &apos;buf&apos;</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by &apos;buf&apos;</string>
+// CHECK-NEXT: <string>Potential leak of memory pointed to by &apos;buf&apos;</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>description</key><string>Memory is never released; potential leak of memory pointed to by &apos;buf&apos;</string>
+// CHECK-NEXT: <key>description</key><string>Potential leak of memory pointed to by &apos;buf&apos;</string>
// CHECK-NEXT: <key>category</key><string>Memory Error</string>
// CHECK-NEXT: <key>type</key><string>Memory leak</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
@@ -1716,11 +1738,11 @@ void use_function_with_leak7() {
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>2</integer>
+// CHECK-NEXT: <key>depth</key><integer>1</integer>
// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>Returned released memory via 1st parameter</string>
+// CHECK-NEXT: <string>Returning; memory was released via 1st parameter</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Returned released memory via 1st parameter</string>
+// CHECK-NEXT: <string>Returning; memory was released via 1st parameter</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>control</string>
@@ -1779,11 +1801,11 @@ void use_function_with_leak7() {
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>1</integer>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>Returned released memory via 1st parameter</string>
+// CHECK-NEXT: <string>Returning; memory was released via 1st parameter</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Returned released memory via 1st parameter</string>
+// CHECK-NEXT: <string>Returning; memory was released via 1st parameter</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>control</string>
@@ -2353,7 +2375,7 @@ void use_function_with_leak7() {
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>1</integer>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>Reallocation of 1st parameter failed</string>
// CHECK-NEXT: <key>message</key>
@@ -2403,12 +2425,12 @@ void use_function_with_leak7() {
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by &apos;buf&apos;</string>
+// CHECK-NEXT: <string>Potential leak of memory pointed to by &apos;buf&apos;</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by &apos;buf&apos;</string>
+// CHECK-NEXT: <string>Potential leak of memory pointed to by &apos;buf&apos;</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>description</key><string>Memory is never released; potential leak of memory pointed to by &apos;buf&apos;</string>
+// CHECK-NEXT: <key>description</key><string>Potential leak of memory pointed to by &apos;buf&apos;</string>
// CHECK-NEXT: <key>category</key><string>Memory Error</string>
// CHECK-NEXT: <key>type</key><string>Memory leak</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
@@ -2621,7 +2643,7 @@ void use_function_with_leak7() {
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>1</integer>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>Returned allocated memory</string>
// CHECK-NEXT: <key>message</key>
@@ -2671,12 +2693,12 @@ void use_function_with_leak7() {
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by &apos;v&apos;</string>
+// CHECK-NEXT: <string>Potential leak of memory pointed to by &apos;v&apos;</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by &apos;v&apos;</string>
+// CHECK-NEXT: <string>Potential leak of memory pointed to by &apos;v&apos;</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>description</key><string>Memory is never released; potential leak of memory pointed to by &apos;v&apos;</string>
+// CHECK-NEXT: <key>description</key><string>Potential leak of memory pointed to by &apos;v&apos;</string>
// CHECK-NEXT: <key>category</key><string>Memory Error</string>
// CHECK-NEXT: <key>type</key><string>Memory leak</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
@@ -2833,12 +2855,12 @@ void use_function_with_leak7() {
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by &apos;m&apos;</string>
+// CHECK-NEXT: <string>Potential leak of memory pointed to by &apos;m&apos;</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by &apos;m&apos;</string>
+// CHECK-NEXT: <string>Potential leak of memory pointed to by &apos;m&apos;</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>description</key><string>Memory is never released; potential leak of memory pointed to by &apos;m&apos;</string>
+// CHECK-NEXT: <key>description</key><string>Potential leak of memory pointed to by &apos;m&apos;</string>
// CHECK-NEXT: <key>category</key><string>Memory Error</string>
// CHECK-NEXT: <key>type</key><string>Memory leak</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
@@ -3038,12 +3060,12 @@ void use_function_with_leak7() {
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>depth</key><integer>1</integer>
// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by &apos;x&apos;</string>
+// CHECK-NEXT: <string>Potential leak of memory pointed to by &apos;x&apos;</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by &apos;x&apos;</string>
+// CHECK-NEXT: <string>Potential leak of memory pointed to by &apos;x&apos;</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>description</key><string>Memory is never released; potential leak of memory pointed to by &apos;x&apos;</string>
+// CHECK-NEXT: <key>description</key><string>Potential leak of memory pointed to by &apos;x&apos;</string>
// CHECK-NEXT: <key>category</key><string>Memory Error</string>
// CHECK-NEXT: <key>type</key><string>Memory leak</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
@@ -3243,12 +3265,12 @@ void use_function_with_leak7() {
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>depth</key><integer>1</integer>
// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by &apos;x&apos;</string>
+// CHECK-NEXT: <string>Potential leak of memory pointed to by &apos;x&apos;</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by &apos;x&apos;</string>
+// CHECK-NEXT: <string>Potential leak of memory pointed to by &apos;x&apos;</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>description</key><string>Memory is never released; potential leak of memory pointed to by &apos;x&apos;</string>
+// CHECK-NEXT: <key>description</key><string>Potential leak of memory pointed to by &apos;x&apos;</string>
// CHECK-NEXT: <key>category</key><string>Memory Error</string>
// CHECK-NEXT: <key>type</key><string>Memory leak</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
@@ -3545,12 +3567,12 @@ void use_function_with_leak7() {
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>depth</key><integer>1</integer>
// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by &apos;x&apos;</string>
+// CHECK-NEXT: <string>Potential leak of memory pointed to by &apos;x&apos;</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by &apos;x&apos;</string>
+// CHECK-NEXT: <string>Potential leak of memory pointed to by &apos;x&apos;</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>description</key><string>Memory is never released; potential leak of memory pointed to by &apos;x&apos;</string>
+// CHECK-NEXT: <key>description</key><string>Potential leak of memory pointed to by &apos;x&apos;</string>
// CHECK-NEXT: <key>category</key><string>Memory Error</string>
// CHECK-NEXT: <key>type</key><string>Memory leak</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
@@ -3847,12 +3869,12 @@ void use_function_with_leak7() {
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>depth</key><integer>1</integer>
// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by &apos;x&apos;</string>
+// CHECK-NEXT: <string>Potential leak of memory pointed to by &apos;x&apos;</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by &apos;x&apos;</string>
+// CHECK-NEXT: <string>Potential leak of memory pointed to by &apos;x&apos;</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>description</key><string>Memory is never released; potential leak of memory pointed to by &apos;x&apos;</string>
+// CHECK-NEXT: <key>description</key><string>Potential leak of memory pointed to by &apos;x&apos;</string>
// CHECK-NEXT: <key>category</key><string>Memory Error</string>
// CHECK-NEXT: <key>type</key><string>Memory leak</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
@@ -4052,12 +4074,12 @@ void use_function_with_leak7() {
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>depth</key><integer>1</integer>
// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by &apos;x&apos;</string>
+// CHECK-NEXT: <string>Potential leak of memory pointed to by &apos;x&apos;</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by &apos;x&apos;</string>
+// CHECK-NEXT: <string>Potential leak of memory pointed to by &apos;x&apos;</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>description</key><string>Memory is never released; potential leak of memory pointed to by &apos;x&apos;</string>
+// CHECK-NEXT: <key>description</key><string>Potential leak of memory pointed to by &apos;x&apos;</string>
// CHECK-NEXT: <key>category</key><string>Memory Error</string>
// CHECK-NEXT: <key>type</key><string>Memory leak</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
@@ -4257,12 +4279,12 @@ void use_function_with_leak7() {
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>depth</key><integer>1</integer>
// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by &apos;x&apos;</string>
+// CHECK-NEXT: <string>Potential leak of memory pointed to by &apos;x&apos;</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Memory is never released; potential leak of memory pointed to by &apos;x&apos;</string>
+// CHECK-NEXT: <string>Potential leak of memory pointed to by &apos;x&apos;</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>description</key><string>Memory is never released; potential leak of memory pointed to by &apos;x&apos;</string>
+// CHECK-NEXT: <key>description</key><string>Potential leak of memory pointed to by &apos;x&apos;</string>
// CHECK-NEXT: <key>category</key><string>Memory Error</string>
// CHECK-NEXT: <key>type</key><string>Memory leak</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
@@ -4441,7 +4463,7 @@ void use_function_with_leak7() {
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>1</integer>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>Returned allocated memory</string>
// CHECK-NEXT: <key>message</key>
@@ -4491,12 +4513,12 @@ void use_function_with_leak7() {
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>Memory is never released; potential leak</string>
+// CHECK-NEXT: <string>Potential memory leak</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Memory is never released; potential leak</string>
+// CHECK-NEXT: <string>Potential memory leak</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>description</key><string>Memory is never released; potential leak</string>
+// CHECK-NEXT: <key>description</key><string>Potential memory leak</string>
// CHECK-NEXT: <key>category</key><string>Memory Error</string>
// CHECK-NEXT: <key>type</key><string>Memory leak</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
@@ -4509,6 +4531,506 @@ void use_function_with_leak7() {
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>path</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>179</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>179</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>179</integer>
+// CHECK-NEXT: <key>col</key><integer>13</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Calling &apos;my_malloc&apos;</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Calling &apos;my_malloc&apos;</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>174</integer>
+// CHECK-NEXT: <key>col</key><integer>1</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>depth</key><integer>1</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Entered call from &apos;testOnlyRefferToVisibleVariables&apos;</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Entered call from &apos;testOnlyRefferToVisibleVariables&apos;</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>174</integer>
+// CHECK-NEXT: <key>col</key><integer>1</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>174</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>175</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>175</integer>
+// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>175</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>175</integer>
+// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>175</integer>
+// CHECK-NEXT: <key>col</key><integer>12</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>175</integer>
+// CHECK-NEXT: <key>col</key><integer>17</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>175</integer>
+// CHECK-NEXT: <key>col</key><integer>12</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>175</integer>
+// CHECK-NEXT: <key>col</key><integer>12</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>175</integer>
+// CHECK-NEXT: <key>col</key><integer>21</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>1</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Memory is allocated</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Memory is allocated</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>179</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>179</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>179</integer>
+// CHECK-NEXT: <key>col</key><integer>13</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Returned allocated memory</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Returned allocated memory</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>179</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>179</integer>
+// CHECK-NEXT: <key>col</key><integer>11</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>180</integer>
+// CHECK-NEXT: <key>col</key><integer>1</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>180</integer>
+// CHECK-NEXT: <key>col</key><integer>1</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>180</integer>
+// CHECK-NEXT: <key>col</key><integer>1</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Potential memory leak</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Potential memory leak</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>description</key><string>Potential memory leak</string>
+// CHECK-NEXT: <key>category</key><string>Memory Error</string>
+// CHECK-NEXT: <key>type</key><string>Memory leak</string>
+// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT: <key>issue_context</key><string>testOnlyRefferToVisibleVariables</string>
+// CHECK-NEXT: <key>issue_hash</key><string>1</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>180</integer>
+// CHECK-NEXT: <key>col</key><integer>1</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>path</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>191</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>191</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>191</integer>
+// CHECK-NEXT: <key>col</key><integer>25</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Calling &apos;my_malloc_into_struct&apos;</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Calling &apos;my_malloc_into_struct&apos;</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>185</integer>
+// CHECK-NEXT: <key>col</key><integer>1</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>depth</key><integer>1</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Entered call from &apos;testMyMalloc&apos;</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Entered call from &apos;testMyMalloc&apos;</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>185</integer>
+// CHECK-NEXT: <key>col</key><integer>1</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>185</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>186</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>186</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>186</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>186</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>187</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>187</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>187</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>187</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>187</integer>
+// CHECK-NEXT: <key>col</key><integer>9</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>187</integer>
+// CHECK-NEXT: <key>col</key><integer>14</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>187</integer>
+// CHECK-NEXT: <key>col</key><integer>9</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>187</integer>
+// CHECK-NEXT: <key>col</key><integer>9</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>187</integer>
+// CHECK-NEXT: <key>col</key><integer>18</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>1</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Memory is allocated</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Memory is allocated</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>191</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>191</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>191</integer>
+// CHECK-NEXT: <key>col</key><integer>25</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Returned allocated memory</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Returned allocated memory</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>191</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>191</integer>
+// CHECK-NEXT: <key>col</key><integer>23</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>192</integer>
+// CHECK-NEXT: <key>col</key><integer>1</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>192</integer>
+// CHECK-NEXT: <key>col</key><integer>1</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>192</integer>
+// CHECK-NEXT: <key>col</key><integer>1</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Potential memory leak</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Potential memory leak</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>description</key><string>Potential memory leak</string>
+// CHECK-NEXT: <key>category</key><string>Memory Error</string>
+// CHECK-NEXT: <key>type</key><string>Memory leak</string>
+// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT: <key>issue_context</key><string>testMyMalloc</string>
+// CHECK-NEXT: <key>issue_hash</key><string>1</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>192</integer>
+// CHECK-NEXT: <key>col</key><integer>1</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </plist>
diff --git a/test/Analysis/malloc.c b/test/Analysis/malloc.c
index 29f5aa69ca..6071d1d435 100644
--- a/test/Analysis/malloc.c
+++ b/test/Analysis/malloc.c
@@ -21,7 +21,7 @@ char *fooRetPtr();
void f1() {
int *p = malloc(12);
- return; // expected-warning{{Memory is never released; potential leak of memory pointed to by 'p'}}
+ return; // expected-warning{{Potential leak of memory pointed to by 'p'}}
}
void f2() {
@@ -46,7 +46,7 @@ void reallocNotNullPtr(unsigned sizeIn) {
char *p = (char*)malloc(size);
if (p) {
char *q = (char*)realloc(p, sizeIn);
- char x = *q; // expected-warning {{Memory is never released; potential leak of memory pointed to by 'q'}}
+ char x = *q; // expected-warning {{Potential leak of memory pointed to by 'q'}}
}
}
@@ -105,7 +105,7 @@ void reallocSizeZero5() {
void reallocPtrZero1() {
char *r = realloc(0, 12);
-} // expected-warning {{Memory is never released; potential leak of memory pointed to by 'r'}}
+} // expected-warning {{Potential leak of memory pointed to by 'r'}}
void reallocPtrZero2() {
char *r = realloc(0, 12);
@@ -122,7 +122,7 @@ void reallocRadar6337483_1() {
char *buf = malloc(100);
buf = (char*)realloc(buf, 0x1000000);
if (!buf) {
- return;// expected-warning {{Memory is never released; potential leak}}
+ return;// expected-warning {{Potential leak of memory pointed to by}}
}
free(buf);
}
@@ -135,7 +135,7 @@ void reallocRadar6337483_2() {
} else {
free(buf2);
}
-} // expected-warning {{Memory is never released; potential leak}}
+} // expected-warning {{Potential leak of memory pointed to by}}
void reallocRadar6337483_3() {
char * buf = malloc(100);
@@ -153,7 +153,7 @@ void reallocRadar6337483_4() {
char *buf = malloc(100);
char *buf2 = (char*)realloc(buf, 0x1000000);
if (!buf2) {
- return; // expected-warning {{Memory is never released; potential leak}}
+ return; // expected-warning {{Potential leak of memory pointed to by}}
} else {
free(buf2);
}
@@ -189,7 +189,7 @@ void reallocfRadar6337483_3() {
void reallocfPtrZero1() {
char *r = reallocf(0, 12);
-} // expected-warning {{Memory is never released; potential leak}}
+} // expected-warning {{Potential leak of memory pointed to by}}
// This case tests that storing malloc'ed memory to a static variable which is
@@ -293,7 +293,7 @@ char mallocGarbage () {
// This tests that calloc() buffers need to be freed
void callocNoFree () {
char *buf = calloc(2,2);
- return; // expected-warning{{never released}}
+ return; // expected-warning{{Potential leak of memory pointed to by 'buf'}}
}
// These test that calloc() buffers are zeroed by default
@@ -312,7 +312,7 @@ char callocZeroesBad () {
if (buf[1] != 0) {
free(buf); // expected-warning{{never executed}}
}
- return result; // expected-warning{{never released}}
+ return result; // expected-warning{{Potential leak of memory pointed to by 'buf'}}
}
void nullFree() {
@@ -387,12 +387,12 @@ void mallocEscapeMalloc() {
int *p = malloc(12);
myfoo(p);
p = malloc(12);
-} // expected-warning{{Memory is never released; potential leak}}
+} // expected-warning{{Potential leak of memory pointed to by}}
void mallocMalloc() {
int *p = malloc(12);
p = malloc(12);
-} // expected-warning {{Memory is never released; potential leak}}
+} // expected-warning {{Potential leak of memory pointed to by}}
void mallocFreeMalloc() {
int *p = malloc(12);
@@ -451,7 +451,7 @@ void mallocFailedOrNotLeak() {
if (p == 0)
return; // no warning
else
- return; // expected-warning {{Memory is never released; potential leak}}
+ return; // expected-warning {{Potential leak of memory pointed to by}}
}
void mallocAssignment() {
@@ -461,7 +461,7 @@ void mallocAssignment() {
int vallocTest() {
char *mem = valloc(12);
- return 0; // expected-warning {{Memory is never released; potential leak}}
+ return 0; // expected-warning {{Potential leak of memory pointed to by}}
}
void vallocEscapeFreeUse() {
@@ -531,6 +531,12 @@ int *testMalloc3() {
return y; // no-warning
}
+void testStructLeak() {
+ StructWithPtr St;
+ St.memP = malloc(12);
+ return; // expected-warning {{Potential leak of memory pointed to by 'St.memP'}}
+}
+
void testElemRegion1() {
char *x = (void*)malloc(2);
int *ix = (int*)x;
@@ -578,7 +584,7 @@ struct X* RegInvalidationDetect1(struct X *s2) {
struct X *px= malloc(sizeof(struct X));
px->p = 0;
px = s2;
- return px; // expected-warning {{Memory is never released; potential leak}}
+ return px; // expected-warning {{Potential leak of memory pointed to by}}
}
struct X* RegInvalidationGiveUp1() {
@@ -592,7 +598,7 @@ int **RegInvalidationDetect2(int **pp) {
int *p = malloc(12);
pp = &p;
pp++;
- return 0;// expected-warning {{Memory is never released; potential leak}}
+ return 0;// expected-warning {{Potential leak of memory pointed to by}}
}
extern void exit(int) __attribute__ ((__noreturn__));
@@ -668,7 +674,7 @@ int *specialMallocWithStruct() {
void testStrdup(const char *s, unsigned validIndex) {
char *s2 = strdup(s);
s2[validIndex + 1] = 'b';
-} // expected-warning {{Memory is never released; potential leak}}
+} // expected-warning {{Potential leak of memory pointed to by}}
int testStrndup(const char *s, unsigned validIndex, unsigned size) {
char *s2 = strndup(s, size);
@@ -676,7 +682,7 @@ int testStrndup(const char *s, unsigned validIndex, unsigned size) {
if (s2[validIndex] != 'a')
return 0;
else
- return 1;// expected-warning {{Memory is never released; potential leak}}
+ return 1;// expected-warning {{Potential leak of memory pointed to by}}
}
void testStrdupContentIsDefined(const char *s, unsigned validIndex) {
@@ -929,6 +935,18 @@ int cmpHeapAllocationToUnknown() {
return 0;
}
+void localArrayTest() {
+ char *p = (char*)malloc(12);
+ char *ArrayL[12];
+ ArrayL[0] = p;
+} // expected-warning {{leak}}
+
+void localStructTest() {
+ StructWithPtr St;
+ StructWithPtr *pSt = &St;
+ pSt->memP = malloc(12);
+} // expected-warning{{Potential leak of memory pointed to by}}
+
#ifdef __INTPTR_TYPE__
// Test double assignment through integers.
typedef __INTPTR_TYPE__ intptr_t;
@@ -1045,50 +1063,18 @@ void testPassToSystemHeaderFunctionIndirectly() {
fakeSystemHeaderCallInt(p);
} // expected-warning {{leak}}
-// ----------------------------------------------------------------------------
-// False negatives.
-
-// TODO: This is another false negative.
-void testMallocWithParam(int **p) {
- *p = (int*) malloc(sizeof(int));
- *p = 0;
-}
-
-void testMallocWithParam_2(int **p) {
- *p = (int*) malloc(sizeof(int));
-}
-
-// Pending on removal of the escaping on assignment to struct fields.
-void testStructLeak() {
- StructWithPtr St;
- St.memP = malloc(12);
- return; // missing warning
-}
-
-void localArrayTest() {
- char *p = (char*)malloc(12);
- char *ArrayL[12];
- ArrayL[0] = p;
-} // missing warning
-
-void localStructTest() {
- StructWithPtr St;
- StructWithPtr *pSt = &St;
- pSt->memP = malloc(12);
-} // missing warning
-
void testPassConstPointerIndirectlyStruct() {
struct HasPtr hp;
hp.p = malloc(10);
memcmp(&hp, &hp, sizeof(hp));
- return; // missing leak
+ return; // expected-warning {{Potential leak of memory pointed to by 'hp.p'}}
}
void testPassToSystemHeaderFunctionIndirectlyStruct() {
SomeStruct ss;
ss.p = malloc(1);
fakeSystemHeaderCall(&ss);
-} // missing leak
+} // expected-warning {{Potential leak of memory pointed to by 'ss.p'}}
int *testOffsetAllocate(size_t size) {
int *memoryBlock = (int *)malloc(size + sizeof(int));
@@ -1121,7 +1107,7 @@ void testOffsetOfRegionFreedAfterFunctionCall() {
int *p = malloc(sizeof(int)*2);
p += 1;
myfoo(p);
- free(p); // no-warning
+ free(p); // expected-warning{{Argument to free() is offset by 4 bytes from the start of memory allocated by malloc()}}
}
void testFixManipulatedPointerBeforeFree() {
@@ -1174,7 +1160,7 @@ void testOffsetZeroDoubleFree() {
void testOffsetPassedToStrlen() {
char * string = malloc(sizeof(char)*10);
string += 1;
- int length = strlen(string); // expected-warning {{Memory is never released; potential leak of memory pointed to by 'string'}}
+ int length = strlen(string); // expected-warning {{Potential leak of memory pointed to by 'string'}}
}
void testOffsetPassedToStrlenThenFree() {
@@ -1191,3 +1177,26 @@ void testOffsetPassedAsConst() {
free(string); // expected-warning {{Argument to free() is offset by 1 byte from the start of memory allocated by malloc()}}
}
+char **_vectorSegments;
+int _nVectorSegments;
+
+void poolFreeC(void* s) {
+ free(s); // no-warning
+}
+void freeMemory() {
+ while (_nVectorSegments) {
+ poolFreeC(_vectorSegments[_nVectorSegments++]);
+ }
+}
+
+// ----------------------------------------------------------------------------
+// False negatives.
+
+void testMallocWithParam(int **p) {
+ *p = (int*) malloc(sizeof(int));
+ *p = 0; // FIXME: should warn here
+}
+
+void testMallocWithParam_2(int **p) {
+ *p = (int*) malloc(sizeof(int)); // no-warning
+}
diff --git a/test/Analysis/malloc.cpp b/test/Analysis/malloc.cpp
index a7c365289f..75d06d66c2 100644
--- a/test/Analysis/malloc.cpp
+++ b/test/Analysis/malloc.cpp
@@ -5,7 +5,7 @@ void *malloc(size_t);
void free(void *);
void *realloc(void *ptr, size_t size);
void *calloc(size_t nmemb, size_t size);
-
+char *strdup(const char *s);
void checkThatMallocCheckerIsRunning() {
malloc(4);
@@ -24,12 +24,18 @@ Foo aFunction() {
// they are defined in system headers and take the const pointer to the
// allocated memory. (radar://11160612)
// Test default parameter.
-int const_ptr_and_callback_def_param(int, const char*, int n, void(*)(void*) = 0);
+int const_ptr_and_callback_def_param(int, const char*, int n, void(*)(void*) = free);
void r11160612_3() {
char *x = (char*)malloc(12);
const_ptr_and_callback_def_param(0, x, 12);
}
+int const_ptr_and_callback_def_param_null(int, const char*, int n, void(*)(void*) = 0);
+void r11160612_no_callback() {
+ char *x = (char*)malloc(12);
+ const_ptr_and_callback_def_param_null(0, x, 12);
+} // expected-warning{{leak}}
+
// Test member function pointer.
struct CanFreeMemory {
static void myFree(void*);
@@ -67,3 +73,36 @@ struct X get() {
result.a = malloc(4);
return result; // no-warning
}
+
+// Ensure that regions accessible through a LazyCompoundVal trigger region escape.
+// Malloc checker used to report leaks for the following two test cases.
+struct Property {
+ char* getterName;
+ Property(char* n)
+ : getterName(n) {}
+
+};
+void append(Property x);
+
+void appendWrapper(char *getterName) {
+ append(Property(getterName));
+}
+void foo(const char* name) {
+ char* getterName = strdup(name);
+ appendWrapper(getterName); // no-warning
+}
+
+struct NestedProperty {
+ Property prop;
+ NestedProperty(Property p)
+ : prop(p) {}
+};
+void appendNested(NestedProperty x);
+
+void appendWrapperNested(char *getterName) {
+ appendNested(NestedProperty(Property(getterName)));
+}
+void fooNested(const char* name) {
+ char* getterName = strdup(name);
+ appendWrapperNested(getterName); // no-warning
+} \ No newline at end of file
diff --git a/test/Analysis/malloc.mm b/test/Analysis/malloc.mm
index 2f583b45fd..c7fe86bf0b 100644
--- a/test/Analysis/malloc.mm
+++ b/test/Analysis/malloc.mm
@@ -68,7 +68,7 @@ void testNSStringFreeWhenDoneNO2(NSUInteger dataLength) {
void testOffsetFree() {
int *p = (int *)malloc(sizeof(int));
- NSData *nsdata = [NSData dataWithBytesNoCopy:++p length:sizeof(int) freeWhenDone:1]; // expected-warning{{Argument to free() is offset by 4 bytes from the start of memory allocated by malloc()}}
+ NSData *nsdata = [NSData dataWithBytesNoCopy:++p length:sizeof(int) freeWhenDone:1]; // expected-warning{{Argument to +dataWithBytesNoCopy:length:freeWhenDone: is offset by 4 bytes from the start of memory allocated by malloc()}}
}
void testRelinquished1() {
@@ -81,7 +81,17 @@ void testRelinquished2() {
void *data = malloc(42);
NSData *nsdata;
free(data);
- [NSData dataWithBytesNoCopy:data length:42]; // expected-warning {{Attempt to free released memory}}
+ [NSData dataWithBytesNoCopy:data length:42]; // expected-warning {{Use of memory after it is freed}}
+}
+
+@interface My
++ (void)param:(void *)p;
+@end
+
+void testUseAfterFree() {
+ int *p = (int *)malloc(sizeof(int));
+ free(p);
+ [My param:p]; // expected-warning{{Use of memory after it is freed}}
}
void testNoCopy() {
diff --git a/test/Analysis/method-arg-decay.m b/test/Analysis/method-arg-decay.m
index a36d81e82b..0af9e3e883 100644
--- a/test/Analysis/method-arg-decay.m
+++ b/test/Analysis/method-arg-decay.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyzer-checker=core -verify %s
+// RUN: %clang_cc1 -analyzer-checker=core -verify %s -Wno-incomplete-implementation
typedef signed char BOOL;
typedef int NSInteger;
typedef unsigned int NSUInteger;
@@ -70,9 +70,9 @@ extern NSMutableArray *XCFindPossibleKeyModules(PBXModule *module, BOOL useExpos
@interface XCPerspectiveModule : PBXProjectModule <PBXSelectionTarget> { // expected-note {{required for direct or indirect protocol 'PBXSelectionTarget'}}
XCExtendedTabView *_perspectivesTabView;
}
-- (PBXModule *) moduleForTab:(NSTabViewItem *)item; // expected-note {{method definition for 'moduleForTab:' not found}}
+- (PBXModule *) moduleForTab:(NSTabViewItem *)item;
@end
-@implementation XCPerspectiveModule // expected-warning {{incomplete implementation}} expected-warning {{method 'performAction:withSelection:' in protocol not implemented}}}
+@implementation XCPerspectiveModule // expected-warning {{method 'performAction:withSelection:' in protocol not implemented}}}
+ (void) openForProjectDocument:(PBXProjectDocument *)projectDocument {
}
- (PBXModule *) type:(Class)type inPerspective:(id)perspectiveIdentifer matchingFunction:(BOOL (void *, void *))comparator usingData:(void *)data {
diff --git a/test/Analysis/misc-ps-region-store.cpp b/test/Analysis/misc-ps-region-store.cpp
index 6fbe441b27..902a5e5271 100644
--- a/test/Analysis/misc-ps-region-store.cpp
+++ b/test/Analysis/misc-ps-region-store.cpp
@@ -721,3 +721,22 @@ void rdar12964481_b(_ComplexT *y) {
*y *= x; // no-warning
}
+// Test case for PR 12921. This previously produced
+// a bogus warning.
+static const int pr12921_arr[] = { 0, 1 };
+static const int pr12921_arrcount = sizeof(pr12921_arr)/sizeof(int);
+
+int pr12921(int argc, char **argv) {
+ int i, retval;
+ for (i = 0; i < pr12921_arrcount; i++) {
+ if (argc == i) {
+ retval = i;
+ break;
+ }
+ }
+
+ // No match
+ if (i == pr12921_arrcount) return 66;
+ return pr12921_arr[retval];
+}
+
diff --git a/test/Analysis/misc-ps-region-store.m b/test/Analysis/misc-ps-region-store.m
index bb22c25998..ba88deca5a 100644
--- a/test/Analysis/misc-ps-region-store.m
+++ b/test/Analysis/misc-ps-region-store.m
@@ -920,7 +920,7 @@ int rdar_7770737_pos(void)
void pr6302(id x, Class y) {
// This previously crashed the analyzer (reported in PR 6302)
- x->isa = y; // expected-warning {{direct access to Objective-C's isa is deprecated in favor of object_setClass() and object_getClass()}}
+ x->isa = y; // expected-warning {{assignment to Objective-C's isa is deprecated in favor of object_setClass()}}
}
//===----------------------------------------------------------------------===//
diff --git a/test/Analysis/misc-ps.c b/test/Analysis/misc-ps.c
index 5369ab1061..b302860a2f 100644
--- a/test/Analysis/misc-ps.c
+++ b/test/Analysis/misc-ps.c
@@ -163,3 +163,15 @@ int PR14634(int x) {
return !y;
}
+
+// PR15684: If a checker generates a sink node after generating a regular node
+// and no state changes between the two, graph trimming would consider the two
+// the same node, forming a loop.
+struct PR15684 {
+ void (*callback)(int);
+};
+void sinkAfterRegularNode(struct PR15684 *context) {
+ int uninitialized;
+ context->callback(uninitialized); // expected-warning {{uninitialized}}
+}
+
diff --git a/test/Analysis/new.cpp b/test/Analysis/new.cpp
index fdd16da3dc..8d3eee9baa 100644
--- a/test/Analysis/new.cpp
+++ b/test/Analysis/new.cpp
@@ -1,11 +1,19 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-store region -std=c++11 -verify %s
+#include "Inputs/system-header-simulator-cxx.h"
void clang_analyzer_eval(bool);
typedef __typeof__(sizeof(int)) size_t;
extern "C" void *malloc(size_t);
+extern "C" void free(void *);
int someGlobal;
+
+class SomeClass {
+public:
+ void f(int *p);
+};
+
void testImplicitlyDeclaredGlobalNew() {
if (someGlobal != 0)
return;
@@ -19,13 +27,6 @@ void testImplicitlyDeclaredGlobalNew() {
clang_analyzer_eval(someGlobal == 0); // expected-warning{{TRUE}}
}
-
-// This is the standard placement new.
-inline void* operator new(size_t, void* __p) throw()
-{
- return __p;
-}
-
void *testPlacementNew() {
int *x = (int *)malloc(sizeof(int));
*x = 1;
@@ -73,7 +74,6 @@ void testScalarInitialization() {
clang_analyzer_eval(*n == 0); // expected-warning{{TRUE}}
}
-
struct PtrWrapper {
int *x;
@@ -82,9 +82,93 @@ struct PtrWrapper {
PtrWrapper *testNewInvalidation() {
// Ensure that we don't consider this a leak.
- return new PtrWrapper(static_cast<int *>(malloc(4)));
+ return new PtrWrapper(static_cast<int *>(malloc(4))); // no-warning
+}
+
+void testNewInvalidationPlacement(PtrWrapper *w) {
+ // Ensure that we don't consider this a leak.
+ new (w) PtrWrapper(static_cast<int *>(malloc(4))); // no-warning
}
+int **testNewInvalidationScalar() {
+ // Ensure that we don't consider this a leak.
+ return new (int *)(static_cast<int *>(malloc(4))); // no-warning
+}
+
+void testNewInvalidationScalarPlacement(int **p) {
+ // Ensure that we don't consider this a leak.
+ new (p) (int *)(static_cast<int *>(malloc(4))); // no-warning
+}
+
+void testCacheOut(PtrWrapper w) {
+ extern bool coin();
+ if (coin())
+ w.x = 0;
+ new (&w.x) (int*)(0); // we cache out here; don't crash
+}
+
+void testUseAfter(int *p) {
+ SomeClass *c = new SomeClass;
+ free(p);
+ c->f(p); // expected-warning{{Use of memory after it is freed}}
+ delete c;
+}
+
+//--------------------------------------------------------------------
+// Check for intersection with other checkers from MallocChecker.cpp
+// bounded with unix.Malloc
+//--------------------------------------------------------------------
+
+// new/delete oparators are subjects of cplusplus.NewDelete.
+void testNewDeleteNoWarn() {
+ int i;
+ delete &i; // no-warning
+
+ int *p1 = new int;
+ delete ++p1; // no-warning
+
+ int *p2 = new int;
+ delete p2;
+ delete p2; // no-warning
+
+ int *p3 = new int; // no-warning
+}
+
+// unix.Malloc does not know about operators new/delete.
+void testDeleteMallocked() {
+ int *x = (int *)malloc(sizeof(int));
+ delete x; // FIXME: Shoud detect pointer escape and keep silent after 'delete' is modeled properly.
+} // expected-warning{{Potential leak of memory pointed to by 'x'}}
+
+void testDeleteOpAfterFree() {
+ int *p = (int *)malloc(sizeof(int));
+ free(p);
+ operator delete(p); // expected-warning{{Use of memory after it is freed}}
+}
+
+void testDeleteAfterFree() {
+ int *p = (int *)malloc(sizeof(int));
+ free(p);
+ delete p; // expected-warning{{Use of memory after it is freed}}
+}
+
+void testStandardPlacementNewAfterFree() {
+ int *p = (int *)malloc(sizeof(int));
+ free(p);
+ p = new(p) int; // expected-warning{{Use of memory after it is freed}}
+}
+
+void testCustomPlacementNewAfterFree() {
+ int *p = (int *)malloc(sizeof(int));
+ free(p);
+ p = new(0, p) int; // expected-warning{{Use of memory after it is freed}}
+}
+
+void testUsingThisAfterDelete() {
+ SomeClass *c = new SomeClass;
+ delete c;
+ c->f(0); // no-warning
+}
//--------------------------------
// Incorrectly-modelled behavior
@@ -95,8 +179,10 @@ int testNoInitialization() {
// Should warn that *n is uninitialized.
if (*n) { // no-warning
+ delete n;
return 0;
}
+ delete n;
return 1;
}
diff --git a/test/Analysis/null-deref-path-notes.m b/test/Analysis/null-deref-path-notes.m
index 66514544dd..e22d520f88 100644
--- a/test/Analysis/null-deref-path-notes.m
+++ b/test/Analysis/null-deref-path-notes.m
@@ -457,28 +457,47 @@ void repeatedStores(int coin) {
// CHECK-NEXT: </array>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>33</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>33</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>33</integer>
+// CHECK-NEXT: <key>col</key><integer>12</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>33</integer>
+// CHECK-NEXT: <key>col</key><integer>12</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>33</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>12</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
-// CHECK-NEXT: <key>ranges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>33</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>33</integer>
-// CHECK-NEXT: <key>col</key><integer>18</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </array>
// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>Access to instance variable &apos;uniqueID&apos; results in a dereference of a null pointer (loaded from variable &apos;self&apos;)</string>
@@ -495,7 +514,7 @@ void repeatedStores(int coin) {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>33</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>12</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -697,11 +716,45 @@ void repeatedStores(int coin) {
// CHECK-NEXT: </array>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>50</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>50</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>50</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>50</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>50</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -735,7 +788,7 @@ void repeatedStores(int coin) {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>50</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
diff --git a/test/Analysis/objc-boxing.m b/test/Analysis/objc-boxing.m
index 16915788d6..98310b52f4 100644
--- a/test/Analysis/objc-boxing.m
+++ b/test/Analysis/objc-boxing.m
@@ -34,7 +34,7 @@ id constant_string() {
}
id dynamic_string() {
- return @(strdup("boxed dynamic string")); // expected-warning{{Memory is never released; potential leak}}
+ return @(strdup("boxed dynamic string")); // expected-warning{{Potential memory leak}}
}
id const_char_pointer(int *x) {
diff --git a/test/Analysis/objc-for.m b/test/Analysis/objc-for.m
index 1561ef8ddf..ef149c4b14 100644
--- a/test/Analysis/objc-for.m
+++ b/test/Analysis/objc-for.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=osx.cocoa.Loops,debug.ExprInspection -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.Loops,debug.ExprInspection -verify %s
void clang_analyzer_eval(int);
@@ -56,3 +56,15 @@ void testWithVarInFor() {
clang_analyzer_eval(x != nil); // expected-warning{{UNKNOWN}}
}
+void testNonNil(id a, id b) {
+ clang_analyzer_eval(a != nil); // expected-warning{{UNKNOWN}}
+ for (id x in a)
+ clang_analyzer_eval(a != nil); // expected-warning{{TRUE}}
+
+ if (b != nil)
+ return;
+ for (id x in b)
+ *(volatile int *)0 = 1; // no-warning
+ clang_analyzer_eval(b != nil); // expected-warning{{FALSE}}
+}
+
diff --git a/test/Analysis/objc-string.mm b/test/Analysis/objc-string.mm
new file mode 100644
index 0000000000..c67ab5e891
--- /dev/null
+++ b/test/Analysis/objc-string.mm
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s
+
+void clang_analyzer_eval(bool);
+@class NSString;
+
+void sanity() {
+ clang_analyzer_eval(@""); // expected-warning{{TRUE}}
+ clang_analyzer_eval(@"abc"); // expected-warning{{TRUE}}
+}
+
+namespace rdar13773117 {
+ NSString *const kConstantGlobalString = @"foo";
+ NSString *globalString = @"bar";
+
+ extern void invalidateGlobals();
+
+ void testGlobals() {
+ clang_analyzer_eval(kConstantGlobalString); // expected-warning{{TRUE}}
+ clang_analyzer_eval(globalString); // expected-warning{{UNKNOWN}}
+
+ globalString = @"baz";
+ clang_analyzer_eval(globalString); // expected-warning{{TRUE}}
+
+ invalidateGlobals();
+
+ clang_analyzer_eval(kConstantGlobalString); // expected-warning{{TRUE}}
+ clang_analyzer_eval(globalString); // expected-warning{{UNKNOWN}}
+ }
+
+ NSString *returnString(NSString *input = @"garply") {
+ return input;
+ }
+
+ void testDefaultArg() {
+ clang_analyzer_eval(returnString(@"")); // expected-warning{{TRUE}}
+ clang_analyzer_eval(returnString(0)); // expected-warning{{FALSE}}
+ clang_analyzer_eval(returnString()); // expected-warning{{TRUE}}
+ }
+}
diff --git a/test/Analysis/objc-subscript.m b/test/Analysis/objc-subscript.m
index 324bf1c785..ae621c9828 100644
--- a/test/Analysis/objc-subscript.m
+++ b/test/Analysis/objc-subscript.m
@@ -39,9 +39,9 @@ typedef unsigned int NSUInteger;
// <rdar://problem/8824416> for subscripting
- (id)getDoesNotRetain:(BOOL)keyed {
if (keyed)
- return [self[self] autorelease]; // expected-warning{{Object sent -autorelease too many times}}
+ return [self[self] autorelease]; // expected-warning{{Object autoreleased too many times}}
else
- return [self[0] autorelease]; // expected-warning{{Object sent -autorelease too many times}}
+ return [self[0] autorelease]; // expected-warning{{Object autoreleased too many times}}
}
// <rdar://problem/9241180> for subscripting
diff --git a/test/Analysis/objc_invalidation.m b/test/Analysis/objc_invalidation.m
index a6f5ec3f84..6919feaccf 100644
--- a/test/Analysis/objc_invalidation.m
+++ b/test/Analysis/objc_invalidation.m
@@ -322,6 +322,47 @@ extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1,
#endif
@end
+@interface SomeNotInvalidatedInPartial : SomeInvalidationImplementingObject {
+ SomeInvalidationImplementingObject *Ivar1;
+ SomeInvalidationImplementingObject *Ivar2;
+#if RUN_IVAR_INVALIDATION
+ // expected-warning@-2 {{Instance variable Ivar2 needs to be invalidated or set to nil}}
+#endif
+}
+-(void)partialInvalidator __attribute__((annotate("objc_instance_variable_invalidator_partial")));
+-(void)partialInvalidatorCallsPartial __attribute__((annotate("objc_instance_variable_invalidator_partial")));
+@end
+@implementation SomeNotInvalidatedInPartial {
+ SomeInvalidationImplementingObject *Ivar3;
+#if RUN_IVAR_INVALIDATION
+ // expected-warning@-2 {{Instance variable Ivar3 needs to be invalidated or set to nil}}
+#endif
+}
+-(void)partialInvalidator {
+ Ivar1 = 0;
+}
+-(void)partialInvalidatorCallsPartial {
+ [self partialInvalidator];
+}
+@end
+
+@interface OnlyPartialDeclsBase : NSObject
+-(void)partialInvalidator __attribute__((annotate("objc_instance_variable_invalidator_partial")));
+@end
+@implementation OnlyPartialDeclsBase
+-(void)partialInvalidator {}
+@end
+
+@interface OnlyPartialDecls : OnlyPartialDeclsBase {
+ SomeInvalidationImplementingObject *Ivar1;
+#if RUN_IVAR_INVALIDATION
+ // expected-warning@-2 {{Instance variable Ivar1 needs to be invalidated; no invalidation method is defined in the @implementation for OnlyPartialDecls}}
+#endif
+}
+@end
+@implementation OnlyPartialDecls
+@end
+
// False negative.
@interface PartialCallsFull : SomeInvalidationImplementingObject {
SomeInvalidationImplementingObject *Ivar1;
diff --git a/test/Analysis/operator-calls.cpp b/test/Analysis/operator-calls.cpp
index 4f686e55fd..7461d75f67 100644
--- a/test/Analysis/operator-calls.cpp
+++ b/test/Analysis/operator-calls.cpp
@@ -49,3 +49,39 @@ namespace UserDefinedConversions {
clang_analyzer_eval(obj); // expected-warning{{TRUE}}
}
}
+
+
+namespace RValues {
+ struct SmallOpaque {
+ float x;
+ int operator +() const {
+ return (int)x;
+ }
+ };
+
+ struct LargeOpaque {
+ float x[4];
+ int operator +() const {
+ return (int)x[0];
+ }
+ };
+
+ SmallOpaque getSmallOpaque() {
+ SmallOpaque obj;
+ obj.x = 1.0;
+ return obj;
+ }
+
+ LargeOpaque getLargeOpaque() {
+ LargeOpaque obj = LargeOpaque();
+ obj.x[0] = 1.0;
+ return obj;
+ }
+
+ void test(int coin) {
+ // Force a cache-out when we try to conjure a temporary region for the operator call.
+ // ...then, don't crash.
+ clang_analyzer_eval(+(coin ? getSmallOpaque() : getSmallOpaque())); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(+(coin ? getLargeOpaque() : getLargeOpaque())); // expected-warning{{UNKNOWN}}
+ }
+}
diff --git a/test/Analysis/plist-output-alternate.m b/test/Analysis/plist-output-alternate.m
index bc9e1032fc..93d0421d66 100644
--- a/test/Analysis/plist-output-alternate.m
+++ b/test/Analysis/plist-output-alternate.m
@@ -113,12 +113,12 @@ void rdar8331641(int x) {
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>6</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>6</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
@@ -130,7 +130,7 @@ void rdar8331641(int x) {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>6</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -164,7 +164,7 @@ void rdar8331641(int x) {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>6</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -256,12 +256,12 @@ void rdar8331641(int x) {
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>12</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>12</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
@@ -273,7 +273,7 @@ void rdar8331641(int x) {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>12</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -307,7 +307,7 @@ void rdar8331641(int x) {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>12</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -462,12 +462,12 @@ void rdar8331641(int x) {
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
@@ -479,7 +479,7 @@ void rdar8331641(int x) {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -513,7 +513,7 @@ void rdar8331641(int x) {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -618,11 +618,45 @@ void rdar8331641(int x) {
// CHECK-NEXT: </array>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>24</integer>
+// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>24</integer>
+// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>24</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>24</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>24</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -656,7 +690,7 @@ void rdar8331641(int x) {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>24</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -811,12 +845,12 @@ void rdar8331641(int x) {
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>31</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>31</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
@@ -828,7 +862,7 @@ void rdar8331641(int x) {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>31</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -862,7 +896,7 @@ void rdar8331641(int x) {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>31</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -988,12 +1022,12 @@ void rdar8331641(int x) {
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>38</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>38</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
@@ -1005,7 +1039,7 @@ void rdar8331641(int x) {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>38</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -1039,7 +1073,7 @@ void rdar8331641(int x) {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>38</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -1328,7 +1362,7 @@ void rdar8331641(int x) {
// CHECK-NEXT: <key>type</key><string>Leak</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
// CHECK-NEXT: <key>issue_context</key><string>rdar8331641</string>
-// CHECK-NEXT: <key>issue_hash</key><string>6</string>
+// CHECK-NEXT: <key>issue_hash</key><string>2</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>58</integer>
diff --git a/test/Analysis/plist-output.m b/test/Analysis/plist-output.m
index d563e88747..3dfd6be2e7 100644
--- a/test/Analysis/plist-output.m
+++ b/test/Analysis/plist-output.m
@@ -155,6 +155,14 @@ void test_loop_diagnostics_3() {
*p = 1;
}
+void test_loop_fast_enumeration(id arr) {
+ int x;
+ for (id obj in arr) {
+ x = 1;
+ }
+ x += 1;
+}
+
@interface RDar12114812 { char *p; }
@end
@@ -176,6 +184,16 @@ int RDar13295437() {
RDar13295437_f(sp->i);
}
+@interface Foo
+- (int *) returnsPointer;
+@end
+
+int testFoo(Foo *x) {
+ if (x)
+ return 1;
+ return *[x returnsPointer];
+}
+
// CHECK: <key>diagnostics</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
@@ -232,12 +250,12 @@ int RDar13295437() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>6</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>6</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
@@ -249,7 +267,7 @@ int RDar13295437() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>6</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -283,7 +301,7 @@ int RDar13295437() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>6</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -375,12 +393,12 @@ int RDar13295437() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>12</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>12</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
@@ -392,7 +410,7 @@ int RDar13295437() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>12</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -426,7 +444,7 @@ int RDar13295437() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>12</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -581,12 +599,12 @@ int RDar13295437() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
@@ -598,7 +616,7 @@ int RDar13295437() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -632,7 +650,7 @@ int RDar13295437() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -737,11 +755,45 @@ int RDar13295437() {
// CHECK-NEXT: </array>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>24</integer>
+// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>24</integer>
+// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>24</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>24</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>24</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -775,7 +827,7 @@ int RDar13295437() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>24</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -930,12 +982,12 @@ int RDar13295437() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>31</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>31</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
@@ -947,7 +999,7 @@ int RDar13295437() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>31</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -981,7 +1033,7 @@ int RDar13295437() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>31</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -1107,12 +1159,12 @@ int RDar13295437() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>38</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>38</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
@@ -1124,7 +1176,7 @@ int RDar13295437() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>38</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -1158,7 +1210,7 @@ int RDar13295437() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>38</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -1410,12 +1462,12 @@ int RDar13295437() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>50</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>50</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
@@ -1427,7 +1479,7 @@ int RDar13295437() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>50</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -1461,7 +1513,7 @@ int RDar13295437() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>50</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -1822,12 +1874,12 @@ int RDar13295437() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>77</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>77</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
@@ -1839,7 +1891,7 @@ int RDar13295437() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>77</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -1873,7 +1925,7 @@ int RDar13295437() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>77</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -2089,7 +2141,7 @@ int RDar13295437() {
// CHECK-NEXT: <key>type</key><string>Leak</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>Objective-C method</string>
// CHECK-NEXT: <key>issue_context</key><string>test2</string>
-// CHECK-NEXT: <key>issue_hash</key><string>4</string>
+// CHECK-NEXT: <key>issue_hash</key><string>2</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>88</integer>
@@ -2350,12 +2402,12 @@ int RDar13295437() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>98</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>98</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
@@ -2367,7 +2419,7 @@ int RDar13295437() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>98</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -2401,7 +2453,7 @@ int RDar13295437() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>98</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -2632,11 +2684,45 @@ int RDar13295437() {
// CHECK-NEXT: </array>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>111</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>111</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>111</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>111</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>111</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -2670,7 +2756,7 @@ int RDar13295437() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>111</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -2901,11 +2987,45 @@ int RDar13295437() {
// CHECK-NEXT: </array>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>121</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>121</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>121</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>121</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>121</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -2939,7 +3059,7 @@ int RDar13295437() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>121</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -3243,11 +3363,45 @@ int RDar13295437() {
// CHECK-NEXT: </array>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>130</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>130</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>130</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>130</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>130</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -3281,7 +3435,7 @@ int RDar13295437() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>130</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -3648,11 +3802,45 @@ int RDar13295437() {
// CHECK-NEXT: </array>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>136</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>136</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>136</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>136</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>136</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -3686,7 +3874,7 @@ int RDar13295437() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>136</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -4087,11 +4275,45 @@ int RDar13295437() {
// CHECK-NEXT: </array>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>145</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>145</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>145</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>145</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>145</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -4125,7 +4347,7 @@ int RDar13295437() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>145</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -4526,11 +4748,45 @@ int RDar13295437() {
// CHECK-NEXT: </array>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>155</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>155</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>155</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>155</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>155</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -4564,7 +4820,7 @@ int RDar13295437() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>155</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -4584,11 +4840,57 @@ int RDar13295437() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>163</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>163</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Value stored to &apos;x&apos; is never read</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Value stored to &apos;x&apos; is never read</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>description</key><string>Value stored to &apos;x&apos; is never read</string>
+// CHECK-NEXT: <key>category</key><string>Dead store</string>
+// CHECK-NEXT: <key>type</key><string>Dead increment</string>
+// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT: <key>issue_context</key><string>test_loop_fast_enumeration</string>
+// CHECK-NEXT: <key>issue_hash</key><string>5</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>163</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>path</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>159</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>159</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>159</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4596,9 +4898,72 @@ int RDar13295437() {
// CHECK-NEXT: </array>
// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>Null pointer value stored to &apos;p&apos;</string>
+// CHECK-NEXT: <string>&apos;x&apos; declared without an initial value</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Null pointer value stored to &apos;p&apos;</string>
+// CHECK-NEXT: <string>&apos;x&apos; declared without an initial value</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>159</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>159</integer>
+// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>160</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>160</integer>
+// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>160</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>160</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>160</integer>
+// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Loop body executed 0 times</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Loop body executed 0 times</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>control</string>
@@ -4608,6 +4973,19 @@ int RDar13295437() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>160</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>160</integer>
+// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>163</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
@@ -4618,19 +4996,40 @@ int RDar13295437() {
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>164</integer>
+// CHECK-NEXT: <key>line</key><integer>163</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>164</integer>
+// CHECK-NEXT: <key>line</key><integer>163</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>163</integer>
+// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>163</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
// CHECK-NEXT: </dict>
@@ -4638,7 +5037,53 @@ int RDar13295437() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>164</integer>
+// CHECK-NEXT: <key>line</key><integer>163</integer>
+// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>163</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>163</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>The left expression of the compound assignment is an uninitialized value. The computed value will also be garbage</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>The left expression of the compound assignment is an uninitialized value. The computed value will also be garbage</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>description</key><string>The left expression of the compound assignment is an uninitialized value. The computed value will also be garbage</string>
+// CHECK-NEXT: <key>category</key><string>Logic error</string>
+// CHECK-NEXT: <key>type</key><string>Assigned value is garbage or undefined</string>
+// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT: <key>issue_context</key><string>test_loop_fast_enumeration</string>
+// CHECK-NEXT: <key>issue_hash</key><string>5</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>163</integer>
+// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>path</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>171</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4646,12 +5091,75 @@ int RDar13295437() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>164</integer>
+// CHECK-NEXT: <key>line</key><integer>171</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>171</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Null pointer value stored to &apos;p&apos;</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Null pointer value stored to &apos;p&apos;</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>171</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>171</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>172</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>172</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>172</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>172</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>164</integer>
+// CHECK-NEXT: <key>line</key><integer>172</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4672,8 +5180,8 @@ int RDar13295437() {
// CHECK-NEXT: <key>issue_hash</key><string>2</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>164</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>line</key><integer>172</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -4684,7 +5192,7 @@ int RDar13295437() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>174</integer>
+// CHECK-NEXT: <key>line</key><integer>182</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4692,12 +5200,12 @@ int RDar13295437() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>174</integer>
+// CHECK-NEXT: <key>line</key><integer>182</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>174</integer>
+// CHECK-NEXT: <key>line</key><integer>182</integer>
// CHECK-NEXT: <key>col</key><integer>25</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4717,12 +5225,12 @@ int RDar13295437() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>174</integer>
+// CHECK-NEXT: <key>line</key><integer>182</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>174</integer>
+// CHECK-NEXT: <key>line</key><integer>182</integer>
// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4730,12 +5238,12 @@ int RDar13295437() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>176</integer>
+// CHECK-NEXT: <key>line</key><integer>184</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>176</integer>
+// CHECK-NEXT: <key>line</key><integer>184</integer>
// CHECK-NEXT: <key>col</key><integer>16</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4747,7 +5255,7 @@ int RDar13295437() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>176</integer>
+// CHECK-NEXT: <key>line</key><integer>184</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4755,12 +5263,12 @@ int RDar13295437() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>176</integer>
+// CHECK-NEXT: <key>line</key><integer>184</integer>
// CHECK-NEXT: <key>col</key><integer>18</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>176</integer>
+// CHECK-NEXT: <key>line</key><integer>184</integer>
// CHECK-NEXT: <key>col</key><integer>22</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4781,9 +5289,249 @@ int RDar13295437() {
// CHECK-NEXT: <key>issue_hash</key><string>3</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>176</integer>
+// CHECK-NEXT: <key>line</key><integer>184</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>path</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>192</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>192</integer>
+// CHECK-NEXT: <key>col</key><integer>4</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>192</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>192</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>192</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>192</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>192</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Assuming &apos;x&apos; is nil</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Assuming &apos;x&apos; is nil</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>192</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>192</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>194</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>194</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>194</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>194</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>194</integer>
+// CHECK-NEXT: <key>col</key><integer>12</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>194</integer>
+// CHECK-NEXT: <key>col</key><integer>12</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>194</integer>
+// CHECK-NEXT: <key>col</key><integer>12</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>194</integer>
+// CHECK-NEXT: <key>col</key><integer>12</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>194</integer>
+// CHECK-NEXT: <key>col</key><integer>12</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>&apos;returnsPointer&apos; not called because the receiver is nil</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>&apos;returnsPointer&apos; not called because the receiver is nil</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>194</integer>
+// CHECK-NEXT: <key>col</key><integer>12</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>194</integer>
+// CHECK-NEXT: <key>col</key><integer>12</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>194</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>194</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>194</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>194</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>194</integer>
+// CHECK-NEXT: <key>col</key><integer>28</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Dereference of null pointer</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Dereference of null pointer</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>description</key><string>Dereference of null pointer</string>
+// CHECK-NEXT: <key>category</key><string>Logic error</string>
+// CHECK-NEXT: <key>type</key><string>Dereference of null pointer</string>
+// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT: <key>issue_context</key><string>testFoo</string>
+// CHECK-NEXT: <key>issue_hash</key><string>3</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>194</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
diff --git a/test/Analysis/pointer-to-member.cpp b/test/Analysis/pointer-to-member.cpp
index 84dfe30646..c9150e8ca5 100644
--- a/test/Analysis/pointer-to-member.cpp
+++ b/test/Analysis/pointer-to-member.cpp
@@ -8,6 +8,9 @@ struct A {
operator MemberPointer() const { return m_ptr ? &A::m_ptr : 0; }
A *m_ptr;
+
+ A *getPtr();
+ typedef A * (A::*MemberFnPointer)(void);
};
void testConditionalUse() {
@@ -22,6 +25,40 @@ void testConditionalUse() {
clang_analyzer_eval(obj.m_ptr); // expected-warning{{FALSE}}
clang_analyzer_eval(A::MemberPointer(0)); // expected-warning{{FALSE}}
clang_analyzer_eval(obj); // expected-warning{{FALSE}}
+
+ clang_analyzer_eval(&A::getPtr); // expected-warning{{TRUE}}
+ clang_analyzer_eval(A::MemberFnPointer(0)); // expected-warning{{FALSE}}
+}
+
+
+void testComparison() {
+ clang_analyzer_eval(&A::getPtr == &A::getPtr); // expected-warning{{TRUE}}
+
+ // FIXME: Should be TRUE.
+ clang_analyzer_eval(&A::m_ptr == &A::m_ptr); // expected-warning{{UNKNOWN}}
+}
+
+namespace PR15742 {
+ template <class _T1, class _T2> struct A {
+ A (const _T1 &, const _T2 &);
+ };
+
+ typedef void *NPIdentifier;
+
+ template <class T> class B {
+ public:
+ typedef A<NPIdentifier, bool (T::*) (const NPIdentifier *, unsigned,
+ NPIdentifier *)> MethodMapMember;
+ };
+
+ class C : public B<C> {
+ public:
+ bool Find(const NPIdentifier *, unsigned, NPIdentifier *);
+ };
+
+ void InitStaticData () {
+ C::MethodMapMember(0, &C::Find); // don't crash
+ }
}
// ---------------
diff --git a/test/Analysis/pr4209.m b/test/Analysis/pr4209.m
index a5e7db51dc..29abe94441 100644
--- a/test/Analysis/pr4209.m
+++ b/test/Analysis/pr4209.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -verify %s
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -Wno-incomplete-implementation -verify %s
// This test case was crashing due to how CFRefCount.cpp resolved the
// ObjCInterfaceDecl* and ClassName in EvalObjCMessageExpr.
@@ -47,14 +47,14 @@ CMProfileLocation;
@interface GBCategoryChooserPanelController : NSWindowController {
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}} expected-note {{using}}
+- (NSMutableDictionary*)categoryDictionaryForCategoryID:(int)inID inRootTreeCategories:(NSMutableArray*)inRootTreeCategories;
+-(NSString*) categoryID; // expected-note {{using}}
@end @interface GSEbayCategory : NSObject <NSCoding> {
}
- (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}}
+@end @implementation GBCategoryChooserPanelController + (int) chooseCategoryIDFromCategories:(NSArray*) inCategories searchRequest:(GBSearchRequest*)inRequest parentWindow:(NSWindow*) inParent {
return 0;
}
- (void) addCategory:(EBayCategoryType*)inCategory toRootTreeCategory:(NSMutableArray*)inRootTreeCategories {
diff --git a/test/Analysis/properties.m b/test/Analysis/properties.m
index 4aa91805fd..ddd0068d36 100644
--- a/test/Analysis/properties.m
+++ b/test/Analysis/properties.m
@@ -102,7 +102,7 @@ typedef struct _NSZone NSZone;
else
value = [[NSNumber alloc] initWithInteger:0];
- return [value autorelease]; // expected-warning {{Object sent -autorelease too many times}}
+ return [value autorelease]; // expected-warning {{Object autoreleased too many times}}
}
@end
@@ -111,7 +111,7 @@ NSNumber* numberFromMyNumberProperty(MyNumber* aMyNumber)
{
NSNumber* result = aMyNumber.myNumber;
- return [result autorelease]; // expected-warning {{Object sent -autorelease too many times}}
+ return [result autorelease]; // expected-warning {{Object autoreleased too many times}}
}
diff --git a/test/Analysis/ptr-arith.c b/test/Analysis/ptr-arith.c
index 9294c1832b..35faff4a17 100644
--- a/test/Analysis/ptr-arith.c
+++ b/test/Analysis/ptr-arith.c
@@ -167,3 +167,116 @@ void PR7527 (int *p) {
if (((int) p) & 1) // not crash
return;
}
+
+void use_symbols(int *lhs, int *rhs) {
+ clang_analyzer_eval(lhs < rhs); // expected-warning{{UNKNOWN}}
+ if (lhs < rhs)
+ return;
+ clang_analyzer_eval(lhs < rhs); // expected-warning{{FALSE}}
+
+ clang_analyzer_eval(lhs - rhs); // expected-warning{{UNKNOWN}}
+ if ((lhs - rhs) != 5)
+ return;
+ clang_analyzer_eval((lhs - rhs) == 5); // expected-warning{{TRUE}}
+}
+
+void equal_implies_zero(int *lhs, int *rhs) {
+ clang_analyzer_eval(lhs == rhs); // expected-warning{{UNKNOWN}}
+ if (lhs == rhs) {
+ clang_analyzer_eval(lhs != rhs); // expected-warning{{FALSE}}
+ clang_analyzer_eval((rhs - lhs) == 0); // expected-warning{{TRUE}}
+ return;
+ }
+ clang_analyzer_eval(lhs == rhs); // expected-warning{{FALSE}}
+ clang_analyzer_eval(lhs != rhs); // expected-warning{{TRUE}}
+ clang_analyzer_eval((rhs - lhs) == 0); // expected-warning{{FALSE}}
+}
+
+void zero_implies_equal(int *lhs, int *rhs) {
+ clang_analyzer_eval((rhs - lhs) == 0); // expected-warning{{UNKNOWN}}
+ if ((rhs - lhs) == 0) {
+ clang_analyzer_eval(lhs != rhs); // expected-warning{{FALSE}}
+ clang_analyzer_eval(lhs == rhs); // expected-warning{{TRUE}}
+ return;
+ }
+ clang_analyzer_eval((rhs - lhs) == 0); // expected-warning{{FALSE}}
+ clang_analyzer_eval(lhs == rhs); // expected-warning{{FALSE}}
+ clang_analyzer_eval(lhs != rhs); // expected-warning{{TRUE}}
+}
+
+void comparisons_imply_size(int *lhs, int *rhs) {
+ clang_analyzer_eval(lhs <= rhs); // expected-warning{{UNKNOWN}}
+
+ if (lhs > rhs) {
+ clang_analyzer_eval((rhs - lhs) == 0); // expected-warning{{FALSE}}
+ return;
+ }
+
+ clang_analyzer_eval(lhs <= rhs); // expected-warning{{TRUE}}
+ clang_analyzer_eval((rhs - lhs) >= 0); // expected-warning{{TRUE}}
+ clang_analyzer_eval((rhs - lhs) > 0); // expected-warning{{UNKNOWN}}
+
+ if (lhs >= rhs) {
+ clang_analyzer_eval((rhs - lhs) == 0); // expected-warning{{TRUE}}
+ return;
+ }
+
+ clang_analyzer_eval(lhs == rhs); // expected-warning{{FALSE}}
+ clang_analyzer_eval(lhs < rhs); // expected-warning{{TRUE}}
+ clang_analyzer_eval((rhs - lhs) > 0); // expected-warning{{TRUE}}
+}
+
+void size_implies_comparison(int *lhs, int *rhs) {
+ clang_analyzer_eval(lhs <= rhs); // expected-warning{{UNKNOWN}}
+
+ if ((rhs - lhs) < 0) {
+ clang_analyzer_eval(lhs == rhs); // expected-warning{{FALSE}}
+ return;
+ }
+
+ clang_analyzer_eval(lhs <= rhs); // expected-warning{{TRUE}}
+ clang_analyzer_eval((rhs - lhs) >= 0); // expected-warning{{TRUE}}
+ clang_analyzer_eval((rhs - lhs) > 0); // expected-warning{{UNKNOWN}}
+
+ if ((rhs - lhs) <= 0) {
+ clang_analyzer_eval(lhs == rhs); // expected-warning{{TRUE}}
+ return;
+ }
+
+ clang_analyzer_eval(lhs == rhs); // expected-warning{{FALSE}}
+ clang_analyzer_eval(lhs < rhs); // expected-warning{{TRUE}}
+ clang_analyzer_eval((rhs - lhs) > 0); // expected-warning{{TRUE}}
+}
+
+//-------------------------------
+// False positives
+//-------------------------------
+
+void zero_implies_reversed_equal(int *lhs, int *rhs) {
+ clang_analyzer_eval((rhs - lhs) == 0); // expected-warning{{UNKNOWN}}
+ if ((rhs - lhs) == 0) {
+ // FIXME: Should be FALSE.
+ clang_analyzer_eval(rhs != lhs); // expected-warning{{UNKNOWN}}
+ // FIXME: Should be TRUE.
+ clang_analyzer_eval(rhs == lhs); // expected-warning{{UNKNOWN}}
+ return;
+ }
+ clang_analyzer_eval((rhs - lhs) == 0); // expected-warning{{FALSE}}
+ // FIXME: Should be FALSE.
+ clang_analyzer_eval(rhs == lhs); // expected-warning{{UNKNOWN}}
+ // FIXME: Should be TRUE.
+ clang_analyzer_eval(rhs != lhs); // expected-warning{{UNKNOWN}}
+}
+
+void canonical_equal(int *lhs, int *rhs) {
+ clang_analyzer_eval(lhs == rhs); // expected-warning{{UNKNOWN}}
+ if (lhs == rhs) {
+ // FIXME: Should be TRUE.
+ clang_analyzer_eval(rhs == lhs); // expected-warning{{UNKNOWN}}
+ return;
+ }
+ clang_analyzer_eval(lhs == rhs); // expected-warning{{FALSE}}
+
+ // FIXME: Should be FALSE.
+ clang_analyzer_eval(rhs == lhs); // expected-warning{{UNKNOWN}}
+}
diff --git a/test/Analysis/reference.cpp b/test/Analysis/reference.cpp
index 8dd0baf8c3..1dabe7bc1a 100644
--- a/test/Analysis/reference.cpp
+++ b/test/Analysis/reference.cpp
@@ -102,7 +102,7 @@ void testRetroactiveNullReference(int *x) {
// "null reference". So the 'if' statement ought to be dead code.
// However, Clang (and other compilers) don't actually check that a pointer
// value is non-null in the implementation of references, so it is possible
- // to produce a supposed "null reference" at runtime. The analyzer shoeuld
+ // to produce a supposed "null reference" at runtime. The analyzer should
// still warn when it can prove such errors.
int &y = *x;
if (x != 0)
@@ -224,3 +224,13 @@ namespace rdar11212286 {
return *x; // no-warning
}
}
+
+namespace PR15694 {
+ class C {
+ bool bit : 1;
+ template <class T> void bar(const T &obj) {}
+ void foo() {
+ bar(bit); // don't crash
+ }
+ };
+}
diff --git a/test/Analysis/reference.mm b/test/Analysis/reference.mm
new file mode 100644
index 0000000000..c5546aac5f
--- /dev/null
+++ b/test/Analysis/reference.mm
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify -Wno-null-dereference %s
+
+@interface Foo
+- (int &)ref;
+@end
+
+Foo *getFoo() { return 0; }
+
+void testNullPointerSuppression() {
+ getFoo().ref = 1;
+}
+
+void testPositiveNullReference() {
+ Foo *x = 0;
+ x.ref = 1; // expected-warning {{The receiver of message 'ref' is nil, which results in forming a null reference}}
+}
+
diff --git a/test/Analysis/region-store.c b/test/Analysis/region-store.c
index d620150085..70bda1117b 100644
--- a/test/Analysis/region-store.c
+++ b/test/Analysis/region-store.c
@@ -1,5 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix -verify %s
-// expected-no-diagnostics
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix,debug.ExprInspection -verify %s
int printf(const char *restrict,...);
@@ -22,3 +21,36 @@ int compoundLiteralTest2() {
}
return 0;
}
+
+int concreteOffsetBindingIsInvalidatedBySymbolicOffsetAssignment(int length,
+ int i) {
+ int values[length];
+ values[i] = 4;
+ return values[0]; // no-warning
+}
+
+struct X{
+ int mem;
+};
+int initStruct(struct X *st);
+int structOffsetBindingIsInvalidated(int length, int i){
+ struct X l;
+ initStruct(&l);
+ return l.mem; // no-warning
+}
+
+void clang_analyzer_eval(int);
+void testConstraintOnRegionOffset(int *values, int length, int i){
+ if (values[1] == 4) {
+ values[i] = 5;
+ clang_analyzer_eval(values[1] == 4);// expected-warning {{UNKNOWN}}
+ }
+}
+
+int initArray(int *values);
+void testConstraintOnRegionOffsetStack(int *values, int length, int i) {
+ if (values[0] == 4) {
+ initArray(values);
+ clang_analyzer_eval(values[0] == 4);// expected-warning {{UNKNOWN}}
+ }
+}
diff --git a/test/Analysis/region-store.cpp b/test/Analysis/region-store.cpp
new file mode 100644
index 0000000000..5ea5c3f82f
--- /dev/null
+++ b/test/Analysis/region-store.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix -verify %s
+// expected-no-diagnostics
+
+class Loc {
+ int x;
+};
+class P1 {
+public:
+ Loc l;
+ void setLoc(Loc L) {
+ l = L;
+ }
+
+};
+class P2 {
+public:
+ int m;
+ int accessBase() {
+ return m;
+ }
+};
+class Derived: public P1, public P2 {
+};
+int radar13445834(Derived *Builder, Loc l) {
+ Builder->setLoc(l);
+ return Builder->accessBase();
+
+} \ No newline at end of file
diff --git a/test/Analysis/retain-release-inline.m b/test/Analysis/retain-release-inline.m
index 6ff9e9a552..8809c8c844 100644
--- a/test/Analysis/retain-release-inline.m
+++ b/test/Analysis/retain-release-inline.m
@@ -361,3 +361,35 @@ CFStringRef testCovariantReturnType() {
}
return Str;
}
+
+// Test that we reanalyze ObjC methods which have been inlined. When reanalyzing
+// them, make sure we inline very small functions.
+id returnInputParam(id x) {
+ return x;
+}
+
+@interface MyClass : NSObject
+- (id)test_reanalyze_as_top_level;
+- (void)test_inline_tiny_when_reanalyzing;
+- (void)inline_test_reanalyze_as_top_level;
+@end
+
+@implementation MyClass
+- (void)test_inline_tiny_when_reanalyzing {
+ id x = [[NSString alloc] init]; // no-warning
+ x = returnInputParam(x);
+ [x release];
+}
+
+- (id)test_reanalyze_as_top_level {
+ // This method does not follow naming conventions, so a warning will be
+ // reported when it is reanalyzed at top level.
+ return [[NSString alloc] init]; // expected-warning {{leak}}
+}
+
+- (void)inline_test_reanalyze_as_top_level {
+ id x = [self test_reanalyze_as_top_level];
+ [x release];
+ [self test_inline_tiny_when_reanalyzing];
+}
+@end
diff --git a/test/Analysis/retain-release-path-notes-gc.m b/test/Analysis/retain-release-path-notes-gc.m
index 913714e6cd..f74d61fa9a 100644
--- a/test/Analysis/retain-release-path-notes-gc.m
+++ b/test/Analysis/retain-release-path-notes-gc.m
@@ -139,7 +139,7 @@ void retainReleaseIgnored () {
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object with a +1 retain count. Core Foundation objects are not automatically garbage collected</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object with a +1 retain count. Core Foundation objects are not automatically garbage collected</string>
+// CHECK-NEXT: <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object with a +1 retain count. Core Foundation objects are not automatically garbage collected</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>control</string>
@@ -202,7 +202,7 @@ void retainReleaseIgnored () {
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>Object leaked: object allocated and stored into &apos;leaked&apos; is not referenced later in this execution path and has a retain count of +1</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Object leaked: object allocated and stored into &apos;leaked&apos; is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK-NEXT: <string>Object leaked: object allocated and stored into &apos;leaked&apos; is not referenced later in this execution path and has a retain count of +1</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
// CHECK-NEXT: <key>description</key><string>Potential leak (when using garbage collection) of an object stored into &apos;leaked&apos;</string>
@@ -210,7 +210,7 @@ void retainReleaseIgnored () {
// CHECK-NEXT: <key>type</key><string>Leak of object when using garbage collection</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
// CHECK-NEXT: <key>issue_context</key><string>creationViaCFCreate</string>
-// CHECK-NEXT: <key>issue_hash</key><string>2</string>
+// CHECK-NEXT: <key>issue_hash</key><string>1</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>44</integer>
@@ -282,7 +282,7 @@ void retainReleaseIgnored () {
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object with a +1 retain count. Core Foundation objects are not automatically garbage collected</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object with a +1 retain count. Core Foundation objects are not automatically garbage collected</string>
+// CHECK-NEXT: <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object with a +1 retain count. Core Foundation objects are not automatically garbage collected</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>control</string>
@@ -357,7 +357,7 @@ void retainReleaseIgnored () {
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>Reference count incremented. The object now has a +2 retain count</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Reference count incremented. The object now has a +2 retain count</string>
+// CHECK-NEXT: <string>Reference count incremented. The object now has a +2 retain count</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>control</string>
@@ -432,7 +432,7 @@ void retainReleaseIgnored () {
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>In GC mode a call to &apos;CFMakeCollectable&apos; decrements an object&apos;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</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>In GC mode a call to &apos;CFMakeCollectable&apos; decrements an object&apos;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</string>
+// CHECK-NEXT: <string>In GC mode a call to &apos;CFMakeCollectable&apos; decrements an object&apos;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</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>control</string>
@@ -507,7 +507,7 @@ void retainReleaseIgnored () {
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>In GC mode a call to &apos;NSMakeCollectable&apos; decrements an object&apos;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</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>In GC mode a call to &apos;NSMakeCollectable&apos; decrements an object&apos;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</string>
+// CHECK-NEXT: <string>In GC mode a call to &apos;NSMakeCollectable&apos; decrements an object&apos;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</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>control</string>
@@ -582,7 +582,7 @@ void retainReleaseIgnored () {
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>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</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>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</string>
+// CHECK-NEXT: <string>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</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>control</string>
@@ -645,7 +645,7 @@ void retainReleaseIgnored () {
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>Object leaked: object allocated and stored into &apos;leaked&apos; is not referenced later in this execution path and has a retain count of +1</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Object leaked: object allocated and stored into &apos;leaked&apos; is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK-NEXT: <string>Object leaked: object allocated and stored into &apos;leaked&apos; is not referenced later in this execution path and has a retain count of +1</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
// CHECK-NEXT: <key>description</key><string>Potential leak (when using garbage collection) of an object stored into &apos;leaked&apos;</string>
@@ -653,7 +653,7 @@ void retainReleaseIgnored () {
// CHECK-NEXT: <key>type</key><string>Leak of object when using garbage collection</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
// CHECK-NEXT: <key>issue_context</key><string>makeCollectable</string>
-// CHECK-NEXT: <key>issue_hash</key><string>6</string>
+// CHECK-NEXT: <key>issue_hash</key><string>1</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>53</integer>
@@ -725,7 +725,7 @@ void retainReleaseIgnored () {
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>Method returns an Objective-C object with a +0 retain count</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Method returns an Objective-C object with a +0 retain count</string>
+// CHECK-NEXT: <string>Method returns an Objective-C object with a +0 retain count</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>control</string>
@@ -800,7 +800,7 @@ void retainReleaseIgnored () {
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>In GC mode the &apos;retain&apos; message has no effect</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>In GC mode the &apos;retain&apos; message has no effect</string>
+// CHECK-NEXT: <string>In GC mode the &apos;retain&apos; message has no effect</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>control</string>
@@ -875,7 +875,7 @@ void retainReleaseIgnored () {
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>In GC mode the &apos;release&apos; message has no effect</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>In GC mode the &apos;release&apos; message has no effect</string>
+// CHECK-NEXT: <string>In GC mode the &apos;release&apos; message has no effect</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>control</string>
@@ -950,7 +950,7 @@ void retainReleaseIgnored () {
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>In GC mode an &apos;autorelease&apos; has no effect</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>In GC mode an &apos;autorelease&apos; has no effect</string>
+// CHECK-NEXT: <string>In GC mode an &apos;autorelease&apos; has no effect</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>control</string>
@@ -1013,7 +1013,7 @@ void retainReleaseIgnored () {
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string>
+// CHECK-NEXT: <string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
// CHECK-NEXT: <key>description</key><string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string>
@@ -1093,7 +1093,7 @@ void retainReleaseIgnored () {
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object with a +1 retain count. Core Foundation objects are not automatically garbage collected</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object with a +1 retain count. Core Foundation objects are not automatically garbage collected</string>
+// CHECK-NEXT: <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object with a +1 retain count. Core Foundation objects are not automatically garbage collected</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>control</string>
@@ -1168,7 +1168,7 @@ void retainReleaseIgnored () {
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>Object returned to caller as an owning reference (single retain count transferred to caller)</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Object returned to caller as an owning reference (single retain count transferred to caller)</string>
+// CHECK-NEXT: <string>Object returned to caller as an owning reference (single retain count transferred to caller)</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>event</string>
@@ -1197,7 +1197,7 @@ void retainReleaseIgnored () {
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>Object leaked: object allocated and stored into &apos;object&apos; and returned from method &apos;getViolation&apos; 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</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Object leaked: object allocated and stored into &apos;object&apos; and returned from method &apos;getViolation&apos; 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</string>
+// CHECK-NEXT: <string>Object leaked: object allocated and stored into &apos;object&apos; and returned from method &apos;getViolation&apos; 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</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
// CHECK-NEXT: <key>description</key><string>Potential leak (when using garbage collection) of an object stored into &apos;object&apos;</string>
@@ -1205,7 +1205,7 @@ void retainReleaseIgnored () {
// CHECK-NEXT: <key>type</key><string>Leak of returned object when using garbage collection</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>Objective-C method</string>
// CHECK-NEXT: <key>issue_context</key><string>getViolation</string>
-// CHECK-NEXT: <key>issue_hash</key><string>2</string>
+// CHECK-NEXT: <key>issue_hash</key><string>1</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>67</integer>
@@ -1277,7 +1277,7 @@ void retainReleaseIgnored () {
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object with a +1 retain count. Core Foundation objects are not automatically garbage collected</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object with a +1 retain count. Core Foundation objects are not automatically garbage collected</string>
+// CHECK-NEXT: <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object with a +1 retain count. Core Foundation objects are not automatically garbage collected</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>control</string>
@@ -1352,7 +1352,7 @@ void retainReleaseIgnored () {
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>Object returned to caller as an owning reference (single retain count transferred to caller)</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Object returned to caller as an owning reference (single retain count transferred to caller)</string>
+// CHECK-NEXT: <string>Object returned to caller as an owning reference (single retain count transferred to caller)</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>event</string>
@@ -1381,7 +1381,7 @@ void retainReleaseIgnored () {
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>Object leaked: object allocated and stored into &apos;object&apos; and returned from method &apos;copyViolation&apos; 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</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Object leaked: object allocated and stored into &apos;object&apos; and returned from method &apos;copyViolation&apos; 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</string>
+// CHECK-NEXT: <string>Object leaked: object allocated and stored into &apos;object&apos; and returned from method &apos;copyViolation&apos; 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</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
// CHECK-NEXT: <key>description</key><string>Potential leak (when using garbage collection) of an object stored into &apos;object&apos;</string>
@@ -1389,7 +1389,7 @@ void retainReleaseIgnored () {
// CHECK-NEXT: <key>type</key><string>Leak of returned object when using garbage collection</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>Objective-C method</string>
// CHECK-NEXT: <key>issue_context</key><string>copyViolation</string>
-// CHECK-NEXT: <key>issue_hash</key><string>2</string>
+// CHECK-NEXT: <key>issue_hash</key><string>1</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>72</integer>
diff --git a/test/Analysis/retain-release-path-notes.m b/test/Analysis/retain-release-path-notes.m
index 8809c573dc..a3c681ae37 100644
--- a/test/Analysis/retain-release-path-notes.m
+++ b/test/Analysis/retain-release-path-notes.m
@@ -86,15 +86,15 @@ void implicitDealloc () {
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}}
+ [object autorelease]; // expected-note{{Object autoreleased}}
+ [object autorelease]; // expected-note{{Object autoreleased}}
+ return; // expected-warning{{Object autoreleased too many times}} expected-note{{Object was autoreleased 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}}
+ [object autorelease]; // expected-note{{Object autoreleased}}
+ return; // expected-warning{{Object autoreleased too many times}} expected-note{{Object was autoreleased but has a +0 retain count}}
}
void makeCollectableIgnored () {
@@ -137,7 +137,7 @@ CFTypeRef CFGetRuleViolation () {
- (id)copyAutorelease {
id result = [[Foo alloc] init]; // expected-note{{Method returns an Objective-C object with a +1 retain count}}
- [result autorelease]; // expected-note{{Object sent -autorelease message}}
+ [result autorelease]; // expected-note{{Object autoreleased}}
return result; // expected-warning{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}} expected-note{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}}
}
@end
@@ -190,6 +190,56 @@ void testDictionary(id key, id value) {
[result release]; // expected-warning{{decrement}} expected-note{{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}}
}
+// Test that we step into the init method when the allocated object is leaked due to early escape within init.
+
+static int Cond;
+@interface MyObj : NSObject
+-(id)initX;
+-(id)initY;
+-(id)initZ;
++(void)test;
+@end
+
+@implementation MyObj
+
+-(id)initX {
+ if (Cond) // expected-note {{Assuming 'Cond' is not equal to 0}}
+ // expected-note@-1{{Taking true branch}}
+ return 0;
+ self = [super init];
+ return self;
+}
+
+-(id)initY {
+ self = [super init]; //expected-note {{Method returns an Objective-C object with a +1 retain count}}
+ return self;
+}
+
+-(id)initZ {
+ self = [super init];
+ return self;
+}
+
++(void)test {
+ // initX is inlined since we explicitely mark it as interesting
+ id x = [[MyObj alloc] initX]; // expected-warning {{Potential leak of an object}}
+ // expected-note@-1 {{Method returns an Objective-C object with a +1 retain count}}
+ // expected-note@-2 {{Calling 'initX'}}
+ // expected-note@-3 {{Returning from 'initX'}}
+ // expected-note@-4 {{Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1}}
+ // initI is inlined because the allocation happens within initY
+ id y = [[MyObj alloc] initY]; // expected-warning {{Potential leak of an object}}
+ // expected-note@-1 {{Calling 'initY'}}
+ // expected-note@-2 {{Returning from 'initY'}}
+
+ // initZ is not inlined
+ id z = [[MyObj alloc] initZ];
+ // expected-note@-1 {{Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1}}
+
+ [x release];
+ [z release];
+}
+@end
// CHECK: <key>diagnostics</key>
// CHECK-NEXT: <array>
@@ -328,7 +378,7 @@ void testDictionary(id key, id value) {
// CHECK-NEXT: <key>type</key><string>Leak</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
// CHECK-NEXT: <key>issue_context</key><string>creationViaAlloc</string>
-// CHECK-NEXT: <key>issue_hash</key><string>2</string>
+// CHECK-NEXT: <key>issue_hash</key><string>1</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>47</integer>
@@ -471,7 +521,7 @@ void testDictionary(id key, id value) {
// CHECK-NEXT: <key>type</key><string>Leak</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
// CHECK-NEXT: <key>issue_context</key><string>creationViaCFCreate</string>
-// CHECK-NEXT: <key>issue_hash</key><string>2</string>
+// CHECK-NEXT: <key>issue_hash</key><string>1</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>52</integer>
@@ -839,7 +889,7 @@ void testDictionary(id key, id value) {
// CHECK-NEXT: <key>type</key><string>Leak</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
// CHECK-NEXT: <key>issue_context</key><string>acquisitionViaMethod</string>
-// CHECK-NEXT: <key>issue_hash</key><string>5</string>
+// CHECK-NEXT: <key>issue_hash</key><string>1</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>60</integer>
@@ -1057,7 +1107,7 @@ void testDictionary(id key, id value) {
// CHECK-NEXT: <key>type</key><string>Leak</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
// CHECK-NEXT: <key>issue_context</key><string>acquisitionViaProperty</string>
-// CHECK-NEXT: <key>issue_hash</key><string>3</string>
+// CHECK-NEXT: <key>issue_hash</key><string>1</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>66</integer>
@@ -1275,7 +1325,7 @@ void testDictionary(id key, id value) {
// CHECK-NEXT: <key>type</key><string>Leak</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
// CHECK-NEXT: <key>issue_context</key><string>acquisitionViaCFFunction</string>
-// CHECK-NEXT: <key>issue_hash</key><string>3</string>
+// CHECK-NEXT: <key>issue_hash</key><string>1</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>72</integer>
@@ -1856,9 +1906,9 @@ void testDictionary(id key, id value) {
// CHECK-NEXT: </array>
// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>Object sent -autorelease message</string>
+// CHECK-NEXT: <string>Object autoreleased</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Object sent -autorelease message</string>
+// CHECK-NEXT: <string>Object autoreleased</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>control</string>
@@ -1931,9 +1981,9 @@ void testDictionary(id key, id value) {
// CHECK-NEXT: </array>
// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>Object sent -autorelease message</string>
+// CHECK-NEXT: <string>Object autoreleased</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Object sent -autorelease message</string>
+// CHECK-NEXT: <string>Object autoreleased</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>control</string>
@@ -1994,14 +2044,14 @@ void testDictionary(id key, id value) {
// CHECK-NEXT: </array>
// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>Object over-autoreleased: object was sent -autorelease 2 times but the object has a +1 retain count</string>
+// CHECK-NEXT: <string>Object was autoreleased 2 times but the object has a +1 retain count</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Object over-autoreleased: object was sent -autorelease 2 times but the object has a +1 retain count</string>
+// CHECK-NEXT: <string>Object was autoreleased 2 times but the object has a +1 retain count</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>description</key><string>Object sent -autorelease too many times</string>
+// CHECK-NEXT: <key>description</key><string>Object autoreleased too many times</string>
// CHECK-NEXT: <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
-// CHECK-NEXT: <key>type</key><string>Object sent -autorelease too many times</string>
+// CHECK-NEXT: <key>type</key><string>Object autoreleased too many times</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
// CHECK-NEXT: <key>issue_context</key><string>overAutorelease</string>
// CHECK-NEXT: <key>issue_hash</key><string>4</string>
@@ -2149,9 +2199,9 @@ void testDictionary(id key, id value) {
// CHECK-NEXT: </array>
// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>Object sent -autorelease message</string>
+// CHECK-NEXT: <string>Object autoreleased</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Object sent -autorelease message</string>
+// CHECK-NEXT: <string>Object autoreleased</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>control</string>
@@ -2212,14 +2262,14 @@ void testDictionary(id key, id value) {
// CHECK-NEXT: </array>
// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>Object over-autoreleased: object was sent -autorelease but the object has a +0 retain count</string>
+// CHECK-NEXT: <string>Object was autoreleased but has a +0 retain count</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Object over-autoreleased: object was sent -autorelease but the object has a +0 retain count</string>
+// CHECK-NEXT: <string>Object was autoreleased but has a +0 retain count</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>description</key><string>Object sent -autorelease too many times</string>
+// CHECK-NEXT: <key>description</key><string>Object autoreleased too many times</string>
// CHECK-NEXT: <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
-// CHECK-NEXT: <key>type</key><string>Object sent -autorelease too many times</string>
+// CHECK-NEXT: <key>type</key><string>Object autoreleased too many times</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
// CHECK-NEXT: <key>issue_context</key><string>autoreleaseUnowned</string>
// CHECK-NEXT: <key>issue_hash</key><string>3</string>
@@ -2515,7 +2565,7 @@ void testDictionary(id key, id value) {
// CHECK-NEXT: <key>type</key><string>Leak</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
// CHECK-NEXT: <key>issue_context</key><string>makeCollectableIgnored</string>
-// CHECK-NEXT: <key>issue_hash</key><string>4</string>
+// CHECK-NEXT: <key>issue_hash</key><string>1</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>104</integer>
@@ -2883,7 +2933,7 @@ void testDictionary(id key, id value) {
// CHECK-NEXT: <key>type</key><string>Leak of returned object</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
// CHECK-NEXT: <key>issue_context</key><string>CFGetRuleViolation</string>
-// CHECK-NEXT: <key>issue_hash</key><string>2</string>
+// CHECK-NEXT: <key>issue_hash</key><string>1</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>114</integer>
@@ -3619,7 +3669,7 @@ void testDictionary(id key, id value) {
// CHECK-NEXT: <key>type</key><string>Leak of returned object</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>Objective-C method</string>
// CHECK-NEXT: <key>issue_context</key><string>getViolation</string>
-// CHECK-NEXT: <key>issue_hash</key><string>2</string>
+// CHECK-NEXT: <key>issue_hash</key><string>1</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>135</integer>
@@ -3764,9 +3814,9 @@ void testDictionary(id key, id value) {
// CHECK-NEXT: </array>
// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>Object sent -autorelease message</string>
+// CHECK-NEXT: <string>Object autoreleased</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Object sent -autorelease message</string>
+// CHECK-NEXT: <string>Object autoreleased</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>control</string>
@@ -4560,4 +4610,735 @@ void testDictionary(id key, id value) {
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>path</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>225</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>225</integer>
+// CHECK-NEXT: <key>col</key><integer>4</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>225</integer>
+// CHECK-NEXT: <key>col</key><integer>11</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>225</integer>
+// CHECK-NEXT: <key>col</key><integer>11</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>225</integer>
+// CHECK-NEXT: <key>col</key><integer>11</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>225</integer>
+// CHECK-NEXT: <key>col</key><integer>11</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>225</integer>
+// CHECK-NEXT: <key>col</key><integer>23</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Method returns an Objective-C object with a +1 retain count</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Method returns an Objective-C object with a +1 retain count</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>225</integer>
+// CHECK-NEXT: <key>col</key><integer>11</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>225</integer>
+// CHECK-NEXT: <key>col</key><integer>11</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>225</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>225</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>225</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>225</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>225</integer>
+// CHECK-NEXT: <key>col</key><integer>30</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Calling &apos;initX&apos;</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Calling &apos;initX&apos;</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>205</integer>
+// CHECK-NEXT: <key>col</key><integer>1</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>depth</key><integer>1</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Entered call from &apos;test&apos;</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Entered call from &apos;test&apos;</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>205</integer>
+// CHECK-NEXT: <key>col</key><integer>1</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>205</integer>
+// CHECK-NEXT: <key>col</key><integer>1</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>206</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>206</integer>
+// CHECK-NEXT: <key>col</key><integer>4</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>206</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>206</integer>
+// CHECK-NEXT: <key>col</key><integer>4</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>206</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>206</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>206</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>206</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>206</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>1</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Assuming &apos;Cond&apos; is not equal to 0</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Assuming &apos;Cond&apos; is not equal to 0</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>206</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>206</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>208</integer>
+// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>208</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>225</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>225</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>225</integer>
+// CHECK-NEXT: <key>col</key><integer>30</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Returning from &apos;initX&apos;</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Returning from &apos;initX&apos;</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>225</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>225</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>225</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>225</integer>
+// CHECK-NEXT: <key>col</key><integer>4</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>225</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>225</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>225</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>description</key><string>Potential leak of an object</string>
+// CHECK-NEXT: <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK-NEXT: <key>type</key><string>Leak</string>
+// CHECK-NEXT: <key>issue_context_kind</key><string>Objective-C method</string>
+// CHECK-NEXT: <key>issue_context</key><string>test</string>
+// CHECK-NEXT: <key>issue_hash</key><string>2</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>225</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>path</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>225</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>225</integer>
+// CHECK-NEXT: <key>col</key><integer>4</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>225</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>225</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>225</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>225</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>231</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>231</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>231</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>231</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>231</integer>
+// CHECK-NEXT: <key>col</key><integer>30</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Calling &apos;initY&apos;</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Calling &apos;initY&apos;</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>213</integer>
+// CHECK-NEXT: <key>col</key><integer>1</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>depth</key><integer>1</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Entered call from &apos;test&apos;</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Entered call from &apos;test&apos;</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>213</integer>
+// CHECK-NEXT: <key>col</key><integer>1</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>213</integer>
+// CHECK-NEXT: <key>col</key><integer>1</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>214</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>214</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>214</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>214</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>214</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>214</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>214</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>214</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>214</integer>
+// CHECK-NEXT: <key>col</key><integer>21</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>1</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Method returns an Objective-C object with a +1 retain count</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Method returns an Objective-C object with a +1 retain count</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>231</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>231</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>231</integer>
+// CHECK-NEXT: <key>col</key><integer>30</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Returning from &apos;initY&apos;</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Returning from &apos;initY&apos;</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>231</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>231</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>236</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>236</integer>
+// CHECK-NEXT: <key>col</key><integer>4</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>236</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>236</integer>
+// CHECK-NEXT: <key>col</key><integer>4</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>236</integer>
+// CHECK-NEXT: <key>col</key><integer>11</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>236</integer>
+// CHECK-NEXT: <key>col</key><integer>11</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>236</integer>
+// CHECK-NEXT: <key>col</key><integer>11</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>236</integer>
+// CHECK-NEXT: <key>col</key><integer>11</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>236</integer>
+// CHECK-NEXT: <key>col</key><integer>23</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>description</key><string>Potential leak of an object</string>
+// CHECK-NEXT: <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK-NEXT: <key>type</key><string>Leak</string>
+// CHECK-NEXT: <key>issue_context_kind</key><string>Objective-C method</string>
+// CHECK-NEXT: <key>issue_context</key><string>test</string>
+// CHECK-NEXT: <key>issue_hash</key><string>8</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>236</integer>
+// CHECK-NEXT: <key>col</key><integer>11</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
diff --git a/test/Analysis/retain-release.m b/test/Analysis/retain-release.m
index 9de6cedaf0..bb4a1d169d 100644
--- a/test/Analysis/retain-release.m
+++ b/test/Analysis/retain-release.m
@@ -479,20 +479,20 @@ void f13_autorelease_b() {
CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks);
[(id) A autorelease];
[(id) A autorelease];
-} // expected-warning{{Object sent -autorelease too many times}}
+} // expected-warning{{Object autoreleased too many times}}
CFMutableArrayRef f13_autorelease_c() {
CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks);
[(id) A autorelease];
[(id) A autorelease];
- return A; // expected-warning{{Object sent -autorelease too many times}}
+ return A; // expected-warning{{Object autoreleased too many times}}
}
CFMutableArrayRef f13_autorelease_d() {
CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks);
[(id) A autorelease];
[(id) A autorelease];
- CFMutableArrayRef B = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning{{Object sent -autorelease too many times}}
+ CFMutableArrayRef B = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning{{Object autoreleased too many times}}
CFRelease(B); // no-warning
while (1) {}
}
@@ -1967,6 +1967,60 @@ void test_drain() {
[obj release]; // no-warning
}
+//===----------------------------------------------------------------------===//
+// Allow cf_returns_retained and cf_returns_not_retained to mark a return
+// value as tracked, even if the object isn't a known CF type.
+//===----------------------------------------------------------------------===//
+
+MyCFType getCustom() __attribute__((cf_returns_not_retained));
+MyCFType makeCustom() __attribute__((cf_returns_retained));
+
+void testCustomReturnsRetained() {
+ MyCFType obj = makeCustom(); // expected-warning {{leak of an object stored into 'obj'}}
+}
+
+void testCustomReturnsNotRetained() {
+ CFRelease(getCustom()); // expected-warning {{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}}
+}
+
+//===----------------------------------------------------------------------===//
+// Don't print variables which are out of the current scope.
+//===----------------------------------------------------------------------===//
+@interface MyObj12706177 : NSObject
+-(id)initX;
++(void)test12706177;
+@end
+static int Cond;
+@implementation MyObj12706177
+-(id)initX {
+ if (Cond)
+ return 0;
+ self = [super init];
+ return self;
+}
++(void)test12706177 {
+ id x = [[MyObj12706177 alloc] initX]; //expected-warning {{Potential leak of an object}}
+ [x release];
+}
+@end
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/13783514> xpc_connection_set_finalizer_f
+//===----------------------------------------------------------------------===//
+
+typedef xpc_object_t xpc_connection_t;
+typedef void (*xpc_finalizer_t)(void *value);
+void xpc_connection_set_context(xpc_connection_t connection, void *ctx);
+void xpc_connection_set_finalizer_f(xpc_connection_t connection,
+ xpc_finalizer_t finalizer);
+void releaseAfterXPC(void *context) {
+ [(NSArray *)context release];
+}
+
+void rdar13783514(xpc_connection_t connection) {
+ xpc_connection_set_context(connection, [[NSMutableArray alloc] init]);
+ xpc_connection_set_finalizer_f(connection, releaseAfterXPC);
+} // no-warning
// CHECK: <key>diagnostics</key>
@@ -8895,9 +8949,9 @@ void test_drain() {
// CHECK-NEXT: </array>
// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>Object sent -autorelease message</string>
+// CHECK-NEXT: <string>Object autoreleased</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Object sent -autorelease message</string>
+// CHECK-NEXT: <string>Object autoreleased</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>control</string>
@@ -8970,9 +9024,9 @@ void test_drain() {
// CHECK-NEXT: </array>
// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>Object sent -autorelease message</string>
+// CHECK-NEXT: <string>Object autoreleased</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Object sent -autorelease message</string>
+// CHECK-NEXT: <string>Object autoreleased</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>control</string>
@@ -9018,14 +9072,14 @@ void test_drain() {
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>Object over-autoreleased: object was sent -autorelease 2 times but the object has a +1 retain count</string>
+// CHECK-NEXT: <string>Object was autoreleased 2 times but the object has a +1 retain count</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Object over-autoreleased: object was sent -autorelease 2 times but the object has a +1 retain count</string>
+// CHECK-NEXT: <string>Object was autoreleased 2 times but the object has a +1 retain count</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>description</key><string>Object sent -autorelease too many times</string>
+// CHECK-NEXT: <key>description</key><string>Object autoreleased too many times</string>
// CHECK-NEXT: <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
-// CHECK-NEXT: <key>type</key><string>Object sent -autorelease too many times</string>
+// CHECK-NEXT: <key>type</key><string>Object autoreleased too many times</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
// CHECK-NEXT: <key>issue_context</key><string>f13_autorelease_b</string>
// CHECK-NEXT: <key>issue_hash</key><string>4</string>
@@ -9173,9 +9227,9 @@ void test_drain() {
// CHECK-NEXT: </array>
// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>Object sent -autorelease message</string>
+// CHECK-NEXT: <string>Object autoreleased</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Object sent -autorelease message</string>
+// CHECK-NEXT: <string>Object autoreleased</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>control</string>
@@ -9248,9 +9302,9 @@ void test_drain() {
// CHECK-NEXT: </array>
// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>Object sent -autorelease message</string>
+// CHECK-NEXT: <string>Object autoreleased</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Object sent -autorelease message</string>
+// CHECK-NEXT: <string>Object autoreleased</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>control</string>
@@ -9311,14 +9365,14 @@ void test_drain() {
// CHECK-NEXT: </array>
// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>Object over-autoreleased: object was sent -autorelease 2 times but the object has a +0 retain count</string>
+// CHECK-NEXT: <string>Object was autoreleased 2 times but the object has a +0 retain count</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Object over-autoreleased: object was sent -autorelease 2 times but the object has a +0 retain count</string>
+// CHECK-NEXT: <string>Object was autoreleased 2 times but the object has a +0 retain count</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>description</key><string>Object sent -autorelease too many times</string>
+// CHECK-NEXT: <key>description</key><string>Object autoreleased too many times</string>
// CHECK-NEXT: <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
-// CHECK-NEXT: <key>type</key><string>Object sent -autorelease too many times</string>
+// CHECK-NEXT: <key>type</key><string>Object autoreleased too many times</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
// CHECK-NEXT: <key>issue_context</key><string>f13_autorelease_c</string>
// CHECK-NEXT: <key>issue_hash</key><string>4</string>
@@ -9466,9 +9520,9 @@ void test_drain() {
// CHECK-NEXT: </array>
// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>Object sent -autorelease message</string>
+// CHECK-NEXT: <string>Object autoreleased</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Object sent -autorelease message</string>
+// CHECK-NEXT: <string>Object autoreleased</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>control</string>
@@ -9541,9 +9595,9 @@ void test_drain() {
// CHECK-NEXT: </array>
// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>Object sent -autorelease message</string>
+// CHECK-NEXT: <string>Object autoreleased</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Object sent -autorelease message</string>
+// CHECK-NEXT: <string>Object autoreleased</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>control</string>
@@ -9638,14 +9692,14 @@ void test_drain() {
// CHECK-NEXT: </array>
// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>Object over-autoreleased: object was sent -autorelease 2 times but the object has a +1 retain count</string>
+// CHECK-NEXT: <string>Object was autoreleased 2 times but the object has a +1 retain count</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Object over-autoreleased: object was sent -autorelease 2 times but the object has a +1 retain count</string>
+// CHECK-NEXT: <string>Object was autoreleased 2 times but the object has a +1 retain count</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>description</key><string>Object sent -autorelease too many times</string>
+// CHECK-NEXT: <key>description</key><string>Object autoreleased too many times</string>
// CHECK-NEXT: <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
-// CHECK-NEXT: <key>type</key><string>Object sent -autorelease too many times</string>
+// CHECK-NEXT: <key>type</key><string>Object autoreleased too many times</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
// CHECK-NEXT: <key>issue_context</key><string>f13_autorelease_d</string>
// CHECK-NEXT: <key>issue_hash</key><string>4</string>
@@ -13571,9 +13625,9 @@ void test_drain() {
// CHECK-NEXT: </array>
// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>Object sent -autorelease message</string>
+// CHECK-NEXT: <string>Object autoreleased</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Object sent -autorelease message</string>
+// CHECK-NEXT: <string>Object autoreleased</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>control</string>
@@ -20093,9 +20147,9 @@ void test_drain() {
// CHECK-NEXT: </array>
// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>Object sent -autorelease message</string>
+// CHECK-NEXT: <string>Object autoreleased</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Object sent -autorelease message</string>
+// CHECK-NEXT: <string>Object autoreleased</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>control</string>
diff --git a/test/Analysis/retain-release.mm b/test/Analysis/retain-release.mm
index d92237b185..3650d88724 100644
--- a/test/Analysis/retain-release.mm
+++ b/test/Analysis/retain-release.mm
@@ -64,6 +64,8 @@ extern const CFArrayCallBacks kCFTypeArrayCallBacks;
typedef const struct __CFArray * CFArrayRef;
typedef struct __CFArray * CFMutableArrayRef;
extern CFMutableArrayRef CFArrayCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFArrayCallBacks *callBacks);
+void abort(void) __attribute__((noreturn));
+CFArrayRef CFArrayCreate(CFAllocatorRef allocator, const void **values, CFIndex numValues, const CFArrayCallBacks *callBacks);
extern const void *CFArrayGetValueAtIndex(CFArrayRef theArray, CFIndex idx);
extern void CFArrayAppendValue(CFMutableArrayRef theArray, const void *value);
typedef struct {
@@ -81,6 +83,7 @@ typedef UInt32 CFStringEncoding;
enum {
kCFStringEncodingMacRoman = 0, kCFStringEncodingWindowsLatin1 = 0x0500, kCFStringEncodingISOLatin1 = 0x0201, kCFStringEncodingNextStepLatin = 0x0B01, kCFStringEncodingASCII = 0x0600, kCFStringEncodingUnicode = 0x0100, kCFStringEncodingUTF8 = 0x08000100, kCFStringEncodingNonLossyASCII = 0x0BFF , kCFStringEncodingUTF16 = 0x0100, kCFStringEncodingUTF16BE = 0x10000100, kCFStringEncodingUTF16LE = 0x14000100, kCFStringEncodingUTF32 = 0x0c000100, kCFStringEncodingUTF32BE = 0x18000100, kCFStringEncodingUTF32LE = 0x1c000100 };
extern CFStringRef CFStringCreateWithCString(CFAllocatorRef alloc, const char *cStr, CFStringEncoding encoding);
+extern CFStringRef CFStringCreateCopy(CFAllocatorRef alloc, CFStringRef theString);
typedef double CFTimeInterval;
typedef CFTimeInterval CFAbsoluteTime;
extern CFAbsoluteTime CFAbsoluteTimeGetCurrent(void);
@@ -267,7 +270,6 @@ extern void CGContextDrawLinearGradient(CGContextRef context,
CGGradientRef gradient, CGPoint startPoint, CGPoint endPoint,
CGGradientDrawingOptions options);
extern CGColorSpaceRef CGColorSpaceCreateDeviceRGB(void);
-
//===----------------------------------------------------------------------===//
// Test cases.
//===----------------------------------------------------------------------===//
@@ -385,3 +387,77 @@ void testCallback() {
val >> process;
}
+//===----------------------------------------------------------------------===//
+// Test handling static initializers.
+//===----------------------------------------------------------------------===//
+
+@interface radar13227740 : NSObject
+@end
+
+@implementation radar13227740
+- (CFArrayRef)test {
+ static CFArrayRef array = ::CFArrayCreate(0, 0, 0, 0);
+ do { if (!((0 != array)/1)) { abort(); } } while (false);
+ return array;
+}
+
+// Previously this reported a bogus leak.
+- (void)test2 {
+ (void)[self test];
+ (void)[self test];
+}
+@end
+
+//===----------------------------------------------------------------------===//
+// Don't crash on getting a null expression from CallEnter corresponding to a
+// destructor.
+//===----------------------------------------------------------------------===//
+
+template <typename X>
+class Holder {
+public:
+ Holder() throw();
+ ~Holder() throw() {}
+ X* get() const throw();
+ void reset(X* p) throw();
+private:
+ X* ptr_;
+};
+
+template<typename X>
+inline
+Holder<X>::Holder() throw()
+: ptr_(0){}
+
+template <typename X>
+inline
+X* Holder<X>::get() const throw() {
+ return ptr_;
+}
+
+template <typename X>
+inline
+void Holder<X>::reset(X* p) throw() {
+ if (ptr_ != p) {
+ if (ptr_ != 0) {
+ ::CFRelease( ptr_ );
+ }
+ ptr_ = p;
+ }
+}
+
+class radar13722286 {
+public:
+ radar13722286() {}
+private:
+ void PrepareBitmap();
+ Holder<const struct __CFString> mStr;
+};
+
+void radar13722286::PrepareBitmap() {
+ if (mStr.get() != 0) {
+ Holder<const struct __CFString> str1;
+ mStr.reset( CFStringCreateCopy( 0, str1.get() ) ); //expected-warning {{Potential leak of an object}}
+ }
+}
+
diff --git a/test/Analysis/simple-stream-checks.c b/test/Analysis/simple-stream-checks.c
index 1fb6de3ec1..ce57fa7ac3 100644
--- a/test/Analysis/simple-stream-checks.c
+++ b/test/Analysis/simple-stream-checks.c
@@ -88,4 +88,4 @@ void testPassToSystemHeaderFunctionIndirectly() {
FileStruct fs;
fs.p = fopen("myfile.txt", "w");
fakeSystemHeaderCall(&fs);
-} // expected leak warning
+} // expected-warning {{Opened file is never closed; potential resource leak}}
diff --git a/test/Analysis/stack-addr-ps.cpp b/test/Analysis/stack-addr-ps.cpp
index 7aefea5095..65d757154c 100644
--- a/test/Analysis/stack-addr-ps.cpp
+++ b/test/Analysis/stack-addr-ps.cpp
@@ -1,7 +1,7 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -verify %s
-// FIXME: Only the stack-address checking in Sema catches this right now, and
-// the stack analyzer doesn't handle the ImplicitCastExpr (lvalue).
+typedef __INTPTR_TYPE__ intptr_t;
+
const int& g() {
int s;
return s; // expected-warning{{Address of stack memory associated with local variable 's' returned}} expected-warning{{reference to stack memory associated with local variable 's' returned}}
@@ -96,3 +96,40 @@ void *radar13226577() {
return p; // expected-warning {{stack memory associated with local variable 'p' returned to caller}}
}
+namespace rdar13296133 {
+ class ConvertsToBool {
+ public:
+ operator bool() const { return this; }
+ };
+
+ class ConvertsToIntptr {
+ public:
+ operator intptr_t() const { return reinterpret_cast<intptr_t>(this); }
+ };
+
+ class ConvertsToPointer {
+ public:
+ operator const void *() const { return this; }
+ };
+
+ intptr_t returnAsNonLoc() {
+ ConvertsToIntptr obj;
+ return obj; // expected-warning{{Address of stack memory associated with local variable 'obj' returned to caller}}
+ }
+
+ bool returnAsBool() {
+ ConvertsToBool obj;
+ return obj; // no-warning
+ }
+
+ intptr_t returnAsNonLocViaPointer() {
+ ConvertsToPointer obj;
+ return reinterpret_cast<intptr_t>(static_cast<const void *>(obj)); // expected-warning{{Address of stack memory associated with local variable 'obj' returned to caller}}
+ }
+
+ bool returnAsBoolViaPointer() {
+ ConvertsToPointer obj;
+ return obj; // no-warning
+ }
+}
+
diff --git a/test/Analysis/stackaddrleak.c b/test/Analysis/stackaddrleak.c
index 10564faff3..4f81f6623e 100644
--- a/test/Analysis/stackaddrleak.c
+++ b/test/Analysis/stackaddrleak.c
@@ -1,5 +1,7 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store region -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify -std=c99 -Dbool=_Bool %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify -x c++ %s
+typedef __INTPTR_TYPE__ intptr_t;
char const *p;
void f0() {
@@ -15,7 +17,7 @@ void f1() {
void f2() {
p = (const char *) __builtin_alloca(12);
-} // expected-warning{{Address of stack memory allocated by call to alloca() on line 17 is still referred to by the global variable 'p' upon returning to the caller. This will be a dangling reference}}
+} // expected-warning{{Address of stack memory allocated by call to alloca() on line 19 is still referred to by the global variable 'p' upon returning to the caller. This will be a dangling reference}}
// PR 7383 - previosly the stack address checker would crash on this example
// because it would attempt to do a direct load from 'pr7383_list'.
@@ -32,3 +34,25 @@ void test_multi_return() {
a = &x;
b = &x;
} // expected-warning{{Address of stack memory associated with local variable 'x' is still referred to by the global variable 'a' upon returning}} expected-warning{{Address of stack memory associated with local variable 'x' is still referred to by the global variable 'b' upon returning}}
+
+intptr_t returnAsNonLoc() {
+ int x;
+ return (intptr_t)&x; // expected-warning{{Address of stack memory associated with local variable 'x' returned to caller}}
+}
+
+bool returnAsBool() {
+ int x;
+ return &x; // no-warning
+}
+
+void assignAsNonLoc() {
+ extern intptr_t ip;
+ int x;
+ ip = (intptr_t)&x;
+} // expected-warning{{Address of stack memory associated with local variable 'x' is still referred to by the global variable 'ip' upon returning}}
+
+void assignAsBool() {
+ extern bool b;
+ int x;
+ b = &x;
+} // no-warning
diff --git a/test/Analysis/string.c b/test/Analysis/string.c
index fd836c471b..6cf52f7a55 100644
--- a/test/Analysis/string.c
+++ b/test/Analysis/string.c
@@ -279,12 +279,16 @@ void strcpy_fn_const(char *x) {
strcpy(x, (const 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}}
}
+extern int globalInt;
void strcpy_effects(char *x, char *y) {
char a = x[0];
+ if (globalInt != 42)
+ return;
clang_analyzer_eval(strcpy(x, y) == x); // expected-warning{{TRUE}}
clang_analyzer_eval(strlen(x) == strlen(y)); // expected-warning{{TRUE}}
clang_analyzer_eval(a == x[0]); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(globalInt == 42); // expected-warning{{TRUE}}
}
void strcpy_overflow(char *y) {
@@ -410,12 +414,6 @@ void strcat_symbolic_dst_length(char *dst) {
clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
}
-void strcat_symbolic_src_length(char *src) {
- char dst[8] = "1234";
- strcat(dst, src);
- clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
-}
-
void strcat_symbolic_dst_length_taint(char *dst) {
scanf("%s", dst); // Taint data.
strcat(dst, "1234");
@@ -521,17 +519,6 @@ void strncpy_exactly_matching_buffer(char *y) {
clang_analyzer_eval(strlen(x) > 4); // expected-warning{{UNKNOWN}}
}
-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.
- clang_analyzer_eval(strlen(x) <= 3); // expected-warning{{TRUE}}
-}
-
void strncpy_zero(char *src) {
char dst[] = "123";
strncpy(dst, src, 0); // no-warning
@@ -1039,3 +1026,81 @@ void strncasecmp_diff_length_6() {
void strncasecmp_embedded_null () {
clang_analyzer_eval(strncasecmp("ab\0zz", "ab\0yy", 4) == 0); // expected-warning{{TRUE}}
}
+
+//===----------------------------------------------------------------------===
+// strsep()
+//===----------------------------------------------------------------------===
+
+char *strsep(char **stringp, const char *delim);
+
+void strsep_null_delim(char *s) {
+ strsep(&s, NULL); // expected-warning{{Null pointer argument in call to strsep()}}
+}
+
+void strsep_null_search() {
+ strsep(NULL, ""); // expected-warning{{Null pointer argument in call to strsep()}}
+}
+
+void strsep_return_original_pointer(char *s) {
+ char *original = s;
+ char *result = strsep(&s, ""); // no-warning
+ clang_analyzer_eval(original == result); // expected-warning{{TRUE}}
+}
+
+void strsep_null_string() {
+ char *s = NULL;
+ char *result = strsep(&s, ""); // no-warning
+ clang_analyzer_eval(result == NULL); // expected-warning{{TRUE}}
+}
+
+void strsep_changes_input_pointer(char *s) {
+ char *original = s;
+ strsep(&s, ""); // no-warning
+ clang_analyzer_eval(s == original); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(s == NULL); // expected-warning{{UNKNOWN}}
+
+ // Check that the value is symbolic.
+ if (s == NULL) {
+ clang_analyzer_eval(s == NULL); // expected-warning{{TRUE}}
+ }
+}
+
+void strsep_changes_input_string() {
+ char str[] = "abc";
+
+ clang_analyzer_eval(str[1] == 'b'); // expected-warning{{TRUE}}
+
+ char *s = str;
+ strsep(&s, "b"); // no-warning
+
+ // The real strsep will change the first delimiter it finds into a NUL
+ // character. For now, we just model the invalidation.
+ clang_analyzer_eval(str[1] == 'b'); // expected-warning{{UNKNOWN}}
+}
+
+//===----------------------------------------------------------------------===
+// FIXMEs
+//===----------------------------------------------------------------------===
+
+// The analyzer_eval call below should evaluate to true. We are being too
+// aggressive in marking the (length of) src symbol dead. The length of dst
+// depends on src. This could be explicitely specified in the checker or the
+// logic for handling MetadataSymbol in SymbolManager needs to change.
+void strcat_symbolic_src_length(char *src) {
+ char dst[8] = "1234";
+ strcat(dst, src);
+ clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{UNKNOWN}}
+}
+
+// The analyzer_eval call below should evaluate to true. Most likely the same
+// issue as the test above.
+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.
+ clang_analyzer_eval(strlen(x) <= 3); // expected-warning{{UNKNOWN}}
+}
diff --git a/test/Analysis/svalbuilder-logic.c b/test/Analysis/svalbuilder-logic.c
index 41d4fe21c2..9cf3f964bc 100644
--- a/test/Analysis/svalbuilder-logic.c
+++ b/test/Analysis/svalbuilder-logic.c
@@ -6,3 +6,11 @@
int SValBuilderLogicNoCrash(int *x) {
return 3 - (int)(x +3);
}
+
+// http://llvm.org/bugs/show_bug.cgi?id=15863
+// Don't crash when mixing 'bool' and 'int' in implicit comparisons to 0.
+void pr15863() {
+ extern int getBool();
+ _Bool a = getBool();
+ (void)!a; // no-warning
+}
diff --git a/test/Analysis/taint-generic.c b/test/Analysis/taint-generic.c
index 696db67713..fe27070026 100644
--- a/test/Analysis/taint-generic.c
+++ b/test/Analysis/taint-generic.c
@@ -212,3 +212,14 @@ int SymSymExprWithDiffTypes(void* p) {
return 5/j; // expected-warning {{Division by a tainted value, possibly zero}}
}
+
+void constraintManagerShouldTreatAsOpaque(int rhs) {
+ int i;
+ scanf("%d", &i);
+ // This comparison used to hit an assertion in the constraint manager,
+ // which didn't handle NonLoc sym-sym comparisons.
+ if (i < rhs)
+ return;
+ if (i < rhs)
+ *(volatile int *) 0; // no-warning
+}
diff --git a/test/Analysis/taint-tester.c b/test/Analysis/taint-tester.c
index 7b0ab2a5fd..6287198eda 100644
--- a/test/Analysis/taint-tester.c
+++ b/test/Analysis/taint-tester.c
@@ -1,10 +1,6 @@
// RUN: %clang_cc1 -Wno-int-to-pointer-cast -analyze -analyzer-checker=alpha.security.taint,debug.TaintTest %s -verify
-#include <stdarg.h>
-
-int scanf(const char *restrict format, ...);
-int getchar(void);
-typedef __typeof(sizeof(int)) size_t;
+#include "Inputs/system-header-simulator.h"
#define BUFSIZE 10
int Buffer[BUFSIZE];
@@ -87,15 +83,6 @@ void getenvTest(char *home) {
}
}
-typedef struct _FILE FILE;
-extern FILE *stdin;
-extern FILE *stdout;
-extern FILE *stderr;
-int fscanf(FILE *restrict stream, const char *restrict format, ...);
-int fprintf(FILE *stream, const char *format, ...);
-int fclose(FILE *stream);
-FILE *fopen(const char *path, const char *mode);
-
int fscanfTest(void) {
FILE *fp;
char s[80];
diff --git a/test/Analysis/temporaries.cpp b/test/Analysis/temporaries.cpp
index 32a4d3bef4..efc0825470 100644
--- a/test/Analysis/temporaries.cpp
+++ b/test/Analysis/temporaries.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify -w %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify -w -std=c++03 %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify -w -std=c++11 %s
extern bool clang_analyzer_eval(bool);
@@ -76,3 +77,35 @@ namespace rdar13281951 {
}
}
+namespace compound_literals {
+ struct POD {
+ int x, y;
+ };
+ struct HasCtor {
+ HasCtor(int x, int y) : x(x), y(y) {}
+ int x, y;
+ };
+ struct HasDtor {
+ int x, y;
+ ~HasDtor();
+ };
+ struct HasCtorDtor {
+ HasCtorDtor(int x, int y) : x(x), y(y) {}
+ ~HasCtorDtor();
+ int x, y;
+ };
+
+ void test() {
+ clang_analyzer_eval(((POD){1, 42}).y == 42); // expected-warning{{TRUE}}
+ clang_analyzer_eval(((HasDtor){1, 42}).y == 42); // expected-warning{{TRUE}}
+
+#if __cplusplus >= 201103L
+ clang_analyzer_eval(((HasCtor){1, 42}).y == 42); // expected-warning{{TRUE}}
+
+ // FIXME: should be TRUE, but we don't inline the constructors of
+ // temporaries because we can't model their destructors yet.
+ clang_analyzer_eval(((HasCtorDtor){1, 42}).y == 42); // expected-warning{{UNKNOWN}}
+#endif
+ }
+}
+
diff --git a/test/Analysis/uninit-vals-ps.c b/test/Analysis/uninit-vals-ps.c
index 09736ef1e3..ad40b15502 100644
--- a/test/Analysis/uninit-vals-ps.c
+++ b/test/Analysis/uninit-vals-ps.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -fblocks -verify %s
struct FPRec {
void (*my_func)(int * x);
@@ -122,6 +122,8 @@ int pr4631_f1_b(void)
return x; // no-warning
}
+// <rdar://problem/12278788> - FP when returning a void-valued expression from
+// a void function...or block.
void foo_radar12278788() { return; }
void test_radar12278788() {
return foo_radar12278788(); // no-warning
@@ -134,3 +136,16 @@ int test_radar12278788_FP() {
RetVoidFuncType f = foo_radar12278788_fp;
return ((RetIntFuncType)f)(); //expected-warning {{Undefined or garbage value returned to caller}}
}
+
+void rdar13665798() {
+ ^() {
+ return foo_radar12278788(); // no-warning
+ }();
+ ^void() {
+ return foo_radar12278788(); // no-warning
+ }();
+ ^int() {
+ RetVoidFuncType f = foo_radar12278788_fp;
+ return ((RetIntFuncType)f)(); //expected-warning {{Undefined or garbage value returned to caller}}
+ }();
+}
diff --git a/test/Analysis/uninit-vals.m b/test/Analysis/uninit-vals.m
index 6813b8ebf8..72b6739800 100644
--- a/test/Analysis/uninit-vals.m
+++ b/test/Analysis/uninit-vals.m
@@ -43,6 +43,7 @@ void PR10163 (void) {
typedef struct {
float x;
float y;
+ float z;
} Point;
typedef struct {
Point origin;
@@ -53,6 +54,7 @@ Point makePoint(float x, float y) {
Point result;
result.x = x;
result.y = y;
+ result.z = 0.0;
return result;
}
@@ -73,22 +75,68 @@ void PR14765_test() {
free(testObj);
}
-void PR14765_incorrectBehavior(Circle *testObj) {
+void PR14765_argument(Circle *testObj) {
int oldSize = testObj->size;
-
clang_analyzer_eval(testObj->size == oldSize); // expected-warning{{TRUE}}
testObj->origin = makePoint(0.0, 0.0);
+ clang_analyzer_eval(testObj->size == oldSize); // expected-warning{{TRUE}}
+}
+
+
+typedef struct {
+ int x;
+ int y;
+ int z;
+} IntPoint;
+typedef struct {
+ IntPoint origin;
+ int size;
+} IntCircle;
+
+IntPoint makeIntPoint(int x, int y) {
+ IntPoint result;
+ result.x = x;
+ result.y = y;
+ result.z = 0;
+ return result;
+}
+
+void PR14765_test_int() {
+ IntCircle *testObj = calloc(sizeof(IntCircle), 1);
+
+ clang_analyzer_eval(testObj->size == 0); // expected-warning{{TRUE}}
+ clang_analyzer_eval(testObj->origin.x == 0); // expected-warning{{TRUE}}
+ clang_analyzer_eval(testObj->origin.y == 0); // expected-warning{{TRUE}}
+ clang_analyzer_eval(testObj->origin.z == 0); // expected-warning{{TRUE}}
+
+ testObj->origin = makeIntPoint(1, 2);
+ if (testObj->size > 0) { ; } // warning occurs here
// FIXME: Assigning to 'testObj->origin' kills the default binding for the
// whole region, meaning that we've forgotten that testObj->size should also
// default to 0. Tracked by <rdar://problem/12701038>.
// This should be TRUE.
- clang_analyzer_eval(testObj->size == oldSize); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(testObj->size == 0); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(testObj->origin.x == 1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(testObj->origin.y == 2); // expected-warning{{TRUE}}
+ clang_analyzer_eval(testObj->origin.z == 0); // expected-warning{{TRUE}}
free(testObj);
}
+void PR14765_argument_int(IntCircle *testObj) {
+ int oldSize = testObj->size;
+ clang_analyzer_eval(testObj->size == oldSize); // expected-warning{{TRUE}}
+
+ testObj->origin = makeIntPoint(1, 2);
+ clang_analyzer_eval(testObj->size == oldSize); // expected-warning{{TRUE}}
+ clang_analyzer_eval(testObj->origin.x == 1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(testObj->origin.y == 2); // expected-warning{{TRUE}}
+ clang_analyzer_eval(testObj->origin.z == 0); // expected-warning{{TRUE}}
+}
+
+
void rdar13292559(Circle input) {
extern void useCircle(Circle);
@@ -100,3 +148,137 @@ void rdar13292559(Circle input) {
useCircle(obj); // no-warning
}
+
+typedef struct {
+ int x;
+ int y;
+} IntPoint2D;
+typedef struct {
+ IntPoint2D origin;
+ int size;
+} IntCircle2D;
+
+IntPoint2D makeIntPoint2D(int x, int y) {
+ IntPoint2D result;
+ result.x = x;
+ result.y = y;
+ return result;
+}
+
+void testSmallStructsCopiedPerField() {
+ IntPoint2D a;
+ a.x = 0;
+
+ IntPoint2D b = a;
+ extern void useInt(int);
+ useInt(b.x); // no-warning
+ useInt(b.y); // expected-warning{{uninitialized}}
+}
+
+void testLargeStructsNotCopiedPerField() {
+ IntPoint a;
+ a.x = 0;
+
+ IntPoint b = a;
+ extern void useInt(int);
+ useInt(b.x); // no-warning
+ useInt(b.y); // no-warning
+}
+
+void testSmallStructInLargerStruct() {
+ IntCircle2D *testObj = calloc(sizeof(IntCircle2D), 1);
+
+ clang_analyzer_eval(testObj->size == 0); // expected-warning{{TRUE}}
+ clang_analyzer_eval(testObj->origin.x == 0); // expected-warning{{TRUE}}
+ clang_analyzer_eval(testObj->origin.y == 0); // expected-warning{{TRUE}}
+
+ testObj->origin = makeIntPoint2D(1, 2);
+ if (testObj->size > 0) { ; } // warning occurs here
+
+ clang_analyzer_eval(testObj->size == 0); // expected-warning{{TRUE}}
+ clang_analyzer_eval(testObj->origin.x == 1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(testObj->origin.y == 2); // expected-warning{{TRUE}}
+
+ free(testObj);
+}
+
+void testCopySmallStructIntoArgument(IntCircle2D *testObj) {
+ int oldSize = testObj->size;
+ clang_analyzer_eval(testObj->size == oldSize); // expected-warning{{TRUE}}
+
+ testObj->origin = makeIntPoint2D(1, 2);
+ clang_analyzer_eval(testObj->size == oldSize); // expected-warning{{TRUE}}
+ clang_analyzer_eval(testObj->origin.x == 1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(testObj->origin.y == 2); // expected-warning{{TRUE}}
+}
+
+void testSmallStructBitfields() {
+ struct {
+ int x : 4;
+ int y : 4;
+ } a, b;
+
+ a.x = 1;
+ a.y = 2;
+
+ b = a;
+ clang_analyzer_eval(b.x == 1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(b.y == 2); // expected-warning{{TRUE}}
+}
+
+void testSmallStructBitfieldsFirstUndef() {
+ struct {
+ int x : 4;
+ int y : 4;
+ } a, b;
+
+ a.y = 2;
+
+ b = a;
+ clang_analyzer_eval(b.y == 2); // expected-warning{{TRUE}}
+ clang_analyzer_eval(b.x == 1); // expected-warning{{garbage}}
+}
+
+void testSmallStructBitfieldsSecondUndef() {
+ struct {
+ int x : 4;
+ int y : 4;
+ } a, b;
+
+ a.x = 1;
+
+ b = a;
+ clang_analyzer_eval(b.x == 1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(b.y == 2); // expected-warning{{garbage}}
+}
+
+void testSmallStructBitfieldsFirstUnnamed() {
+ struct {
+ int : 4;
+ int y : 4;
+ } a, b, c;
+
+ a.y = 2;
+
+ b = a;
+ clang_analyzer_eval(b.y == 2); // expected-warning{{TRUE}}
+
+ b = c;
+ clang_analyzer_eval(b.y == 2); // expected-warning{{garbage}}
+}
+
+void testSmallStructBitfieldsSecondUnnamed() {
+ struct {
+ int x : 4;
+ int : 4;
+ } a, b, c;
+
+ a.x = 1;
+
+ b = a;
+ clang_analyzer_eval(b.x == 1); // expected-warning{{TRUE}}
+
+ b = c;
+ clang_analyzer_eval(b.x == 1); // expected-warning{{garbage}}
+}
+
diff --git a/test/Analysis/unix-fns.c b/test/Analysis/unix-fns.c
index cfd5d14e8a..46c10136ed 100644
--- a/test/Analysis/unix-fns.c
+++ b/test/Analysis/unix-fns.c
@@ -552,7 +552,7 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
// CHECK-NEXT: <key>description</key><string>Call to &apos;dispatch_once&apos; uses the local variable &apos;pred&apos; for the predicate value. Using such transient memory for the predicate is potentially dangerous. Perhaps you intended to declare the variable as &apos;static&apos;?</string>
-// CHECK-NEXT: <key>category</key><string>Mac OS X API</string>
+// CHECK-NEXT: <key>category</key><string>API Misuse (Apple)</string>
// CHECK-NEXT: <key>type</key><string>Improper use of &apos;dispatch_once&apos;</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
// CHECK-NEXT: <key>issue_context</key><string>test_dispatch_once</string>
@@ -1352,7 +1352,7 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
// CHECK-NEXT: <key>description</key><string>Call to &apos;dispatch_once&apos; uses the local variable &apos;pred&apos; for the predicate value. Using such transient memory for the predicate is potentially dangerous. Perhaps you intended to declare the variable as &apos;static&apos;?</string>
-// CHECK-NEXT: <key>category</key><string>Mac OS X API</string>
+// CHECK-NEXT: <key>category</key><string>API Misuse (Apple)</string>
// CHECK-NEXT: <key>type</key><string>Improper use of &apos;dispatch_once&apos;</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
// CHECK-NEXT: <key>issue_context</key><string>test_dispatch_once_in_macro</string>
@@ -1662,11 +1662,45 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: </array>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>192</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>192</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>192</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>192</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>192</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -1697,7 +1731,7 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>192</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -2013,11 +2047,45 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: </array>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>202</integer>
+// CHECK-NEXT: <key>col</key><integer>4</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>202</integer>
+// CHECK-NEXT: <key>col</key><integer>4</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>202</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>202</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>202</integer>
-// CHECK-NEXT: <key>col</key><integer>4</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -2048,7 +2116,7 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>202</integer>
-// CHECK-NEXT: <key>col</key><integer>4</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 8da2ba4ab4..a11b83a854 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -29,7 +29,7 @@ endif ()
set(CLANG_TEST_DEPS
clang clang-headers
c-index-test diagtool arcmt-test c-arcmt-test
- clang-check
+ clang-check clang-format
)
set(CLANG_TEST_PARAMS
clang_site_config=${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg
@@ -44,7 +44,7 @@ endif()
if( NOT CLANG_BUILT_STANDALONE )
list(APPEND CLANG_TEST_DEPS
- llc opt FileCheck count not
+ llc opt FileCheck count not llvm-symbolizer
)
add_lit_testsuite(check-clang "Running the Clang regression tests"
diff --git a/test/CXX/basic/basic.link/p6.cpp b/test/CXX/basic/basic.link/p6.cpp
new file mode 100644
index 0000000000..8faec76fb3
--- /dev/null
+++ b/test/CXX/basic/basic.link/p6.cpp
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// C++11 [basic.link]p6:
+// The name of a function declared in block scope and the name
+// of a variable declared by a block scope extern declaration
+// have linkage. If there is a visible declaration of an entity
+// with linkage having the same name and type, ignoring entities
+// declared outside the innermost enclosing namespace scope, the
+// block scope declaration declares that same entity and
+// receives the linkage of the previous declaration.
+
+// rdar://13535367
+namespace test0 {
+ extern "C" int test0_array[];
+ void declare() { extern int test0_array[100]; }
+ extern "C" int test0_array[];
+ int value = sizeof(test0_array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int []'}}
+}
+
+namespace test1 {
+ extern "C" int test1_array[];
+ void test() {
+ { extern int test1_array[100]; }
+ extern int test1_array[];
+ int x = sizeof(test1_array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int []'}}
+ }
+}
+
+namespace test2 {
+ void declare() { extern int test2_array[100]; }
+ extern int test2_array[];
+ int value = sizeof(test2_array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int []'}}
+}
+
+namespace test3 {
+ void test() {
+ { extern int test3_array[100]; }
+ extern int test3_array[];
+ int x = sizeof(test3_array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int []'}}
+ }
+}
+
+
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp b/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp
index 7ecedd5a6a..1f78a738f3 100644
--- a/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp
+++ b/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
struct X0 {
X0 f1();
X0 f2();
@@ -25,3 +26,92 @@ struct X0::X0 X0::f2() { return X0(); }
template<typename T> X1<T>::X1<T> X1<T>::f2() { } // expected-error{{qualified reference to 'X1' is a constructor name rather than a template name wherever a constructor can be declared}}
template<typename T> X1<T>::X1<T> (X1<T>::f2)(int) { } // expected-error{{qualified reference to 'X1' is a constructor name rather than a template name wherever a constructor can be declared}}
template<typename T> struct X1<T>::X1<T> (X1<T>::f2)(float) { }
+
+// We have a special case for lookup within using-declarations that are
+// member-declarations: foo::bar::baz::baz always names baz's constructor
+// in such a context, even if looking up 'baz' within foo::bar::baz would
+// not find the injected-class-name. Likewise foo::bar::baz<T>::baz also
+// names the constructor.
+namespace InhCtor {
+ struct A {
+ A(int);
+ protected:
+ int T();
+ };
+ typedef A T;
+ struct B : A {
+ // This is a using-declaration for 'int A::T()' in C++98, but is an
+ // inheriting constructor declaration in C++11.
+ using InhCtor::T::T;
+ };
+#if __cplusplus < 201103L
+ B b(123); // expected-error {{no matching constructor}}
+ // expected-note@-7 2{{candidate constructor}}
+ int n = b.T(); // ok, accessible
+#else
+ B b(123); // ok, inheriting constructor
+ int n = b.T(); // expected-error {{'T' is a protected member of 'InhCtor::A'}}
+ // expected-note@-15 {{declared protected here}}
+
+ template<typename T>
+ struct S : T {
+ struct U : S {
+ using S::S;
+ };
+ using T::T;
+ };
+
+ S<A>::U ua(0);
+ S<B>::U ub(0);
+
+ template<typename T>
+ struct X : T {
+ using T::Z::U::U;
+ };
+ template<typename T>
+ struct X2 : T {
+ using T::Z::template V<int>::V;
+ };
+ struct Y {
+ struct Z {
+ typedef Y U;
+ template<typename T> using V = Y;
+ };
+ Y(int);
+ };
+ X<Y> xy(0);
+
+ namespace Repeat {
+ struct A {
+ struct T {
+ T(int);
+ };
+ };
+ struct Z : A {
+ using A::A::A;
+ };
+ template<typename T>
+ struct ZT : T::T {
+ using T::T::T;
+ };
+ }
+
+ namespace NS {
+ struct NS {};
+ }
+ struct DerivedFromNS : NS::NS {
+ // No special case unless the NNS names a class.
+ using InhCtor::NS::NS; // expected-error {{using declaration in class refers into 'InhCtor::NS::', which is not a class}}
+
+ };
+
+ typedef int I;
+ struct UsingInt {
+ using I::I; // expected-error {{expected a class or namespace}}
+ };
+ template<typename T> struct UsingIntTemplate {
+ using T::T; // expected-error {{type 'int' cannot be used prior to '::' because it has no members}}
+ };
+ UsingIntTemplate<int> uit; // expected-note {{here}}
+#endif
+}
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.unqual/p14.cpp b/test/CXX/basic/basic.lookup/basic.lookup.unqual/p14.cpp
index 4ffe538beb..6fba972989 100644
--- a/test/CXX/basic/basic.lookup/basic.lookup.unqual/p14.cpp
+++ b/test/CXX/basic/basic.lookup/basic.lookup.unqual/p14.cpp
@@ -17,3 +17,56 @@ namespace N {
int i = 2;
N::S N::j = i;
N::S N::j2(i);
+
+// <rdar://problem/13317030>
+namespace M {
+ class X { };
+ inline X operator-(int, X);
+
+ template<typename T>
+ class Y { };
+
+ typedef Y<float> YFloat;
+
+ namespace yfloat {
+ YFloat operator-(YFloat, YFloat);
+ }
+ using namespace yfloat;
+}
+
+using namespace M;
+
+namespace M {
+
+class Other {
+ void foo(YFloat a, YFloat b);
+};
+
+}
+
+void Other::foo(YFloat a, YFloat b) {
+ YFloat c = a - b;
+}
+
+// <rdar://problem/13540899>
+namespace Other {
+ void other_foo();
+}
+
+namespace M2 {
+ using namespace Other;
+
+ extern "C" {
+ namespace MInner {
+ extern "C" {
+ class Bar {
+ void bar();
+ };
+ }
+ }
+ }
+}
+
+void M2::MInner::Bar::bar() {
+ other_foo();
+}
diff --git a/test/CXX/basic/basic.types/p10.cpp b/test/CXX/basic/basic.types/p10.cpp
index 6401c29dcf..9d99a77744 100644
--- a/test/CXX/basic/basic.types/p10.cpp
+++ b/test/CXX/basic/basic.types/p10.cpp
@@ -1,9 +1,16 @@
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++1y %s -DCXX1Y
struct NonLiteral { NonLiteral(); };
// A type is a literal type if it is:
+// [C++1y] - void
+constexpr void f() {}
+#ifndef CXX1Y
+// expected-error@-2 {{'void' is not a literal type}}
+#endif
+
// - a scalar type
constexpr int f1(double) { return 0; }
@@ -11,7 +18,6 @@ constexpr int f1(double) { return 0; }
struct S { S(); };
constexpr int f2(S &) { return 0; }
-// FIXME: I'm not entirely sure whether the following is legal or not...
struct BeingDefined;
extern BeingDefined beingdefined;
struct BeingDefined {
@@ -32,13 +38,13 @@ constexpr ClassTemp<int> classtemplate2[] = {};
// - it has a trivial destructor
struct UserProvDtor {
- constexpr int f(); // expected-error {{non-literal type 'UserProvDtor' cannot have constexpr members}}
+ constexpr int f() const; // expected-error {{non-literal type 'UserProvDtor' cannot have constexpr members}}
~UserProvDtor(); // expected-note {{has a user-provided destructor}}
};
struct NonTrivDtor {
constexpr NonTrivDtor();
- constexpr int f(); // expected-error {{non-literal type 'NonTrivDtor' cannot have constexpr members}}
+ constexpr int f() const; // expected-error {{non-literal type 'NonTrivDtor' cannot have constexpr members}}
virtual ~NonTrivDtor() = default; // expected-note {{has a non-trivial destructor}} expected-note {{because it is virtual}}
};
struct NonTrivDtorBase {
@@ -71,11 +77,11 @@ struct CtorTemplate {
};
struct CopyCtorOnly { // expected-note {{'CopyCtorOnly' is not literal because it is not an aggregate and has no constexpr constructors other than copy or move constructors}}
constexpr CopyCtorOnly(CopyCtorOnly&);
- constexpr int f(); // expected-error {{non-literal type 'CopyCtorOnly' cannot have constexpr members}}
+ constexpr int f() const; // expected-error {{non-literal type 'CopyCtorOnly' cannot have constexpr members}}
};
struct MoveCtorOnly { // expected-note {{no constexpr constructors other than copy or move constructors}}
constexpr MoveCtorOnly(MoveCtorOnly&&);
- constexpr int f(); // expected-error {{non-literal type 'MoveCtorOnly' cannot have constexpr members}}
+ constexpr int f() const; // expected-error {{non-literal type 'MoveCtorOnly' cannot have constexpr members}}
};
template<typename T>
struct CtorArg {
@@ -104,7 +110,7 @@ constexpr int f(NonLitMember) {} // expected-error {{1st parameter type 'NonLitM
struct NonLitBase :
S { // expected-note {{base class 'S' of non-literal type}}
constexpr NonLitBase();
- constexpr int f() { return 0; } // expected-error {{non-literal type 'NonLitBase' cannot have constexpr members}}
+ constexpr int f() const { return 0; } // expected-error {{non-literal type 'NonLitBase' cannot have constexpr members}}
};
struct LitMemBase : Agg {
Agg agg;
@@ -117,7 +123,7 @@ struct MemberType {
constexpr int f(MemberType<int>) { return 0; }
constexpr int f(MemberType<NonLiteral>) { return 0; } // expected-error {{not a literal type}}
-// - an array of literal type
+// - an array of literal type [C++1y] other than an array of runtime bound
struct ArrGood {
Agg agg[24];
double d[12];
@@ -130,3 +136,7 @@ struct ArrBad {
S s[3]; // expected-note {{data member 's' of non-literal type 'S [3]'}}
};
constexpr int f(ArrBad) { return 0; } // expected-error {{1st parameter type 'ArrBad' is not a literal type}}
+
+constexpr int arb(int n) {
+ int a[n]; // expected-error {{variable of non-literal type 'int [n]' cannot be defined in a constexpr function}}
+}
diff --git a/test/CXX/class.derived/class.abstract/p16.cpp b/test/CXX/class.derived/class.abstract/p16.cpp
index 93f905cd33..c237ed9044 100644
--- a/test/CXX/class.derived/class.abstract/p16.cpp
+++ b/test/CXX/class.derived/class.abstract/p16.cpp
@@ -14,3 +14,29 @@ struct C: A {
virtual void a();
virtual void b() = delete;
};
+
+struct E;
+struct F;
+struct G;
+struct H;
+struct D {
+ virtual E &operator=(const E &); // expected-note {{here}}
+ virtual F &operator=(const F &);
+ virtual G &operator=(G&&);
+ virtual H &operator=(H&&); // expected-note {{here}}
+ friend struct F;
+
+private:
+ D &operator=(const D&) = default;
+ D &operator=(D&&) = default;
+ virtual ~D(); // expected-note 2{{here}}
+};
+struct E : D {}; // expected-error {{deleted function '~E' cannot override a non-deleted function}} \
+ // expected-error {{deleted function 'operator=' cannot override a non-deleted function}}
+struct F : D {};
+// No move ctor here, because it would be deleted.
+struct G : D {}; // expected-error {{deleted function '~G' cannot override a non-deleted function}}
+struct H : D {
+ H &operator=(H&&) = default; // expected-error {{deleted function 'operator=' cannot override a non-deleted function}}
+ ~H();
+};
diff --git a/test/CXX/class/class.friend/p6.cpp b/test/CXX/class/class.friend/p6.cpp
index 7d7a06419a..82ca50e485 100644
--- a/test/CXX/class/class.friend/p6.cpp
+++ b/test/CXX/class/class.friend/p6.cpp
@@ -1,10 +1,18 @@
-// RUN: %clang_cc1 -fsyntax-only -Wc++11-compat -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wc++11-compat -verify -std=c++98 %s
+// RUN: %clang_cc1 -fsyntax-only -Wc++11-compat -verify -std=c++11 %s
class A {
friend static class B; // expected-error {{'static' is invalid in friend declarations}}
friend extern class C; // expected-error {{'extern' is invalid in friend declarations}}
- friend auto class D; // expected-warning {{incompatible with C++11}} expected-error {{'auto' is invalid in friend declarations}}
friend register class E; // expected-error {{'register' is invalid in friend declarations}}
friend mutable class F; // expected-error {{'mutable' is invalid in friend declarations}}
friend typedef class G; // expected-error {{'typedef' is invalid in friend declarations}}
+ friend __thread class G; // expected-error {{'__thread' is invalid in friend declarations}}
+ friend _Thread_local class G; // expected-error {{'_Thread_local' is invalid in friend declarations}}
+ friend static _Thread_local class G; // expected-error {{'static _Thread_local' is invalid in friend declarations}}
+#if __cplusplus < 201103L
+ friend auto class D; // expected-warning {{incompatible with C++11}} expected-error {{'auto' is invalid in friend declarations}}
+#else
+ friend thread_local class G; // expected-error {{'thread_local' is invalid in friend declarations}}
+#endif
};
diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.memdef/p3.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.memdef/p3.cpp
index 069ca0a925..11372dd48a 100644
--- a/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.memdef/p3.cpp
+++ b/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.memdef/p3.cpp
@@ -91,3 +91,104 @@ namespace test5 {
template void f<int>(int);
template void f<long>(long); //expected-note {{instantiation}}
}
+
+// rdar://13393749
+namespace test6 {
+ class A;
+ namespace ns {
+ class B {
+ static void foo(); // expected-note {{implicitly declared private here}}
+ friend union A;
+ };
+
+ union A {
+ void test() {
+ B::foo();
+ }
+ };
+ }
+
+ class A {
+ void test() {
+ ns::B::foo(); // expected-error {{'foo' is a private member of 'test6::ns::B'}}
+ }
+ };
+}
+
+// We seem to be following a correct interpretation with these, but
+// the standard could probably be a bit clearer.
+namespace test7a {
+ namespace ns {
+ class A;
+ }
+
+ using namespace ns;
+ class B {
+ static void foo();
+ friend class A;
+ };
+
+ class ns::A {
+ void test() {
+ B::foo();
+ }
+ };
+}
+namespace test7b {
+ namespace ns {
+ class A;
+ }
+
+ using ns::A;
+ class B {
+ static void foo();
+ friend class A;
+ };
+
+ class ns::A {
+ void test() {
+ B::foo();
+ }
+ };
+}
+namespace test7c {
+ namespace ns1 {
+ class A;
+ }
+
+ namespace ns2 {
+ // ns1::A appears as if declared in test7c according to [namespace.udir]p2.
+ // I think that means we aren't supposed to find it.
+ using namespace ns1;
+ class B {
+ static void foo(); // expected-note {{implicitly declared private here}}
+ friend class A;
+ };
+ }
+
+ class ns1::A {
+ void test() {
+ ns2::B::foo(); // expected-error {{'foo' is a private member of 'test7c::ns2::B'}}
+ }
+ };
+}
+namespace test7d {
+ namespace ns1 {
+ class A;
+ }
+
+ namespace ns2 {
+ // Honor the lexical context of a using-declaration, though.
+ using ns1::A;
+ class B {
+ static void foo();
+ friend class A;
+ };
+ }
+
+ class ns1::A {
+ void test() {
+ ns2::B::foo();
+ }
+ };
+}
diff --git a/test/CXX/dcl.dcl/dcl.link/p7-2.cpp b/test/CXX/dcl.dcl/dcl.link/p7-2.cpp
new file mode 100644
index 0000000000..40f61c6445
--- /dev/null
+++ b/test/CXX/dcl.dcl/dcl.link/p7-2.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -ast-print -o - %s | FileCheck %s
+
+extern "C" void f(void);
+// CHECK: extern "C" void f()
+
+extern "C" void v;
+// CHECK: extern "C" void v
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
index a3a964a1ca..122a400d9b 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
@@ -71,7 +71,7 @@ struct ConstexprDtor {
template <typename T> constexpr T ft(T t) { return t; }
template <typename T> T gt(T t) { return t; }
struct S {
- template<typename T> constexpr T f();
+ template<typename T> constexpr T f(); // expected-warning {{C++1y}}
template<typename T> T g() const;
};
@@ -81,7 +81,7 @@ template <> char ft(char c) { return c; } // expected-note {{previous}}
template <> constexpr char ft(char nl); // expected-error {{constexpr declaration of 'ft<char>' follows non-constexpr declaration}}
template <> constexpr int gt(int nl) { return nl; }
template <> notlit S::f() const { return notlit(); }
-template <> constexpr int S::g() { return 0; } // expected-note {{previous}}
+template <> constexpr int S::g() { return 0; } // expected-note {{previous}} expected-warning {{C++1y}}
template <> int S::g() const; // expected-error {{non-constexpr declaration of 'g<int>' follows constexpr declaration}}
// specializations can drop the 'constexpr' but not the implied 'const'.
template <> char S::g() { return 0; } // expected-error {{no function template matches}}
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp
index cafdd63551..4393727c19 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -verify -std=c++11 %s
+// RUN: %clang_cc1 -verify -fcxx-exceptions -triple=x86_64-linux-gnu -std=c++11 -Werror=c++1y-extensions %s
+// RUN: %clang_cc1 -verify -fcxx-exceptions -triple=x86_64-linux-gnu -std=c++1y -DCXX1Y %s
namespace N {
typedef char C;
@@ -8,7 +9,7 @@ namespace M {
typedef double D;
}
-struct NonLiteral { // expected-note 2{{no constexpr constructors}}
+struct NonLiteral { // expected-note 3{{no constexpr constructors}}
NonLiteral() {}
NonLiteral(int) {}
};
@@ -28,45 +29,53 @@ struct SS : S {
// constraints:
struct T : SS, NonLiteral { // expected-note {{base class 'NonLiteral' of non-literal type}}
constexpr T();
- constexpr int f(); // expected-error {{non-literal type 'T' cannot have constexpr members}}
+ constexpr int f() const; // expected-error {{non-literal type 'T' cannot have constexpr members}}
// - it shall not be virtual;
- virtual constexpr int ExplicitlyVirtual() { return 0; } // expected-error {{virtual function cannot be constexpr}}
+ virtual constexpr int ExplicitlyVirtual() const { return 0; } // expected-error {{virtual function cannot be constexpr}}
- constexpr int ImplicitlyVirtual() { return 0; } // expected-error {{virtual function cannot be constexpr}}
+ constexpr int ImplicitlyVirtual() const { return 0; } // expected-error {{virtual function cannot be constexpr}}
// - its return type shall be a literal type;
- constexpr NonLiteral NonLiteralReturn() { return {}; } // expected-error {{constexpr function's return type 'NonLiteral' is not a literal type}}
- constexpr void VoidReturn() { return; } // expected-error {{constexpr function's return type 'void' is not a literal type}}
+ constexpr NonLiteral NonLiteralReturn() const { return {}; } // expected-error {{constexpr function's return type 'NonLiteral' is not a literal type}}
+ constexpr void VoidReturn() const { return; }
+#ifndef CXX1Y
+ // expected-error@-2 {{constexpr function's return type 'void' is not a literal type}}
+#endif
constexpr ~T(); // expected-error {{destructor cannot be marked constexpr}}
- typedef NonLiteral F();
+ typedef NonLiteral F() const;
constexpr F NonLiteralReturn2; // ok until definition
// - each of its parameter types shall be a literal type;
- constexpr int NonLiteralParam(NonLiteral) { return 0; } // expected-error {{constexpr function's 1st parameter type 'NonLiteral' is not a literal type}}
- typedef int G(NonLiteral);
+ constexpr int NonLiteralParam(NonLiteral) const { return 0; } // expected-error {{constexpr function's 1st parameter type 'NonLiteral' is not a literal type}}
+ typedef int G(NonLiteral) const;
constexpr G NonLiteralParam2; // ok until definition
// - its function-body shall be = delete, = default,
- constexpr int Deleted() = delete;
- // It's not possible for the function-body to legally be "= default" here.
+ constexpr int Deleted() const = delete;
+ // It's not possible for the function-body to legally be "= default" here
+ // (that is, for a non-constructor function) in C++11.
// Other than constructors, only the copy- and move-assignment operators and
// destructor can be defaulted. Destructors can't be constexpr since they
// don't have a literal return type. Defaulted assignment operators can't be
// constexpr since they can't be const.
- constexpr T &operator=(const T&) = default; // expected-error {{an explicitly-defaulted copy assignment operator may not have 'const', 'constexpr' or 'volatile' qualifiers}}
+ constexpr T &operator=(const T&) = default;
+#ifndef CXX1Y
+ // expected-error@-2 {{an explicitly-defaulted copy assignment operator may not have 'const', 'constexpr' or 'volatile' qualifiers}}
+ // expected-warning@-3 {{C++1y}}
+#endif
};
struct U {
- constexpr U SelfReturn();
- constexpr int SelfParam(U);
+ constexpr U SelfReturn() const;
+ constexpr int SelfParam(U) const;
};
struct V : virtual U { // expected-note {{here}}
- constexpr int F() { return 0; } // expected-error {{constexpr member function not allowed in struct with virtual base class}}
+ constexpr int F() const { return 0; } // expected-error {{constexpr member function not allowed in struct with virtual base class}}
};
-// or a compound-statememt that contains only
-constexpr int AllowedStmts() {
+// or a compound-statememt that contains only [CXX11]
+constexpr int AllowedStmtsCXX11() {
// - null statements
;
@@ -91,34 +100,118 @@ constexpr int AllowedStmts() {
// - and exactly one return statement
return sizeof(K) + sizeof(C) + sizeof(K);
}
+
+// or a compound-statement that does not contain [CXX1Y]
+constexpr int DisallowedStmtsCXX1Y_1() {
+ // - an asm-definition
+ asm("int3"); // expected-error {{statement not allowed in constexpr function}}
+ return 0;
+}
+constexpr int DisallowedStmtsCXX1Y_2() {
+ // - a goto statement
+ goto x; // expected-error {{statement not allowed in constexpr function}}
+x:
+ return 0;
+}
+constexpr int DisallowedStmtsCXX1Y_3() {
+ // - a try-block,
+ try {} catch (...) {} // expected-error {{statement not allowed in constexpr function}}
+ return 0;
+}
+constexpr int DisallowedStmtsCXX1Y_4() {
+ // - a definition of a variable of non-literal type
+ NonLiteral nl; // expected-error {{variable of non-literal type 'NonLiteral' cannot be defined in a constexpr function}}
+ return 0;
+}
+constexpr int DisallowedStmtsCXX1Y_5() {
+ // - a definition of a variable of static storage duration
+ static constexpr int n = 123; // expected-error {{static variable not permitted in a constexpr function}}
+ return n;
+}
+constexpr int DisallowedStmtsCXX1Y_6() {
+ // - a definition of a variable of thread storage duration
+ thread_local constexpr int n = 123; // expected-error {{thread_local variable not permitted in a constexpr function}}
+ return n;
+}
+constexpr int DisallowedStmtsCXX1Y_7() {
+ // - a definition of a variable for which no initialization is performed
+ int n; // expected-error {{variables defined in a constexpr function must be initialized}}
+ return 0;
+}
+
constexpr int ForStmt() {
- for (int n = 0; n < 10; ++n) // expected-error {{statement not allowed in constexpr function}}
+ for (int n = 0; n < 10; ++n)
+#ifndef CXX1Y
+ // expected-error@-2 {{statement not allowed in constexpr function}}
+#endif
return 0;
}
constexpr int VarDecl() {
- constexpr int a = 0; // expected-error {{variables cannot be declared in a constexpr function}}
+ int a = 0;
+#ifndef CXX1Y
+ // expected-error@-2 {{variable declaration in a constexpr function is a C++1y extension}}
+#endif
+ return 0;
+}
+constexpr int ConstexprVarDecl() {
+ constexpr int a = 0;
+#ifndef CXX1Y
+ // expected-error@-2 {{variable declaration in a constexpr function is a C++1y extension}}
+#endif
return 0;
}
+constexpr int VarWithCtorDecl() {
+ Literal a;
+#ifndef CXX1Y
+ // expected-error@-2 {{variable declaration in a constexpr function is a C++1y extension}}
+#endif
+ return 0;
+}
+NonLiteral nl;
+constexpr NonLiteral &ExternNonLiteralVarDecl() {
+ extern NonLiteral nl;
+#ifndef CXX1Y
+ // expected-error@-2 {{variable declaration in a constexpr function is a C++1y extension}}
+#endif
+ return nl;
+}
+static_assert(&ExternNonLiteralVarDecl() == &nl, "");
constexpr int FuncDecl() {
- constexpr int ForwardDecl(int); // expected-error {{statement not allowed in constexpr function}}
+ constexpr int ForwardDecl(int);
+#ifndef CXX1Y
+ // expected-error@-2 {{use of this statement in a constexpr function is a C++1y extension}}
+#endif
return ForwardDecl(42);
}
constexpr int ClassDecl1() {
- typedef struct { } S1; // expected-error {{types cannot be defined in a constexpr function}}
+ typedef struct { } S1;
+#ifndef CXX1Y
+ // expected-error@-2 {{type definition in a constexpr function is a C++1y extension}}
+#endif
return 0;
}
constexpr int ClassDecl2() {
- using S2 = struct { }; // expected-error {{types cannot be defined in a constexpr function}}
+ using S2 = struct { };
+#ifndef CXX1Y
+ // expected-error@-2 {{type definition in a constexpr function is a C++1y extension}}
+#endif
return 0;
}
constexpr int ClassDecl3() {
- struct S3 { }; // expected-error {{types cannot be defined in a constexpr function}}
+ struct S3 { };
+#ifndef CXX1Y
+ // expected-error@-2 {{type definition in a constexpr function is a C++1y extension}}
+#endif
return 0;
}
constexpr int NoReturn() {} // expected-error {{no return statement in constexpr function}}
constexpr int MultiReturn() {
- return 0; // expected-note {{return statement}}
- return 0; // expected-error {{multiple return statements in constexpr function}}
+ return 0;
+ return 0;
+#ifndef CXX1Y
+ // expected-error@-2 {{multiple return statements in constexpr function}}
+ // expected-note@-4 {{return statement}}
+#endif
}
// - every constructor call and implicit conversion used in initializing the
@@ -137,3 +230,60 @@ namespace DR1364 {
return kGlobal; // expected-note {{read of non-const}}
}
}
+
+namespace rdar13584715 {
+ typedef __PTRDIFF_TYPE__ ptrdiff_t;
+
+ template<typename T> struct X {
+ static T value() {};
+ };
+
+ void foo(ptrdiff_t id) {
+ switch (id) {
+ case reinterpret_cast<ptrdiff_t>(&X<long>::value): // expected-error{{case value is not a constant expression}} \
+ // expected-note{{reinterpret_cast is not allowed in a constant expression}}
+ break;
+ }
+ }
+}
+
+namespace std_example {
+ constexpr int square(int x) {
+ return x * x;
+ }
+ constexpr long long_max() {
+ return 2147483647;
+ }
+ constexpr int abs(int x) {
+ if (x < 0)
+#ifndef CXX1Y
+ // expected-error@-2 {{C++1y}}
+#endif
+ x = -x;
+ return x;
+ }
+ constexpr int first(int n) {
+ static int value = n; // expected-error {{static variable not permitted}}
+ return value;
+ }
+ constexpr int uninit() {
+ int a; // expected-error {{must be initialized}}
+ return a;
+ }
+ constexpr int prev(int x) {
+ return --x;
+ }
+#ifndef CXX1Y
+ // expected-error@-4 {{never produces a constant expression}}
+ // expected-note@-4 {{subexpression}}
+#endif
+ constexpr int g(int x, int n) {
+ int r = 1;
+ while (--n > 0) r *= x;
+ return r;
+ }
+#ifndef CXX1Y
+ // expected-error@-5 {{C++1y}}
+ // expected-error@-5 {{statement not allowed}}
+#endif
+}
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp
index ad156c8ded..8a4fa42f00 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -verify -std=c++11 -fcxx-exceptions %s
+// RUN: %clang_cc1 -verify -std=c++11 -fcxx-exceptions -Werror=c++1y-extensions %s
+// RUN: %clang_cc1 -verify -std=c++1y -fcxx-exceptions -DCXX1Y %s
namespace N {
typedef char C;
@@ -82,26 +83,47 @@ struct V {
}
constexpr V(int(&)[1]) {
- for (int n = 0; n < 10; ++n) // expected-error {{statement not allowed in constexpr constructor}}
+ for (int n = 0; n < 10; ++n)
/**/;
+#ifndef CXX1Y
+ // expected-error@-3 {{statement not allowed in constexpr constructor}}
+#endif
}
constexpr V(int(&)[2]) {
- constexpr int a = 0; // expected-error {{variables cannot be declared in a constexpr constructor}}
+ constexpr int a = 0;
+#ifndef CXX1Y
+ // expected-error@-2 {{variable declaration in a constexpr constructor is a C++1y extension}}
+#endif
}
constexpr V(int(&)[3]) {
- constexpr int ForwardDecl(int); // expected-error {{statement not allowed in constexpr constructor}}
+ constexpr int ForwardDecl(int);
+#ifndef CXX1Y
+ // expected-error@-2 {{use of this statement in a constexpr constructor is a C++1y extension}}
+#endif
}
constexpr V(int(&)[4]) {
- typedef struct { } S1; // expected-error {{types cannot be defined in a constexpr constructor}}
+ typedef struct { } S1;
+#ifndef CXX1Y
+ // expected-error@-2 {{type definition in a constexpr constructor is a C++1y extension}}
+#endif
}
constexpr V(int(&)[5]) {
- using S2 = struct { }; // expected-error {{types cannot be defined in a constexpr constructor}}
+ using S2 = struct { };
+#ifndef CXX1Y
+ // expected-error@-2 {{type definition in a constexpr constructor is a C++1y extension}}
+#endif
}
constexpr V(int(&)[6]) {
- struct S3 { }; // expected-error {{types cannot be defined in a constexpr constructor}}
+ struct S3 { };
+#ifndef CXX1Y
+ // expected-error@-2 {{type definition in a constexpr constructor is a C++1y extension}}
+#endif
}
constexpr V(int(&)[7]) {
- return; // expected-error {{statement not allowed in constexpr constructor}}
+ return;
+#ifndef CXX1Y
+ // expected-error@-2 {{use of this statement in a constexpr constructor is a C++1y extension}}
+#endif
}
};
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p5.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p5.cpp
index bca73ee85f..5e40f69d77 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p5.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p5.cpp
@@ -102,7 +102,7 @@ X x = cmin(X(), X()); // ok, not constexpr
template<typename T>
struct Y {
constexpr Y() {}
- constexpr int get() { return T(); }
+ constexpr int get() { return T(); } // expected-warning {{C++1y}}
};
struct Z { operator int(); };
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p6.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p6.cpp
index 1a6dc9ecfb..bb7f7ac326 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p6.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p6.cpp
@@ -24,7 +24,7 @@ struct S {
struct T {};
template<typename T> struct ImplicitVirtualFromDependentBase : T {
- constexpr int ImplicitlyVirtual() { return 0; }
+ constexpr int ImplicitlyVirtual() const { return 0; }
};
constexpr int a = ImplicitVirtualFromDependentBase<S>().ImplicitlyVirtual(); // expected-error {{constant expression}} expected-note {{cannot evaluate virtual function call}}
@@ -32,7 +32,7 @@ constexpr int b = ImplicitVirtualFromDependentBase<T>().ImplicitlyVirtual(); //
constexpr int c = ImplicitVirtualFromDependentBase<S>().ImplicitVirtualFromDependentBase<S>::ImplicitlyVirtual();
template<typename R> struct ConstexprMember {
- constexpr R F() { return 0; }
+ constexpr R F() const { return 0; }
};
constexpr int d = ConstexprMember<int>().F(); // ok
constexpr int e = ConstexprMember<NonLiteral>().F(); // expected-error {{constant expression}}
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p8.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p8.cpp
index 344f8ce8c4..40aa600ba1 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p8.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p8.cpp
@@ -3,13 +3,13 @@
using size_t = decltype(sizeof(int));
struct S {
- constexpr int f();
+ constexpr int f(); // expected-warning {{C++1y}}
constexpr int g() const;
- constexpr int h();
+ constexpr int h(); // expected-warning {{C++1y}}
int h();
static constexpr int Sf();
/*static*/ constexpr void *operator new(size_t) noexcept;
- template<typename T> constexpr T tm();
+ template<typename T> constexpr T tm(); // expected-warning {{C++1y}}
template<typename T> static constexpr T ts();
};
@@ -26,12 +26,12 @@ void f(const S &s) {
}
constexpr int S::f() const { return 0; }
-constexpr int S::g() { return 1; }
-constexpr int S::h() { return 0; }
+constexpr int S::g() { return 1; } // expected-warning {{C++1y}}
+constexpr int S::h() { return 0; } // expected-warning {{C++1y}}
int S::h() { return 0; }
constexpr int S::Sf() { return 2; }
constexpr void *S::operator new(size_t) noexcept { return 0; }
-template<typename T> constexpr T S::tm() { return T(); }
+template<typename T> constexpr T S::tm() { return T(); } // expected-warning {{C++1y}}
template<typename T> constexpr T S::ts() { return T(); }
namespace std_example {
@@ -39,7 +39,7 @@ namespace std_example {
class debug_flag { // expected-note {{not an aggregate and has no constexpr constructors}}
public:
explicit debug_flag(bool);
- constexpr bool is_on(); // expected-error {{non-literal type 'std_example::debug_flag' cannot have constexpr members}}
+ constexpr bool is_on() const; // expected-error {{non-literal type 'std_example::debug_flag' cannot have constexpr members}}
private:
bool flag;
};
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p2.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p2.cpp
index a385aa9132..83b12d4b25 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p2.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p2.cpp
@@ -7,7 +7,7 @@ struct S {
// Note, this is not permitted: conversion-declarator cannot have a trailing return type.
// FIXME: don't issue the second diagnostic for this.
- operator auto(*)()->int(); // expected-error{{'auto' not allowed here}} expected-error {{C++ requires a type specifier}}
+ operator auto(*)()->int(); // expected-error{{'auto' not allowed in conversion function type}} expected-error {{C++ requires a type specifier}}
};
typedef auto Fun(int a) -> decltype(a + a);
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-1y.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-1y.cpp
new file mode 100644
index 0000000000..39c547b9ae
--- /dev/null
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-1y.cpp
@@ -0,0 +1,74 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++1y -DCXX1Y
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 -Wno-c++1y-extensions
+
+// FIXME: This is in p11 (?) in C++1y.
+void f() {
+ decltype(auto) a = a; // expected-error{{variable 'a' declared with 'auto' type cannot appear in its own initializer}}
+ if (decltype(auto) b = b) {} // expected-error {{variable 'b' declared with 'auto' type cannot appear in its own initializer}}
+ decltype(auto) c = ({ decltype(auto) d = c; 0; }); // expected-error {{variable 'c' declared with 'auto' type cannot appear in its own initializer}}
+}
+
+void g() {
+ decltype(auto) a; // expected-error{{declaration of variable 'a' with type 'decltype(auto)' requires an initializer}}
+
+ decltype(auto) *b; // expected-error{{cannot form pointer to 'decltype(auto)'}} expected-error{{declaration of variable 'b' with type 'decltype(auto) *' requires an initializer}}
+
+ if (decltype(auto) b) {} // expected-error {{must have an initializer}}
+ for (;decltype(auto) b;) {} // expected-error {{must have an initializer}}
+ while (decltype(auto) b) {} // expected-error {{must have an initializer}}
+ if (decltype(auto) b = true) { (void)b; }
+}
+
+decltype(auto) n(1,2,3); // expected-error{{initializer for variable 'n' with type 'decltype(auto)' contains multiple expressions}}
+
+namespace N
+{
+ // All of these are references, because a string literal is an lvalue.
+ decltype(auto) a = "const char (&)[19]", b = a, c = (a);
+}
+
+void h() {
+ decltype(auto) b = 42ULL;
+
+ for (decltype(auto) c = 0; c < b; ++c) {
+ }
+}
+
+template<typename T, typename U> struct same;
+template<typename T> struct same<T, T> {};
+
+void i() {
+ decltype(auto) x = 5;
+ decltype(auto) int r; // expected-error {{cannot combine with previous 'decltype(auto)' declaration specifier}} expected-error {{requires an initializer}}
+}
+
+namespace p3_example {
+ template<typename T, typename U> struct is_same_impl {
+ static const bool value = false;
+ };
+ template<typename T> struct is_same_impl<T, T> {
+ static const bool value = true;
+ };
+ template<typename T, typename U> constexpr bool is_same() {
+ return is_same_impl<T,U>::value;
+ }
+
+ auto x = 5;
+ const auto *v = &x, u = 6;
+ static auto y = 0.0;
+ auto int r; // expected-warning {{storage class}} expected-error {{file-scope}}
+
+ static_assert(is_same<decltype(x), int>(), "");
+ static_assert(is_same<decltype(v), const int*>(), "");
+ static_assert(is_same<decltype(u), const int>(), "");
+ static_assert(is_same<decltype(y), double>(), "");
+
+#ifdef CXX1Y
+ auto f() -> int;
+ auto g() { return 0.0; }
+ auto h();
+
+ static_assert(is_same<decltype(f), int()>(), "");
+ static_assert(is_same<decltype(g), double()>(), "");
+#endif
+}
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 7499829185..0cdf3c6e05 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
@@ -11,7 +11,7 @@ struct S {
friend auto; // expected-error{{'auto' not allowed in non-static struct member}}
- operator auto(); // expected-error{{'auto' not allowed here}}
+ operator auto(); // expected-error{{'auto' not allowed in conversion function type}}
};
// PR 9278: auto is not allowed in typedefs, except with a trailing return type.
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p6-1y.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p6-1y.cpp
new file mode 100644
index 0000000000..66085eda3d
--- /dev/null
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p6-1y.cpp
@@ -0,0 +1,97 @@
+// RUN: %clang_cc1 -verify -std=c++1y %s
+
+namespace std {
+ template<typename T> struct initializer_list {
+ const T *p;
+ unsigned long n;
+ initializer_list(const T *p, unsigned long n);
+ };
+}
+
+// FIXME: This may not be p6 in C++1y; N3638 isn't very clear whether paragraphs
+// were added. It might be p8?
+
+int i;
+int &&f();
+
+using Int = int;
+using IntLRef = int&;
+using IntRRef = int&&;
+using InitListInt = std::initializer_list<int>;
+using IntPtr = int*;
+
+auto x3a = i;
+decltype(auto) x3d = i;
+using Int = decltype(x3a);
+using Int = decltype(x3d);
+
+auto x4a = (i);
+decltype(auto) x4d = (i);
+using Int = decltype(x4a);
+using IntLRef = decltype(x4d);
+
+auto x5a = f();
+decltype(auto) x5d = f();
+using Int = decltype(x5a);
+using IntRRef = decltype(x5d);
+
+auto x6a = { 1, 2 };
+decltype(auto) x6d = { 1, 2 }; // expected-error {{cannot deduce 'decltype(auto)' from initializer list}}
+using InitListInt = decltype(x6a);
+
+auto *x7a = &i;
+decltype(auto) *x7d = &i; // expected-error {{cannot form pointer to 'decltype(auto)'}}
+using IntPtr = decltype(x7a);
+
+struct S {};
+
+decltype(auto) f1();
+decltype(auto) (*f2)(); // expected-error {{'decltype(auto)' can only be used as a return type in a function declaration}} expected-error {{requires an initializer}}
+decltype(auto) *f3(); // expected-error {{cannot form pointer to 'decltype(auto)'}}
+const decltype(auto) f4(); // expected-error {{'decltype(auto)' cannot be combined with other type specifiers}}
+typedef decltype(auto) f5(); // expected-error {{'decltype(auto)' can only be used as a return type in a function declaration}}
+decltype(auto) ((((((f6))))())); // ok
+decltype(auto) f7()(); // expected-error {{'decltype(auto)' can only be used as a return type in a function declaration}} expected-error {{function cannot return function type}}
+decltype(auto) (S::*f8)(); // expected-error {{'decltype(auto)' can only be used as a return type in a function declaration}} expected-error {{requires an initializer}}
+decltype(auto) &f9(); // expected-error {{cannot form reference to 'decltype(auto)'}}
+decltype(auto) (&f10())[10]; // expected-error {{cannot form array of 'decltype(auto)'}}
+
+decltype(auto) ((((((v1)))))) = 0; // ok
+decltype(auto) v2[1] = { 0 }; // expected-error {{cannot form array of 'decltype(auto)'}}
+decltype(auto) &v3 = { 0 }; // expected-error {{cannot form reference to 'decltype(auto)'}}
+decltype(auto) *v4 = { 0 }; // expected-error {{cannot form pointer to 'decltype(auto)'}}
+
+auto multi1a = 0, &multi1b = multi1a;
+auto multi1c = multi1a, multi1d = multi1b;
+decltype(auto) multi1e = multi1a, multi1f = multi1b; // expected-error {{'decltype(auto)' deduced as 'int' in declaration of 'multi1e' and deduced as 'int &' in declaration of 'multi1f'}}
+
+auto f1a() { return 0; }
+decltype(auto) f1d() { return 0; }
+using Int = decltype(f1a());
+using Int = decltype(f1d());
+
+auto f2a(int n) { return n; }
+decltype(auto) f2d(int n) { return n; }
+using Int = decltype(f2a(0));
+using Int = decltype(f2d(0));
+
+auto f3a(int n) { return (n); }
+decltype(auto) f3d(int n) { return (n); } // expected-warning {{reference to stack memory}}
+using Int = decltype(f3a(0));
+using IntLRef = decltype(f3d(0));
+
+auto f4a(int n) { return f(); }
+decltype(auto) f4d(int n) { return f(); }
+using Int = decltype(f4a(0));
+using IntRRef = decltype(f4d(0));
+
+auto f5aa(int n) { auto x = f(); return x; }
+auto f5ad(int n) { decltype(auto) x = f(); return x; }
+decltype(auto) f5da(int n) { auto x = f(); return x; }
+decltype(auto) f5dd(int n) { decltype(auto) x = f(); return x; } // expected-error {{rvalue reference to type 'int' cannot bind to lvalue}}
+using Int = decltype(f5aa(0));
+using Int = decltype(f5ad(0));
+using Int = decltype(f5da(0));
+
+auto init_list_1() { return { 1, 2, 3 }; } // expected-error {{cannot deduce return type from initializer list}}
+decltype(auto) init_list_2() { return { 1, 2, 3 }; } // expected-error {{cannot deduce return type from initializer list}}
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p5-cxx0x.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p5-cxx0x.cpp
index 093bc14d47..1ed93b1375 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p5-cxx0x.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p5-cxx0x.cpp
@@ -41,7 +41,9 @@ decltype(
PD(), // expected-error {{private destructor}}
PD()) pd1; // expected-error {{private destructor}}
decltype(DD(), // expected-error {{deleted function}}
- DD()) dd1; // expected-error {{deleted function}}
+ DD()) dd1;
+decltype(A(),
+ DD()) dd2; // expected-error {{deleted function}}
decltype(
PD(), // expected-error {{temporary of type 'PD' has private destructor}}
0) pd2;
@@ -76,7 +78,7 @@ namespace libcxx_example {
template<typename T> struct swappable {
typedef decltype(swap(declval<T&>(), declval<T&>())) type;
static const bool value = !is_same<type, nat>::value;
- constexpr operator bool() { return value; }
+ constexpr operator bool() const { return value; }
};
static_assert(swappable<int>(), "");
diff --git a/test/CXX/dcl.dcl/p4-0x.cpp b/test/CXX/dcl.dcl/p4-0x.cpp
index 31d49127e7..1f4cdda1a1 100644
--- a/test/CXX/dcl.dcl/p4-0x.cpp
+++ b/test/CXX/dcl.dcl/p4-0x.cpp
@@ -2,15 +2,15 @@
struct S {
constexpr S(bool b) : b(b) {}
- constexpr explicit operator bool() { return b; }
+ constexpr explicit operator bool() const { return b; }
bool b;
};
struct T {
- constexpr operator int() { return 1; }
+ constexpr operator int() const { return 1; }
};
struct U {
- constexpr operator int() { return 1; } // expected-note {{candidate}}
- constexpr operator long() { return 0; } // expected-note {{candidate}}
+ constexpr operator int() const { return 1; } // expected-note {{candidate}}
+ constexpr operator long() const { return 0; } // expected-note {{candidate}}
};
static_assert(S(true), "");
diff --git a/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp b/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp
index 783aba1823..b9a1bc5288 100644
--- a/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp
+++ b/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp
@@ -6,8 +6,8 @@ struct S1 {
constexpr S1() = default; // expected-error {{defaulted definition of default constructor is not constexpr}}
constexpr S1(const S1&) = default;
constexpr S1(S1&&) = default;
- constexpr S1 &operator=(const S1&) = default; // expected-error {{explicitly-defaulted copy assignment operator may not have}}
- constexpr S1 &operator=(S1&&) = default; // expected-error {{explicitly-defaulted move assignment operator may not have}}
+ constexpr S1 &operator=(const S1&) const = default; // expected-error {{explicitly-defaulted copy assignment operator may not have}}
+ constexpr S1 &operator=(S1&&) const = default; // expected-error {{explicitly-defaulted move assignment operator may not have}}
constexpr ~S1() = default; // expected-error {{destructor cannot be marked constexpr}}
int n;
};
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1-0x.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1-0x.cpp
index fef3692609..8767678362 100644
--- a/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1-0x.cpp
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1-0x.cpp
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++1y %s -DCXX1Y
// An aggregate is an array or a class...
struct Aggr {
@@ -18,9 +19,6 @@ struct NonAggr1a { // expected-note 2 {{candidate constructor}}
NonAggr1a(int, int); // expected-note {{candidate constructor}}
int k;
};
-// In C++0x, 'user-provided' is only defined for special member functions, so
-// this type is considered to be an aggregate. This is considered to be
-// a language defect.
NonAggr1a na1a = { 42 }; // expected-error {{no matching constructor for initialization of 'NonAggr1a'}}
struct NonAggr1b {
@@ -30,10 +28,15 @@ struct NonAggr1b {
NonAggr1b na1b = { 42 }; // expected-error {{no matching constructor for initialization of 'NonAggr1b'}}
// no brace-or-equal-initializers for non-static data members, ...
-struct NonAggr2 { // expected-note 3 {{candidate constructor}}
+// Note, this bullet was removed in C++1y.
+struct NonAggr2 {
int m = { 123 };
};
-NonAggr2 na2 = { 42 }; // expected-error {{no matching constructor for initialization of 'NonAggr2'}}
+NonAggr2 na2 = { 42 };
+#ifndef CXX1Y
+// expected-error@-2 {{no matching constructor for initialization of 'NonAggr2'}}
+// expected-note@-6 3 {{candidate constructor}}
+#endif
// no private...
struct NonAggr3 { // expected-note 3 {{candidate constructor}}
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p7.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p7.cpp
new file mode 100644
index 0000000000..d1fbe766d5
--- /dev/null
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p7.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -std=c++1y %s -verify
+
+// expected-no-diagnostics
+
+struct S { int a; const char *b; int c; int d = b[a]; };
+constexpr S ss = { 1, "asdf" };
+
+static_assert(ss.a == 1, "");
+static_assert(ss.b[2] == 'd', "");
+static_assert(ss.c == 0, "");
+static_assert(ss.d == 's', "");
+
+struct X { int i, j, k = 42; };
+constexpr X a[] = { 1, 2, 3, 4, 5, 6 };
+constexpr X b[2] = { { 1, 2, 3 }, { 4, 5, 6 } };
+
+constexpr bool operator==(X a, X b) {
+ return a.i == b.i && a.j == b.j && a.k == b.k;
+}
+
+static_assert(sizeof(a) == sizeof(b), "");
+static_assert(a[0] == b[0], "");
+static_assert(a[1] == b[1], "");
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp
index c7fb24fb44..d61f6e3d19 100644
--- a/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp
@@ -110,3 +110,13 @@ namespace bullet8 {
int j { 1 };
int k { };
}
+
+namespace rdar13395022 {
+ struct MoveOnly {
+ MoveOnly(MoveOnly&&); // expected-note{{copy constructor is implicitly deleted because 'MoveOnly' has a user-declared move constructor}}
+ };
+
+ void test(MoveOnly mo) {
+ auto &&list = {mo}; // expected-error{{call to implicitly-deleted copy constructor of 'rdar13395022::MoveOnly'}}
+ }
+}
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp
index adbdff6efe..fdfa6781fe 100644
--- a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp
@@ -192,3 +192,45 @@ namespace PR11003 {
Value y(Move(0));
}
}
+
+namespace rdar13278115 {
+ struct X { };
+ struct Y : X { };
+ X &&f0(X &x) { return x; } // expected-error{{rvalue reference to type 'rdar13278115::X' cannot bind to lvalue of type 'rdar13278115::X'}}
+ X &&f1(Y &y) { return y; } // expected-error{{rvalue reference to type 'rdar13278115::X' cannot bind to lvalue of type 'rdar13278115::Y'}}
+ const X &&f2(Y &y) { return y; } // expected-error{{rvalue reference to type 'const rdar13278115::X' cannot bind to lvalue of type 'rdar13278115::Y'}}
+}
+
+namespace bitfields {
+ struct IntBitfield {
+ int i : 17; // expected-note 3 {{bit-field is declared here}}
+ };
+
+ // A simplified version of std::move.
+ template <typename T>
+ T &&move(T &obj) {
+ return static_cast<T &&>(obj);
+ }
+
+ void test() {
+ int & ir1 = (lvalue<IntBitfield>().i); // expected-error{{non-const reference cannot bind to bit-field 'i'}}
+ int & ir2 = (xvalue<IntBitfield>().i); // expected-error{{non-const lvalue reference to type 'int' cannot bind to a temporary of type 'int'}}
+ int && ir3 = (xvalue<IntBitfield>().i); // no-warning
+ int && ir4 = move(lvalue<IntBitfield>()).i; // no-warning
+
+ volatile int & vir1 = (lvalue<IntBitfield>().i); // expected-error{{non-const reference cannot bind to bit-field 'i'}}
+ volatile int & vir2 = (xvalue<IntBitfield>().i); // expected-error{{volatile lvalue reference to type 'volatile int' cannot bind to a temporary of type 'int'}}
+ volatile int && vir3 = (xvalue<IntBitfield>().i); // no-warning
+ volatile int && vir4 = move(lvalue<IntBitfield>()).i; // no-warning
+
+ const int & cir1 = (lvalue<IntBitfield>().i); // no-warning
+ const int & cir2 = (xvalue<IntBitfield>().i); // no-warning
+ const int && cir3 = (xvalue<IntBitfield>().i); // no-warning
+ const int && cir4 = move(lvalue<IntBitfield>()).i; // no-warning
+
+ const volatile int & cvir1 = (lvalue<IntBitfield>().i); // expected-error{{non-const reference cannot bind to bit-field 'i'}}
+ const volatile int & cvir2 = (xvalue<IntBitfield>().i); // expected-error{{volatile lvalue reference to type 'const volatile int' cannot bind to a temporary of type 'int'}}
+ const volatile int && cvir3 = (xvalue<IntBitfield>().i); // no-warning
+ const volatile int && cvir4 = move(lvalue<IntBitfield>()).i; // no-warning
+ }
+}
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp
index 51d61a52a6..263f661208 100644
--- a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp
@@ -38,3 +38,26 @@ namespace PR6066 {
return 0;
}
}
+
+namespace test3 {
+ struct A {
+ unsigned bitX : 4; // expected-note 4 {{bit-field is declared here}}
+ unsigned bitY : 4; // expected-note {{bit-field is declared here}}
+ unsigned var;
+
+ void foo();
+ };
+
+ void test(A *a) {
+ unsigned &t0 = a->bitX; // expected-error {{non-const reference cannot bind to bit-field 'bitX'}}
+ unsigned &t1 = (unsigned&) a->bitX; // expected-error {{non-const reference cannot bind to bit-field 'bitX'}}
+ unsigned &t2 = const_cast<unsigned&>(a->bitX); // expected-error {{const_cast from bit-field lvalue to reference type 'unsigned int &'}}
+ unsigned &t3 = (a->foo(), a->bitX); // expected-error {{non-const reference cannot bind to bit-field 'bitX'}}
+ unsigned &t4 = (a->var ? a->bitX : a->bitY); // expected-error {{non-const reference cannot bind to bit-field}}
+ unsigned &t5 = (a->var ? a->bitX : a->bitX); // expected-error {{non-const reference cannot bind to bit-field}}
+ unsigned &t6 = (a->var ? a->bitX : a->var); // expected-error {{non-const reference cannot bind to bit-field}}
+ unsigned &t7 = (a->var ? a->var : a->bitY); // expected-error {{non-const reference cannot bind to bit-field}}
+ unsigned &t8 = (a->bitX = 3); // expected-error {{non-const reference cannot bind to bit-field 'bitX'}}
+ unsigned &t9 = (a->bitY += 3); // expected-error {{non-const reference cannot bind to bit-field 'bitY'}}
+ }
+}
diff --git a/test/CXX/except/except.spec/p1.cpp b/test/CXX/except/except.spec/p1.cpp
index e184ec4ffa..a32f37d552 100644
--- a/test/CXX/except/except.spec/p1.cpp
+++ b/test/CXX/except/except.spec/p1.cpp
@@ -55,7 +55,7 @@ namespace noex {
struct A {};
void g1() noexcept(A()); // expected-error {{not contextually convertible}}
- void g2(bool b) noexcept(b); // expected-error {{argument to noexcept specifier must be a constant expression}}
+ void g2(bool b) noexcept(b); // expected-error {{argument to noexcept specifier must be a constant expression}} expected-note {{read of non-const variable 'b'}} expected-note {{here}}
}
diff --git a/test/CXX/except/except.spec/p14.cpp b/test/CXX/except/except.spec/p14.cpp
index 99ed2fdee1..dda69e9aad 100644
--- a/test/CXX/except/except.spec/p14.cpp
+++ b/test/CXX/except/except.spec/p14.cpp
@@ -112,3 +112,26 @@ namespace rdar13017229 {
Typo foo(); // expected-error{{unknown type name 'Typo'}}
};
}
+
+namespace InhCtor {
+ template<int> struct X {};
+ struct Base {
+ Base(X<0>) noexcept(true);
+ Base(X<1>) noexcept(false);
+ Base(X<2>) throw(X<2>);
+ template<typename T> Base(T) throw(T);
+ };
+ template<typename T> struct Throw {
+ Throw() throw(T);
+ };
+ struct Derived : Base, Throw<X<3>> {
+ using Base::Base;
+ Throw<X<4>> x;
+ };
+ struct Test {
+ friend Derived::Derived(X<0>) throw(X<3>, X<4>);
+ friend Derived::Derived(X<1>) noexcept(false);
+ friend Derived::Derived(X<2>) throw(X<2>, X<3>, X<4>);
+ };
+ static_assert(!noexcept(Derived{X<5>{}}), "");
+}
diff --git a/test/CXX/expr/expr.ass/p9-cxx11.cpp b/test/CXX/expr/expr.ass/p9-cxx11.cpp
index 206c82c985..ecc6d2c3d5 100644
--- a/test/CXX/expr/expr.ass/p9-cxx11.cpp
+++ b/test/CXX/expr/expr.ass/p9-cxx11.cpp
@@ -24,8 +24,8 @@ struct S {
int a, b;
};
struct T {
- constexpr int operator=(S s) { return s.a; }
- constexpr int operator+=(S s) { return s.b; }
+ constexpr int operator=(S s) const { return s.a; }
+ constexpr int operator+=(S s) const { return s.b; }
};
static_assert((T() = {4, 9}) == 4, "");
static_assert((T() += {4, 9}) == 9, "");
diff --git a/test/CXX/expr/expr.const/p2-0x.cpp b/test/CXX/expr/expr.const/p2-0x.cpp
index 065a12b3f2..634dee3782 100644
--- a/test/CXX/expr/expr.const/p2-0x.cpp
+++ b/test/CXX/expr/expr.const/p2-0x.cpp
@@ -118,7 +118,7 @@ namespace IncompleteClassTypeAddr {
constexpr S (*p2)[] = &sArr; // ok
struct S {
- constexpr S *operator&() { return nullptr; }
+ constexpr S *operator&() const { return nullptr; }
};
constexpr S *q = &s; // ok
static_assert(!q, "");
@@ -205,7 +205,7 @@ namespace UndefinedBehavior {
constexpr const int &np = (*(int(*)[4])nullptr)[2]; // expected-error {{constant expression}} expected-note {{cannot access array element of null pointer}}
struct C {
- constexpr int f() { return 0; }
+ constexpr int f() const { return 0; }
} constexpr c = C();
constexpr int k1 = c.f(); // ok
constexpr int k2 = ((C*)nullptr)->f(); // expected-error {{constant expression}} expected-note {{cannot call member function on null pointer}}
@@ -481,14 +481,14 @@ namespace UnspecifiedRelations {
public:
constexpr A() : a(0), b(0) {}
int a;
- constexpr bool cmp() { return &a < &b; } // expected-error {{constexpr function never produces a constant expression}} expected-note {{comparison of address of fields 'a' and 'b' of 'A' with differing access specifiers (public vs private) has unspecified value}}
+ constexpr bool cmp() const { return &a < &b; } // expected-error {{constexpr function never produces a constant expression}} expected-note {{comparison of address of fields 'a' and 'b' of 'A' with differing access specifiers (public vs private) has unspecified value}}
private:
int b;
};
class B {
public:
A a;
- constexpr bool cmp() { return &a.a < &b.a; } // expected-error {{constexpr function never produces a constant expression}} expected-note {{comparison of address of fields 'a' and 'b' of 'B' with differing access specifiers (public vs protected) has unspecified value}}
+ constexpr bool cmp() const { return &a.a < &b.a; } // expected-error {{constexpr function never produces a constant expression}} expected-note {{comparison of address of fields 'a' and 'b' of 'B' with differing access specifiers (public vs protected) has unspecified value}}
protected:
A b;
};
diff --git a/test/CXX/expr/expr.const/p3-0x.cpp b/test/CXX/expr/expr.const/p3-0x.cpp
index 6ddd11bcee..047e238190 100644
--- a/test/CXX/expr/expr.const/p3-0x.cpp
+++ b/test/CXX/expr/expr.const/p3-0x.cpp
@@ -101,7 +101,7 @@ int n = Val<bool, &S::operator int>::value; // expected-error {{conversion from
namespace NonConstLValue {
struct S {
- constexpr operator int() { return 10; }
+ constexpr operator int() const { return 10; }
};
S s; // not constexpr
// Under the FDIS, this is not a converted constant expression.
diff --git a/test/CXX/expr/expr.const/p5-0x.cpp b/test/CXX/expr/expr.const/p5-0x.cpp
index bdb2b23ec7..0a4ac22d06 100644
--- a/test/CXX/expr/expr.const/p5-0x.cpp
+++ b/test/CXX/expr/expr.const/p5-0x.cpp
@@ -7,8 +7,8 @@ namespace std_example {
struct A {
constexpr A(int i) : val(i) { }
- constexpr operator int() { return val; }
- constexpr operator long() { return 43; }
+ constexpr operator int() const { return val; }
+ constexpr operator long() const { return 43; }
private:
int val;
};
@@ -21,17 +21,17 @@ int ary[a]; // expected-error {{size of array has non-integer type 'const std_ex
struct OK {
constexpr OK() {}
- constexpr operator int() { return 8; }
+ constexpr operator int() const { return 8; }
} constexpr ok;
extern struct Incomplete incomplete; // expected-note 4{{forward decl}}
struct Explicit {
constexpr Explicit() {}
- constexpr explicit operator int() { return 4; } // expected-note 4{{here}}
+ constexpr explicit operator int() const { return 4; } // expected-note 4{{here}}
} constexpr expl;
struct Ambiguous {
constexpr Ambiguous() {}
- constexpr operator int() { return 2; } // expected-note 4{{here}}
- constexpr operator long() { return 1; } // expected-note 4{{here}}
+ constexpr operator int() const { return 2; } // expected-note 4{{here}}
+ constexpr operator long() const { return 1; } // expected-note 4{{here}}
} constexpr ambig;
constexpr int test_ok = ok; // ok
diff --git a/test/CXX/expr/expr.post/expr.const.cast/p1-0x.cpp b/test/CXX/expr/expr.post/expr.const.cast/p1-0x.cpp
index be898761fa..76ea96fe14 100644
--- a/test/CXX/expr/expr.post/expr.const.cast/p1-0x.cpp
+++ b/test/CXX/expr/expr.post/expr.const.cast/p1-0x.cpp
@@ -1,5 +1,4 @@
// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
-// expected-no-diagnostics
// The result of the expression const_cast<T>(v) is of type T. If T is
// an lvalue reference to object type, the result is an lvalue; if T
@@ -16,3 +15,19 @@ void test_classification(const int *ptr) {
int *ptr1 = const_cast<int *&&>(xvalue<const int*>());
int *ptr2 = const_cast<int *&&>(prvalue<const int*>());
}
+
+struct A {
+ volatile unsigned ubf : 4;
+ volatile unsigned uv;
+ volatile int sv;
+ void foo();
+ bool pred();
+};
+
+void test(A &a) {
+ unsigned &t0 = const_cast<unsigned&>(a.ubf); // expected-error {{const_cast from bit-field lvalue to reference type}}
+ unsigned &t1 = const_cast<unsigned&>(a.foo(), a.ubf); // expected-error {{const_cast from bit-field lvalue to reference type}}
+ unsigned &t2 = const_cast<unsigned&>(a.pred() ? a.ubf : a.ubf); // expected-error {{const_cast from bit-field lvalue to reference type}}
+ unsigned &t3 = const_cast<unsigned&>(a.pred() ? a.ubf : a.uv); // expected-error {{const_cast from bit-field lvalue to reference type}}
+ unsigned &t4 = const_cast<unsigned&>(a.pred() ? a.ubf : a.sv); // expected-error {{const_cast from rvalue to reference type}}
+}
diff --git a/test/CXX/expr/expr.prim/expr.prim.general/p3-0x.cpp b/test/CXX/expr/expr.prim/expr.prim.general/p3-0x.cpp
index b84cec61c3..66579915c7 100644
--- a/test/CXX/expr/expr.prim/expr.prim.general/p3-0x.cpp
+++ b/test/CXX/expr/expr.prim/expr.prim.general/p3-0x.cpp
@@ -61,9 +61,26 @@ namespace PR10036 {
}
}
+namespace PR15290 {
+ template<typename T>
+ class A {
+ T v_;
+ friend int add_to_v(A &t) noexcept(noexcept(v_ + 42))
+ {
+ return t.v_ + 42;
+ }
+ };
+ void f()
+ {
+ A<int> t;
+ add_to_v(t);
+ }
+}
+
namespace Static {
struct X1 {
int m;
+ // FIXME: This should be accepted.
static auto f() -> decltype(m); // expected-error{{'this' cannot be implicitly used in a static member function declaration}}
static auto g() -> decltype(this->m); // expected-error{{'this' cannot be used in a static member function declaration}}
@@ -99,3 +116,23 @@ namespace PR12564 {
void foo(Derived& d) noexcept(noexcept(d.bar(d))) {} // expected-error {{cannot bind to a value of unrelated type}}
};
}
+
+namespace rdar13473493 {
+ template <typename F>
+ class wrap
+ {
+ public:
+ template <typename... Args>
+ auto operator()(Args&&... args) const -> decltype(wrapped(args...)) // expected-note{{candidate template ignored: substitution failure [with Args = <int>]: use of undeclared identifier 'wrapped'}}
+ {
+ return wrapped(args...);
+ }
+
+ private:
+ F wrapped;
+ };
+
+ void test(wrap<int (*)(int)> w) {
+ w(5); // expected-error{{no matching function for call to object of type 'wrap<int (*)(int)>'}}
+ }
+}
diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/default-arguments.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/default-arguments.cpp
index 5dac886d4d..38d5d0a6cd 100644
--- a/test/CXX/expr/expr.prim/expr.prim.lambda/default-arguments.cpp
+++ b/test/CXX/expr/expr.prim/expr.prim.lambda/default-arguments.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -Wno-lambda-extensions -verify
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify
void defargs() {
auto l1 = [](int i, int j = 17, int k = 18) { return i + j + k; };
diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp
index 9dffc1ff26..dc2c209af2 100644
--- a/test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp
+++ b/test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp
@@ -39,12 +39,10 @@ void test_quals() {
bogus_override_if_virtual<decltype(l)> bogus;
}
-// Default arguments (8.3.6) shall not be specified in the
-// parameter-declaration-clause of a lambda- declarator.
-// Note: Removed by core issue 974.
+// Core issue 974: default arguments (8.3.6) may be specified in the
+// parameter-declaration-clause of a lambda-declarator.
int test_default_args() {
- return [](int i = 5, // expected-warning{{C++11 forbids default arguments for lambda expressions}}
- int j = 17) { return i+j;}(5, 6);
+ return [](int i = 5, int j = 17) { return i+j;}(5, 6);
}
// Any exception-specification specified on a lambda-expression
diff --git a/test/CXX/expr/expr.unary/expr.sizeof/p1.cpp b/test/CXX/expr/expr.unary/expr.sizeof/p1.cpp
new file mode 100644
index 0000000000..6a59e3d7ae
--- /dev/null
+++ b/test/CXX/expr/expr.unary/expr.sizeof/p1.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct A {
+ unsigned bitX : 4;
+ unsigned bitY : 4;
+ unsigned var;
+
+ void foo();
+};
+
+void test(A *a) {
+ int x;
+ x = sizeof(a->bitX); // expected-error {{invalid application of 'sizeof' to bit-field}}
+ x = sizeof((unsigned) a->bitX);
+ x = sizeof(a->foo(), a->bitX); // expected-error {{invalid application of 'sizeof' to bit-field}}
+ x = sizeof(a->var ? a->bitX : a->bitY); // expected-error {{invalid application of 'sizeof' to bit-field}}
+ x = sizeof(a->var ? a->bitX : a->bitX); // expected-error {{invalid application of 'sizeof' to bit-field}}
+ x = sizeof(a->bitX = 3); // expected-error {{invalid application of 'sizeof' to bit-field}}
+ x = sizeof(a->bitY += 3); // expected-error {{invalid application of 'sizeof' to bit-field}}
+}
diff --git a/test/CXX/over/over.oper/over.literal/p2.cpp b/test/CXX/over/over.oper/over.literal/p2.cpp
index c012104314..00466fb311 100644
--- a/test/CXX/over/over.oper/over.literal/p2.cpp
+++ b/test/CXX/over/over.oper/over.literal/p2.cpp
@@ -33,3 +33,12 @@ template<char...> void operator "" _h() {}
template<> void operator "" _h<'a', 'b', 'c'>() {}
template void operator "" _h<'a', 'b', 'c', 'd'>();
+
+namespace rdar13605348 {
+
+class C {
+ double operator"" _x(long double value) { return double(value); } // expected-error{{literal operator 'operator "" _x' must be in a namespace or global scope}}
+ double value() { return 3.2_x; } // expected-error{{no matching literal operator for call to}}
+};
+
+}
diff --git a/test/CXX/special/class.dtor/p5-0x.cpp b/test/CXX/special/class.dtor/p5-0x.cpp
index 0d073cea52..e32279ef12 100644
--- a/test/CXX/special/class.dtor/p5-0x.cpp
+++ b/test/CXX/special/class.dtor/p5-0x.cpp
@@ -88,9 +88,10 @@ struct C4 : virtual InaccessibleDtor { C4(); } c4; // expected-error {{deleted f
class D1 {
void operator delete(void*);
public:
- virtual ~D1() = default;
+ virtual ~D1() = default; // expected-note {{here}}
} d1; // ok
-struct D2 : D1 { // expected-note {{virtual destructor requires an unambiguous, accessible 'operator delete'}}
+struct D2 : D1 { // expected-note {{virtual destructor requires an unambiguous, accessible 'operator delete'}} \
+ // expected-error {{deleted function '~D2' cannot override a non-deleted}}
// implicitly-virtual destructor
} d2; // expected-error {{deleted function}}
struct D3 { // expected-note {{virtual destructor requires an unambiguous, accessible 'operator delete'}}
diff --git a/test/CXX/special/class.inhctor/elsewhere.cpp b/test/CXX/special/class.inhctor/elsewhere.cpp
index 09fd3d50dc..b986f65824 100644
--- a/test/CXX/special/class.inhctor/elsewhere.cpp
+++ b/test/CXX/special/class.inhctor/elsewhere.cpp
@@ -9,49 +9,56 @@ struct B1 {
B1(int);
};
-using B1::B1; // expected-error {{using declaration can not refer to class member}} expected-error {{not supported}}
+using B1::B1; // expected-error {{using declaration can not refer to class member}}
-// C++0x [namespace.udecl]p10:
+// C++11 [namespace.udecl]p10:
// A using-declaration is a declaration and can therefore be used repeatedly
// where (and only where) multiple declarations are allowed.
struct I1 : B1 {
- using B1::B1; // expected-note {{previous using declaration}} expected-error {{not supported}}
- using B1::B1; // expected-error {{redeclaration of using decl}} expected-error {{not supported}}
+ using B1::B1; // expected-note {{previous using declaration}}
+ using B1::B1; // expected-error {{redeclaration of using decl}}
};
-// C++0x [namespace.udecl]p3:
+// C++11 [namespace.udecl]p3:
// In a using declaration used as a member-declaration, the nested-name-
// specifier shall name a base class of the class being defined.
// If such a using-declaration names a constructor, the nested-name-specifier
// shall name a direct base class of the class being defined.
struct D1 : I1 {
- using B1::B1; // expected-error {{'B1' is not a direct base of 'D1', can not inherit constructors}} expected-error {{not supported}}
+ using B1::B1; // expected-error {{'B1' is not a direct base of 'D1', can not inherit constructors}}
};
template<typename T> struct A {};
template<typename T> struct B : A<bool>, A<char> {
- using A<T>::A; // expected-error {{'A<double>::', which is not a base class of 'B<double>'}} expected-error {{not supported}}
+ using A<T>::A; // expected-error {{'A<double>::', which is not a base class of 'B<double>'}}
};
B<bool> bb;
B<char> bc;
B<double> bd; // expected-note {{here}}
template<typename T> struct C : A<T> {
- using A<bool>::A; // expected-error {{'A<bool>::', which is not a base class of 'C<char>'}} expected-error {{not supported}}
+ using A<bool>::A; // expected-error {{'A<bool>::', which is not a base class of 'C<char>'}}
};
C<bool> cb;
C<char> cc; // expected-note {{here}}
template<typename T> struct D : A<T> {};
template<typename T> struct E : D<T> {
- using A<bool>::A; // expected-error {{'A<bool>' is not a direct base of 'E<bool>', can not inherit}} expected-error {{not supported}}
+ using A<bool>::A; // expected-error {{'A<bool>' is not a direct base of 'E<bool>', can not inherit}}
};
E<bool> eb; // expected-note {{here}}
template<typename T> struct F : D<bool> {
- using A<T>::A; // expected-error {{'A<bool>' is not a direct base of 'F<bool>'}} expected-error {{not supported}}
+ using A<T>::A; // expected-error {{'A<bool>' is not a direct base of 'F<bool>'}}
};
F<bool> fb; // expected-note {{here}}
+
+template<typename T>
+struct G : T {
+ using T::T;
+ G(int &) : G(0) {}
+};
+G<B1> g(123);
diff --git a/test/CXX/special/class.inhctor/p1.cpp b/test/CXX/special/class.inhctor/p1.cpp
new file mode 100644
index 0000000000..8721dec1b4
--- /dev/null
+++ b/test/CXX/special/class.inhctor/p1.cpp
@@ -0,0 +1,64 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s
+// Per a core issue (no number yet), an ellipsis is always dropped.
+struct A {
+ A(...); // expected-note {{here}}
+ A(int = 0, int = 0, int = 0, int = 0, ...); // expected-note 9{{here}}
+ A(int = 0, int = 0, ...); // expected-note {{here}}
+
+ template<typename T> A(T, int = 0, ...); // expected-note 5{{here}}
+
+ template<typename T, int N> A(const T (&)[N]); // expected-note 2{{here}}
+ template<typename T, int N> A(const T (&)[N], int = 0); // expected-note 2{{here}}
+};
+
+struct B : A { // expected-note 6{{candidate}}
+ using A::A; // expected-warning 4{{inheriting constructor does not inherit ellipsis}} expected-note 16{{candidate}} expected-note 3{{deleted}}
+};
+
+struct C {} c;
+
+B b0{};
+// expected-error@-1 {{call to implicitly-deleted default constructor}}
+// expected-note@-8 {{default constructor of 'B' is implicitly deleted because base class 'A' has multiple default constructors}}
+
+B b1{1};
+// FIXME: explain why the inheriting constructor was deleted
+// expected-error@-2 {{call to implicitly-deleted function of 'B'}}
+
+B b2{1,2};
+// expected-error@-1 {{call to implicitly-deleted function of 'B'}}
+
+B b3{1,2,3};
+// ok
+
+B b4{1,2,3,4};
+// ok
+
+B b5{1,2,3,4,5};
+// expected-error@-1 {{no matching constructor for initialization of 'B'}}
+
+B b6{c};
+// ok
+
+B b7{c,0};
+// ok
+
+B b8{c,0,1};
+// expected-error@-1 {{no matching constructor}}
+
+B b9{"foo"};
+// FIXME: explain why the inheriting constructor was deleted
+// expected-error@-2 {{call to deleted constructor of 'B'}}
+
+namespace PR15755 {
+ struct X {
+ template<typename...Ts> X(int, Ts...);
+ };
+ struct Y : X {
+ using X::X;
+ };
+ struct Z : Y {
+ using Y::Y;
+ };
+ Z z(0);
+}
diff --git a/test/CXX/special/class.inhctor/p2.cpp b/test/CXX/special/class.inhctor/p2.cpp
new file mode 100644
index 0000000000..e6abd6840e
--- /dev/null
+++ b/test/CXX/special/class.inhctor/p2.cpp
@@ -0,0 +1,121 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s
+
+template<int> struct X {};
+
+// Constructor characteristics are:
+// - the template parameter list
+// - the parameter-type-list
+// - absence or presence of explicit
+// - absence or presence of constexpr
+struct A {
+ A(X<0>) {} // expected-note 2{{here}}
+ constexpr A(X<1>) {}
+ explicit A(X<2>) {} // expected-note 3{{here}}
+ explicit constexpr A(X<3>) {} // expected-note 2{{here}}
+};
+
+A a0 { X<0>{} };
+A a0i = { X<0>{} };
+constexpr A a0c { X<0>{} }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}}
+constexpr A a0ic = { X<0>{} }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}}
+
+A a1 { X<1>{} };
+A a1i = { X<1>{} };
+constexpr A a1c { X<1>{} };
+constexpr A a1ic = { X<1>{} };
+
+A a2 { X<2>{} };
+A a2i = { X<2>{} }; // expected-error {{constructor is explicit}}
+constexpr A a2c { X<2>{} }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}}
+constexpr A a2ic = { X<2>{} }; // expected-error {{constructor is explicit}}
+
+A a3 { X<3>{} };
+A a3i = { X<3>{} }; // expected-error {{constructor is explicit}}
+constexpr A a3c { X<3>{} };
+constexpr A a3ic = { X<3>{} }; // expected-error {{constructor is explicit}}
+
+
+struct B : A {
+ using A::A; // expected-note 7{{here}}
+};
+
+B b0 { X<0>{} };
+B b0i = { X<0>{} };
+constexpr B b0c { X<0>{} }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}}
+constexpr B b0ic = { X<0>{} }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}}
+
+B b1 { X<1>{} };
+B b1i = { X<1>{} };
+constexpr B b1c { X<1>{} };
+constexpr B b1ic = { X<1>{} };
+
+B b2 { X<2>{} };
+B b2i = { X<2>{} }; // expected-error {{constructor is explicit}}
+constexpr B b2c { X<2>{} }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}}
+constexpr B b2ic = { X<2>{} }; // expected-error {{constructor is explicit}}
+
+B b3 { X<3>{} };
+B b3i = { X<3>{} }; // expected-error {{constructor is explicit}}
+constexpr B b3c { X<3>{} };
+constexpr B b3ic = { X<3>{} }; // expected-error {{constructor is explicit}}
+
+
+// 'constexpr' is OK even if the constructor doesn't obey the constraints.
+struct NonLiteral { NonLiteral(); };
+struct NonConstexpr { NonConstexpr(); constexpr NonConstexpr(int); }; // expected-note {{here}}
+struct Constexpr { constexpr Constexpr(int) {} };
+
+struct BothNonLiteral : NonLiteral, Constexpr { using Constexpr::Constexpr; }; // expected-note {{base class 'NonLiteral' of non-literal type}}
+constexpr BothNonLiteral bothNL{42}; // expected-error {{constexpr variable cannot have non-literal type 'const BothNonLiteral'}}
+
+struct BothNonConstexpr : NonConstexpr, Constexpr { using Constexpr::Constexpr; }; // expected-note {{non-constexpr constructor 'NonConstexpr}}
+constexpr BothNonConstexpr bothNC{42}; // expected-error {{must be initialized by a constant expression}} expected-note {{in call to 'BothNonConstexpr(42)'}}
+
+
+struct ConstexprEval {
+ constexpr ConstexprEval(int a, const char *p) : k(p[a]) {}
+ char k;
+};
+struct ConstexprEval2 {
+ char k2 = 'x';
+};
+struct ConstexprEval3 : ConstexprEval, ConstexprEval2 {
+ using ConstexprEval::ConstexprEval;
+};
+constexpr ConstexprEval3 ce{4, "foobar"};
+static_assert(ce.k == 'a', "");
+static_assert(ce.k2 == 'x', "");
+
+
+struct TemplateCtors {
+ constexpr TemplateCtors() {}
+ template<template<int> class T> TemplateCtors(X<0>, T<0>);
+ template<int N> TemplateCtors(X<1>, X<N>);
+ template<typename T> TemplateCtors(X<2>, T);
+
+ template<typename T = int> TemplateCtors(int, int = 0, int = 0); // expected-note {{inherited from here}}
+};
+
+struct UsingTemplateCtors : TemplateCtors {
+ using TemplateCtors::TemplateCtors; // expected-note 4{{here}} expected-note {{candidate}}
+
+ constexpr UsingTemplateCtors(X<0>, X<0>) {}
+ constexpr UsingTemplateCtors(X<1>, X<1>) {}
+ constexpr UsingTemplateCtors(X<2>, X<2>) {}
+
+ template<int = 0> constexpr UsingTemplateCtors(int) {} // expected-note {{candidate}}
+ template<typename T = void> constexpr UsingTemplateCtors(int, int) {}
+ template<typename T, typename U> constexpr UsingTemplateCtors(int, int, int) {}
+};
+
+template<int> struct Y {};
+constexpr UsingTemplateCtors uct1{ X<0>{}, X<0>{} };
+constexpr UsingTemplateCtors uct2{ X<0>{}, Y<0>{} }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}}
+constexpr UsingTemplateCtors uct3{ X<1>{}, X<0>{} }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}}
+constexpr UsingTemplateCtors uct4{ X<1>{}, X<1>{} };
+constexpr UsingTemplateCtors uct5{ X<2>{}, 0 }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}}
+constexpr UsingTemplateCtors uct6{ X<2>{}, X<2>{} };
+
+constexpr UsingTemplateCtors utc7{ 0 }; // expected-error {{ambiguous}}
+constexpr UsingTemplateCtors utc8{ 0, 0 }; // ok
+constexpr UsingTemplateCtors utc9{ 0, 0, 0 }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}}
diff --git a/test/CXX/special/class.inhctor/p3.cpp b/test/CXX/special/class.inhctor/p3.cpp
index d7093fb369..7aaaa7a6f0 100644
--- a/test/CXX/special/class.inhctor/p3.cpp
+++ b/test/CXX/special/class.inhctor/p3.cpp
@@ -5,7 +5,7 @@ struct B1 {
B1(int, int);
};
struct D1 : B1 {
- using B1::B1; // expected-error {{not supported}}
+ using B1::B1;
};
D1 d1a(1), d1b(1, 1);
@@ -15,7 +15,7 @@ struct B2 {
explicit B2(int, int = 0, int = 0);
};
struct D2 : B2 { // expected-note 2 {{candidate constructor}}
- using B2::B2; // expected-error {{not supported}}
+ using B2::B2;
};
D2 d2a(1), d2b(1, 1), d2c(1, 1, 1);
@@ -25,18 +25,18 @@ struct B3 {
B3(void*); // expected-note {{inherited from here}}
};
struct D3 : B3 { // expected-note 2 {{candidate constructor}}
- using B3::B3; // expected-note {{candidate constructor (inherited)}} expected-error {{not supported}}
+ using B3::B3; // expected-note {{candidate constructor (inherited)}}
};
D3 fd3() { return 1; } // expected-error {{no viable conversion}}
template<typename T> struct T1 : B1 {
- using B1::B1; // expected-error {{not supported}}
+ using B1::B1;
};
template<typename T> struct T2 : T1<T> {
- using T1<int>::T1; // expected-error {{not supported}}
+ using T1<int>::T1;
};
template<typename T> struct T3 : T1<int> {
- using T1<T>::T1; // expected-error {{not supported}}
+ using T1<T>::T1;
};
struct U {
friend T1<int>::T1(int);
@@ -46,3 +46,13 @@ struct U {
friend T3<int>::T3(int);
friend T3<int>::T3(int, int);
};
+
+struct B4 {
+ template<typename T> explicit B4(T, int = 0);
+};
+template<typename T> struct T4 : B4 {
+ using B4::B4; // expected-note {{here}}
+ template<typename U> T4(U);
+};
+T4<void> t4a = {0};
+T4<void> t4b = {0, 0}; // expected-error {{chosen constructor is explicit}}
diff --git a/test/CXX/special/class.inhctor/p4.cpp b/test/CXX/special/class.inhctor/p4.cpp
new file mode 100644
index 0000000000..512705e4dd
--- /dev/null
+++ b/test/CXX/special/class.inhctor/p4.cpp
@@ -0,0 +1,72 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s
+
+template<int> struct X {};
+
+// A[n inheriting] constructor [...] has the same access as the corresponding
+// constructor [in the base class].
+struct A {
+public:
+ A(X<0>) {}
+protected:
+ A(X<1>) {}
+private:
+ A(X<2>) {} // expected-note {{declared private here}}
+ friend class FA;
+};
+
+struct B : A {
+ using A::A; // expected-error {{private constructor}} expected-note {{implicitly declared protected here}}
+ friend class FB;
+};
+
+B b0{X<0>{}};
+B b1{X<1>{}}; // expected-error {{calling a protected constructor}}
+B b2{X<2>{}}; // expected-note {{first required here}}
+
+struct C : B {
+ C(X<0> x) : B(x) {}
+ C(X<1> x) : B(x) {}
+};
+
+struct FB {
+ B b0{X<0>{}};
+ B b1{X<1>{}};
+};
+
+struct FA : A {
+ using A::A; // expected-note 2{{here}}
+};
+FA fa0{X<0>{}};
+FA fa1{X<1>{}}; // expected-error {{calling a protected constructor}}
+FA fa2{X<2>{}}; // expected-error {{calling a private constructor}}
+
+
+// It is deleted if the corresponding constructor [...] is deleted.
+struct G {
+ G(int) = delete;
+ template<typename T> G(T*) = delete;
+};
+struct H : G {
+ using G::G; // expected-note 2{{marked deleted here}}
+};
+H h1(5); // expected-error {{call to implicitly-deleted function of 'H'}}
+H h2("foo"); // expected-error {{call to deleted constructor of 'H'}}
+
+
+// Core defect: It is also deleted if multiple base constructors generate the
+// same signature.
+namespace DRnnnn {
+ struct A {
+ constexpr A(int, float = 0) {}
+ explicit A(int, int = 0) {}
+
+ A(int, int, int = 0) = delete;
+ };
+ struct B : A {
+ // FIXME: produce notes indicating why it was deleted
+ using A::A; // expected-note {{here}}
+ };
+
+ constexpr B b0(0, 0.0f); // ok, constexpr
+ B b1(0, 1); // expected-error {{call to implicitly-deleted}}
+}
diff --git a/test/CXX/special/class.inhctor/p7.cpp b/test/CXX/special/class.inhctor/p7.cpp
index bfaa3ac359..a57e8558f5 100644
--- a/test/CXX/special/class.inhctor/p7.cpp
+++ b/test/CXX/special/class.inhctor/p7.cpp
@@ -8,12 +8,12 @@ struct B2 {
B2(int); // expected-note {{conflicting constructor}}
};
struct D1 : B1, B2 {
- using B1::B1; // expected-note {{inherited here}} expected-error {{not supported}}
- using B2::B2; // expected-error {{already inherited constructor with the same signature}} expected-error {{not supported}}
+ using B1::B1; // expected-note {{inherited here}}
+ using B2::B2; // expected-error {{already inherited constructor with the same signature}}
};
struct D2 : B1, B2 {
- using B1::B1; // expected-error {{not supported}}
- using B2::B2; // expected-error {{not supported}}
+ using B1::B1;
+ using B2::B2;
D2(int);
};
@@ -22,8 +22,26 @@ template<typename T> struct B3 {
};
template<typename T> struct B4 : B3<T>, B1 {
B4();
- using B3<T>::B3; // expected-note {{inherited here}} expected-error {{not supported}}
- using B1::B1; // expected-error {{already inherited}} expected-error {{not supported}}
+ using B3<T>::B3; // expected-note {{inherited here}}
+ using B1::B1; // expected-error {{already inherited}}
};
B4<char> b4c;
B4<int> b4i; // expected-note {{here}}
+
+struct B5 {
+ template<typename T> B5(T); // expected-note {{previous constructor}}
+};
+struct B6 {
+ template<typename T> B6(T); // expected-note {{conflicting constructor}}
+};
+struct B7 {
+ template<typename T, int> B7(T);
+};
+struct D56 : B5, B6, B7 {
+ using B5::B5; // expected-note {{inherited here}}
+ using B6::B6; // expected-error {{already inherited}}
+};
+struct D57 : B5, B6, B7 {
+ using B5::B5;
+ using B7::B7; // ok, not the same signature
+};
diff --git a/test/CXX/special/class.inhctor/p8.cpp b/test/CXX/special/class.inhctor/p8.cpp
new file mode 100644
index 0000000000..0c857382e3
--- /dev/null
+++ b/test/CXX/special/class.inhctor/p8.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s
+
+// expected-no-diagnostics
+struct A {
+ constexpr A(const int&) : rval(false) {}
+ constexpr A(const int&&) : rval(true) {}
+ bool rval;
+};
+struct B : A {
+ using A::A;
+};
+
+constexpr int k = 0;
+constexpr A a0{0};
+constexpr A a1{k};
+constexpr B b0{0};
+// This performs static_cast<(const int&)&&>(k), so calls the A(const int&)
+// constructor.
+constexpr B b1{k};
+
+static_assert(a0.rval && !a1.rval && b0.rval && !b1.rval, "");
+
+struct C {
+ template<typename T> constexpr C(T t) : v(t) {}
+ int v;
+};
+struct D : C {
+ using C::C;
+};
+static_assert(D(123).v == 123, "");
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 3952afdeff..b159a15b8d 100644
--- a/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp
+++ b/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp
@@ -242,3 +242,13 @@ void example() {
for (int &x : array)
x *= 2;
}
+
+namespace rdar13712739 {
+ template<typename T>
+ void foo(const T& t) {
+ auto &x = t.get(); // expected-error{{member reference base type 'const int' is not a structure or union}}
+ for (auto &blah : x) { }
+ }
+
+ template void foo(const int&); // expected-note{{in instantiation of function template specialization}}
+}
diff --git a/test/CXX/stmt.stmt/stmt.select/stmt.switch/p2-0x.cpp b/test/CXX/stmt.stmt/stmt.select/stmt.switch/p2-0x.cpp
index d0f15d4d3d..fda0c5cff1 100644
--- a/test/CXX/stmt.stmt/stmt.select/stmt.switch/p2-0x.cpp
+++ b/test/CXX/stmt.stmt/stmt.select/stmt.switch/p2-0x.cpp
@@ -3,12 +3,12 @@
struct Value {
constexpr Value(int n) : n(n) {}
- constexpr operator short() { return n; }
+ constexpr operator short() const { return n; }
int n;
};
enum E { E0, E1 };
struct Alt {
- constexpr operator E() { return E0; }
+ constexpr operator E() const { return E0; }
};
constexpr short s = Alt();
diff --git a/test/CXX/temp/temp.arg/temp.arg.nontype/p1-11.cpp b/test/CXX/temp/temp.arg/temp.arg.nontype/p1-11.cpp
index 59ce8b68b7..3f65466dfc 100644
--- a/test/CXX/temp/temp.arg/temp.arg.nontype/p1-11.cpp
+++ b/test/CXX/temp/temp.arg/temp.arg.nontype/p1-11.cpp
@@ -1,19 +1,23 @@
-// RUN: %clang_cc1 -std=c++11 %s -verify
+// RUN: %clang_cc1 -std=c++11 %s -verify -triple x86_64-linux-gnu
namespace std {
typedef decltype(nullptr) nullptr_t;
}
-template<int *ip> struct IP { // expected-note 4 {{template parameter is declared here}}
+template<int *ip> struct IP { // expected-note 5 {{template parameter is declared here}}
IP<ip> *ip2;
};
+template<int &ip> struct IR {};
+
constexpr std::nullptr_t get_nullptr() { return nullptr; }
constexpr std::nullptr_t np = nullptr;
std::nullptr_t nonconst_np; // expected-note{{declared here}}
+thread_local int tl; // expected-note {{refers here}}
+
IP<0> ip0; // expected-error{{null non-type template argument must be cast to template parameter type 'int *'}}
IP<(0)> ip1; // expected-error{{null non-type template argument must be cast to template parameter type 'int *'}}
IP<nullptr> ip2;
@@ -23,6 +27,9 @@ IP<np> ip5;
IP<nonconst_np> ip5; // expected-error{{non-type template argument of type 'std::nullptr_t' (aka 'nullptr_t') is not a constant expression}} \
// expected-note{{read of non-constexpr variable 'nonconst_np' is not allowed in a constant expression}}
IP<(float*)0> ip6; // expected-error{{null non-type template argument of type 'float *' does not match template parameter of type 'int *'}}
+IP<&tl> ip7; // expected-error{{non-type template argument of type 'int *' is not a constant expression}}
+
+IR<tl> ir1; // expected-error{{non-type template argument refers to thread-local object}}
struct X { };
template<int X::*pm> struct PM { // expected-note 2 {{template parameter is declared here}}
diff --git a/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp b/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp
index e0ffef5007..82114cfa9d 100644
--- a/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp
+++ b/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp
@@ -193,18 +193,18 @@ namespace PacksAtDifferentLevels {
template<typename...A>
struct X6 {
template<typename...B>
- constexpr auto f1(A ...a) -> decltype(g(A(a + B())...)) { return g(A(a + B())...); }
+ constexpr auto f1(A ...a) const -> decltype(g(A(a + B())...)) { return g(A(a + B())...); }
template<typename...B>
- constexpr auto f2(A ...a, B ...b) -> decltype(g((&a)[b] ...)) { return g((&a)[b] ...); } // expected-note {{past-the-end}}
+ constexpr auto f2(A ...a, B ...b) const -> decltype(g((&a)[b] ...)) { return g((&a)[b] ...); } // expected-note {{past-the-end}}
template<typename...B> struct Inner {
template<typename...C>
- constexpr auto f(A ...a, B ...b, C ...c) -> decltype(g(a+b+c...)) { return g(a+b+c...); }
+ constexpr auto f(A ...a, B ...b, C ...c) const -> decltype(g(a+b+c...)) { return g(a+b+c...); }
};
};
- struct A { constexpr operator int() { return 2; } };
- struct B { constexpr operator int() { return 1; } };
+ struct A { constexpr operator int() const { return 2; } };
+ struct B { constexpr operator int() const { return 1; } };
static_assert(X6<unsigned char, int>().f1<A, B>(255, 1) == 12, "");
static_assert(X6<int, int>().f2(3, 4, 0, 0) == 34, "");
diff --git a/test/CXX/temp/temp.spec/temp.explicit/p1-0x.cpp b/test/CXX/temp/temp.spec/temp.explicit/p1-0x.cpp
index e0c7b35a79..f804d4db12 100644
--- a/test/CXX/temp/temp.spec/temp.explicit/p1-0x.cpp
+++ b/test/CXX/temp/temp.spec/temp.explicit/p1-0x.cpp
@@ -9,7 +9,7 @@ template inline void X<int>::f(); // expected-error{{explicit instantiation cann
template<typename T>
struct Y {
- constexpr int f() { return 0; }
+ constexpr int f() { return 0; } // expected-warning{{C++1y}}
};
template constexpr int Y<int>::f() const; // expected-error{{explicit instantiation cannot be 'constexpr'}}
diff --git a/test/CodeGen/2010-02-10-PointerName.c b/test/CodeGen/2010-02-10-PointerName.c
index 2837de4b8b..2321c01c6f 100644
--- a/test/CodeGen/2010-02-10-PointerName.c
+++ b/test/CodeGen/2010-02-10-PointerName.c
@@ -1,4 +1,6 @@
-// RUN: %clang_cc1 %s -emit-llvm -g -o - | grep DW_TAG_pointer_type | grep -v {"char"}
+// RUN: %clang_cc1 %s -emit-llvm -g -o - | FileCheck %s
+// CHECK: DW_TAG_pointer_type
+// CHECK-NOT: {"char"}
char i = 1;
void foo() {
diff --git a/test/CodeGen/arm-asm-diag.c b/test/CodeGen/arm-asm-diag.c
new file mode 100644
index 0000000000..eea7920b10
--- /dev/null
+++ b/test/CodeGen/arm-asm-diag.c
@@ -0,0 +1,23 @@
+// REQUIRES: arm-registered-target
+// RUN: %clang_cc1 -triple armv7 %s -S -o /dev/null 2>&1 | FileCheck %s
+
+// rdar://13446483
+typedef __attribute__((neon_vector_type(2))) long long int64x2_t;
+typedef struct int64x2x4_t {
+ int64x2_t val[4];
+} int64x2x4_t;
+int64x2x4_t t1(const long long a[]) {
+ int64x2x4_t r;
+ __asm__("vldm %[a], { %q[r0], %q[r1], %q[r2], %q[r3] }"
+ : [r0] "=r"(r.val[0]), // expected-warning {{the value is truncated when put into register, use a modifier to specify the size}}
+ [r1] "=r"(r.val[1]), // expected-warning {{the value is truncated when put into register, use a modifier to specify the size}}
+ [r2] "=r"(r.val[2]), // expected-warning {{the value is truncated when put into register, use a modifier to specify the size}}
+ [r3] "=r"(r.val[3]) // expected-warning {{the value is truncated when put into register, use a modifier to specify the size}}
+ : [a] "r"(a));
+ return r;
+}
+// We should see all four errors, rather than report a fatal error after the first.
+// CHECK: error: non-trivial scalar-to-vector conversion, possible invalid constraint for vector type
+// CHECK: error: non-trivial scalar-to-vector conversion, possible invalid constraint for vector type
+// CHECK: error: non-trivial scalar-to-vector conversion, possible invalid constraint for vector type
+// CHECK: error: non-trivial scalar-to-vector conversion, possible invalid constraint for vector type
diff --git a/test/CodeGen/builtins-aarch64.c b/test/CodeGen/builtins-aarch64.c
new file mode 100644
index 0000000000..8a93cb41fa
--- /dev/null
+++ b/test/CodeGen/builtins-aarch64.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -O3 -emit-llvm -o - %s | FileCheck %s
+
+void f0(char *a, char *b) {
+ __clear_cache(a,b);
+// CHECK: call {{.*}} @__clear_cache
+}
diff --git a/test/CodeGen/c-strings.c b/test/CodeGen/c-strings.c
index 1021010a6d..60a6b01912 100644
--- a/test/CodeGen/c-strings.c
+++ b/test/CodeGen/c-strings.c
@@ -3,12 +3,19 @@
// Should be 3 hello strings, two global (of different sizes), the rest are
// shared.
+// CHECK: @align = global i8 [[ALIGN:[0-9]+]]
// CHECK: @.str = private unnamed_addr constant [6 x i8] c"hello\00"
// CHECK: @f1.x = internal global i8* getelementptr inbounds ([6 x i8]* @.str, i32 0, i32 0)
-// CHECK: @f2.x = internal global [6 x i8] c"hello\00", align 1
-// CHECK: @f3.x = internal global [8 x i8] c"hello\00\00\00", align 1
+// CHECK: @f2.x = internal global [6 x i8] c"hello\00", align [[ALIGN]]
+// CHECK: @f3.x = internal global [8 x i8] c"hello\00\00\00", align [[ALIGN]]
// CHECK: @f4.x = internal global %struct.s { i8* getelementptr inbounds ([6 x i8]* @.str, i32 0, i32 0) }
-// CHECK: @x = global [3 x i8] c"ola", align 1
+// CHECK: @x = global [3 x i8] c"ola", align [[ALIGN]]
+
+#if defined(__s390x__)
+unsigned char align = 2;
+#else
+unsigned char align = 1;
+#endif
void bar(const char *);
diff --git a/test/CodeGen/catch-undef-behavior.c b/test/CodeGen/catch-undef-behavior.c
index 3e180a445b..ebe39feea4 100644
--- a/test/CodeGen/catch-undef-behavior.c
+++ b/test/CodeGen/catch-undef-behavior.c
@@ -285,13 +285,16 @@ void int_fp16_overflow(int n, __fp16 *p) {
// CHECK: @float_int_overflow
// CHECK-TRAP: @float_int_overflow
int float_int_overflow(float f) {
- // CHECK: %[[GE:.*]] = fcmp oge float %[[F:.*]], 0xC1E0000000000000
- // CHECK: %[[LE:.*]] = fcmp ole float %[[F]], 0x41DFFFFFE0000000
+ // CHECK: %[[GE:.*]] = fcmp ogt float %[[F:.*]], 0xC1E0000020000000
+ // CHECK: %[[LE:.*]] = fcmp olt float %[[F]], 0x41E0000000000000
// CHECK: and i1 %[[GE]], %[[LE]]
- // CHECK: call void @__ubsan_handle_float_cast_overflow(
- // CHECK-TRAP: %[[GE:.*]] = fcmp oge float %[[F:.*]], 0xC1E0000000000000
- // CHECK-TRAP: %[[LE:.*]] = fcmp ole float %[[F]], 0x41DFFFFFE0000000
+ // CHECK: %[[CAST:.*]] = bitcast float %[[F]] to i32
+ // CHECK: %[[ARG:.*]] = zext i32 %[[CAST]] to i64
+ // CHECK: call void @__ubsan_handle_float_cast_overflow({{.*}}, i64 %[[ARG]]
+
+ // CHECK-TRAP: %[[GE:.*]] = fcmp ogt float %[[F:.*]], 0xC1E0000020000000
+ // CHECK-TRAP: %[[LE:.*]] = fcmp olt float %[[F]], 0x41E0000000000000
// CHECK-TRAP: %[[INBOUNDS:.*]] = and i1 %[[GE]], %[[LE]]
// CHECK-TRAP-NEXT: br i1 %[[INBOUNDS]]
@@ -300,16 +303,38 @@ int float_int_overflow(float f) {
return f;
}
+// CHECK: @long_double_int_overflow
+// CHECK-TRAP: @long_double_int_overflow
+int long_double_int_overflow(long double ld) {
+ // CHECK: alloca x86_fp80
+ // CHECK: %[[GE:.*]] = fcmp ogt x86_fp80 %[[F:.*]], 0xKC01E8000000100000000
+ // CHECK: %[[LE:.*]] = fcmp olt x86_fp80 %[[F]], 0xK401E8000000000000000
+ // CHECK: and i1 %[[GE]], %[[LE]]
+
+ // CHECK: store x86_fp80 %[[F]], x86_fp80* %[[ALLOCA:.*]]
+ // CHECK: %[[ARG:.*]] = ptrtoint x86_fp80* %[[ALLOCA]] to i64
+ // CHECK: call void @__ubsan_handle_float_cast_overflow({{.*}}, i64 %[[ARG]]
+
+ // CHECK-TRAP: %[[GE:.*]] = fcmp ogt x86_fp80 %[[F:.*]], 0xKC01E800000010000000
+ // CHECK-TRAP: %[[LE:.*]] = fcmp olt x86_fp80 %[[F]], 0xK401E800000000000000
+ // CHECK-TRAP: %[[INBOUNDS:.*]] = and i1 %[[GE]], %[[LE]]
+ // CHECK-TRAP-NEXT: br i1 %[[INBOUNDS]]
+
+ // CHECK-TRAP: call void @llvm.trap() [[NR_NUW]]
+ // CHECK-TRAP-NEXT: unreachable
+ return ld;
+}
+
// CHECK: @float_uint_overflow
// CHECK-TRAP: @float_uint_overflow
unsigned float_uint_overflow(float f) {
- // CHECK: %[[GE:.*]] = fcmp oge float %[[F:.*]], 0.{{0*}}e+00
- // CHECK: %[[LE:.*]] = fcmp ole float %[[F]], 0x41EFFFFFE0000000
+ // CHECK: %[[GE:.*]] = fcmp ogt float %[[F:.*]], -1.{{0*}}e+00
+ // CHECK: %[[LE:.*]] = fcmp olt float %[[F]], 0x41F0000000000000
// CHECK: and i1 %[[GE]], %[[LE]]
// CHECK: call void @__ubsan_handle_float_cast_overflow(
- // CHECK-TRAP: %[[GE:.*]] = fcmp oge float %[[F:.*]], 0.{{0*}}e+00
- // CHECK-TRAP: %[[LE:.*]] = fcmp ole float %[[F]], 0x41EFFFFFE0000000
+ // CHECK-TRAP: %[[GE:.*]] = fcmp ogt float %[[F:.*]], -1.{{0*}}e+00
+ // CHECK-TRAP: %[[LE:.*]] = fcmp olt float %[[F]], 0x41F0000000000000
// CHECK-TRAP: %[[INBOUNDS:.*]] = and i1 %[[GE]], %[[LE]]
// CHECK-TRAP-NEXT: br i1 %[[INBOUNDS]]
@@ -321,13 +346,13 @@ unsigned float_uint_overflow(float f) {
// CHECK: @fp16_char_overflow
// CHECK-TRAP: @fp16_char_overflow
signed char fp16_char_overflow(__fp16 *p) {
- // CHECK: %[[GE:.*]] = fcmp oge float %[[F:.*]], -1.28{{0*}}e+02
- // CHECK: %[[LE:.*]] = fcmp ole float %[[F]], 1.27{{0*}}e+02
+ // CHECK: %[[GE:.*]] = fcmp ogt float %[[F:.*]], -1.29{{0*}}e+02
+ // CHECK: %[[LE:.*]] = fcmp olt float %[[F]], 1.28{{0*}}e+02
// CHECK: and i1 %[[GE]], %[[LE]]
// CHECK: call void @__ubsan_handle_float_cast_overflow(
- // CHECK-TRAP: %[[GE:.*]] = fcmp oge float %[[F:.*]], -1.28{{0*}}e+02
- // CHECK-TRAP: %[[LE:.*]] = fcmp ole float %[[F]], 1.27{{0*}}e+02
+ // CHECK-TRAP: %[[GE:.*]] = fcmp ogt float %[[F:.*]], -1.29{{0*}}e+02
+ // CHECK-TRAP: %[[LE:.*]] = fcmp olt float %[[F]], 1.28{{0*}}e+02
// CHECK-TRAP: %[[INBOUNDS:.*]] = and i1 %[[GE]], %[[LE]]
// CHECK-TRAP-NEXT: br i1 %[[INBOUNDS]]
@@ -339,14 +364,17 @@ signed char fp16_char_overflow(__fp16 *p) {
// CHECK: @float_float_overflow
// CHECK-TRAP: @float_float_overflow
float float_float_overflow(double f) {
- // CHECK: %[[GE:.*]] = fcmp oge double %[[F:.*]], 0xC7EFFFFFE0000000
- // CHECK: %[[LE:.*]] = fcmp ole double %[[F]], 0x47EFFFFFE0000000
+ // CHECK: %[[F:.*]] = call double @llvm.fabs.f64(
+ // CHECK: %[[GE:.*]] = fcmp ogt double %[[F]], 0x47EFFFFFE0000000
+ // CHECK: %[[LE:.*]] = fcmp olt double %[[F]], 0x7FF0000000000000
// CHECK: and i1 %[[GE]], %[[LE]]
// CHECK: call void @__ubsan_handle_float_cast_overflow(
- // CHECK-TRAP: %[[GE:.*]] = fcmp oge double %[[F:.*]], 0xC7EFFFFFE0000000
- // CHECK-TRAP: %[[LE:.*]] = fcmp ole double %[[F]], 0x47EFFFFFE0000000
- // CHECK-TRAP: %[[INBOUNDS:.*]] = and i1 %[[GE]], %[[LE]]
+ // CHECK-TRAP: %[[F:.*]] = call double @llvm.fabs.f64(
+ // CHECK-TRAP: %[[GE:.*]] = fcmp ogt double %[[F]], 0x47EFFFFFE0000000
+ // CHECK-TRAP: %[[LE:.*]] = fcmp olt double %[[F]], 0x7FF0000000000000
+ // CHECK-TRAP: %[[OUTOFBOUNDS:.*]] = and i1 %[[GE]], %[[LE]]
+ // CHECK-TRAP: %[[INBOUNDS:.*]] = xor i1 %[[OUTOFBOUNDS]], true
// CHECK-TRAP-NEXT: br i1 %[[INBOUNDS]]
// CHECK-TRAP: call void @llvm.trap() [[NR_NUW]]
diff --git a/test/CodeGen/code-coverage.c b/test/CodeGen/code-coverage.c
index f165e30e6f..1b87d649dd 100644
--- a/test/CodeGen/code-coverage.c
+++ b/test/CodeGen/code-coverage.c
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -emit-llvm -disable-red-zone -femit-coverage-data %s -o - | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -disable-red-zone -femit-coverage-data -coverage-no-function-names-in-data %s -o - | FileCheck %s --check-prefix WITHOUTNAMES
// <rdar://problem/12843084>
@@ -15,8 +16,15 @@ int test1(int a) {
// Check that the noredzone flag is set on the generated functions.
// CHECK: void @__llvm_gcov_indirect_counter_increment(i32* %{{.*}}, i64** %{{.*}}) unnamed_addr [[NRZ:#[0-9]+]]
+
+// Inside llvm_gcov_writeout, check that -coverage-no-function-names-in-data
+// passes null as the function name.
// CHECK: void @__llvm_gcov_writeout() unnamed_addr [[NRZ]]
+// CHECK: call void @llvm_gcda_emit_function({{.*}}, i8* getelementptr {{.*}}, {{.*}})
+// WITHOUTNAMES: void @__llvm_gcov_writeout() unnamed_addr
+// WITHOUTNAMES: call void @llvm_gcda_emit_function({{.*}}, i8* null, {{.*}})
+
+// CHECK: void @__llvm_gcov_flush() unnamed_addr [[NRZ]]
// CHECK: void @__llvm_gcov_init() unnamed_addr [[NRZ]]
-// CHECK: void @__gcov_flush() unnamed_addr [[NRZ]]
// CHECK: attributes [[NRZ]] = { {{.*}}noredzone{{.*}} }
diff --git a/test/CodeGen/frame-pointer-elim.c b/test/CodeGen/frame-pointer-elim.c
deleted file mode 100644
index b105a199f1..0000000000
--- a/test/CodeGen/frame-pointer-elim.c
+++ /dev/null
@@ -1,40 +0,0 @@
-// REQUIRES: x86-registered-target
-
-// RUN: %clang -target i386-apple-darwin -S -o - %s | \
-// RUN: FileCheck --check-prefix=DARWIN %s
-// DARWIN: f0:
-// DARWIN: pushl %ebp
-// DARWIN: ret
-// DARWIN: f1:
-// DARWIN: pushl %ebp
-// DARWIN: ret
-
-// RUN: %clang -target i386-pc-linux-gnu -S -o - %s | \
-// RUN: FileCheck --check-prefix=LINUX %s
-// LINUX: f0:
-// LINUX-NOT: pushl %ebp
-// LINUX: ret
-// LINUX: f1:
-// LINUX: pushl %ebp
-// LINUX: ret
-
-// RUN: %clang -target i386-darwin -S -o - -fomit-frame-pointer %s | \
-// RUN: FileCheck --check-prefix=OMIT_ALL %s
-// OMIT_ALL: f0:
-// OMIT_ALL-NOT: pushl %ebp
-// OMIT_ALL: ret
-// OMIT_ALL: f1:
-// OMIT_ALL-NOT: pushl %ebp
-// OMIT_ALL: ret
-
-// RUN: %clang -target i386-darwin -S -o - -momit-leaf-frame-pointer %s | \
-// RUN: FileCheck --check-prefix=OMIT_LEAF %s
-// OMIT_LEAF: f0:
-// OMIT_LEAF-NOT: pushl %ebp
-// OMIT_LEAF: ret
-// OMIT_LEAF: f1:
-// OMIT_LEAF: pushl %ebp
-// OMIT_LEAF: ret
-
-void f0() {}
-void f1() { f0(); }
diff --git a/test/CodeGen/global-blocks-lines.c b/test/CodeGen/global-blocks-lines.c
new file mode 100644
index 0000000000..36e4618dde
--- /dev/null
+++ b/test/CodeGen/global-blocks-lines.c
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -fblocks -g -emit-llvm %s -o - | FileCheck %s
+// Make sure we do not generate line info for debugging-related frame setup.
+// CHECK: define {{.*}}block_invoke
+// CHECK-NOT: store {{.*}}%struct.__block_descriptor*{{.*}}dbg
+// CHECK: store {{.*}}%struct.__block_descriptor*{{.*}}, align
+// CHECK: ret
+// CHECK: define {{.*}}block_invoke
+// CHECK-NOT: store {{.*}}%struct.__block_descriptor*{{.*}}dbg
+// CHECK: store {{.*}}%struct.__block_descriptor*{{.*}}, align
+// CHECK: ret
+// CHECK: define {{.*}}block_invoke
+// CHECK-NOT: store {{.*}}%struct.__block_descriptor*{{.*}}dbg
+// CHECK: store {{.*}}%struct.__block_descriptor*{{.*}}, align
+// CHECK: ret
+int printf(const char*, ...);
+
+static void* _NSConcreteGlobalBlock;
+
+
+typedef void (^ HelloBlock_t)(const char * name);
+
+ /* Breakpoint for first Block function. */
+HelloBlock_t helloBlock = ^(const char * name) {
+ printf("Hello there, %s!\n", name);
+};
+
+ /* Breakpoint for second Block function. */
+static HelloBlock_t s_helloBlock = ^(const char * name) {
+ printf("Hello there, %s!\n", name);
+};
+
+/* Breakpoint for third Block function. */
+int X = 1234;
+int (^CP)(void) = ^{ X = X+1; return X; };
+
+int
+main(int argc, char * argv[])
+{
+ helloBlock("world");
+ s_helloBlock("world");
+
+ CP();
+ printf ("X = %d\n", X);
+ return X - 1235;
+}
diff --git a/test/CodeGen/le32-regparm.c b/test/CodeGen/le32-regparm.c
index 8c1ae5eb45..c8f70694c4 100644
--- a/test/CodeGen/le32-regparm.c
+++ b/test/CodeGen/le32-regparm.c
@@ -1,41 +1,4 @@
-// RUN: %clang_cc1 -triple le32-unknown-nacl %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple le32-unknown-nacl %s -fsyntax-only -verify
-#define FASTCALL __attribute__((regparm(2)))
+void __attribute__((regparm(2))) fc_f1(int i, int j, int k) {} // expected-error{{'regparm' is not valid on this platform}}
-typedef struct {
- int aaa;
- double bbbb;
- int ccc[200];
-} foo;
-
-// 2 inreg arguments are supported.
-void FASTCALL f1(int i, int j, int k);
-// CHECK: define void @f1(i32 inreg %i, i32 inreg %j, i32 %k)
-void f1(int i, int j, int k) { }
-
-// inreg structs are not supported.
-// CHECK: define void @f2(%struct.foo* inreg %a)
-void __attribute__((regparm(1))) f2(foo* a) {}
-
-// Only the first 2 arguments can be passed inreg, and the first
-// non-integral type consumes remaining available registers.
-// CHECK: define void @f3(%struct.foo* byval %a, i32 %b)
-void __attribute__((regparm(2))) f3(foo a, int b) {}
-
-// Only 64 total bits are supported
-// CHECK: define void @f4(i64 inreg %g, i32 %h)
-void __attribute__((regparm(2))) f4(long long g, int h) {}
-
-typedef void (*FType)(int, int) __attribute ((regparm (2)));
-FType bar;
-extern void FASTCALL reduced(char b, double c, foo* d, double e, int f);
-
-int
-main(void) {
- // The presence of double c means that foo* d is not passed inreg. This
- // behavior is different from current x86-32 behavior
- // CHECK: call void @reduced(i8 inreg signext 0, {{.*}} %struct.foo* null
- reduced(0, 0.0, 0, 0.0, 0);
- // CHECK: call void {{.*}}(i32 inreg 1, i32 inreg 2)
- bar(1,2);
-}
diff --git a/test/CodeGen/lifetime2.c b/test/CodeGen/lifetime2.c
new file mode 100644
index 0000000000..ffff5cca12
--- /dev/null
+++ b/test/CodeGen/lifetime2.c
@@ -0,0 +1,17 @@
+// RUN: %clang -S -emit-llvm -o - -O2 %s | FileCheck %s -check-prefix=O2
+// RUN: %clang -S -emit-llvm -o - -O0 %s | FileCheck %s -check-prefix=O0
+
+extern int bar(char *A, int n);
+
+// O0-NOT: @llvm.lifetime.start
+int foo (int n) {
+ if (n) {
+// O2: @llvm.lifetime.start
+ char A[100];
+ return bar(A, 1);
+ } else {
+// O2: @llvm.lifetime.start
+ char A[100];
+ return bar(A, 2);
+ }
+}
diff --git a/test/CodeGen/linetable-endscope.c b/test/CodeGen/linetable-endscope.c
new file mode 100644
index 0000000000..236f605d7e
--- /dev/null
+++ b/test/CodeGen/linetable-endscope.c
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -emit-llvm -g -triple x86_64-apple-darwin10 %s -o - | FileCheck %s
+
+// Check the line numbers for the ret instruction. We expect it to be
+// at the closing of the lexical scope in this case. See the comments in
+// CodeGenFunction::FinishFunction() for more details.
+
+// CHECK: define {{.*}}foo
+// CHECK: store {{.*}}, !dbg ![[CONV:[0-9]+]]
+// CHECK: ret {{.*}}, !dbg ![[RET:[0-9]+]]
+
+void foo(char c)
+{
+ int i;
+ // CHECK: ![[CONV]] = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null}
+ i = c;
+ // CHECK: ![[RET]] = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null}
+}
diff --git a/test/CodeGen/linux-arm-atomic.c b/test/CodeGen/linux-arm-atomic.c
new file mode 100644
index 0000000000..c7ce1d228b
--- /dev/null
+++ b/test/CodeGen/linux-arm-atomic.c
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=armv7-unknown-linux | FileCheck %s
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=armv6-unknown-linux | FileCheck %s
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=thumbv7-unknown-linux | FileCheck %s
+
+typedef int _Atomic_word;
+_Atomic_word exchange_and_add(volatile _Atomic_word *__mem, int __val) {
+ return __atomic_fetch_add(__mem, __val, __ATOMIC_ACQ_REL);
+}
+
+// CHECK: define {{.*}} @exchange_and_add
+// CHECK: atomicrmw {{.*}} add
diff --git a/test/CodeGen/may-alias.c b/test/CodeGen/may-alias.c
index b73ee15f87..c76724444b 100644
--- a/test/CodeGen/may-alias.c
+++ b/test/CodeGen/may-alias.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -Werror -triple i386-unknown-unknown -emit-llvm -O1 -disable-llvm-optzns -o %t %s
-// RUN: FileCheck < %t %s
+// RUN: %clang_cc1 -Werror -triple i386-unknown-unknown -emit-llvm -O1 -disable-llvm-optzns -o - %s | FileCheck %s
+// RUN: %clang_cc1 -Werror -triple i386-unknown-unknown -emit-llvm -O1 -struct-path-tbaa -disable-llvm-optzns -o - %s | FileCheck %s -check-prefix=PATH
// Types with the may_alias attribute should be considered equivalent
// to char for aliasing.
@@ -9,8 +9,10 @@ typedef int __attribute__((may_alias)) aliasing_int;
void test0(aliasing_int *ai, int *i)
{
// CHECK: store i32 0, i32* %{{.*}}, !tbaa !1
+// PATH: store i32 0, i32* %{{.*}}, !tbaa [[TAG_CHAR:!.*]]
*ai = 0;
// CHECK: store i32 1, i32* %{{.*}}, !tbaa !3
+// PATH: store i32 1, i32* %{{.*}}, !tbaa [[TAG_INT:!.*]]
*i = 1;
}
@@ -19,8 +21,10 @@ struct Test1 { int x; };
struct Test1MA { int x; } __attribute__((may_alias));
void test1(struct Test1MA *p1, struct Test1 *p2) {
// CHECK: store i32 2, i32* {{%.*}}, !tbaa !1
+ // PATH: store i32 2, i32* {{%.*}}, !tbaa [[TAG_CHAR]]
p1->x = 2;
// CHECK: store i32 3, i32* {{%.*}}, !tbaa !3
+ // PATH: store i32 3, i32* {{%.*}}, !tbaa [[TAG_test1_x:!.*]]
p2->x = 3;
}
@@ -28,3 +32,10 @@ void test1(struct Test1MA *p1, struct Test1 *p2) {
// CHECK: !1 = metadata !{metadata !"omnipotent char", metadata !2}
// CHECK: !2 = metadata !{metadata !"Simple C/C++ TBAA"}
// CHECK: !3 = metadata !{metadata !"int", metadata !1}
+
+// PATH: [[TYPE_CHAR:!.*]] = metadata !{metadata !"omnipotent char", metadata !{{.*}}
+// PATH: [[TAG_CHAR]] = metadata !{metadata [[TYPE_CHAR]], metadata [[TYPE_CHAR]], i64 0}
+// PATH: [[TAG_INT]] = metadata !{metadata [[TYPE_INT:!.*]], metadata [[TYPE_INT]], i64 0}
+// PATH: [[TYPE_INT]] = metadata !{metadata !"int", metadata [[TYPE_CHAR]]
+// PATH: [[TAG_test1_x]] = metadata !{metadata [[TYPE_test1:!.*]], metadata [[TYPE_INT]], i64 0}
+// PATH: [[TYPE_test1]] = metadata !{metadata !"_ZTS5Test1", metadata [[TYPE_INT]], i64 0}
diff --git a/test/CodeGen/mips-inline-asm-modifiers.c b/test/CodeGen/mips-inline-asm-modifiers.c
new file mode 100644
index 0000000000..7c4ca2ce14
--- /dev/null
+++ b/test/CodeGen/mips-inline-asm-modifiers.c
@@ -0,0 +1,35 @@
+// RUN: %clang -target mipsel-unknown-linux -S -o - -emit-llvm %s \
+// RUN: | FileCheck %s
+
+// This checks that the frontend will accept inline asm operand modifiers
+
+int printf(const char*, ...);
+
+ // CHECK: %{{[0-9]+}} = call i32 asm ".set noreorder;\0Alw $0,$1;\0A.set reorder;\0A", "=r,*m"(i32* getelementptr inbounds ([8 x i32]* @b, i32 {{[0-9]+}}, i32 {{[0-9]+}})) #2, !srcloc !0
+ // CHECK: %{{[0-9]+}} = call i32 asm "lw $0,${1:D};\0A", "=r,*m"(i32* getelementptr inbounds ([8 x i32]* @b, i32 {{[0-9]+}}, i32 {{[0-9]+}})) #2, !srcloc !1
+int b[8] = {0,1,2,3,4,5,6,7};
+int main()
+{
+ int i;
+
+ // The first word. Notice, no 'D'
+ {asm (
+ ".set noreorder;\n"
+ "lw %0,%1;\n"
+ ".set reorder;\n"
+ : "=r" (i)
+ : "m" (*(b+4)));}
+
+ printf("%d\n",i);
+
+ // The second word
+ {asm (
+ "lw %0,%D1;\n"
+ : "=r" (i)
+ : "m" (*(b+4))
+ );}
+
+ printf("%d\n",i);
+
+ return 1;
+}
diff --git a/test/CodeGen/mips16-attr.c b/test/CodeGen/mips16-attr.c
new file mode 100644
index 0000000000..18799be6f0
--- /dev/null
+++ b/test/CodeGen/mips16-attr.c
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -triple mipsel-linux-gnu -emit-llvm -o - %s | FileCheck %s
+void __attribute__((mips16)) foo (void) {
+
+}
+
+// CHECK: define void @foo() [[MIPS16:#[0-9]+]]
+
+void __attribute__((nomips16)) nofoo (void) {
+
+}
+
+// CHECK: define void @nofoo() [[NOMIPS16:#[0-9]+]]
+
+// CHECK: attributes [[MIPS16]] = { nounwind {{.*}} "mips16" {{.*}} }
+
+// CHECK: attributes [[NOMIPS16]] = { nounwind {{.*}} "nomips16" {{.*}} }
+
diff --git a/test/CodeGen/ms-inline-asm-64.c b/test/CodeGen/ms-inline-asm-64.c
index 8d2940d4e0..dd7b9b3349 100644
--- a/test/CodeGen/ms-inline-asm-64.c
+++ b/test/CodeGen/ms-inline-asm-64.c
@@ -5,14 +5,42 @@ void t1() {
int var = 10;
__asm mov rax, offset var ; rax = address of myvar
// CHECK: t1
-// CHECK: call void asm sideeffect inteldialect "mov rax, $0", "r,~{rax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) [[NUW:#[0-9]+]]
+// CHECK: call void asm sideeffect inteldialect "mov rax, $0", "r,~{rax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
}
void t2() {
int var = 10;
__asm mov [eax], offset var
// CHECK: t2
-// CHECK: call void asm sideeffect inteldialect "mov [eax], $0", "r,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) [[NUW]]
+// CHECK: call void asm sideeffect inteldialect "mov [eax], $0", "r,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
}
-// CHECK: attributes [[NUW]] = { nounwind }
+struct t3_type { int a, b; };
+
+int t3() {
+ struct t3_type foo;
+ foo.a = 1;
+ foo.b = 2;
+ __asm {
+ lea ebx, foo
+ mov eax, [ebx].0
+ mov [ebx].4, ecx
+ }
+ return foo.b;
+// CHECK: t3
+// CHECK: call void asm sideeffect inteldialect "lea ebx, qword ptr $0\0A\09mov eax, [ebx].0\0A\09mov [ebx].4, ecx", "*m,~{eax},~{ebx},~{dirflag},~{fpsr},~{flags}"(%struct.t3_type* %{{.*}})
+}
+
+int t4() {
+ struct t3_type foo;
+ foo.a = 1;
+ foo.b = 2;
+ __asm {
+ lea ebx, foo
+ mov eax, [ebx].foo.a
+ mov [ebx].foo.b, ecx
+ }
+ return foo.b;
+// CHECK: t4
+// CHECK: call void asm sideeffect inteldialect "lea ebx, qword ptr $0\0A\09mov eax, [ebx].0\0A\09mov [ebx].4, ecx", "*m,~{eax},~{ebx},~{dirflag},~{fpsr},~{flags}"(%struct.t3_type* %{{.*}})
+}
diff --git a/test/CodeGen/ms-inline-asm.c b/test/CodeGen/ms-inline-asm.c
index 7f130d697b..c71a8df0ec 100644
--- a/test/CodeGen/ms-inline-asm.c
+++ b/test/CodeGen/ms-inline-asm.c
@@ -3,16 +3,16 @@
void t1() {
// CHECK: @t1
-// CHECK: call void asm sideeffect inteldialect "", "~{dirflag},~{fpsr},~{flags}"() [[NUW:#[0-9]+]]
+// CHECK: call void asm sideeffect inteldialect "", "~{dirflag},~{fpsr},~{flags}"()
// CHECK: ret void
__asm {}
}
void t2() {
// CHECK: @t2
-// CHECK: call void asm sideeffect inteldialect "nop", "~{dirflag},~{fpsr},~{flags}"() [[NUW]]
-// CHECK: call void asm sideeffect inteldialect "nop", "~{dirflag},~{fpsr},~{flags}"() [[NUW]]
-// CHECK: call void asm sideeffect inteldialect "nop", "~{dirflag},~{fpsr},~{flags}"() [[NUW]]
+// CHECK: call void asm sideeffect inteldialect "nop", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "nop", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "nop", "~{dirflag},~{fpsr},~{flags}"()
// CHECK: ret void
__asm nop
__asm nop
@@ -21,15 +21,15 @@ void t2() {
void t3() {
// CHECK: @t3
-// CHECK: call void asm sideeffect inteldialect "nop\0A\09nop\0A\09nop", "~{dirflag},~{fpsr},~{flags}"() [[NUW]]
+// CHECK: call void asm sideeffect inteldialect "nop\0A\09nop\0A\09nop", "~{dirflag},~{fpsr},~{flags}"()
// CHECK: ret void
__asm nop __asm nop __asm nop
}
void t4(void) {
// CHECK: @t4
-// CHECK: call void asm sideeffect inteldialect "mov ebx, eax", "~{ebx},~{dirflag},~{fpsr},~{flags}"() [[NUW]]
-// CHECK: call void asm sideeffect inteldialect "mov ecx, ebx", "~{ecx},~{dirflag},~{fpsr},~{flags}"() [[NUW]]
+// CHECK: call void asm sideeffect inteldialect "mov ebx, eax", "~{ebx},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov ecx, ebx", "~{ecx},~{dirflag},~{fpsr},~{flags}"()
// CHECK: ret void
__asm mov ebx, eax
__asm mov ecx, ebx
@@ -37,7 +37,7 @@ void t4(void) {
void t5(void) {
// CHECK: @t5
-// CHECK: call void asm sideeffect inteldialect "mov ebx, eax\0A\09mov ecx, ebx", "~{ebx},~{ecx},~{dirflag},~{fpsr},~{flags}"() [[NUW]]
+// CHECK: call void asm sideeffect inteldialect "mov ebx, eax\0A\09mov ecx, ebx", "~{ebx},~{ecx},~{dirflag},~{fpsr},~{flags}"()
// CHECK: ret void
__asm mov ebx, eax __asm mov ecx, ebx
}
@@ -45,7 +45,7 @@ void t5(void) {
void t6(void) {
__asm int 0x2c
// CHECK: t6
-// CHECK: call void asm sideeffect inteldialect "int $$0x2c", "~{dirflag},~{fpsr},~{flags}"() [[NUW]]
+// CHECK: call void asm sideeffect inteldialect "int $$0x2c", "~{dirflag},~{fpsr},~{flags}"()
}
void t7() {
@@ -54,8 +54,8 @@ void t7() {
}
__asm {}
// CHECK: t7
-// CHECK: call void asm sideeffect inteldialect "int $$0x2c", "~{dirflag},~{fpsr},~{flags}"() [[NUW]]
-// CHECK: call void asm sideeffect inteldialect "", "~{dirflag},~{fpsr},~{flags}"() [[NUW]]
+// CHECK: call void asm sideeffect inteldialect "int $$0x2c", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "", "~{dirflag},~{fpsr},~{flags}"()
}
int t8() {
@@ -64,9 +64,9 @@ int t8() {
__asm int 4
return 10;
// CHECK: t8
-// CHECK: call void asm sideeffect inteldialect "int $$4", "~{dirflag},~{fpsr},~{flags}"() [[NUW]]
-// CHECK: call void asm sideeffect inteldialect "", "~{dirflag},~{fpsr},~{flags}"() [[NUW]]
-// CHECK: call void asm sideeffect inteldialect "int $$4", "~{dirflag},~{fpsr},~{flags}"() [[NUW]]
+// CHECK: call void asm sideeffect inteldialect "int $$4", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "int $$4", "~{dirflag},~{fpsr},~{flags}"()
// CHECK: ret i32 10
}
@@ -77,7 +77,7 @@ void t9() {
pop ebx
}
// CHECK: t9
-// CHECK: call void asm sideeffect inteldialect "push ebx\0A\09mov ebx, $$0x07\0A\09pop ebx", "~{ebx},~{dirflag},~{fpsr},~{flags}"() [[NUW]]
+// CHECK: call void asm sideeffect inteldialect "push ebx\0A\09mov ebx, $$0x07\0A\09pop ebx", "~{ebx},~{dirflag},~{fpsr},~{flags}"()
}
unsigned t10(void) {
@@ -91,7 +91,7 @@ unsigned t10(void) {
// CHECK: [[I:%[a-zA-Z0-9]+]] = alloca i32, align 4
// CHECK: [[J:%[a-zA-Z0-9]+]] = alloca i32, align 4
// CHECK: store i32 1, i32* [[I]], align 4
-// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $1\0A\09mov dword ptr $0, eax", "=*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}) [[NUW]]
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $1\0A\09mov dword ptr $0, eax", "=*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}})
// CHECK: [[RET:%[a-zA-Z0-9]+]] = load i32* [[J]], align 4
// CHECK: ret i32 [[RET]]
}
@@ -99,7 +99,7 @@ unsigned t10(void) {
void t11(void) {
__asm mov eax, 1
// CHECK: t11
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"() [[NUW]]
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"()
}
unsigned t12(void) {
@@ -112,7 +112,7 @@ unsigned t12(void) {
}
return j + m;
// CHECK: t12
-// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $2\0A\09mov dword ptr $0, eax\0A\09mov eax, dword ptr $3\0A\09mov dword ptr $1, eax", "=*m,=*m,*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}}) [[NUW]]
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $2\0A\09mov dword ptr $0, eax\0A\09mov eax, dword ptr $3\0A\09mov dword ptr $1, eax", "=*m,=*m,*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}})
}
void t13() {
@@ -121,8 +121,8 @@ void t13() {
__asm movzx eax, i
__asm movzx eax, j
// CHECK: t13
-// CHECK: call void asm sideeffect inteldialect "movzx eax, byte ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i8* %{{.*}}) [[NUW]]
-// CHECK: call void asm sideeffect inteldialect "movzx eax, word ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i16* %{{.*}}) [[NUW]]
+// CHECK: call void asm sideeffect inteldialect "movzx eax, byte ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i8* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "movzx eax, word ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i16* %{{.*}})
}
void t14() {
@@ -135,7 +135,7 @@ void t14() {
.endif
}
// CHECK: t14
-// CHECK: call void asm sideeffect inteldialect ".if 1\0A\09mov eax, dword ptr $0\0A\09.else\0A\09mov ebx, j\0A\09.endif", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) [[NUW]]
+// CHECK: call void asm sideeffect inteldialect ".if 1\0A\09mov eax, dword ptr $0\0A\09.else\0A\09mov ebx, j\0A\09.endif", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
}
int gvar = 10;
@@ -145,16 +145,16 @@ void t15() {
__asm mov eax, offset lvar ; eax = address of lvar
__asm mov eax, offset gvar ; eax = address of gvar
// CHECK: t15
-// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) [[NUW]]
-// CHECK: call void asm sideeffect inteldialect "mov eax, $0", "r,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) [[NUW]]
-// CHECK: call void asm sideeffect inteldialect "mov eax, $0", "r,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* @{{.*}}) [[NUW]]
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, $0", "r,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, $0", "r,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* @{{.*}})
}
void t16() {
int var = 10;
__asm mov [eax], offset var
// CHECK: t16
-// CHECK: call void asm sideeffect inteldialect "mov [eax], $0", "r,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) [[NUW]]
+// CHECK: call void asm sideeffect inteldialect "mov [eax], $0", "r,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
}
void t17() {
@@ -163,40 +163,10 @@ void t17() {
__asm _emit 0x4B
__asm _EMIT 0x4B
// CHECK: t17
-// CHECK: call void asm sideeffect inteldialect ".byte 0x4A", "~{dirflag},~{fpsr},~{flags}"() [[NUW]]
-// CHECK: call void asm sideeffect inteldialect ".byte 0x43", "~{dirflag},~{fpsr},~{flags}"() [[NUW]]
-// CHECK: call void asm sideeffect inteldialect ".byte 0x4B", "~{dirflag},~{fpsr},~{flags}"() [[NUW]]
-// CHECK: call void asm sideeffect inteldialect ".byte 0x4B", "~{dirflag},~{fpsr},~{flags}"() [[NUW]]
-}
-
-struct t18_type { int a, b; };
-
-int t18() {
- struct t18_type foo;
- foo.a = 1;
- foo.b = 2;
- __asm {
- lea ebx, foo
- mov eax, [ebx].0
- mov [ebx].4, ecx
- }
- return foo.b;
-// CHECK: t18
-// CHECK: call void asm sideeffect inteldialect "lea ebx, foo\0A\09mov eax, [ebx].0\0A\09mov [ebx].4, ecx", "~{eax},~{dirflag},~{fpsr},~{flags}"() [[NUW]]
-}
-
-int t19() {
- struct t18_type foo;
- foo.a = 1;
- foo.b = 2;
- __asm {
- lea ebx, foo
- mov eax, [ebx].foo.a
- mov [ebx].foo.b, ecx
- }
- return foo.b;
-// CHECK: t19
-// CHECK: call void asm sideeffect inteldialect "lea ebx, foo\0A\09mov eax, [ebx].0\0A\09mov [ebx].4, ecx", "~{eax},~{dirflag},~{fpsr},~{flags}"() [[NUW]]
+// CHECK: call void asm sideeffect inteldialect ".byte 0x4A", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect ".byte 0x43", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect ".byte 0x4B", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect ".byte 0x4B", "~{dirflag},~{fpsr},~{flags}"()
}
void t20() {
@@ -210,28 +180,28 @@ void t20() {
__asm mov eax, LENGTH _foo
__asm mov eax, LENGTH _bar
// CHECK: t20
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"() [[NUW]]
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"() [[NUW]]
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"() [[NUW]]
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$2", "~{eax},~{dirflag},~{fpsr},~{flags}"() [[NUW]]
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$2", "~{eax},~{dirflag},~{fpsr},~{flags}"()
__asm mov eax, TYPE foo
__asm mov eax, TYPE bar
__asm mov eax, TYPE _foo
__asm mov eax, TYPE _bar
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"() [[NUW]]
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"() [[NUW]]
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"() [[NUW]]
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"() [[NUW]]
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"()
__asm mov eax, SIZE foo
__asm mov eax, SIZE bar
__asm mov eax, SIZE _foo
__asm mov eax, SIZE _bar
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"() [[NUW]]
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"() [[NUW]]
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$16", "~{eax},~{dirflag},~{fpsr},~{flags}"() [[NUW]]
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$2", "~{eax},~{dirflag},~{fpsr},~{flags}"() [[NUW]]
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$16", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$2", "~{eax},~{dirflag},~{fpsr},~{flags}"()
}
void t21() {
@@ -241,7 +211,7 @@ void t21() {
__asm pop ebx
}
// CHECK: t21
-// CHECK: call void asm sideeffect inteldialect "push ebx\0A\09mov ebx, $$0x07\0A\09pop ebx", "~{ebx},~{dirflag},~{fpsr},~{flags}"() [[NUW]]
+// CHECK: call void asm sideeffect inteldialect "push ebx\0A\09mov ebx, $$0x07\0A\09pop ebx", "~{ebx},~{dirflag},~{fpsr},~{flags}"()
}
extern void t22_helper(int x);
@@ -257,9 +227,9 @@ void t22() {
__asm pop ebx
}
// CHECK: t22
-// CHECK: call void asm sideeffect inteldialect "push ebx\0A\09mov ebx, esp", "~{ebx},~{dirflag},~{fpsr},~{flags}"() [[NUW]]
+// CHECK: call void asm sideeffect inteldialect "push ebx\0A\09mov ebx, esp", "~{ebx},~{dirflag},~{fpsr},~{flags}"()
// CHECK: call void @t22_helper
-// CHECK: call void asm sideeffect inteldialect "mov esp, ebx\0A\09pop ebx", "~{ebx},~{esp},~{dirflag},~{fpsr},~{flags}"() [[NUW]]
+// CHECK: call void asm sideeffect inteldialect "mov esp, ebx\0A\09pop ebx", "~{ebx},~{esp},~{dirflag},~{fpsr},~{flags}"()
}
void t23() {
@@ -267,14 +237,14 @@ void t23() {
the_label:
}
// CHECK: t23
-// CHECK: call void asm sideeffect inteldialect "the_label:", "~{dirflag},~{fpsr},~{flags}"() [[NUW]]
+// CHECK: call void asm sideeffect inteldialect "the_label:", "~{dirflag},~{fpsr},~{flags}"()
}
void t24_helper(void) {}
void t24() {
__asm call t24_helper
// CHECK: t24
-// CHECK: call void asm sideeffect inteldialect "call $0", "r,~{dirflag},~{fpsr},~{flags}"(void ()* @t24_helper) [[NUW]]
+// CHECK: call void asm sideeffect inteldialect "call $0", "r,~{dirflag},~{fpsr},~{flags}"(void ()* @t24_helper)
}
void t25() {
@@ -284,11 +254,11 @@ void t25() {
__asm mov eax, 0xa2h
__asm mov eax, 0xa2
// CHECK: t25
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$0ffffffffh", "~{eax},~{dirflag},~{fpsr},~{flags}"() [[NUW]]
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$0fh", "~{eax},~{dirflag},~{fpsr},~{flags}"() [[NUW]]
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$0a2h", "~{eax},~{dirflag},~{fpsr},~{flags}"() [[NUW]]
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$0xa2h", "~{eax},~{dirflag},~{fpsr},~{flags}"() [[NUW]]
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$0xa2", "~{eax},~{dirflag},~{fpsr},~{flags}"() [[NUW]]
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$4294967295", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$15", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$162", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$0xa2h", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$0xa2", "~{eax},~{dirflag},~{fpsr},~{flags}"()
}
void t26() {
@@ -299,18 +269,18 @@ void t26() {
__asm __EMIT 0a2h
__asm popad
// CHECK: t26
-// CHECK: call void asm sideeffect inteldialect "pushad", "~{dirflag},~{fpsr},~{flags}"() [[NUW]]
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$0", "~{eax},~{dirflag},~{fpsr},~{flags}"() [[NUW]]
-// CHECK: call void asm sideeffect inteldialect ".byte 0fh", "~{dirflag},~{fpsr},~{flags}"() [[NUW]]
-// CHECK: call void asm sideeffect inteldialect ".byte 0a2h", "~{dirflag},~{fpsr},~{flags}"() [[NUW]]
-// CHECK: call void asm sideeffect inteldialect ".byte 0a2h", "~{dirflag},~{fpsr},~{flags}"() [[NUW]]
-// CHECK: call void asm sideeffect inteldialect "popad", "~{dirflag},~{fpsr},~{flags}"() [[NUW]]
+// CHECK: call void asm sideeffect inteldialect "pushad", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$0", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect ".byte 0fh", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect ".byte 0a2h", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect ".byte 0a2h", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "popad", "~{dirflag},~{fpsr},~{flags}"()
}
void t27() {
__asm mov eax, fs:[0h]
// CHECK: t27
-// CHECK: call void asm sideeffect inteldialect "mov eax, fs:[0h]", "~{eax},~{dirflag},~{fpsr},~{flags}"() [[NUW]]
+// CHECK: call void asm sideeffect inteldialect "mov eax, fs:[$$0h]", "~{eax},~{dirflag},~{fpsr},~{flags}"()
}
void t28() {
@@ -319,10 +289,10 @@ void t28() {
__asm align 128;
__asm ALIGN 256;
// CHECK: t28
-// CHECK: call void asm sideeffect inteldialect ".align 3", "~{dirflag},~{fpsr},~{flags}"() [[NUW]]
-// CHECK: call void asm sideeffect inteldialect ".align 4", "~{dirflag},~{fpsr},~{flags}"() [[NUW]]
-// CHECK: call void asm sideeffect inteldialect ".align 7", "~{dirflag},~{fpsr},~{flags}"() [[NUW]]
-// CHECK: call void asm sideeffect inteldialect ".align 8", "~{dirflag},~{fpsr},~{flags}"() [[NUW]]
+// CHECK: call void asm sideeffect inteldialect ".align 3", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect ".align 4", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect ".align 7", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect ".align 8", "~{dirflag},~{fpsr},~{flags}"()
}
void t29() {
@@ -332,9 +302,9 @@ void t29() {
__asm mov osize, SIZE arr
__asm mov otype, TYPE arr
// CHECK: t29
-// CHECK: call void asm sideeffect inteldialect "mov dword ptr $0, $$2", "=*m,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) [[NUW]]
-// CHECK: call void asm sideeffect inteldialect "mov dword ptr $0, $$8", "=*m,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) [[NUW]]
-// CHECK: call void asm sideeffect inteldialect "mov dword ptr $0, $$4", "=*m,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) [[NUW]]
+// CHECK: call void asm sideeffect inteldialect "mov dword ptr $0, $$2", "=*m,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov dword ptr $0, $$8", "=*m,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov dword ptr $0, $$4", "=*m,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
}
int results[2] = {13, 37};
@@ -345,16 +315,126 @@ int *t30()
__asm mov res, edi
return res;
// CHECK: t30
-// CHECK: call void asm sideeffect inteldialect "lea edi, dword ptr $0", "*m,~{edi},~{dirflag},~{fpsr},~{flags}"([2 x i32]* @{{.*}}) [[NUW]]
-// CHECK: call void asm sideeffect inteldialect "mov dword ptr $0, edi", "=*m,~{dirflag},~{fpsr},~{flags}"(i32** %{{.*}}) [[NUW]]
+// CHECK: call void asm sideeffect inteldialect "lea edi, dword ptr $0", "*m,~{edi},~{dirflag},~{fpsr},~{flags}"([2 x i32]* @{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov dword ptr $0, edi", "=*m,~{dirflag},~{fpsr},~{flags}"(i32** %{{.*}})
}
void t31() {
__asm pushad
__asm popad
// CHECK: t31
-// CHECK: call void asm sideeffect inteldialect "pushad", "~{dirflag},~{fpsr},~{flags}"() [[NUW]]
-// CHECK: call void asm sideeffect inteldialect "popad", "~{dirflag},~{fpsr},~{flags}"() [[NUW]]
+// CHECK: call void asm sideeffect inteldialect "pushad", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "popad", "~{dirflag},~{fpsr},~{flags}"()
+}
+
+void t32() {
+ int i;
+ __asm mov eax, i
+ __asm mov eax, dword ptr i
+ __asm mov ax, word ptr i
+ __asm mov al, byte ptr i
+// CHECK: t32
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov ax, word ptr $0", "*m,~{ax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov al, byte ptr $0", "*m,~{al},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
}
-// CHECK: attributes [[NUW]] = { nounwind }
+void t33() {
+ int i;
+ __asm mov eax, [i]
+ __asm mov eax, dword ptr [i]
+ __asm mov ax, word ptr [i]
+ __asm mov al, byte ptr [i]
+// CHECK: t33
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov ax, word ptr $0", "*m,~{ax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov al, byte ptr $0", "*m,~{al},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
+}
+
+void t34() {
+ __asm prefetchnta 64[eax]
+ __asm mov eax, dword ptr 4[eax]
+// CHECK: t34
+// CHECK: call void asm sideeffect inteldialect "prefetchnta $$64[eax]", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$4[eax]", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+}
+
+void t35() {
+ __asm prefetchnta [eax + (200*64)]
+ __asm mov eax, dword ptr [eax + (200*64)]
+// CHECK: t35
+// CHECK: call void asm sideeffect inteldialect "prefetchnta [eax + ($$200*$$64)]", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr [eax + ($$200*$$64)]", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+}
+
+void t36() {
+ int arr[4];
+ __asm mov eax, 4[arr]
+ __asm mov eax, 4[arr + 4]
+ __asm mov eax, 8[arr + 4 + 32*2 - 4]
+ __asm mov eax, 12[4 + arr]
+ __asm mov eax, 4[4 + arr + 4]
+ __asm mov eax, 4[64 + arr + (2*32)]
+ __asm mov eax, 4[64 + arr - 2*32]
+ __asm mov eax, [arr + 4]
+ __asm mov eax, [arr + 4 + 32*2 - 4]
+ __asm mov eax, [4 + arr]
+ __asm mov eax, [4 + arr + 4]
+ __asm mov eax, [64 + arr + (2*32)]
+ __asm mov eax, [64 + arr - 2*32]
+// CHECK: t36
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$4$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$8$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$72$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$16$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$12$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$132$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$4$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$4$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$64$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$4$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$8$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$128$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+}
+
+void t37() {
+ __asm mov eax, 4 + 8
+ __asm mov eax, 4 + 8 * 16
+ __asm mov eax, -4 + 8 * 16
+ __asm mov eax, (4 + 4) * 16
+ __asm mov eax, 4 + 8 * -16
+ __asm mov eax, 4 + 16 / -8
+ __asm mov eax, (16 + 16) / -8
+// CHECK: t37
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$12", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$132", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$124", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$128", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$4294967172", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$2", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$4294967292", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+}
+
+void t38() {
+ int arr[4];
+ __asm mov eax, 4+4[arr]
+ __asm mov eax, (4+4)[arr + 4]
+ __asm mov eax, 8*2[arr + 4 + 32*2 - 4]
+ __asm mov eax, 12+20[4 + arr]
+ __asm mov eax, 4*16+4[4 + arr + 4]
+ __asm mov eax, 4*4[64 + arr + (2*32)]
+ __asm mov eax, 4*(4-2)[64 + arr - 2*32]
+ __asm mov eax, 32*(4-2)[arr - 2*32]
+// CHECK: t38
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$8$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$12$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$80$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$36$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$76$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$144$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$8$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$0$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+}
diff --git a/test/CodeGen/ms-inline-asm.cpp b/test/CodeGen/ms-inline-asm.cpp
new file mode 100644
index 0000000000..8f824f9947
--- /dev/null
+++ b/test/CodeGen/ms-inline-asm.cpp
@@ -0,0 +1,105 @@
+// REQUIRES: x86-64-registered-target
+// RUN: %clang_cc1 -x c++ %s -triple i386-apple-darwin10 -O0 -fasm-blocks -emit-llvm -o - | FileCheck %s
+
+// rdar://13645930
+
+struct Foo {
+ static int *ptr;
+ static int a, b;
+ int arr[4];
+ struct Bar {
+ static int *ptr;
+ char arr[2];
+ };
+};
+
+void t1() {
+ Foo::ptr = (int *)0xDEADBEEF;
+ Foo::Bar::ptr = (int *)0xDEADBEEF;
+ __asm mov eax, Foo ::ptr
+ __asm mov eax, Foo :: Bar :: ptr
+ __asm mov eax, [Foo:: ptr]
+ __asm mov eax, dword ptr [Foo :: ptr]
+ __asm mov eax, dword ptr [Foo :: ptr]
+// CHECK: @_Z2t1v
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @_ZN3Foo3ptrE)
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @_ZN3Foo3Bar3ptrE)
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @_ZN3Foo3ptrE)
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @_ZN3Foo3ptrE)
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @_ZN3Foo3ptrE)
+}
+
+int gvar = 10;
+void t2() {
+ int lvar = 10;
+ __asm mov eax, offset Foo::ptr
+ __asm mov eax, offset Foo::Bar::ptr
+// CHECK: t2
+// CHECK: call void asm sideeffect inteldialect "mov eax, $0", "r,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @_ZN3Foo3ptrE)
+// CHECK: call void asm sideeffect inteldialect "mov eax, $0", "r,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @_ZN3Foo3Bar3ptrE)
+}
+
+// CHECK: define void @_Z2t3v()
+void t3() {
+ __asm mov eax, LENGTH Foo::ptr
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+ __asm mov eax, LENGTH Foo::Bar::ptr
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+ __asm mov eax, LENGTH Foo::arr
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+ __asm mov eax, LENGTH Foo::Bar::arr
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$2", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+
+ __asm mov eax, TYPE Foo::ptr
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+ __asm mov eax, TYPE Foo::Bar::ptr
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+ __asm mov eax, TYPE Foo::arr
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+ __asm mov eax, TYPE Foo::Bar::arr
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+
+ __asm mov eax, SIZE Foo::ptr
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+ __asm mov eax, SIZE Foo::Bar::ptr
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+ __asm mov eax, SIZE Foo::arr
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$16", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+ __asm mov eax, SIZE Foo::Bar::arr
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$2", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+
+}
+
+struct T4 {
+ int x;
+ static int y;
+ void test();
+};
+
+// CHECK: define void @_ZN2T44testEv(
+void T4::test() {
+// CHECK: [[T0:%.*]] = alloca [[T4:%.*]]*,
+// CHECK: [[THIS:%.*]] = load [[T4]]** [[T0]]
+// CHECK: [[X:%.*]] = getelementptr inbounds [[T4]]* [[THIS]], i32 0, i32 0
+ __asm mov eax, x;
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* [[X]])
+ __asm mov y, eax;
+// CHECK: call void asm sideeffect inteldialect "mov dword ptr $0, eax", "=*m,~{dirflag},~{fpsr},~{flags}"(i32* @_ZN2T41yE)
+}
+
+template <class T> struct T5 {
+ template <class U> static T create(U);
+ void run();
+};
+// CHECK: define void @_Z5test5v()
+void test5() {
+ // CHECK: [[X:%.*]] = alloca i32
+ // CHECK: [[Y:%.*]] = alloca i32
+ int x, y;
+ __asm push y
+ // CHECK: call void asm sideeffect inteldialect "push dword ptr $0", "=*m,~{dirflag},~{fpsr},~{flags}"(i32* [[Y]])
+ __asm call T5<int>::create<float>
+ // CHECK: call void asm sideeffect inteldialect "call $0", "r,~{dirflag},~{fpsr},~{flags}"(i32 (float)* @_ZN2T5IiE6createIfEEiT_)
+ __asm mov x, eax
+ // CHECK: call void asm sideeffect inteldialect "mov dword ptr $0, eax", "=*m,~{dirflag},~{fpsr},~{flags}"(i32* [[X]])
+}
diff --git a/test/CodeGen/mult-alt-generic.c b/test/CodeGen/mult-alt-generic.c
index 6cf6f0a270..111679e3a9 100644
--- a/test/CodeGen/mult-alt-generic.c
+++ b/test/CodeGen/mult-alt-generic.c
@@ -6,7 +6,9 @@
// RUN: %clang_cc1 -triple mipsel %s -emit-llvm -o - | FileCheck %s
// RUN: %clang_cc1 -triple powerpc %s -emit-llvm -o - | FileCheck %s
// RUN: %clang_cc1 -triple powerpc64 %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple s390x %s -emit-llvm -o - | FileCheck %s
// RUN: %clang_cc1 -triple sparc %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple sparcv9 %s -emit-llvm -o - | FileCheck %s
// RUN: %clang_cc1 -triple thumb %s -emit-llvm -o - | FileCheck %s
int mout0;
diff --git a/test/CodeGen/nvptx-cpus.c b/test/CodeGen/nvptx-cpus.c
new file mode 100644
index 0000000000..c9c7680d67
--- /dev/null
+++ b/test/CodeGen/nvptx-cpus.c
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -triple nvptx-unknown-unknown -target-cpu sm_20 -O3 -S -o %t %s -emit-llvm
+// RUN: %clang_cc1 -triple nvptx-unknown-unknown -target-cpu sm_21 -O3 -S -o %t %s -emit-llvm
+// RUN: %clang_cc1 -triple nvptx-unknown-unknown -target-cpu sm_30 -O3 -S -o %t %s -emit-llvm
+// RUN: %clang_cc1 -triple nvptx-unknown-unknown -target-cpu sm_35 -O3 -S -o %t %s -emit-llvm
+
+// Make sure clang accepts all supported architectures.
+
+void foo(float* a,
+ float* b) {
+ a[0] = b[0];
+}
diff --git a/test/CodeGen/pragma-pack-1.c b/test/CodeGen/pragma-pack-1.c
index c30a62ac3c..2a71c8f79b 100644
--- a/test/CodeGen/pragma-pack-1.c
+++ b/test/CodeGen/pragma-pack-1.c
@@ -1,7 +1,68 @@
-// RUN: %clang_cc1 -emit-llvm -o - %s
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.7.0 -emit-llvm -o - %s | FileCheck %s
// PR4610
#pragma pack(4)
struct ref {
struct ref *next;
} refs;
+
+// PR13580
+struct S
+{
+ char a[3];
+#pragma pack(1)
+ struct T
+ {
+ char b;
+ int c;
+ } d;
+#pragma pack()
+ struct T2
+ {
+ char b;
+ int c;
+ } d2;
+} ss;
+
+struct S3
+{
+ char a[3];
+#pragma pack(push, 2)
+ struct T3
+ {
+ char b;
+ int c;
+ } d;
+#pragma pack(pop)
+ struct T32
+ {
+ char b;
+ int c;
+ } e;
+} s3;
+
+struct S4
+{
+ char a[3];
+#pragma align=packed
+ struct T4
+ {
+ char b;
+ int c;
+ } d;
+ int e;
+} s4;
+
+// CHECK: [[struct_ref:%[a-zA-Z0-9_.]+]] = type <{ [[struct_ref]]* }>
+// CHECK: [[struct_S:%[a-zA-Z0-9_.]+]] = type { [3 x i8], [[struct_T:%[a-zA-Z0-9_.]+]], [[struct_T2:%[a-zA-Z0-9_.]+]] }
+// CHECK: [[struct_T]] = type <{ i8, i32 }>
+// CHECK: [[struct_T2]] = type { i8, i32 }
+
+// CHECK: %struct.S3 = type <{ [3 x i8], i8, %struct.T3, [2 x i8], %struct.T32 }>
+// CHECK: %struct.T3 = type <{ i8, i8, i32 }>
+// CHECK: %struct.T32 = type { i8, i32 }
+// CHECK: %struct.S4 = type { [3 x i8], %struct.T4, i32 }
+// CHECK: %struct.T4 = type <{ i8, i32 }>
+
+// CHECK: @refs = common global [[struct_ref]]
+// CHECK: @ss = common global [[struct_S]]
diff --git a/test/CodeGen/prefetchw-builtins.c b/test/CodeGen/prefetchw-builtins.c
new file mode 100644
index 0000000000..9c5fdc7233
--- /dev/null
+++ b/test/CodeGen/prefetchw-builtins.c
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +prfchw -emit-llvm -o - %s | FileCheck %s
+
+// Don't include mm_malloc.h, it's system specific.
+#define __MM_MALLOC_H
+
+#include <x86intrin.h>
+
+void prefetch_w(void *p) {
+ return _m_prefetchw(p);
+// CHECK: @prefetch_w
+// CHECK: call void @llvm.prefetch({{.*}}, i32 1, i32 3, i32 1)
+}
diff --git a/test/CodeGen/rdrand-builtins.c b/test/CodeGen/rdrand-builtins.c
index b7970f4dd4..15414a3345 100644
--- a/test/CodeGen/rdrand-builtins.c
+++ b/test/CodeGen/rdrand-builtins.c
@@ -1,9 +1,9 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +rdrnd -emit-llvm -S -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +rdrnd -target-feature +rdseed -emit-llvm -o - %s | FileCheck %s
// Don't include mm_malloc.h, it's system specific.
#define __MM_MALLOC_H
-#include <immintrin.h>
+#include <x86intrin.h>
int rdrand16(unsigned short *p) {
return _rdrand16_step(p);
@@ -25,3 +25,24 @@ int rdrand64(unsigned long long *p) {
// CHECK: call { i64, i32 } @llvm.x86.rdrand.64
// CHECK: store i64
}
+
+int rdseed16(unsigned short *p) {
+ return _rdseed16_step(p);
+// CHECK: @rdseed16
+// CHECK: call { i16, i32 } @llvm.x86.rdseed.16
+// CHECK: store i16
+}
+
+int rdseed32(unsigned *p) {
+ return _rdseed32_step(p);
+// CHECK: @rdseed32
+// CHECK: call { i32, i32 } @llvm.x86.rdseed.32
+// CHECK: store i32
+}
+
+int rdseed64(unsigned long long *p) {
+ return _rdseed64_step(p);
+// CHECK: @rdseed64
+// CHECK: call { i64, i32 } @llvm.x86.rdseed.64
+// CHECK: store i64
+}
diff --git a/test/CodeGen/rtm-builtins.c b/test/CodeGen/rtm-builtins.c
index c4939a9a3d..5660d8e241 100644
--- a/test/CodeGen/rtm-builtins.c
+++ b/test/CodeGen/rtm-builtins.c
@@ -21,3 +21,8 @@ test_xabort(void) {
// CHECK: void @llvm.x86.xabort(i8 2)
_xabort(2);
}
+
+unsigned int test_xtest(void) {
+ // CHECK: i32 @llvm.x86.xtest()
+ return _xtest();
+}
diff --git a/test/CodeGen/sanitize-init-order.cpp b/test/CodeGen/sanitize-init-order.cpp
new file mode 100644
index 0000000000..3e94620193
--- /dev/null
+++ b/test/CodeGen/sanitize-init-order.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -fsanitize=address,init-order -emit-llvm -o - %s | FileCheck %s
+
+struct PODStruct {
+ int x;
+};
+PODStruct s1;
+
+struct PODWithDtor {
+ ~PODWithDtor() { }
+ int x;
+};
+PODWithDtor s2;
+
+struct PODWithCtorAndDtor {
+ PODWithCtorAndDtor() { }
+ ~PODWithCtorAndDtor() { }
+ int x;
+};
+PODWithCtorAndDtor s3;
+
+// Check that ASan init-order checking ignores structs with trivial default
+// constructor.
+// CHECK: !llvm.asan.dynamically_initialized_globals = !{[[GLOB:![0-9]+]]}
+// CHECK: [[GLOB]] = metadata !{%struct.PODWithCtorAndDtor
diff --git a/test/CodeGen/sanitize-use-after-scope.c b/test/CodeGen/sanitize-use-after-scope.c
new file mode 100644
index 0000000000..8f920385bc
--- /dev/null
+++ b/test/CodeGen/sanitize-use-after-scope.c
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -S -emit-llvm -o - -fsanitize=address,use-after-scope %s \
+// RUN: | FileCheck %s -check-prefix=USE-AFTER-SCOPE
+// RUN: %clang_cc1 -S -emit-llvm -o - -fsanitize=address %s \
+// RUN: | FileCheck %s -check-prefix=ADDRESS-ONLY
+
+extern int bar(char *A, int n);
+
+// ADDRESS-ONLY-NOT: @llvm.lifetime.start
+int foo (int n) {
+ if (n) {
+ // USE-AFTER-SCOPE: @llvm.lifetime.start(i64 10, i8* {{.*}})
+ char A[10];
+ return bar(A, 1);
+ // USE-AFTER-SCOPE: @llvm.lifetime.end(i64 10, i8* {{.*}})
+ } else {
+ // USE-AFTER-SCOPE: @llvm.lifetime.start(i64 20, i8* {{.*}})
+ char A[20];
+ return bar(A, 2);
+ // USE-AFTER-SCOPE: @llvm.lifetime.end(i64 20, i8* {{.*}})
+ }
+}
+
diff --git a/test/CodeGen/sparc-target-data.c b/test/CodeGen/sparc-target-data.c
new file mode 100644
index 0000000000..bb32a2196a
--- /dev/null
+++ b/test/CodeGen/sparc-target-data.c
@@ -0,0 +1,5 @@
+// RUN: %clang -target sparc-sun-solaris -o - -emit-llvm -S %s | FileCheck %s -check-prefix=V8
+// RUN: %clang -target sparcv9-sun-solaris -o - -emit-llvm -S %s | FileCheck %s -check-prefix=V9
+
+// V8: E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32-S64
+// V9: E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32:64-S128
diff --git a/test/CodeGen/systemz-inline-asm.c b/test/CodeGen/systemz-inline-asm.c
new file mode 100644
index 0000000000..8e5854f1bb
--- /dev/null
+++ b/test/CodeGen/systemz-inline-asm.c
@@ -0,0 +1,131 @@
+// RUN: %clang_cc1 -triple s390x-linux-gnu -O2 -emit-llvm -o - %s | FileCheck %s
+
+unsigned int gi;
+unsigned long gl;
+
+void test_store_m(unsigned int i) {
+ asm("st %1, %0" : "=m" (gi) : "r" (i));
+// CHECK: define void @test_store_m(i32 zeroext %i)
+// CHECK: call void asm "st $1, $0", "=*m,r"(i32* @gi, i32 %i)
+}
+
+void test_store_Q(unsigned int i) {
+ asm("st %1, %0" : "=Q" (gi) : "r" (i));
+// CHECK: define void @test_store_Q(i32 zeroext %i)
+// CHECK: call void asm "st $1, $0", "=*Q,r"(i32* @gi, i32 %i)
+}
+
+void test_store_R(unsigned int i) {
+ asm("st %1, %0" : "=R" (gi) : "r" (i));
+// CHECK: define void @test_store_R(i32 zeroext %i)
+// CHECK: call void asm "st $1, $0", "=*R,r"(i32* @gi, i32 %i)
+}
+
+void test_store_S(unsigned int i) {
+ asm("st %1, %0" : "=S" (gi) : "r" (i));
+// CHECK: define void @test_store_S(i32 zeroext %i)
+// CHECK: call void asm "st $1, $0", "=*S,r"(i32* @gi, i32 %i)
+}
+
+void test_store_T(unsigned int i) {
+ asm("st %1, %0" : "=T" (gi) : "r" (i));
+// CHECK: define void @test_store_T(i32 zeroext %i)
+// CHECK: call void asm "st $1, $0", "=*T,r"(i32* @gi, i32 %i)
+}
+
+int test_load_m() {
+ unsigned int i;
+ asm("l %0, %1" : "=r" (i) : "m" (gi));
+ return i;
+// CHECK: define signext i32 @test_load_m()
+// CHECK: call i32 asm "l $0, $1", "=r,*m"(i32* @gi)
+}
+
+int test_load_Q() {
+ unsigned int i;
+ asm("l %0, %1" : "=r" (i) : "Q" (gi));
+ return i;
+// CHECK: define signext i32 @test_load_Q()
+// CHECK: call i32 asm "l $0, $1", "=r,*Q"(i32* @gi)
+}
+
+int test_load_R() {
+ unsigned int i;
+ asm("l %0, %1" : "=r" (i) : "R" (gi));
+ return i;
+// CHECK: define signext i32 @test_load_R()
+// CHECK: call i32 asm "l $0, $1", "=r,*R"(i32* @gi)
+}
+
+int test_load_S() {
+ unsigned int i;
+ asm("l %0, %1" : "=r" (i) : "S" (gi));
+ return i;
+// CHECK: define signext i32 @test_load_S()
+// CHECK: call i32 asm "l $0, $1", "=r,*S"(i32* @gi)
+}
+
+int test_load_T() {
+ unsigned int i;
+ asm("l %0, %1" : "=r" (i) : "T" (gi));
+ return i;
+// CHECK: define signext i32 @test_load_T()
+// CHECK: call i32 asm "l $0, $1", "=r,*T"(i32* @gi)
+}
+
+void test_mI(unsigned char *c) {
+ asm volatile("cli %0, %1" :: "Q" (*c), "I" (100));
+// CHECK: define void @test_mI(i8* %c)
+// CHECK: call void asm sideeffect "cli $0, $1", "*Q,I"(i8* %c, i32 100)
+}
+
+unsigned int test_dJa(unsigned int i, unsigned int j) {
+ asm("sll %0, %2(%3)" : "=d" (i) : "0" (i), "J" (1000), "a" (j));
+ return i;
+// CHECK: define zeroext i32 @test_dJa(i32 zeroext %i, i32 zeroext %j)
+// CHECK: call i32 asm "sll $0, $2($3)", "=d,0,J,a"(i32 %i, i32 1000, i32 %j)
+}
+
+unsigned long test_rK(unsigned long i) {
+ asm("aghi %0, %2" : "=r" (i) : "0" (i), "K" (-30000));
+ return i;
+// CHECK: define i64 @test_rK(i64 %i)
+// CHECK: call i64 asm "aghi $0, $2", "=r,0,K"(i64 %i, i32 -30000)
+}
+
+unsigned long test_rL(unsigned long i) {
+ asm("sllg %0, %1, %2" : "=r" (i) : "r" (i), "L" (500000));
+ return i;
+// CHECK: define i64 @test_rL(i64 %i)
+// CHECK: call i64 asm "sllg $0, $1, $2", "=r,r,L"(i64 %i, i32 500000)
+}
+
+void test_M() {
+ asm volatile("#FOO %0" :: "M"(0x7fffffff));
+// CHECK: define void @test_M()
+// CHECK: call void asm sideeffect "#FOO $0", "M"(i32 2147483647)
+}
+
+float test_f32(float f, float g) {
+ asm("aebr %0, %2" : "=f" (f) : "0" (f), "f" (g));
+ return f;
+// CHECK: define float @test_f32(float %f, float %g)
+// CHECK: call float asm "aebr $0, $2", "=f,0,f"(float %f, float %g)
+}
+
+double test_f64(double f, double g) {
+ asm("adbr %0, %2" : "=f" (f) : "0" (f), "f" (g));
+ return f;
+// CHECK: define double @test_f64(double %f, double %g)
+// CHECK: call double asm "adbr $0, $2", "=f,0,f"(double %f, double %g)
+}
+
+long double test_f128(long double f, long double g) {
+ asm("axbr %0, %2" : "=f" (f) : "0" (f), "f" (g));
+ return f;
+// CHECK: define void @test_f128(fp128* noalias nocapture sret [[DEST:%.*]], fp128* byval nocapture, fp128* byval nocapture)
+// CHECK: %f = load fp128* %0
+// CHECK: %g = load fp128* %1
+// CHECK: [[RESULT:%.*]] = tail call fp128 asm "axbr $0, $2", "=f,0,f"(fp128 %f, fp128 %g)
+// CHECK: store fp128 [[RESULT]], fp128* [[DEST]]
+}
diff --git a/test/CodeGen/tbaa-class.cpp b/test/CodeGen/tbaa-class.cpp
new file mode 100644
index 0000000000..967ba19a04
--- /dev/null
+++ b/test/CodeGen/tbaa-class.cpp
@@ -0,0 +1,226 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -disable-llvm-optzns %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -struct-path-tbaa -disable-llvm-optzns %s -emit-llvm -o - | FileCheck %s -check-prefix=PATH
+// Test TBAA metadata generated by front-end.
+
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned int uint32_t;
+typedef unsigned long long uint64_t;
+class StructA
+{
+public:
+ uint16_t f16;
+ uint32_t f32;
+ uint16_t f16_2;
+ uint32_t f32_2;
+};
+class StructB
+{
+public:
+ uint16_t f16;
+ StructA a;
+ uint32_t f32;
+};
+class StructC
+{
+public:
+ uint16_t f16;
+ StructB b;
+ uint32_t f32;
+};
+class StructD
+{
+public:
+ uint16_t f16;
+ StructB b;
+ uint32_t f32;
+ uint8_t f8;
+};
+
+class StructS
+{
+public:
+ uint16_t f16;
+ uint32_t f32;
+};
+class StructS2 : public StructS
+{
+public:
+ uint16_t f16_2;
+ uint32_t f32_2;
+};
+
+uint32_t g(uint32_t *s, StructA *A, uint64_t count) {
+// CHECK: define i32 @{{.*}}(
+// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
+// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
+// PATH: define i32 @{{.*}}(
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_i32:!.*]]
+// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32:!.*]]
+ *s = 1;
+ A->f32 = 4;
+ return *s;
+}
+
+uint32_t g2(uint32_t *s, StructA *A, uint64_t count) {
+// CHECK: define i32 @{{.*}}(
+// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
+// CHECK: store i16 4, i16* %{{.*}}, align 2, !tbaa !5
+// PATH: define i32 @{{.*}}(
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_i32]]
+// PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa [[TAG_A_f16:!.*]]
+ *s = 1;
+ A->f16 = 4;
+ return *s;
+}
+
+uint32_t g3(StructA *A, StructB *B, uint64_t count) {
+// CHECK: define i32 @{{.*}}(
+// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
+// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
+// PATH: define i32 @{{.*}}(
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]]
+// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_B_a_f32:!.*]]
+ A->f32 = 1;
+ B->a.f32 = 4;
+ return A->f32;
+}
+
+uint32_t g4(StructA *A, StructB *B, uint64_t count) {
+// CHECK: define i32 @{{.*}}(
+// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
+// CHECK: store i16 4, i16* %{{.*}}, align 2, !tbaa !5
+// PATH: define i32 @{{.*}}(
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]]
+// PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa [[TAG_B_a_f16:!.*]]
+ A->f32 = 1;
+ B->a.f16 = 4;
+ return A->f32;
+}
+
+uint32_t g5(StructA *A, StructB *B, uint64_t count) {
+// CHECK: define i32 @{{.*}}(
+// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
+// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
+// PATH: define i32 @{{.*}}(
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]]
+// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_B_f32:!.*]]
+ A->f32 = 1;
+ B->f32 = 4;
+ return A->f32;
+}
+
+uint32_t g6(StructA *A, StructB *B, uint64_t count) {
+// CHECK: define i32 @{{.*}}(
+// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
+// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
+// PATH: define i32 @{{.*}}(
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]]
+// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_B_a_f32_2:!.*]]
+ A->f32 = 1;
+ B->a.f32_2 = 4;
+ return A->f32;
+}
+
+uint32_t g7(StructA *A, StructS *S, uint64_t count) {
+// CHECK: define i32 @{{.*}}(
+// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
+// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
+// PATH: define i32 @{{.*}}(
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]]
+// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_S_f32:!.*]]
+ A->f32 = 1;
+ S->f32 = 4;
+ return A->f32;
+}
+
+uint32_t g8(StructA *A, StructS *S, uint64_t count) {
+// CHECK: define i32 @{{.*}}(
+// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
+// CHECK: store i16 4, i16* %{{.*}}, align 2, !tbaa !5
+// PATH: define i32 @{{.*}}(
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]]
+// PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa [[TAG_S_f16:!.*]]
+ A->f32 = 1;
+ S->f16 = 4;
+ return A->f32;
+}
+
+uint32_t g9(StructS *S, StructS2 *S2, uint64_t count) {
+// CHECK: define i32 @{{.*}}(
+// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
+// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
+// PATH: define i32 @{{.*}}(
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_S_f32]]
+// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_S_f32:!.*]]
+ S->f32 = 1;
+ S2->f32 = 4;
+ return S->f32;
+}
+
+uint32_t g10(StructS *S, StructS2 *S2, uint64_t count) {
+// CHECK: define i32 @{{.*}}(
+// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
+// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
+// PATH: define i32 @{{.*}}(
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_S_f32]]
+// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_S2_f32_2:!.*]]
+ S->f32 = 1;
+ S2->f32_2 = 4;
+ return S->f32;
+}
+
+uint32_t g11(StructC *C, StructD *D, uint64_t count) {
+// CHECK: define i32 @{{.*}}(
+// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
+// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
+// PATH: define i32 @{{.*}}(
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_C_b_a_f32:!.*]]
+// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_D_b_a_f32:!.*]]
+ C->b.a.f32 = 1;
+ D->b.a.f32 = 4;
+ return C->b.a.f32;
+}
+
+uint32_t g12(StructC *C, StructD *D, uint64_t count) {
+// CHECK: define i32 @{{.*}}(
+// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
+// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
+// TODO: differentiate the two accesses.
+// PATH: define i32 @{{.*}}(
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_B_a_f32]]
+// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_B_a_f32]]
+ StructB *b1 = &(C->b);
+ StructB *b2 = &(D->b);
+ // b1, b2 have different context.
+ b1->a.f32 = 1;
+ b2->a.f32 = 4;
+ return b1->a.f32;
+}
+
+// CHECK: !1 = metadata !{metadata !"omnipotent char", metadata !2}
+// CHECK: !2 = metadata !{metadata !"Simple C/C++ TBAA"}
+// CHECK: !4 = metadata !{metadata !"int", metadata !1}
+// CHECK: !5 = metadata !{metadata !"short", metadata !1}
+
+// PATH: [[TYPE_CHAR:!.*]] = metadata !{metadata !"omnipotent char", metadata !3
+// PATH: [[TAG_i32]] = metadata !{metadata [[TYPE_INT:!.*]], metadata [[TYPE_INT]], i64 0}
+// PATH: [[TYPE_INT]] = metadata !{metadata !"int", metadata [[TYPE_CHAR]]
+// PATH: [[TAG_A_f32]] = metadata !{metadata [[TYPE_A:!.*]], metadata [[TYPE_INT]], i64 4}
+// PATH: [[TYPE_A]] = metadata !{metadata !"_ZTS7StructA", metadata [[TYPE_SHORT:!.*]], i64 0, metadata [[TYPE_INT]], i64 4, metadata [[TYPE_SHORT]], i64 8, metadata [[TYPE_INT]], i64 12}
+// PATH: [[TYPE_SHORT:!.*]] = metadata !{metadata !"short", metadata [[TYPE_CHAR]]
+// PATH: [[TAG_A_f16]] = metadata !{metadata [[TYPE_A]], metadata [[TYPE_SHORT]], i64 0}
+// PATH: [[TAG_B_a_f32]] = metadata !{metadata [[TYPE_B:!.*]], metadata [[TYPE_INT]], i64 8}
+// PATH: [[TYPE_B]] = metadata !{metadata !"_ZTS7StructB", metadata [[TYPE_SHORT]], i64 0, metadata [[TYPE_A]], i64 4, metadata [[TYPE_INT]], i64 20}
+// PATH: [[TAG_B_a_f16]] = metadata !{metadata [[TYPE_B]], metadata [[TYPE_SHORT]], i64 4}
+// PATH: [[TAG_B_f32]] = metadata !{metadata [[TYPE_B]], metadata [[TYPE_INT]], i64 20}
+// PATH: [[TAG_B_a_f32_2]] = metadata !{metadata [[TYPE_B]], metadata [[TYPE_INT]], i64 16}
+// PATH: [[TAG_S_f32]] = metadata !{metadata [[TYPE_S:!.*]], metadata [[TYPE_INT]], i64 4}
+// PATH: [[TYPE_S]] = metadata !{metadata !"_ZTS7StructS", metadata [[TYPE_SHORT]], i64 0, metadata [[TYPE_INT]], i64 4}
+// PATH: [[TAG_S_f16]] = metadata !{metadata [[TYPE_S]], metadata [[TYPE_SHORT]], i64 0}
+// PATH: [[TAG_S2_f32_2]] = metadata !{metadata [[TYPE_S2:!.*]], metadata [[TYPE_INT]], i64 12}
+// PATH: [[TYPE_S2]] = metadata !{metadata !"_ZTS8StructS2", metadata [[TYPE_SHORT]], i64 8, metadata [[TYPE_INT]], i64 12}
+// PATH: [[TAG_C_b_a_f32]] = metadata !{metadata [[TYPE_C:!.*]], metadata [[TYPE_INT]], i64 12}
+// PATH: [[TYPE_C]] = metadata !{metadata !"_ZTS7StructC", metadata [[TYPE_SHORT]], i64 0, metadata [[TYPE_B]], i64 4, metadata [[TYPE_INT]], i64 28}
+// PATH: [[TAG_D_b_a_f32]] = metadata !{metadata [[TYPE_D:!.*]], metadata [[TYPE_INT]], i64 12}
+// PATH: [[TYPE_D]] = metadata !{metadata !"_ZTS7StructD", metadata [[TYPE_SHORT]], i64 0, metadata [[TYPE_B]], i64 4, metadata [[TYPE_INT]], i64 28, metadata [[TYPE_CHAR]], i64 32}
diff --git a/test/CodeGen/tbaa-struct.cpp b/test/CodeGen/tbaa-struct.cpp
index 8b30aa0a49..6d593a3c1b 100644
--- a/test/CodeGen/tbaa-struct.cpp
+++ b/test/CodeGen/tbaa-struct.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm -o - -O1 %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o - -O1 %s | FileCheck %s
//
// Check that we generate !tbaa.struct metadata for struct copies.
struct A {
@@ -14,4 +14,61 @@ void copy(struct A *a, struct A *b) {
// CHECK: target datalayout = "{{.*}}p:[[P:64|32]]
// CHECK: call void @llvm.memcpy.p0i8.p0i8.i[[P]](i8* %{{.*}}, i8* %{{.*}}, i[[P]] 16, i32 4, i1 false), !tbaa.struct [[TS:!.*]]
+
+struct B {
+ char c1;
+ struct A a;
+ int ii;
+};
+
+void copy2(struct B *a, struct B *b) {
+ *a = *b;
+}
+
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i[[P]](i8* %{{.*}}, i8* %{{.*}}, i[[P]] 24, i32 4, i1 false), !tbaa.struct [[TS2:!.*]]
+
+typedef _Complex int T2;
+typedef _Complex char T5;
+typedef _Complex int T7;
+typedef struct T4 { T5 field0; T7 field1; } T4;
+typedef union T1 { T2 field0; T4 field1; } T1;
+
+void copy3 (T1 *a, T1 *b) {
+ *a = *b;
+}
+
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i[[P]](i8* %{{.*}}, i8* %{{.*}}, i[[P]] 12, i32 4, i1 false), !tbaa.struct [[TS3:!.*]]
+
+// Make sure that zero-length bitfield works.
+#define ATTR __attribute__ ((ms_struct))
+struct five {
+ char a;
+ int :0; /* ignored; prior field is not a bitfield. */
+ char b;
+ char c;
+} ATTR;
+void copy4(struct five *a, struct five *b) {
+ *a = *b;
+}
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i[[P]](i8* %{{.*}}, i8* %{{.*}}, i[[P]] 3, i32 1, i1 false), !tbaa.struct [[TS4:!.*]]
+
+struct six {
+ char a;
+ int :0;
+ char b;
+ char c;
+};
+void copy5(struct six *a, struct six *b) {
+ *a = *b;
+}
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i[[P]](i8* %{{.*}}, i8* %{{.*}}, i[[P]] 6, i32 1, i1 false), !tbaa.struct [[TS5:!.*]]
+
// CHECK: [[TS]] = metadata !{i64 0, i64 2, metadata !{{.*}}, i64 4, i64 4, metadata !{{.*}}, i64 8, i64 1, metadata !{{.*}}, i64 12, i64 4, metadata !{{.*}}}
+// CHECK: [[CHAR:!.*]] = metadata !{metadata !"omnipotent char", metadata !{{.*}}}
+// CHECK: [[INT:!.*]] = metadata !{metadata !"int", metadata [[CHAR]]}
+// (offset, size) = (0,1) char; (4,2) short; (8,4) int; (12,1) char; (16,4) int; (20,4) int
+// CHECK: [[TS2]] = metadata !{i64 0, i64 1, metadata !{{.*}}, i64 4, i64 2, metadata !{{.*}}, i64 8, i64 4, metadata !{{.*}}, i64 12, i64 1, metadata !{{.*}}, i64 16, i64 4, metadata {{.*}}, i64 20, i64 4, metadata {{.*}}}
+// (offset, size) = (0,8) char; (0,2) char; (4,8) char
+// CHECK: [[TS3]] = metadata !{i64 0, i64 8, metadata !{{.*}}, i64 0, i64 2, metadata !{{.*}}, i64 4, i64 8, metadata !{{.*}}}
+// CHECK: [[TS4]] = metadata !{i64 0, i64 1, metadata [[CHAR]], i64 1, i64 1, metadata [[CHAR]], i64 2, i64 1, metadata [[CHAR]]}
+// CHECK: [[TS5]] = metadata !{i64 0, i64 1, metadata [[CHAR]], i64 4, i64 4, metadata [[INT]], i64 4, i64 1, metadata [[CHAR]], i64 5, i64 1, metadata [[CHAR]]}
diff --git a/test/CodeGen/tbaa.cpp b/test/CodeGen/tbaa.cpp
new file mode 100644
index 0000000000..afb8893d3e
--- /dev/null
+++ b/test/CodeGen/tbaa.cpp
@@ -0,0 +1,255 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -disable-llvm-optzns %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -struct-path-tbaa -disable-llvm-optzns %s -emit-llvm -o - | FileCheck %s -check-prefix=PATH
+// Test TBAA metadata generated by front-end.
+
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned int uint32_t;
+typedef unsigned long long uint64_t;
+typedef struct
+{
+ uint16_t f16;
+ uint32_t f32;
+ uint16_t f16_2;
+ uint32_t f32_2;
+} StructA;
+typedef struct
+{
+ uint16_t f16;
+ StructA a;
+ uint32_t f32;
+} StructB;
+typedef struct
+{
+ uint16_t f16;
+ StructB b;
+ uint32_t f32;
+} StructC;
+typedef struct
+{
+ uint16_t f16;
+ StructB b;
+ uint32_t f32;
+ uint8_t f8;
+} StructD;
+
+typedef struct
+{
+ uint16_t f16;
+ uint32_t f32;
+} StructS;
+typedef struct
+{
+ uint16_t f16;
+ uint32_t f32;
+} StructS2;
+
+uint32_t g(uint32_t *s, StructA *A, uint64_t count) {
+// CHECK: define i32 @{{.*}}(
+// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
+// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
+// PATH: define i32 @{{.*}}(
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_i32:!.*]]
+// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32:!.*]]
+ *s = 1;
+ A->f32 = 4;
+ return *s;
+}
+
+uint32_t g2(uint32_t *s, StructA *A, uint64_t count) {
+// CHECK: define i32 @{{.*}}(
+// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
+// CHECK: store i16 4, i16* %{{.*}}, align 2, !tbaa !5
+// PATH: define i32 @{{.*}}(
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_i32]]
+// PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa [[TAG_A_f16:!.*]]
+ *s = 1;
+ A->f16 = 4;
+ return *s;
+}
+
+uint32_t g3(StructA *A, StructB *B, uint64_t count) {
+// CHECK: define i32 @{{.*}}(
+// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
+// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
+// PATH: define i32 @{{.*}}(
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]]
+// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_B_a_f32:!.*]]
+ A->f32 = 1;
+ B->a.f32 = 4;
+ return A->f32;
+}
+
+uint32_t g4(StructA *A, StructB *B, uint64_t count) {
+// CHECK: define i32 @{{.*}}(
+// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
+// CHECK: store i16 4, i16* %{{.*}}, align 2, !tbaa !5
+// PATH: define i32 @{{.*}}(
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]]
+// PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa [[TAG_B_a_f16:!.*]]
+ A->f32 = 1;
+ B->a.f16 = 4;
+ return A->f32;
+}
+
+uint32_t g5(StructA *A, StructB *B, uint64_t count) {
+// CHECK: define i32 @{{.*}}(
+// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
+// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
+// PATH: define i32 @{{.*}}(
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]]
+// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_B_f32:!.*]]
+ A->f32 = 1;
+ B->f32 = 4;
+ return A->f32;
+}
+
+uint32_t g6(StructA *A, StructB *B, uint64_t count) {
+// CHECK: define i32 @{{.*}}(
+// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
+// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
+// PATH: define i32 @{{.*}}(
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]]
+// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_B_a_f32_2:!.*]]
+ A->f32 = 1;
+ B->a.f32_2 = 4;
+ return A->f32;
+}
+
+uint32_t g7(StructA *A, StructS *S, uint64_t count) {
+// CHECK: define i32 @{{.*}}(
+// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
+// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
+// PATH: define i32 @{{.*}}(
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]]
+// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_S_f32:!.*]]
+ A->f32 = 1;
+ S->f32 = 4;
+ return A->f32;
+}
+
+uint32_t g8(StructA *A, StructS *S, uint64_t count) {
+// CHECK: define i32 @{{.*}}(
+// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
+// CHECK: store i16 4, i16* %{{.*}}, align 2, !tbaa !5
+// PATH: define i32 @{{.*}}(
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]]
+// PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa [[TAG_S_f16:!.*]]
+ A->f32 = 1;
+ S->f16 = 4;
+ return A->f32;
+}
+
+uint32_t g9(StructS *S, StructS2 *S2, uint64_t count) {
+// CHECK: define i32 @{{.*}}(
+// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
+// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
+// PATH: define i32 @{{.*}}(
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_S_f32]]
+// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_S2_f32:!.*]]
+ S->f32 = 1;
+ S2->f32 = 4;
+ return S->f32;
+}
+
+uint32_t g10(StructS *S, StructS2 *S2, uint64_t count) {
+// CHECK: define i32 @{{.*}}(
+// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
+// CHECK: store i16 4, i16* %{{.*}}, align 2, !tbaa !5
+// PATH: define i32 @{{.*}}(
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_S_f32]]
+// PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa [[TAG_S2_f16:!.*]]
+ S->f32 = 1;
+ S2->f16 = 4;
+ return S->f32;
+}
+
+uint32_t g11(StructC *C, StructD *D, uint64_t count) {
+// CHECK: define i32 @{{.*}}(
+// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
+// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
+// PATH: define i32 @{{.*}}(
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_C_b_a_f32:!.*]]
+// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_D_b_a_f32:!.*]]
+ C->b.a.f32 = 1;
+ D->b.a.f32 = 4;
+ return C->b.a.f32;
+}
+
+uint32_t g12(StructC *C, StructD *D, uint64_t count) {
+// CHECK: define i32 @{{.*}}(
+// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
+// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
+// TODO: differentiate the two accesses.
+// PATH: define i32 @{{.*}}(
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_B_a_f32]]
+// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_B_a_f32]]
+ StructB *b1 = &(C->b);
+ StructB *b2 = &(D->b);
+ // b1, b2 have different context.
+ b1->a.f32 = 1;
+ b2->a.f32 = 4;
+ return b1->a.f32;
+}
+
+// Make sure that zero-length bitfield works.
+#define ATTR __attribute__ ((ms_struct))
+struct five {
+ char a;
+ int :0; /* ignored; prior field is not a bitfield. */
+ char b;
+ char c;
+} ATTR;
+char g13(struct five *a, struct five *b) {
+ return a->b;
+// CHECK: define signext i8 @{{.*}}(
+// CHECK: load i8* %{{.*}}, align 1, !tbaa !1
+// PATH: define signext i8 @{{.*}}(
+// PATH: load i8* %{{.*}}, align 1, !tbaa [[TAG_five_b:!.*]]
+}
+
+struct six {
+ char a;
+ int :0;
+ char b;
+ char c;
+};
+char g14(struct six *a, struct six *b) {
+// CHECK: define signext i8 @{{.*}}(
+// CHECK: load i8* %{{.*}}, align 1, !tbaa !1
+// PATH: define signext i8 @{{.*}}(
+// PATH: load i8* %{{.*}}, align 1, !tbaa [[TAG_six_b:!.*]]
+ return a->b;
+}
+
+// CHECK: !1 = metadata !{metadata !"omnipotent char", metadata !2}
+// CHECK: !2 = metadata !{metadata !"Simple C/C++ TBAA"}
+// CHECK: !4 = metadata !{metadata !"int", metadata !1}
+// CHECK: !5 = metadata !{metadata !"short", metadata !1}
+
+// PATH: [[TYPE_CHAR:!.*]] = metadata !{metadata !"omnipotent char", metadata !3
+// PATH: [[TAG_i32]] = metadata !{metadata [[TYPE_INT:!.*]], metadata [[TYPE_INT]], i64 0}
+// PATH: [[TYPE_INT]] = metadata !{metadata !"int", metadata [[TYPE_CHAR]]
+// PATH: [[TAG_A_f32]] = metadata !{metadata [[TYPE_A:!.*]], metadata [[TYPE_INT]], i64 4}
+// PATH: [[TYPE_A]] = metadata !{metadata !"_ZTS7StructA", metadata [[TYPE_SHORT:!.*]], i64 0, metadata [[TYPE_INT]], i64 4, metadata [[TYPE_SHORT]], i64 8, metadata [[TYPE_INT]], i64 12}
+// PATH: [[TYPE_SHORT:!.*]] = metadata !{metadata !"short", metadata [[TYPE_CHAR]]
+// PATH: [[TAG_A_f16]] = metadata !{metadata [[TYPE_A]], metadata [[TYPE_SHORT]], i64 0}
+// PATH: [[TAG_B_a_f32]] = metadata !{metadata [[TYPE_B:!.*]], metadata [[TYPE_INT]], i64 8}
+// PATH: [[TYPE_B]] = metadata !{metadata !"_ZTS7StructB", metadata [[TYPE_SHORT]], i64 0, metadata [[TYPE_A]], i64 4, metadata [[TYPE_INT]], i64 20}
+// PATH: [[TAG_B_a_f16]] = metadata !{metadata [[TYPE_B]], metadata [[TYPE_SHORT]], i64 4}
+// PATH: [[TAG_B_f32]] = metadata !{metadata [[TYPE_B]], metadata [[TYPE_INT]], i64 20}
+// PATH: [[TAG_B_a_f32_2]] = metadata !{metadata [[TYPE_B]], metadata [[TYPE_INT]], i64 16}
+// PATH: [[TAG_S_f32]] = metadata !{metadata [[TYPE_S:!.*]], metadata [[TYPE_INT]], i64 4}
+// PATH: [[TYPE_S]] = metadata !{metadata !"_ZTS7StructS", metadata [[TYPE_SHORT]], i64 0, metadata [[TYPE_INT]], i64 4}
+// PATH: [[TAG_S_f16]] = metadata !{metadata [[TYPE_S]], metadata [[TYPE_SHORT]], i64 0}
+// PATH: [[TAG_S2_f32]] = metadata !{metadata [[TYPE_S2:!.*]], metadata [[TYPE_INT]], i64 4}
+// PATH: [[TYPE_S2]] = metadata !{metadata !"_ZTS8StructS2", metadata [[TYPE_SHORT]], i64 0, metadata [[TYPE_INT]], i64 4}
+// PATH: [[TAG_S2_f16]] = metadata !{metadata [[TYPE_S2]], metadata [[TYPE_SHORT]], i64 0}
+// PATH: [[TAG_C_b_a_f32]] = metadata !{metadata [[TYPE_C:!.*]], metadata [[TYPE_INT]], i64 12}
+// PATH: [[TYPE_C]] = metadata !{metadata !"_ZTS7StructC", metadata [[TYPE_SHORT]], i64 0, metadata [[TYPE_B]], i64 4, metadata [[TYPE_INT]], i64 28}
+// PATH: [[TAG_D_b_a_f32]] = metadata !{metadata [[TYPE_D:!.*]], metadata [[TYPE_INT]], i64 12}
+// PATH: [[TYPE_D]] = metadata !{metadata !"_ZTS7StructD", metadata [[TYPE_SHORT]], i64 0, metadata [[TYPE_B]], i64 4, metadata [[TYPE_INT]], i64 28, metadata [[TYPE_CHAR]], i64 32}
+// PATH: [[TAG_five_b]] = metadata !{metadata [[TYPE_five:!.*]], metadata [[TYPE_CHAR]], i64 1}
+// PATH: [[TYPE_five]] = metadata !{metadata !"_ZTS4five", metadata [[TYPE_CHAR]], i64 0, metadata [[TYPE_CHAR]], i64 1, metadata [[TYPE_CHAR]], i64 2}
+// PATH: [[TAG_six_b]] = metadata !{metadata [[TYPE_six:!.*]], metadata [[TYPE_CHAR]], i64 4}
+// PATH: [[TYPE_six]] = metadata !{metadata !"_ZTS3six", metadata [[TYPE_CHAR]], i64 0, metadata [[TYPE_INT]], i64 4, metadata [[TYPE_CHAR]], i64 4, metadata [[TYPE_CHAR]], i64 5}
diff --git a/test/CodeGen/thread-specifier.c b/test/CodeGen/thread-specifier.c
index a2d3e62c8c..8e21651cd8 100644
--- a/test/CodeGen/thread-specifier.c
+++ b/test/CodeGen/thread-specifier.c
@@ -10,6 +10,9 @@
// CHECK: @i = thread_local(initialexec) global
// CHECK: @j = thread_local(localexec) global
+// CHECK-NOT: @_ZTW
+// CHECK-NOT: @_ZTH
+
__thread int a;
extern __thread int b;
int c() { return *&b; }
diff --git a/test/CodeGen/x86_32-arguments-darwin.c b/test/CodeGen/x86_32-arguments-darwin.c
index 917ba72e0b..4aa4295ffd 100644
--- a/test/CodeGen/x86_32-arguments-darwin.c
+++ b/test/CodeGen/x86_32-arguments-darwin.c
@@ -229,7 +229,7 @@ v4i32 f55(v4i32 arg) { return arg+arg; }
// CHECK: define void @f56(
// CHECK: i8 signext %a0, %struct.s56_0* byval align 4 %a1,
-// CHECK: x86_mmx %a2.coerce, %struct.s56_1* byval align 4,
+// CHECK: i64 %a2.coerce, %struct.s56_1* byval align 4,
// CHECK: i64 %a4.coerce, %struct.s56_2* byval align 4,
// CHECK: <4 x i32> %a6, %struct.s56_3* byval align 16 %a7,
// CHECK: <2 x double> %a8, %struct.s56_4* byval align 16 %a9,
@@ -238,7 +238,7 @@ v4i32 f55(v4i32 arg) { return arg+arg; }
// CHECK: call void (i32, ...)* @f56_0(i32 1,
// CHECK: i32 %{{[^ ]*}}, %struct.s56_0* byval align 4 %{{[^ ]*}},
-// CHECK: x86_mmx %{{[^ ]*}}, %struct.s56_1* byval align 4 %{{[^ ]*}},
+// CHECK: i64 %{{[^ ]*}}, %struct.s56_1* byval align 4 %{{[^ ]*}},
// CHECK: i64 %{{[^ ]*}}, %struct.s56_2* byval align 4 %{{[^ ]*}},
// CHECK: <4 x i32> %{{[^ ]*}}, %struct.s56_3* byval align 16 %{{[^ ]*}},
// CHECK: <2 x double> %{{[^ ]*}}, %struct.s56_4* byval align 16 %{{[^ ]*}},
diff --git a/test/CodeGen/x86_32-arguments-linux.c b/test/CodeGen/x86_32-arguments-linux.c
index 81dcaf6af5..e93f9dccbf 100644
--- a/test/CodeGen/x86_32-arguments-linux.c
+++ b/test/CodeGen/x86_32-arguments-linux.c
@@ -3,7 +3,7 @@
// CHECK: define void @f56(
// CHECK: i8 signext %a0, %struct.s56_0* byval align 4 %a1,
-// CHECK: x86_mmx %a2.coerce, %struct.s56_1* byval align 4,
+// CHECK: i64 %a2.coerce, %struct.s56_1* byval align 4,
// CHECK: <1 x double> %a4, %struct.s56_2* byval align 4,
// CHECK: <4 x i32> %a6, %struct.s56_3* byval align 4,
// CHECK: <2 x double> %a8, %struct.s56_4* byval align 4,
@@ -12,7 +12,7 @@
// CHECK: call void (i32, ...)* @f56_0(i32 1,
// CHECK: i32 %{{.*}}, %struct.s56_0* byval align 4 %{{[^ ]*}},
-// CHECK: x86_mmx %{{[^ ]*}}, %struct.s56_1* byval align 4 %{{[^ ]*}},
+// CHECK: i64 %{{[^ ]*}}, %struct.s56_1* byval align 4 %{{[^ ]*}},
// CHECK: <1 x double> %{{[^ ]*}}, %struct.s56_2* byval align 4 %{{[^ ]*}},
// CHECK: <4 x i32> %{{[^ ]*}}, %struct.s56_3* byval align 4 %{{[^ ]*}},
// CHECK: <2 x double> %{{[^ ]*}}, %struct.s56_4* byval align 4 %{{[^ ]*}},
diff --git a/test/CodeGen/x86_32-arguments-win32.c b/test/CodeGen/x86_32-arguments-win32.c
index f18bb30fa4..77ff9e2ff3 100644
--- a/test/CodeGen/x86_32-arguments-win32.c
+++ b/test/CodeGen/x86_32-arguments-win32.c
@@ -1,7 +1,7 @@
// RUN: %clang_cc1 -w -triple i386-pc-win32 -emit-llvm -o - %s | FileCheck %s
// CHECK: define i64 @f1_1()
-// CHECK: define void @f1_2(i32 %a0.0, i32 %a0.1)
+// CHECK: define void @f1_2(%struct.s1* byval align 4 %a0)
struct s1 {
int a;
int b;
@@ -31,7 +31,7 @@ struct s4 {
struct s4 f4_1(void) { while (1) {} }
// CHECK: define i64 @f5_1()
-// CHECK: define void @f5_2(double %a0.0)
+// CHECK: define void @f5_2(%struct.s5* byval align 4)
struct s5 {
double a;
};
@@ -39,7 +39,7 @@ struct s5 f5_1(void) { while (1) {} }
void f5_2(struct s5 a0) {}
// CHECK: define i32 @f6_1()
-// CHECK: define void @f6_2(float %a0.0)
+// CHECK: define void @f6_2(%struct.s6* byval align 4 %a0)
struct s6 {
float a;
};
diff --git a/test/CodeGen/x86_32-inline-asm.c b/test/CodeGen/x86_32-inline-asm.c
index 527ad85581..473f78ebca 100644
--- a/test/CodeGen/x86_32-inline-asm.c
+++ b/test/CodeGen/x86_32-inline-asm.c
@@ -7,7 +7,7 @@ typedef u_int32_t uint32_t;
typedef unsigned long long u_int64_t;
typedef u_int64_t uint64_t;
-int func() {
+int func1() {
// Error out if size is > 32-bits.
uint32_t msr = 0x8b;
uint64_t val = 0;
diff --git a/test/CodeGenCUDA/ptx-kernels.cu b/test/CodeGenCUDA/ptx-kernels.cu
index f0bf2952a1..8d34f4f3a6 100644
--- a/test/CodeGenCUDA/ptx-kernels.cu
+++ b/test/CodeGenCUDA/ptx-kernels.cu
@@ -2,11 +2,15 @@
#include "../SemaCUDA/cuda.h"
-// CHECK: define ptx_device{{.*}}device_function
+// CHECK: define void @device_function
+extern "C"
__device__ void device_function() {}
-// CHECK: define ptx_kernel{{.*}}global_function
+// CHECK: define void @global_function
+extern "C"
__global__ void global_function() {
- // CHECK: call ptx_device{{.*}}device_function
+ // CHECK: call void @device_function
device_function();
}
+
+// CHECK: !{{[0-9]+}} = metadata !{void ()* @global_function, metadata !"kernel", i32 1}
diff --git a/test/CodeGenCXX/2010-07-23-DeclLoc.cpp b/test/CodeGenCXX/2010-07-23-DeclLoc.cpp
index 74054481cd..4c689029b8 100644
--- a/test/CodeGenCXX/2010-07-23-DeclLoc.cpp
+++ b/test/CodeGenCXX/2010-07-23-DeclLoc.cpp
@@ -1,9 +1,9 @@
// RUN: %clang_cc1 -emit-llvm -g %s -o - | FileCheck %s
// Require the template function declaration refer to the correct filename.
// First, locate the function decl in metadata, and pluck out the file handle:
-// CHECK: {{extract_dwarf_data_from_header.*extract_dwarf_data_from_header.*extract_dwarf_data_from_header.*[^ ]+", metadata !}}[[filehandle:[0-9]+]],
+// CHECK: metadata [[filehandle:![0-9]+]], {{[^,]*}}, {{.*extract_dwarf_data_from_header.*extract_dwarf_data_from_header.*extract_dwarf_data_from_header.*[^ ]+", }}
// Second: Require that filehandle refer to the correct filename:
-// CHECK: {{^!}}[[filehandle]] = metadata {{![{].*}} metadata !"decl_should_be_here.hpp",
+// CHECK: [[filehandle]] = {{.*}}decl_should_be_here.hpp"
typedef long unsigned int __darwin_size_t;
typedef __darwin_size_t size_t;
typedef unsigned char uint8_t;
diff --git a/test/CodeGenCXX/arm.cpp b/test/CodeGenCXX/arm.cpp
index 3d3b147aa1..48f2f00840 100644
--- a/test/CodeGenCXX/arm.cpp
+++ b/test/CodeGenCXX/arm.cpp
@@ -56,15 +56,15 @@ namespace test1 {
// CHECK: [[THIS:%.*]] = alloca [[A]]*, align 4
// CHECK: store [[A]]* {{.*}}, [[A]]** [[THIS]]
// CHECK: [[THIS1:%.*]] = load [[A]]** [[THIS]]
- // CHECK: call [[A]]* @_ZN5test11AC2Ei(
- // CHECK: ret [[A]]* [[THIS1]]
+ // CHECK: [[THIS2:%.*]] = call [[A]]* @_ZN5test11AC2Ei(
+ // CHECK: ret [[A]]* [[THIS2]]
// CHECK: define linkonce_odr [[A]]* @_ZN5test11AD1Ev([[A]]* %this) unnamed_addr
// CHECK: [[THIS:%.*]] = alloca [[A]]*, align 4
// CHECK: store [[A]]* {{.*}}, [[A]]** [[THIS]]
// CHECK: [[THIS1:%.*]] = load [[A]]** [[THIS]]
- // CHECK: call [[A]]* @_ZN5test11AD2Ev(
- // CHECK: ret [[A]]* [[THIS1]]
+ // CHECK: [[THIS2:%.*]] = call [[A]]* @_ZN5test11AD2Ev(
+ // CHECK: ret [[A]]* [[THIS2]]
}
// Awkward virtual cases.
diff --git a/test/CodeGenCXX/blocks.cpp b/test/CodeGenCXX/blocks.cpp
index 1500c0d698..81eef0e028 100644
--- a/test/CodeGenCXX/blocks.cpp
+++ b/test/CodeGenCXX/blocks.cpp
@@ -120,9 +120,11 @@ namespace test4 {
}
// CHECK: define void @_ZN5test44testEv()
// CHECK: define internal void @___ZN5test44testEv_block_invoke
- // CHECK: [[TMP:%.*]] = alloca [[A:%.*]], align 1
- // CHECK-NEXT: bitcast i8*
- // CHECK-NEXT: call void @_ZN5test41AC1Ev([[A]]* [[TMP]])
+ // CHECK: [[TMP:%.*]] = alloca [[A:%.*]], align 1
+ // CHECK-NEXT: store i8* [[BLOCKDESC:%.*]], i8** {{.*}}, align 8
+ // CHECK-NEXT: load i8*
+ // CHECK-NEXT: bitcast i8* [[BLOCKDESC]] to <{ i8*, i32, i32, i8*, %struct.__block_descriptor* }>*
+ // CHECK: call void @_ZN5test41AC1Ev([[A]]* [[TMP]])
// CHECK-NEXT: call void @_ZN5test43fooENS_1AE([[A]]* [[TMP]])
// CHECK-NEXT: call void @_ZN5test41AD1Ev([[A]]* [[TMP]])
// CHECK-NEXT: ret void
@@ -226,3 +228,28 @@ namespace test8 {
template int X::foo<int>();
}
+
+// rdar://13459289
+namespace test9 {
+ struct B {
+ void *p;
+ B();
+ B(const B&);
+ ~B();
+ };
+
+ void use_block(void (^)());
+ void use_block_2(void (^)(), const B &a);
+
+ // Ensuring that creating a non-trivial capture copy expression
+ // doesn't end up stealing the block registration for the block we
+ // just parsed. That block must have captures or else it won't
+ // force registration. Must occur within a block for some reason.
+ void test() {
+ B x;
+ use_block(^{
+ int y;
+ use_block_2(^{ (void)y; }, x);
+ });
+ }
+}
diff --git a/test/CodeGenCXX/constructor-alias.cpp b/test/CodeGenCXX/constructor-alias.cpp
new file mode 100644
index 0000000000..18a4777501
--- /dev/null
+++ b/test/CodeGenCXX/constructor-alias.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -emit-llvm -triple mipsel--linux-gnu -mconstructor-aliases -o - %s | FileCheck %s
+
+// The target attribute code used to get confused with aliases. Make sure
+// we don't crash when an alias is used.
+
+struct B {
+ B();
+};
+B::B() {
+}
+
+// CHECK: @_ZN1BC1Ev = alias void (%struct.B*)* @_ZN1BC2Ev
diff --git a/test/CodeGenCXX/constructor-destructor-return-this.cpp b/test/CodeGenCXX/constructor-destructor-return-this.cpp
new file mode 100644
index 0000000000..1ff922de60
--- /dev/null
+++ b/test/CodeGenCXX/constructor-destructor-return-this.cpp
@@ -0,0 +1,60 @@
+//RUN: %clang_cc1 %s -emit-llvm -o - -triple=thumbv7-apple-ios3.0 -target-abi apcs-gnu | FileCheck %s
+
+// For constructors/desctructors that return 'this', if there exists a callsite
+// that returns 'this' and is immediately before the return instruction, make
+// sure we are using the return value from the callsite.
+// rdar://12818789
+
+// CHECK: define linkonce_odr [[A:%.*]] @_ZN11ObjectCacheC1Ev([[A]] %this) unnamed_addr
+// CHECK: [[THIS1:%.*]] = call [[A]] @_ZN11ObjectCacheC2Ev(
+// CHECK-NEXT: ret [[A]] [[THIS1]]
+
+// CHECK: define linkonce_odr [[A:%.*]] @_ZN5TimerI11ObjectCacheEC1EPS0_MS0_FvPS1_E([[A]] %this
+// CHECK: [[THIS1:%.*]] = call [[A]] @_ZN5TimerI11ObjectCacheEC2EPS0_MS0_FvPS1_E(
+// CHECK-NEXT: ret [[A]] [[THIS1]]
+
+// CHECK: define linkonce_odr [[A:%.*]] @_ZN5TimerI11ObjectCacheED1Ev([[A]] %this) unnamed_addr
+// CHECK: [[THIS1:%.*]] = call [[A]] @_ZN5TimerI11ObjectCacheED2Ev(
+// CHECK-NEXT: ret [[A]] [[THIS1]]
+
+// CHECK: define linkonce_odr [[A:%.*]] @_ZN5TimerI11ObjectCacheED2Ev([[A]] %this) unnamed_addr
+// CHECK: [[THIS1:%.*]] = call [[B:%.*]] @_ZN9TimerBaseD2Ev(
+// CHECK-NEXT: [[THIS2:%.*]] = bitcast [[B]] [[THIS1]] to [[A]]
+// CHECK-NEXT: ret [[A]] [[THIS2]]
+
+class TimerBase {
+public:
+ TimerBase();
+ virtual ~TimerBase();
+};
+
+template <typename TimerFiredClass> class Timer : public TimerBase {
+public:
+ typedef void (TimerFiredClass::*TimerFiredFunction)(Timer*);
+
+ Timer(TimerFiredClass* o, TimerFiredFunction f)
+ : m_object(o), m_function(f) { }
+
+private:
+ virtual void fired() { (m_object->*m_function)(this); }
+
+ TimerFiredClass* m_object;
+ TimerFiredFunction m_function;
+};
+
+class ObjectCache {
+public:
+ explicit ObjectCache();
+ ~ObjectCache();
+
+private:
+ Timer<ObjectCache> m_notificationPostTimer;
+};
+
+inline ObjectCache::ObjectCache() : m_notificationPostTimer(this, 0) { }
+inline ObjectCache::~ObjectCache() { }
+
+ObjectCache *test() {
+ ObjectCache *dd = new ObjectCache();
+ return dd;
+}
diff --git a/test/CodeGenCXX/coverage.cpp b/test/CodeGenCXX/coverage.cpp
new file mode 100644
index 0000000000..1f1611bd8f
--- /dev/null
+++ b/test/CodeGenCXX/coverage.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - -test-coverage -femit-coverage-notes | FileCheck %s
+
+extern "C" void test_name1() {}
+void test_name2() {}
+
+// CHECK: metadata !"test_name1", metadata !"test_name1", metadata !"",{{.*}}DW_TAG_subprogram
+// CHECK: metadata !"test_name2", metadata !"test_name2", metadata !"_Z10test_name2v",{{.*}}DW_TAG_subprogram
diff --git a/test/CodeGenCXX/cp-blocks-linetables.cpp b/test/CodeGenCXX/cp-blocks-linetables.cpp
new file mode 100644
index 0000000000..d5dd46cbe0
--- /dev/null
+++ b/test/CodeGenCXX/cp-blocks-linetables.cpp
@@ -0,0 +1,61 @@
+// RUN: %clang_cc1 -fblocks -g -emit-llvm %s -o - | FileCheck %s
+// Ensure that we generate a line table entry for the block cleanup.
+// CHECK: define {{.*}} @__main_block_invoke
+// CHECK: _NSConcreteStackBlock
+// CHECK: = bitcast {{.*}}, !dbg ![[L1:[0-9]+]]
+// CHECK-NOT: call {{.*}} @_Block_object_dispose{{.*}}, !dbg ![[L1]]
+// CHECK: ret
+
+void * _NSConcreteStackBlock;
+#ifdef __cplusplus
+extern "C" void exit(int);
+#else
+extern void exit(int);
+#endif
+
+enum numbers {
+ zero, one, two, three, four
+};
+
+typedef enum numbers (^myblock)(enum numbers);
+
+
+double test(myblock I) {
+ return I(three);
+}
+
+int main() {
+ __block enum numbers x = one;
+ __block enum numbers y = two;
+
+ /* Breakpoint for first Block function. */
+ myblock CL = ^(enum numbers z)
+ { enum numbers savex = x;
+ { __block enum numbers x = savex;
+ y = z;
+ if (y != three)
+ exit (6);
+ test (
+ /* Breakpoint for second Block function. */
+ ^ (enum numbers z) {
+ if (y != three) {
+ exit(1);
+ }
+ if (x != one)
+ exit(2);
+ x = z;
+ if (x != three)
+ exit(3);
+ if (y != three)
+ exit(4);
+ return (enum numbers) four;
+ });}
+ return x;
+ };
+
+ enum numbers res = (enum numbers)test(CL);
+
+ if (res != one)
+ exit (5);
+ return 0;
+}
diff --git a/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp b/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp
index 8d9fce040f..d683493a83 100644
--- a/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp
+++ b/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp
@@ -51,6 +51,12 @@ struct wantslist1 {
// CHECK: @globalInitList1 = global %{{[^ ]+}} { i32* getelementptr inbounds ([3 x i32]* @_ZL25globalInitList1__initlist, i32 0, i32 0), i{{32|64}} 3 }
std::initializer_list<int> globalInitList1 = {1, 2, 3};
+namespace thread_local_global_array {
+ // CHECK: @_ZN25thread_local_global_arrayL11x__initlistE = internal thread_local global [4 x i32] [i32 1, i32 2, i32 3, i32 4]
+ // CHECK: @_ZN25thread_local_global_array1xE = thread_local global {{.*}} @_ZN25thread_local_global_arrayL11x__initlistE, {{.*}} i64 4
+ std::initializer_list<int> thread_local x = { 1, 2, 3, 4 };
+}
+
// CHECK: @_ZL25globalInitList2__initlist = internal global [2 x %{{[^ ]*}}] zeroinitializer
// CHECK: @globalInitList2 = global %{{[^ ]+}} { %[[WITHARG:[^ *]+]]* getelementptr inbounds ([2 x
// CHECK: appending global
@@ -250,3 +256,22 @@ namespace PR12178 {
map m{ {1, 2}, {3, 4} };
}
+
+namespace rdar13325066 {
+ struct X { ~X(); };
+
+ // CHECK: define void @_ZN12rdar133250664loopERNS_1XES1_
+ void loop(X &x1, X &x2) {
+ // CHECK: br label
+ // CHECK: br i1
+ // CHECK: br label
+ // CHECK call void @_ZN12rdar133250661XD1Ev
+ // CHECK: br label
+ // CHECK: br label
+ // CHECK: call void @_ZN12rdar133250661XD1Ev
+ // CHECK: br i1
+ // CHECK: br label
+ // CHECK: ret void
+ for (X x : { x1, x2 }) { }
+ }
+}
diff --git a/test/CodeGenCXX/cxx11-thread-local-reference.cpp b/test/CodeGenCXX/cxx11-thread-local-reference.cpp
new file mode 100644
index 0000000000..2ea9acda48
--- /dev/null
+++ b/test/CodeGenCXX/cxx11-thread-local-reference.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s
+
+int &f();
+
+// CHECK: @r = thread_local global i32* null
+thread_local int &r = f();
+
+// CHECK: @_ZTH1r = alias void ()* @__tls_init
+
+int &g() { return r; }
+
+// CHECK: define {{.*}} @[[R_INIT:.*]]()
+// CHECK: call i32* @_Z1fv()
+// CHECK: store i32* %{{.*}}, i32** @r, align 8
+
+// CHECK: define i32* @_Z1gv()
+// CHECK: call i32* @_ZTW1r()
+// CHECK: ret i32* %{{.*}}
+
+// CHECK: define weak_odr hidden i32* @_ZTW1r() {
+// CHECK: call void @_ZTH1r()
+// CHECK: load i32** @r, align 8
+// CHECK: ret i32* %{{.*}}
+
+// CHECK: define internal void @__tls_init()
+// CHECK: call void @[[R_INIT]]()
diff --git a/test/CodeGenCXX/cxx11-thread-local.cpp b/test/CodeGenCXX/cxx11-thread-local.cpp
new file mode 100644
index 0000000000..a7141d133b
--- /dev/null
+++ b/test/CodeGenCXX/cxx11-thread-local.cpp
@@ -0,0 +1,173 @@
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s
+
+int f();
+int g();
+
+// CHECK: @a = thread_local global i32 0
+thread_local int a = f();
+extern thread_local int b;
+// CHECK: @c = global i32 0
+int c = b;
+// CHECK: @_ZL1d = internal thread_local global i32 0
+static thread_local int d = g();
+
+struct U { static thread_local int m; };
+// CHECK: @_ZN1U1mE = thread_local global i32 0
+thread_local int U::m = f();
+
+template<typename T> struct V { static thread_local int m; };
+template<typename T> thread_local int V<T>::m = g();
+
+// CHECK: @e = global i32 0
+int e = V<int>::m;
+
+// CHECK: @_ZN1VIiE1mE = weak_odr thread_local global i32 0
+
+// CHECK: @_ZZ1fvE1n = internal thread_local global i32 0
+
+// CHECK: @_ZGVZ1fvE1n = internal thread_local global i8 0
+
+// CHECK: @_ZZ8tls_dtorvE1s = internal thread_local global
+// CHECK: @_ZGVZ8tls_dtorvE1s = internal thread_local global i8 0
+
+// CHECK: @_ZZ8tls_dtorvE1t = internal thread_local global
+// CHECK: @_ZGVZ8tls_dtorvE1t = internal thread_local global i8 0
+
+// CHECK: @_ZZ8tls_dtorvE1u = internal thread_local global
+// CHECK: @_ZGVZ8tls_dtorvE1u = internal thread_local global i8 0
+// CHECK: @_ZGRZ8tls_dtorvE1u = internal thread_local global
+
+// CHECK: @_ZGVN1VIiE1mE = weak_odr thread_local global i64 0
+
+// CHECK: @__tls_guard = internal thread_local global i8 0
+
+// CHECK: @llvm.global_ctors = appending global {{.*}} @[[GLOBAL_INIT:[^ ]*]]
+
+// CHECK: @_ZTH1a = alias void ()* @__tls_init
+// CHECK: @_ZTHL1d = alias internal void ()* @__tls_init
+// CHECK: @_ZTHN1U1mE = alias void ()* @__tls_init
+// CHECK: @_ZTHN1VIiE1mE = alias weak_odr void ()* @__tls_init
+
+
+// Individual variable initialization functions:
+
+// CHECK: define {{.*}} @[[A_INIT:.*]]()
+// CHECK: call i32 @_Z1fv()
+// CHECK-NEXT: store i32 {{.*}}, i32* @a, align 4
+
+// CHECK: define i32 @_Z1fv()
+int f() {
+ // CHECK: %[[GUARD:.*]] = load i8* @_ZGVZ1fvE1n, align 1
+ // CHECK: %[[NEED_INIT:.*]] = icmp eq i8 %[[GUARD]], 0
+ // CHECK: br i1 %[[NEED_INIT]]
+
+ // CHECK: %[[CALL:.*]] = call i32 @_Z1gv()
+ // CHECK: store i32 %[[CALL]], i32* @_ZZ1fvE1n, align 4
+ // CHECK: store i8 1, i8* @_ZGVZ1fvE1n
+ // CHECK: br label
+ static thread_local int n = g();
+
+ // CHECK: load i32* @_ZZ1fvE1n, align 4
+ return n;
+}
+
+// CHECK: define {{.*}} @[[C_INIT:.*]]()
+// CHECK: call i32* @_ZTW1b()
+// CHECK-NEXT: load i32* %{{.*}}, align 4
+// CHECK-NEXT: store i32 %{{.*}}, i32* @c, align 4
+
+// CHECK: define weak_odr hidden i32* @_ZTW1b()
+// CHECK: br i1 icmp ne (void ()* @_ZTH1b, void ()* null),
+// not null:
+// CHECK: call void @_ZTH1b()
+// CHECK: br label
+// finally:
+// CHECK: ret i32* @b
+
+// CHECK: define {{.*}} @[[D_INIT:.*]]()
+// CHECK: call i32 @_Z1gv()
+// CHECK-NEXT: store i32 %{{.*}}, i32* @_ZL1d, align 4
+
+// CHECK: define {{.*}} @[[U_M_INIT:.*]]()
+// CHECK: call i32 @_Z1fv()
+// CHECK-NEXT: store i32 %{{.*}}, i32* @_ZN1U1mE, align 4
+
+// CHECK: define {{.*}} @[[E_INIT:.*]]()
+// CHECK: call i32* @_ZTWN1VIiE1mE()
+// CHECK-NEXT: load i32* %{{.*}}, align 4
+// CHECK-NEXT: store i32 %{{.*}}, i32* @e, align 4
+
+// CHECK: define weak_odr hidden i32* @_ZTWN1VIiE1mE()
+// CHECK: call void @_ZTHN1VIiE1mE()
+// CHECK: ret i32* @_ZN1VIiE1mE
+
+
+struct S { S(); ~S(); };
+struct T { ~T(); };
+
+// CHECK: define void @_Z8tls_dtorv()
+void tls_dtor() {
+ // CHECK: load i8* @_ZGVZ8tls_dtorvE1s
+ // CHECK: call void @_ZN1SC1Ev(%struct.S* @_ZZ8tls_dtorvE1s)
+ // CHECK: call i32 @__cxa_thread_atexit({{.*}}@_ZN1SD1Ev {{.*}} @_ZZ8tls_dtorvE1s{{.*}} @__dso_handle
+ // CHECK: store i8 1, i8* @_ZGVZ8tls_dtorvE1s
+ static thread_local S s;
+
+ // CHECK: load i8* @_ZGVZ8tls_dtorvE1t
+ // CHECK-NOT: _ZN1T
+ // CHECK: call i32 @__cxa_thread_atexit({{.*}}@_ZN1TD1Ev {{.*}}@_ZZ8tls_dtorvE1t{{.*}} @__dso_handle
+ // CHECK: store i8 1, i8* @_ZGVZ8tls_dtorvE1t
+ static thread_local T t;
+
+ // CHECK: load i8* @_ZGVZ8tls_dtorvE1u
+ // CHECK: call void @_ZN1SC1Ev(%struct.S* @_ZGRZ8tls_dtorvE1u)
+ // CHECK: call i32 @__cxa_thread_atexit({{.*}}@_ZN1SD1Ev {{.*}} @_ZGRZ8tls_dtorvE1u{{.*}} @__dso_handle
+ // CHECK: store i8 1, i8* @_ZGVZ8tls_dtorvE1u
+ static thread_local const S &u = S();
+}
+
+// CHECK: declare i32 @__cxa_thread_atexit(void (i8*)*, i8*, i8*)
+
+// CHECK: define {{.*}} @[[V_M_INIT:.*]]()
+// CHECK: load i8* bitcast (i64* @_ZGVN1VIiE1mE to i8*)
+// CHECK: %[[V_M_INITIALIZED:.*]] = icmp eq i8 %{{.*}}, 0
+// CHECK: br i1 %[[V_M_INITIALIZED]],
+// need init:
+// CHECK: call i32 @_Z1gv()
+// CHECK: store i32 %{{.*}}, i32* @_ZN1VIiE1mE, align 4
+// CHECK: store i64 1, i64* @_ZGVN1VIiE1mE
+// CHECK: br label
+
+// CHECK: define {{.*}}@[[GLOBAL_INIT:.*]]()
+// CHECK: call void @[[C_INIT]]()
+// CHECK: call void @[[E_INIT]]()
+
+
+// CHECK: define {{.*}}@__tls_init()
+// CHECK: load i8* @__tls_guard
+// CHECK: %[[NEED_TLS_INIT:.*]] = icmp eq i8 %{{.*}}, 0
+// CHECK: store i8 1, i8* @__tls_guard
+// CHECK: br i1 %[[NEED_TLS_INIT]],
+// init:
+// CHECK: call void @[[A_INIT]]()
+// CHECK: call void @[[D_INIT]]()
+// CHECK: call void @[[U_M_INIT]]()
+// CHECK: call void @[[V_M_INIT]]()
+
+
+// CHECK: define weak_odr hidden i32* @_ZTW1a() {
+// CHECK: call void @_ZTH1a()
+// CHECK: ret i32* @a
+// CHECK: }
+
+
+// CHECK: declare extern_weak void @_ZTH1b()
+
+
+// CHECK: define internal hidden i32* @_ZTWL1d()
+// CHECK: call void @_ZTHL1d()
+// CHECK: ret i32* @_ZL1d
+
+// CHECK: define weak_odr hidden i32* @_ZTWN1U1mE()
+// CHECK: call void @_ZTHN1U1mE()
+// CHECK: ret i32* @_ZN1U1mE
diff --git a/test/CodeGenCXX/cxx1y-initializer-aggregate.cpp b/test/CodeGenCXX/cxx1y-initializer-aggregate.cpp
new file mode 100644
index 0000000000..ef78c434e3
--- /dev/null
+++ b/test/CodeGenCXX/cxx1y-initializer-aggregate.cpp
@@ -0,0 +1,74 @@
+// RUN: %clang_cc1 -std=c++1y %s -triple x86_64-linux-gnu -emit-llvm -o - | FileCheck %s
+
+struct A {
+ int n = 0;
+ const char *p;
+ char k = p[n];
+ int f();
+ int x = f();
+ union {
+ char c;
+ double d = 1.0;
+ };
+};
+
+int f();
+
+union B {
+ int a;
+ int f();
+ int b = f();
+};
+
+A a { .p = "foobar" };
+A b { 4, "bazquux", .x = 42, .c = 9 };
+A c { 1, 0, 'A', f(), { 3 } };
+
+// CHECK: @[[STR_A:.*]] = {{.*}} [7 x i8] c"foobar\00"
+// CHECK: @[[STR_B:.*]] = {{.*}} [8 x i8] c"bazquux\00"
+
+B x;
+B y {};
+B z { 1 };
+// CHECK: @z = global {{.*}} { i32 1 }
+
+// Initialization of 'a':
+
+// CHECK: store i32 0, i32* getelementptr inbounds ({{.*}} @a, i32 0, i32 0)
+// CHECK: store i8* {{.*}} @[[STR_A]]{{.*}}, i8** getelementptr inbounds ({{.*}} @a, i32 0, i32 1)
+// CHECK: load i32* getelementptr inbounds ({{.*}} @a, i32 0, i32 0)
+// CHECK: load i8** getelementptr inbounds ({{.*}} @a, i32 0, i32 1)
+// CHECK: getelementptr inbounds i8* %{{.*}}, {{.*}} %{{.*}}
+// CHECK: store i8 %{{.*}}, i8* getelementptr inbounds ({{.*}} @a, i32 0, i32 2)
+// CHECK: call i32 @_ZN1A1fEv({{.*}} @a)
+// CHECK: store i32 %{{.*}}, i32* getelementptr inbounds ({{.*}}* @a, i32 0, i32 3)
+// CHECK: call void @{{.*}}C1Ev({{.*}} getelementptr inbounds (%struct.A* @a, i32 0, i32 4))
+
+// Initialization of 'b':
+
+// CHECK: store i32 4, i32* getelementptr inbounds ({{.*}} @b, i32 0, i32 0)
+// CHECK: store i8* {{.*}} @[[STR_B]]{{.*}}, i8** getelementptr inbounds ({{.*}} @b, i32 0, i32 1)
+// CHECK: load i32* getelementptr inbounds ({{.*}} @b, i32 0, i32 0)
+// CHECK: load i8** getelementptr inbounds ({{.*}} @b, i32 0, i32 1)
+// CHECK: getelementptr inbounds i8* %{{.*}}, {{.*}} %{{.*}}
+// CHECK: store i8 %{{.*}}, i8* getelementptr inbounds ({{.*}} @b, i32 0, i32 2)
+// CHECK-NOT: @_ZN1A1fEv
+// CHECK: store i32 42, i32* getelementptr inbounds ({{.*}}* @b, i32 0, i32 3)
+// CHECK-NOT: C1Ev
+// CHECK: store i8 9, i8* {{.*}} @b, i32 0, i32 4)
+
+// Initialization of 'c':
+
+// CHECK: store i32 1, i32* getelementptr inbounds ({{.*}} @c, i32 0, i32 0)
+// CHECK: store i8* null, i8** getelementptr inbounds ({{.*}} @c, i32 0, i32 1)
+// CHECK-NOT: load
+// CHECK: store i8 65, i8* getelementptr inbounds ({{.*}} @c, i32 0, i32 2)
+// CHECK: call i32 @_Z1fv()
+// CHECK: store i32 %{{.*}}, i32* getelementptr inbounds ({{.*}}* @c, i32 0, i32 3)
+// CHECK-NOT: C1Ev
+// CHECK: store i8 3, i8* {{.*}} @c, i32 0, i32 4)
+
+// CHECK: call void @_ZN1BC1Ev({{.*}} @x)
+
+// CHECK: call i32 @_ZN1B1fEv({{.*}} @y)
+// CHECK: store i32 %{{.*}}, i32* getelementptr inbounds ({{.*}} @y, i32 0, i32 0)
diff --git a/test/CodeGenCXX/debug-info-artificial-arg.cpp b/test/CodeGenCXX/debug-info-artificial-arg.cpp
index e9d8a4d28e..ff0f6638f6 100644
--- a/test/CodeGenCXX/debug-info-artificial-arg.cpp
+++ b/test/CodeGenCXX/debug-info-artificial-arg.cpp
@@ -22,9 +22,8 @@ int main(int argc, char **argv) {
A reallyA (500);
}
-// FIXME: The numbers are truly awful.
-// CHECK: ![[ARTARG:.*]] = metadata !{i32 786447, i32 0, metadata !"", i32 0, i32 0, i64 64, i64 64, i64 0, i32 1088, metadata ![[CLASSTYPE:.*]]} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [artificial] [from A]
-// CHECK: ![[CLASSTYPE]] = metadata !{i32 {{.*}}, null, metadata !"A", metadata !{{.*}}, i32 8, i64 128, i64 64, i32 0, i32 0, null, metadata !{{.*}}, i32 0, metadata ![[CLASSTYPE]], null} ; [ DW_TAG_class_type ]
-// CHECK: metadata ![[CLASSTYPE]], metadata !"A", metadata !"A", metadata !"", metadata !{{.*}}, i32 12, metadata !{{.*}}, i1 false, i1 false, i32 0, i32 0, null, i32 256, i1 false, null, null, i32 0, metadata !{{.*}}, i32 12} ; [ DW_TAG_subprogram ]
-// CHECK: metadata !"", i32 0, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata ![[FUNCTYPE:.*]], i32 0, i32 0} ; [ DW_TAG_subroutine_type ]
-// CHECK: ![[FUNCTYPE]] = metadata !{null, metadata ![[ARTARG]], metadata !{{.*}}, metadata !{{.*}}}
+// CHECK: ![[ARTARG:.*]] = {{.*}} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [artificial] [from A]
+// CHECK: ![[CLASSTYPE:.*]] = {{.*}} ; [ DW_TAG_class_type ] [A]
+// CHECK: metadata ![[CLASSTYPE]], {{.*}} ; [ DW_TAG_subprogram ] [line 12] [A]
+// CHECK: metadata [[FUNCTYPE:![0-9]*]], i32 0, i32 0} ; [ DW_TAG_subroutine_type ]
+// CHECK: [[FUNCTYPE]] = metadata !{null, metadata ![[ARTARG]], metadata !{{.*}}, metadata !{{.*}}}
diff --git a/test/CodeGenCXX/debug-info-byval.cpp b/test/CodeGenCXX/debug-info-byval.cpp
index 56ffe13237..e6317fc2de 100644
--- a/test/CodeGenCXX/debug-info-byval.cpp
+++ b/test/CodeGenCXX/debug-info-byval.cpp
@@ -23,7 +23,7 @@ void foo(EVT e);
EVT bar();
void get(int *i, unsigned dl, VAL v, VAL *p, unsigned n, EVT missing_arg) {
-//CHECK: .asciz "missing_arg"
+//CHECK: .{{asciz|string}} "missing_arg"
EVT e = bar();
if (dl == n)
foo(missing_arg);
diff --git a/test/CodeGenCXX/debug-info-char16.cpp b/test/CodeGenCXX/debug-info-char16.cpp
index 34cfb29192..06a05b31dd 100644
--- a/test/CodeGenCXX/debug-info-char16.cpp
+++ b/test/CodeGenCXX/debug-info-char16.cpp
@@ -3,4 +3,4 @@
// 16 is DW_ATE_UTF (0x10) encoding attribute.
char16_t char_a = u'h';
-// CHECK: !{{.*}} = metadata !{i32 {{.*}}, null, metadata !"char16_t", null, i32 0, i64 16, i64 16, i64 0, i32 0, i32 16} ; [ DW_TAG_base_type ]
+// CHECK: !{{.*}} = {{.*}} ; [ DW_TAG_base_type ] [char16_t]
diff --git a/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp b/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp
index 5d1b3a5c28..04fe7a03e1 100644
--- a/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp
+++ b/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp
@@ -19,6 +19,6 @@ protected:
Test t;
-// CHECK: metadata !"", null, i32 0, i64 64, i64 64, i64 0, i32 0, metadata {{.*}} [ DW_TAG_pointer_type ]
-// CHECK: metadata !"data", metadata !{{.*}}, i32 14, i64 32, i64 32, i32 0, i32 0
-// CHECK-NOT: metadata !"data", metadata {{.*}}, i32 14, i64 0, i64 0, i32 0, i32 4,
+// CHECK: ; [ DW_TAG_pointer_type ]
+// CHECK: ; [ DW_TAG_structure_type ] [data]
+// CHECK-NOT: ; [ DW_TAG_structure_type ] [data]
diff --git a/test/CodeGenCXX/debug-info-enum-class.cpp b/test/CodeGenCXX/debug-info-enum-class.cpp
index 7bbaa749f9..929327b798 100644
--- a/test/CodeGenCXX/debug-info-enum-class.cpp
+++ b/test/CodeGenCXX/debug-info-enum-class.cpp
@@ -9,10 +9,10 @@ B b;
C c;
D d;
-// CHECK: metadata !{i32 {{.*}}, null, metadata !"A", metadata ![[FILE:.*]], i32 3, i64 32, i64 32, i32 0, i32 0, metadata !{{.*}}, metadata !{{.*}}, i32 0, i32 0} ; [ DW_TAG_enumeration_type ]
-// CHECK: metadata !{i32 {{.*}}, null, metadata !"B", metadata ![[FILE]], i32 4, i64 64, i64 64, i32 0, i32 0, metadata !{{.*}}, metadata !{{.*}}, i32 0, i32 0} ; [ DW_TAG_enumeration_type ]
-// CHECK: metadata !{i32 {{.*}}, null, metadata !"C", metadata ![[FILE]], i32 5, i64 32, i64 32, i32 0, i32 0, null, metadata !{{.*}}, i32 0, i32 0} ; [ DW_TAG_enumeration_type ]
-// CHECK: metadata !{i32 {{.*}}, null, metadata !"D", metadata ![[FILE]], i32 6, i64 16, i64 16, i32 0, i32 4, null, null, i32 0} ; [ DW_TAG_enumeration_type ]
+// CHECK: ; [ DW_TAG_enumeration_type ] [A] [line 3, size 32, align 32, offset 0] [from int]
+// CHECK: ; [ DW_TAG_enumeration_type ] [B] [line 4, size 64, align 64, offset 0] [from long unsigned int]
+// CHECK: ; [ DW_TAG_enumeration_type ] [C] [line 5, size 32, align 32, offset 0] [from ]
+// CHECK: ; [ DW_TAG_enumeration_type ] [D] [line 6, size 16, align 16, offset 0] [fwd] [from ]
namespace PR14029 {
// Make sure this doesn't crash/assert.
diff --git a/test/CodeGenCXX/debug-info-fwd-ref.cpp b/test/CodeGenCXX/debug-info-fwd-ref.cpp
index 69dd192bd9..c479506c61 100644
--- a/test/CodeGenCXX/debug-info-fwd-ref.cpp
+++ b/test/CodeGenCXX/debug-info-fwd-ref.cpp
@@ -18,8 +18,7 @@ int main(int argc, char** argv) {
// Make sure we have two DW_TAG_structure_types for baz and bar and no forward
// references.
-// CHECK: metadata !{i32 {{.*}}, null, metadata !"bar", metadata ![[FILE:.*]], i32 8, i64 128, i64 64, i32 0, i32 0, null, metadata !{{.*}}, i32 0, null, null} ; [ DW_TAG_structure_type ]
-// CHECK: metadata !{i32 {{.*}}, null, metadata !"baz", metadata ![[FILE]], i32 3, i64 32, i64 32, i32 0, i32 0, null, metadata !{{.*}}, i32 0, null, null} ; [ DW_TAG_structure_type ]
-// CHECK-NOT: metadata !{i32 {{.*}}, null, metadata !"bar", metadata ![[FILE]], i32 8, i64 0, i64 0, i32 0, i32 4, i32 0, null, i32 0, i32 0} ; [ DW_TAG_structure_type ]
-// CHECK-NOT: metadata !{i32 {{.*}}, null, metadata !"baz", metadata ![[FILE]], i32 3, i64 0, i64 0, i32 0, i32 4, null, null, i32 0, null, null} ; [ DW_TAG_structure_type ]
-
+// CHECK-NOT: [fwd]
+// CHECK: [ DW_TAG_structure_type ] [bar]
+// CHECK: [ DW_TAG_structure_type ] [baz]
+// CHECK-NOT: [fwd]
diff --git a/test/CodeGenCXX/debug-info-namespace.cpp b/test/CodeGenCXX/debug-info-namespace.cpp
index 27f5eae978..13a7914b7b 100644
--- a/test/CodeGenCXX/debug-info-namespace.cpp
+++ b/test/CodeGenCXX/debug-info-namespace.cpp
@@ -1,12 +1,37 @@
-// RUN: %clang -g -S -fverbose-asm %s -o - | FileCheck %s
+// RUN: %clang -g -S -emit-llvm %s -o - | FileCheck %s
-// CHECK: TAG_namespace
namespace A {
- enum numbers {
- ZERO,
- ONE
- };
+#line 1 "foo.cpp"
+namespace B {
+int i;
+}
+using namespace B;
}
using namespace A;
-numbers n;
+
+int func(bool b) {
+ if (b) {
+ using namespace A::B;
+ return i;
+ }
+ using namespace A;
+ return B::i;
+}
+
+// CHECK: [[CU:![0-9]*]] = {{.*}}[[MODULES:![0-9]*]], metadata !""} ; [ DW_TAG_compile_unit ]
+// CHECK: [[FILE:![0-9]*]] {{.*}}debug-info-namespace.cpp"
+// CHECK: [[FUNC:![0-9]*]] {{.*}} ; [ DW_TAG_subprogram ] [line 9] [def] [func]
+// CHECK: [[FILE2:![0-9]*]]} ; [ DW_TAG_file_type ] [{{.*}}foo.cpp]
+// CHECK: [[VAR:![0-9]*]] = {{.*}}, metadata [[NS:![0-9]*]], metadata !"i", {{.*}} ; [ DW_TAG_variable ] [i]
+// CHECK: [[NS]] = {{.*}}, metadata [[FILE2]], metadata [[CTXT:![0-9]*]], {{.*}} ; [ DW_TAG_namespace ] [B] [line 1]
+// CHECK: [[CTXT]] = {{.*}}, metadata [[FILE]], null, {{.*}} ; [ DW_TAG_namespace ] [A] [line 3]
+// CHECK: [[MODULES]] = metadata !{metadata [[M1:![0-9]*]], metadata [[M2:![0-9]*]], metadata [[M3:![0-9]*]], metadata [[M4:![0-9]*]]}
+// CHECK: [[M1]] = metadata !{i32 {{[0-9]*}}, metadata [[CTXT]], metadata [[NS]], i32 4} ; [ DW_TAG_imported_module ]
+// CHECK: [[M2]] = metadata !{i32 {{[0-9]*}}, metadata [[CU]], metadata [[CTXT]], i32 7} ; [ DW_TAG_imported_module ]
+// CHECK: [[M3]] = metadata !{i32 {{[0-9]*}}, metadata [[LEX:![0-9]*]], metadata [[NS]], i32 11} ; [ DW_TAG_imported_module ]
+// CHECK: [[LEX]] = metadata !{i32 {{[0-9]*}}, metadata [[FILE2]], metadata [[FUNC]], i32 10, i32 0, i32 0} ; [ DW_TAG_lexical_block ]
+// CHECK: [[M4]] = metadata !{i32 {{[0-9]*}}, metadata [[FUNC]], metadata [[CTXT]], i32 14} ; [ DW_TAG_imported_module ]
+
+// FIXME: It is confused on win32 to generate file entry when dosish filename is given.
+// REQUIRES: shell
diff --git a/test/CodeGenCXX/debug-info-nullptr.cpp b/test/CodeGenCXX/debug-info-nullptr.cpp
index 4cc7e546d8..42e9741d19 100644
--- a/test/CodeGenCXX/debug-info-nullptr.cpp
+++ b/test/CodeGenCXX/debug-info-nullptr.cpp
@@ -4,4 +4,4 @@ void foo() {
decltype(nullptr) t = 0;
}
-// CHECK: metadata !{i32 {{.*}}, null, metadata !"nullptr_t", null, i32 0, i64 0, i64 0, i64 0, i32 0, i32 0} ; [ DW_TAG_unspecified_type ]
+// CHECK: [ DW_TAG_unspecified_type ] [nullptr_t]
diff --git a/test/CodeGenCXX/debug-info-same-line.cpp b/test/CodeGenCXX/debug-info-same-line.cpp
new file mode 100644
index 0000000000..ad245031ab
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-same-line.cpp
@@ -0,0 +1,98 @@
+// RUN: %clang_cc1 -g -emit-llvm -o - %s | FileCheck %s
+
+// Make sure that clang outputs distinct debug info for a function
+// that is inlined twice on the same line. Otherwise it would appear
+// as if the function was only inlined once.
+
+#define INLINE inline __attribute__((always_inline))
+
+INLINE int
+product (int x, int y)
+{
+ int result = x * y;
+ return result;
+}
+
+INLINE int
+sum (int a, int b)
+{
+ int result = a + b;
+ return result;
+}
+
+int
+strange_max (int m, int n)
+{
+ if (m > n)
+ return m;
+ else if (n > m)
+ return n;
+ else
+ return 0;
+}
+
+int
+foo (int i, int j)
+{
+ if (strange_max (i, j) == i)
+ return product (i, j);
+ else if (strange_max (i, j) == j)
+ return sum (i, j);
+ else
+ return product (sum (i, i), sum (j, j));
+}
+
+int
+main(int argc, char const *argv[])
+{
+
+ int array[3];
+ int n;
+
+ array[0] = foo (1238, 78392);
+ array[1] = foo (379265, 23674);
+ array[2] = foo (872934, 234);
+
+ n = strange_max(array[0], strange_max(array[1], array[2]));
+
+ return n & 0xf;
+}
+
+// CHECK: define {{.*}} @_Z3fooii
+// i
+// CHECK: call void @llvm.dbg.declare
+// j
+// CHECK: call void @llvm.dbg.declare
+// x
+// CHECK: call void @llvm.dbg.declare
+// y
+// CHECK: call void @llvm.dbg.declare
+// result
+// CHECK: call void @llvm.dbg.declare
+
+// CHECK: call void @llvm.dbg.declare(metadata !{i32* %{{.*}}}, metadata ![[A_MD:[0-9]+]]), !dbg ![[A_DI:[0-9]+]]
+// CHECK: call void @llvm.dbg.declare(metadata !{i32* %{{.*}}}, metadata ![[B_MD:[0-9]+]]), !dbg ![[B_DI:[0-9]+]]
+// result
+// CHECK: call void @llvm.dbg.declare
+
+// We want to see a distinct !dbg node.
+// CHECK-NOT: call void @llvm.dbg.declare(metadata !{i32* %{{.*}}}, metadata ![[A_MD]]), !dbg ![[A_DI]]
+// CHECK: call void @llvm.dbg.declare(metadata !{i32* %{{.*}}}, metadata ![[A_MD]]), !dbg !{{.*}}
+// CHECK-NOT: call void @llvm.dbg.declare(metadata !{i32* %{{.*}}}, metadata ![[B_MD]]), !dbg ![[B_DI]]
+// CHECK: call void @llvm.dbg.declare(metadata !{i32* %{{.*}}}, metadata ![[B_MD]]), !dbg !{{.*}}
+// result
+// CHECK: call void @llvm.dbg.declare
+
+// CHECK: define {{.*}} @main
+// CHECK: call {{.*}} @_Z3fooii
+// CHECK: call {{.*}} @_Z3fooii
+// CHECK: call {{.*}} @_Z3fooii
+// CHECK: store
+// CHECK: getelementptr
+// We want to see the same !dbg node for non-inlined functions.
+// Needed for GDB compatibility.
+// CHECK: load {{.*}} !dbg ![[DBG:.*]]
+// CHECK: load {{.*}} !dbg ![[DBG]]
+// CHECK: load {{.*}} !dbg ![[DBG]]
+// CHECK: call {{.*}} @_Z11strange_maxii(i32 {{.*}}, i32 {{.*}}), !dbg ![[DBG]]
+// CHECK: call {{.*}} @_Z11strange_maxii(i32 {{.*}}, i32 {{.*}}), !dbg ![[DBG]]
diff --git a/test/CodeGenCXX/debug-info-static-fns.cpp b/test/CodeGenCXX/debug-info-static-fns.cpp
index 376f28825b..136261cdbc 100644
--- a/test/CodeGenCXX/debug-info-static-fns.cpp
+++ b/test/CodeGenCXX/debug-info-static-fns.cpp
@@ -7,4 +7,4 @@ namespace A {
}
// Verify that a is present and mangled.
-// CHECK: metadata !{i32 {{.*}}, i32 0, metadata !{{.*}}, metadata !"a", metadata !"a", metadata !"_ZN1AL1aEi", metadata !{{.*}}, i32 4, metadata !{{.*}}, i1 true, i1 true, i32 0, i32 0, null, i32 256, i1 false, i32 (i32)* @_ZN1AL1aEi, null, null, metadata !{{.*}}, i32 4} ; [ DW_TAG_subprogram ]
+// CHECK: metadata !"_ZN1AL1aEi", {{.*}}, i32 (i32)* @_ZN1AL1aEi, {{.*}} ; [ DW_TAG_subprogram ] [line 4] [local] [def] [a]
diff --git a/test/CodeGenCXX/debug-info-template-member.cpp b/test/CodeGenCXX/debug-info-template-member.cpp
index 6208c80aeb..6be7f9bd24 100644
--- a/test/CodeGenCXX/debug-info-template-member.cpp
+++ b/test/CodeGenCXX/debug-info-template-member.cpp
@@ -16,6 +16,6 @@ private:
MyClass m;
-// CHECK: metadata !{i32 {{.*}}, null, metadata !"MyClass", metadata {{.*}}, i32 {{.*}}, i64 8, i64 8, i32 0, i32 0, null, metadata [[C_MEM:.*]], i32 0, null, null} ; [ DW_TAG_class_type ]
-// CHECK: [[C_MEM]] = metadata !{metadata {{.*}}, metadata [[C_TEMP:.*]], metadata {{.*}}}
-// CHECK: [[C_TEMP]] = metadata !{i32 {{.*}}, i32 0, metadata {{.*}}, metadata !"add<2>", metadata !"add<2>", metadata !"_ZN7MyClass3addILi2EEEii", metadata {{.*}}
+// CHECK: metadata [[C_MEM:![0-9]*]], i32 0, null, null} ; [ DW_TAG_class_type ] [MyClass]
+// CHECK: [[C_MEM]] = metadata !{metadata {{.*}}, metadata [[C_TEMP:![0-9]*]], metadata {{.*}}}
+// CHECK: [[C_TEMP]] = {{.*}} ; [ DW_TAG_subprogram ] [line 11] [private] [add<2>]
diff --git a/test/CodeGenCXX/debug-info-template-quals.cpp b/test/CodeGenCXX/debug-info-template-quals.cpp
index 283874abbc..335c8abb11 100644
--- a/test/CodeGenCXX/debug-info-template-quals.cpp
+++ b/test/CodeGenCXX/debug-info-template-quals.cpp
@@ -15,12 +15,13 @@ void foo (const char *c) {
str.assign(c, str);
}
-// CHECK: [[P:.*]] = metadata !{i32 {{.*}}, metadata [[CON:.*]]} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from ]
-// CHECK: [[CON]] = metadata !{i32 {{.*}}, metadata [[CH:.*]]} ; [ DW_TAG_const_type ] [line 0, size 0, align 0, offset 0] [from char]
-// CHECK: [[CH]] = metadata !{i32 {{.*}}, metadata !"char", {{.*}}} ; [ DW_TAG_base_type ] [char] [line 0, size 8, align 8, offset 0, enc DW_ATE_signed_char]
-// CHECK: metadata !{i32 {{.*}}, metadata !"_ZN12basic_stringIcE6assignEPKcRKS0_", metadata ![[FILE:.*]], i32 7, metadata [[TYPE:.*]], i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, %struct.basic_string* (%struct.basic_string*, i8*, %struct.basic_string*)* @_ZN12basic_stringIcE6assignEPKcRKS0_, null, metadata !{{.*}}, metadata !{{.*}}, i32 8} ; [ DW_TAG_subprogram ] [line 7] [def] [scope 8] [assign]
-// CHECK: [[TYPE]] = metadata !{i32 {{.*}}, null, metadata [[ARGS:.*]], i32 0, i32 0}
+// CHECK: [[P:.*]] = {{.*}}, metadata [[CON:![0-9]*]]} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from ]
+// CHECK: [[CON]] = {{.*}}, metadata [[CH:![0-9]*]]} ; [ DW_TAG_const_type ] [line 0, size 0, align 0, offset 0] [from char]
+// CHECK: [[CH]] = {{.*}} ; [ DW_TAG_base_type ] [char] [line 0, size 8, align 8, offset 0, enc DW_ATE_signed_char]
+
+// CHECK: {{.*}} metadata [[TYPE:![0-9]*]], {{.*}}, metadata !{{[0-9]*}}, metadata !{{[0-9]*}}, i32 8} ; [ DW_TAG_subprogram ] [line 7] [def] [scope 8] [assign]
+// CHECK: [[TYPE]] = metadata !{i32 {{.*}}, metadata [[ARGS:.*]], i32 0, i32 0} ; [ DW_TAG_subroutine_type ]
// CHECK: [[ARGS]] = metadata !{metadata !{{.*}}, metadata !{{.*}}, metadata [[P]], metadata [[R:.*]]}
-// CHECK: [[BS:.*]] = metadata !{i32 {{.*}}, null, metadata !"basic_string<char>", metadata ![[FILE]], i32 4, i64 8, i64 8, i32 0, i32 0, null, metadata !{{.*}}, i32 0, null, metadata !{{.*}}} ; [ DW_TAG_structure_type ] [basic_string<char>] [line 4, size 8, align 8, offset 0] [from ]
-// CHECK: [[R]] = metadata !{i32 {{.*}}, null, null, null, i32 0, i64 0, i64 0, i64 0, i32 0, metadata [[CON2:.*]]} ; [ DW_TAG_reference_type ] [line 0, size 0, align 0, offset 0] [from ]
-// CHECK: [[CON2]] = metadata !{i32 {{.*}}, metadata [[BS]]} ; [ DW_TAG_const_type ] [line 0, size 0, align 0, offset 0] [from basic_string<char>]
+// CHECK: [[BS:.*]] = {{.*}} ; [ DW_TAG_structure_type ] [basic_string<char>] [line 4, size 8, align 8, offset 0] [from ]
+// CHECK: [[R]] = {{.*}}, metadata [[CON2:![0-9]*]]} ; [ DW_TAG_reference_type ] [line 0, size 0, align 0, offset 0] [from ]
+// CHECK: [[CON2]] = {{.*}}, metadata [[BS]]} ; [ DW_TAG_const_type ] [line 0, size 0, align 0, offset 0] [from basic_string<char>]
diff --git a/test/CodeGenCXX/debug-info-union-template.cpp b/test/CodeGenCXX/debug-info-union-template.cpp
new file mode 100644
index 0000000000..f5e6e14a71
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-union-template.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -emit-llvm -g -triple x86_64-linux-gnu %s -o - | FileCheck %s
+
+// Make sure that the union type has template parameters.
+
+namespace PR15637 {
+ template <typename T> union Value { int a; };
+ void g(float value) {
+ Value<float> tempValue;
+ }
+ Value<float> f;
+}
+
+// CHECK: {{.*}}, metadata !"Value<float>", {{.*}}, null, metadata [[TTPARAM:.*]]} ; [ DW_TAG_union_type ] [Value<float>]
+// CHECK: [[TTPARAM]] = metadata !{metadata [[PARAMS:.*]]}
+// CHECK: [[PARAMS]] = metadata !{{{.*}}metadata !"T",{{.*}}} ; [ DW_TAG_template_type_parameter ]
diff --git a/test/CodeGenCXX/debug-info-union.cpp b/test/CodeGenCXX/debug-info-union.cpp
index 588fa20336..0aa48dc8a5 100644
--- a/test/CodeGenCXX/debug-info-union.cpp
+++ b/test/CodeGenCXX/debug-info-union.cpp
@@ -10,7 +10,7 @@ union E {
E e;
-// CHECK: metadata !{i32 {{.*}}, null, metadata !"E", metadata !{{.*}}, i32 3, i64 32, i64 32, i64 0, i32 0, null, metadata !{{.*}}, i32 0, null} ; [ DW_TAG_union_type ]
-// CHECK: metadata !{i32 {{.*}}, i32 0, metadata !{{.*}}, metadata !"bb", metadata !"bb", metadata !"_ZN1E2bbEv", metadata !{{.*}}, i32 6, metadata !{{.*}}, i1 false, i1 false, i32 0, i32 0, null, i32 256, i1 false, null, null, i32 0, metadata !{{.*}}, i32 6} ; [ DW_TAG_subprogram ]
-// CHECK: metadata !{i32 {{.*}}, i32 0, metadata !{{.*}}, metadata !"aa", metadata !"aa", metadata !"_ZN1E2aaEv", metadata !{{.*}}, i32 7, metadata !{{.*}}, i1 false, i1 false, i32 0, i32 0, null, i32 256, i1 false, null, null, i32 0, metadata !{{.*}}, i32 7} ; [ DW_TAG_subprogram ]
-// CHECK: metadata !{i32 {{.*}}, i32 0, metadata !{{.*}}, metadata !"E", metadata !"E", metadata !"", metadata !{{.*}}, i32 8, metadata !{{.*}}, i1 false, i1 false, i32 0, i32 0, null, i32 256, i1 false, null, null, i32 0, metadata !{{.*}}, i32 8} ; [ DW_TAG_subprogram ]
+// CHECK: {{.*}} ; [ DW_TAG_union_type ] [E] [line 3, size 32, align 32, offset 0]
+// CHECK: {{.*}} ; [ DW_TAG_subprogram ] [line 6] [bb]
+// CHECK: {{.*}} ; [ DW_TAG_subprogram ] [line 7] [aa]
+// CHECK: {{.*}} ; [ DW_TAG_subprogram ] [line 8] [E]
diff --git a/test/CodeGenCXX/debug-info-use-after-free.cpp b/test/CodeGenCXX/debug-info-use-after-free.cpp
index 9757ca4d37..852e148956 100644
--- a/test/CodeGenCXX/debug-info-use-after-free.cpp
+++ b/test/CodeGenCXX/debug-info-use-after-free.cpp
@@ -192,6 +192,7 @@ __gnu_cxx {
public:
typedef _EqualKey
key_equal;
+ typedef void key_type;
};
using
std::equal_to;
@@ -217,7 +218,7 @@ __gnu_cxx {
_Alloc >
_Ht;
public:
- typename _Ht::key_type;
+ typedef typename _Ht::key_type key_type;
typedef typename
_Ht::key_equal
key_equal;
diff --git a/test/CodeGenCXX/debug-info-zero-length-arrays.cpp b/test/CodeGenCXX/debug-info-zero-length-arrays.cpp
index 4faed5f87d..fb47022b64 100644
--- a/test/CodeGenCXX/debug-info-zero-length-arrays.cpp
+++ b/test/CodeGenCXX/debug-info-zero-length-arrays.cpp
@@ -6,8 +6,7 @@ class A {
};
A a;
-// CHECK: !{{.*}} = metadata !{i32 {{.*}}, metadata {{.*}}, metadata !"x", metadata {{.*}}, i32 5, i64 0, i64 0, i64 0, i32 1, metadata [[ARRAY_TYPE:.*]]} ; [ DW_TAG_member ]
-// CHECK: [[ARRAY_TYPE]] = metadata !{i32 {{.*}}, null, metadata !"", null, i32 0, i64 0, i64 32, i32 0, i32 0, metadata [[BASE_TYPE:.*]], metadata [[ELEM_TYPE:.*]], i32 0, i32 0} ; [ DW_TAG_array_type ]
-// CHECK: [[BASE_TYPE]] = metadata !{i32 {{.*}}, null, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ]
+// CHECK: metadata [[ARRAY_TYPE:![0-9]*]]} ; [ DW_TAG_member ] [x]
+// CHECK: metadata [[ELEM_TYPE:![0-9]*]], i32 0, i32 0} ; [ DW_TAG_array_type ] [line 0, size 0, align 32, offset 0] [from int]
// CHECK: [[ELEM_TYPE]] = metadata !{metadata [[SUBRANGE:.*]]}
// CHECK: [[SUBRANGE]] = metadata !{i32 786465, i64 0, i64 -1} ; [ DW_TAG_subrange_type ] [unbounded]
diff --git a/test/CodeGenCXX/debug-lambda-expressions.cpp b/test/CodeGenCXX/debug-lambda-expressions.cpp
index 05ec523c88..39c9a445c4 100644
--- a/test/CodeGenCXX/debug-lambda-expressions.cpp
+++ b/test/CodeGenCXX/debug-lambda-expressions.cpp
@@ -15,57 +15,57 @@ struct D { D(); D(const D&); int x; };
int d(int x) { D y[10]; [x,y] { return y[x].x; }(); }
// Randomness for file. -- 6
-// CHECK: [[FILE:.*]] = metadata !{i32 {{.*}}, metadata !{{.*}}debug-lambda-expressions.cpp{{.*}}; [ DW_TAG_file_type ]
+// CHECK: [[FILE:.*]] = {{.*}} [ DW_TAG_file_type ] [{{.*}}debug-lambda-expressions.cpp]
// A: 10
-// CHECK: [[A_FUNC:.*]] = metadata !{i32 {{.*}}, i32 0, metadata [[FILE]], metadata !"a", metadata !"a", metadata !"_Z1av", metadata {{.*}}, i32 [[A_LINE:.*]], metadata {{.*}}, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, i32 ()* @_Z1av, null, null, {{.*}} [ DW_TAG_subprogram ]
+// CHECK: [[A_FUNC:.*]] = {{.*}} [ DW_TAG_subprogram ] [line [[A_LINE:.*]]] [def] [a]
// B: 14
-// CHECK: [[B_FUNC:.*]] = metadata !{i32 786478, i32 0, metadata [[FILE]], metadata !"b", metadata !"b", metadata !"_Z1bi", metadata [[FILE]], i32 [[B_LINE:.*]], metadata {{.*}}, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, i32 (i32)* @_Z1bi, null, null, {{.*}} ; [ DW_TAG_subprogram ]
+// CHECK: [[B_FUNC:.*]] = {{.*}} [ DW_TAG_subprogram ] [line [[B_LINE:.*]]] [def] [b]
// C: 17
-// CHECK: [[C_FUNC:.*]] = metadata !{i32 {{.*}}, i32 0, metadata [[FILE]], metadata !"c", metadata !"c", metadata !"_Z1ci", metadata [[FILE]], i32 [[C_LINE:.*]], metadata {{.*}}, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, i32 (i32)* @_Z1ci, null, null, metadata {{.*}} ; [ DW_TAG_subprogram ]
+// CHECK: [[C_FUNC:.*]] = {{.*}} [ DW_TAG_subprogram ] [line [[C_LINE:.*]]] [def] [c]
// D: 18
-// CHECK: [[D_FUNC:.*]] = metadata !{i32 {{.*}}, i32 0, metadata [[FILE]], metadata !"d", metadata !"d", metadata !"_Z1di", metadata [[FILE]], i32 [[D_LINE:.*]], metadata {{.*}}, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, i32 (i32)* @_Z1di, null, null, metadata {{.*}} ; [ DW_TAG_subprogram ]
+// CHECK: [[D_FUNC:.*]] = {{.*}} [ DW_TAG_subprogram ] [line [[D_LINE:.*]]] [def] [d]
// Back to D. -- 24
-// CHECK: [[LAM_D:.*]] = metadata !{i32 {{.*}}, metadata [[D_FUNC]], metadata !"", metadata [[FILE]], i32 [[D_LINE]], i64 352, i64 32, i32 0, i32 0, null, metadata [[LAM_D_ARGS:.*]], i32 0, null, null} ; [ DW_TAG_class_type ]
+// CHECK: [[LAM_D:.*]] = {{.*}}, metadata [[D_FUNC]], {{.*}}, metadata [[LAM_D_ARGS:.*]], i32 0, null, null} ; [ DW_TAG_class_type ] [line [[D_LINE]],
// CHECK: [[LAM_D_ARGS]] = metadata !{metadata [[CAP_D_X:.*]], metadata [[CAP_D_Y:.*]], metadata [[CON_LAM_D:.*]], metadata [[DES_LAM_D:.*]]}
-// CHECK: [[CAP_D_X]] = metadata !{i32 {{.*}}, metadata [[LAM_D]], metadata !"x", metadata [[FILE]], i32 [[D_LINE]], i64 32, i64 32, i64 0, i32 1, metadata {{.*}} ; [ DW_TAG_member ]
-// CHECK: [[CAP_D_Y]] = metadata !{i32 {{.*}}, metadata [[LAM_D]], metadata !"y", metadata [[FILE]], i32 [[D_LINE]], i64 320, i64 32, i64 32, i32 1, metadata {{.*}} ; [ DW_TAG_member ]
-// CHECK: [[CON_LAM_D]] = metadata {{.*}}[[LAM_D]], metadata !"operator()", metadata !"operator()"{{.*}}[ DW_TAG_subprogram ]
-// CHECK: [[DES_LAM_D]] = metadata {{.*}}[[LAM_D]], metadata !"~", metadata !"~"{{.*}}[ DW_TAG_subprogram ]
+// CHECK: [[CAP_D_X]] = {{.*}}, metadata [[LAM_D]], {{.*}} [ DW_TAG_member ] [x] [line [[D_LINE]],
+// CHECK: [[CAP_D_Y]] = {{.*}}, metadata [[LAM_D]], {{.*}} [ DW_TAG_member ] [y] [line [[D_LINE]],
+// CHECK: [[CON_LAM_D]] = {{.*}}, metadata [[LAM_D]], {{.*}} [ DW_TAG_subprogram ] [line [[D_LINE]]] [operator()]
+// CHECK: [[DES_LAM_D]] = {{.*}}, metadata [[LAM_D]], {{.*}} [ DW_TAG_subprogram ] [line [[D_LINE]]] [~]
// Back to C. -- 55
-// CHECK: [[LAM_C:.*]] = metadata !{i32 {{.*}}, metadata [[C_FUNC]], metadata !"", metadata [[FILE]], i32 [[C_LINE]], i64 64, i64 64, i32 0, i32 0, null, metadata [[LAM_C_ARGS:.*]], i32 0, null, null} ; [ DW_TAG_class_type ]
+// CHECK: [[LAM_C:.*]] = {{.*}}, metadata [[C_FUNC]], {{.*}}, metadata [[LAM_C_ARGS:.*]], i32 0, null, null} ; [ DW_TAG_class_type ] [line [[C_LINE]],
// CHECK: [[LAM_C_ARGS]] = metadata !{metadata [[CAP_C:.*]], metadata [[CON_LAM_C:.*]], metadata [[DES_LAM_C:.*]]}
// Ignoring the member type for now.
-// CHECK: [[CAP_C]] = metadata !{i32 {{.*}}, metadata [[LAM_C]], metadata !"x", metadata [[FILE]], i32 [[C_LINE]], i64 64, i64 64, i64 0, i32 1, metadata {{.*}}} ; [ DW_TAG_member ]
-// CHECK: [[CON_LAM_C]] = metadata {{.*}}[[LAM_C]], metadata !"operator()", metadata !"operator()"{{.*}}[ DW_TAG_subprogram ]
-// CHECK: [[DES_LAM_C]] = metadata {{.*}}[[LAM_C]], metadata !"~", metadata !"~"{{.*}}[ DW_TAG_subprogram ]
+// CHECK: [[CAP_C]] = {{.*}}, metadata [[LAM_C]], {{.*}}} ; [ DW_TAG_member ] [x] [line [[C_LINE]],
+// CHECK: [[CON_LAM_C]] = {{.*}}, metadata [[LAM_C]], {{.*}} [ DW_TAG_subprogram ] [line [[C_LINE]]] [operator()]
+// CHECK: [[DES_LAM_C]] = {{.*}}, metadata [[LAM_C]], {{.*}} [ DW_TAG_subprogram ] [line [[C_LINE]]] [~]
// Back to B. -- 67
-// CHECK: [[LAM_B:.*]] = metadata !{i32 {{.*}}, metadata [[B_FUNC]], metadata !"", metadata [[FILE]], i32 [[B_LINE]], i64 32, i64 32, i32 0, i32 0, null, metadata [[LAM_B_ARGS:.*]], i32 0, null, null} ; [ DW_TAG_class_type ]
+// CHECK: [[LAM_B:.*]] = {{.*}}, metadata [[B_FUNC]], {{.*}}, metadata [[LAM_B_ARGS:.*]], i32 0, null, null} ; [ DW_TAG_class_type ] [line [[B_LINE]],
// CHECK: [[LAM_B_ARGS]] = metadata !{metadata [[CAP_B:.*]], metadata [[CON_LAM_B:.*]], metadata [[DES_LAM_B:.*]]}
-// CHECK: [[CAP_B]] = metadata !{i32 {{.*}}, metadata [[LAM_B]], metadata !"x", metadata [[FILE]], i32 [[B_LINE]], i64 32, i64 32, i64 0, i32 1, metadata {{.*}}} ; [ DW_TAG_member ]
-// CHECK: [[CON_LAM_B]] = metadata {{.*}}[[LAM_B]], metadata !"operator()", metadata !"operator()"{{.*}}[ DW_TAG_subprogram ]
-// CHECK: [[DES_LAM_B]] = metadata {{.*}}[[LAM_B]], metadata !"~", metadata !"~"{{.*}}[ DW_TAG_subprogram ]
+// CHECK: [[CAP_B]] = {{.*}}, metadata [[LAM_B]], {{.*}}} ; [ DW_TAG_member ] [x] [line [[B_LINE]],
+// CHECK: [[CON_LAM_B]] = {{.*}}, metadata [[LAM_B]], {{.*}} [ DW_TAG_subprogram ] [line [[B_LINE]]] [operator()]
+// CHECK: [[DES_LAM_B]] = {{.*}}, metadata [[LAM_B]], {{.*}} [ DW_TAG_subprogram ] [line [[B_LINE]]] [~]
// Back to A. -- 78
-// CHECK: [[LAM_A:.*]] = metadata !{i32 {{.*}}, metadata [[A_FUNC]], metadata !"", metadata [[FILE]], i32 [[A_LINE]], i64 8, i64 8, i32 0, i32 0, null, metadata [[LAM_A_ARGS:.*]], i32 0, null, null} ; [ DW_TAG_class_type ]
+// CHECK: [[LAM_A:.*]] = {{.*}}, metadata [[A_FUNC]], {{.*}}, metadata [[LAM_A_ARGS:.*]], i32 0, null, null} ; [ DW_TAG_class_type ] [line [[A_LINE]],
// CHECK: [[LAM_A_ARGS]] = metadata !{metadata [[CON_LAM_A:.*]], metadata [[DES_LAM_A:.*]]}
-// CHECK: [[CON_LAM_A]] = metadata {{.*}}[[LAM_A]], metadata !"operator()", metadata !"operator()"{{.*}}[ DW_TAG_subprogram ]
-// CHECK: [[DES_LAM_A]] = metadata {{.*}}[[LAM_A]], metadata !"~", metadata !"~"{{.*}}[ DW_TAG_subprogram ]
+// CHECK: [[CON_LAM_A]] = {{.*}}, metadata [[LAM_A]], {{.*}} [ DW_TAG_subprogram ] [line [[A_LINE]]] [operator()]
+// CHECK: [[DES_LAM_A]] = {{.*}}, metadata [[LAM_A]], {{.*}} [ DW_TAG_subprogram ] [line [[A_LINE]]] [~]
// CVAR:
-// CHECK: metadata !{i32 {{.*}}, i32 0, null, metadata !"cvar", metadata !"cvar", metadata !"", metadata [[FILE]], i32 [[CVAR_LINE:.*]], metadata ![[CVAR_T:.*]], i32 0, i32 1, %class.anon.0* @cvar, null} ; [ DW_TAG_variable ]
-// CHECK: [[CVAR_T]] = metadata !{i32 {{.*}}, null, metadata !"", metadata [[FILE]], i32 [[CVAR_LINE]], i64 8, i64 8, i32 0, i32 0, null, metadata ![[CVAR_ARGS:.*]], i32 0, null, null} ; [ DW_TAG_class_type ]
+// CHECK: {{.*}} metadata [[CVAR_T:![0-9]*]], {{.*}} ; [ DW_TAG_variable ] [cvar] [line [[CVAR_LINE:[0-9]*]]]
+// CHECK: [[CVAR_T]] = {{.*}}, metadata ![[CVAR_ARGS:.*]], i32 0, null, null} ; [ DW_TAG_class_type ] [line [[CVAR_LINE]],
// CHECK: [[CVAR_ARGS]] = metadata !{metadata !{{.*}}, metadata !{{.*}}, metadata !{{.*}}}
// VAR:
-// CHECK: metadata !{i32 {{.*}}, i32 0, null, metadata !"var", metadata !"var", metadata !"", metadata [[FILE]], i32 [[VAR_LINE:.*]], metadata ![[VAR_T:.*]], i32 1, i32 1, %class.anon* @var, null} ; [ DW_TAG_variable ]
-// CHECK: [[VAR_T]] = metadata !{i32 {{.*}}, null, metadata !"", metadata [[FILE]], i32 [[VAR_LINE]], i64 8, i64 8, i32 0, i32 0, null, metadata ![[VAR_ARGS:.*]], i32 0, null, null} ; [ DW_TAG_class_type ]
+// CHECK: {{.*}} metadata [[VAR_T:![0-9]*]], {{.*}} ; [ DW_TAG_variable ] [var] [line [[VAR_LINE:[0-9]*]]]
+// CHECK: [[VAR_T]] = {{.*}}, metadata [[VAR_ARGS:![0-9]*]], i32 0, null, null} ; [ DW_TAG_class_type ] [line [[VAR_LINE]],
// CHECK: [[VAR_ARGS]] = metadata !{metadata !{{.*}}, metadata !{{.*}}, metadata !{{.*}}}
diff --git a/test/CodeGenCXX/debug-lambda-this.cpp b/test/CodeGenCXX/debug-lambda-this.cpp
index 0844da0a81..e7155e76a1 100644
--- a/test/CodeGenCXX/debug-lambda-this.cpp
+++ b/test/CodeGenCXX/debug-lambda-this.cpp
@@ -12,4 +12,4 @@ int D::d(int x) {
}();
}
-// CHECK: metadata !{i32 {{.*}}, metadata !"this", metadata !{{.*}}, i32 11, i64 64, i64 64, i64 0, i32 1, metadata !{{.*}}} ; [ DW_TAG_member ] [this] [line 11, size 64, align 64, offset 0] [private] [from ]
+// CHECK: {{.*}} [ DW_TAG_member ] [this] [line 11, size 64, align 64, offset 0] [private] [from ]
diff --git a/test/CodeGenCXX/extern-c.cpp b/test/CodeGenCXX/extern-c.cpp
index a8c4f0cdbd..5899b9348c 100644
--- a/test/CodeGenCXX/extern-c.cpp
+++ b/test/CodeGenCXX/extern-c.cpp
@@ -36,3 +36,30 @@ namespace test2 {
extern "C" X test2_b;
X test2_b;
}
+
+extern "C" {
+ static int unused_var;
+ static int unused_fn() { return 0; }
+
+ __attribute__((used)) static int internal_var;
+ __attribute__((used)) static int internal_fn() { return 0; }
+
+ __attribute__((used)) static int duplicate_internal_var;
+ __attribute__((used)) static int duplicate_internal_fn() { return 0; }
+
+ namespace N {
+ __attribute__((used)) static int duplicate_internal_var;
+ __attribute__((used)) static int duplicate_internal_fn() { return 0; }
+ }
+
+ // CHECK: @llvm.used = appending global {{.*}} @internal_var {{.*}} @internal_fn
+
+ // CHECK-NOT: @unused
+ // CHECK-NOT: @duplicate_internal
+ // CHECK: @internal_var = alias internal i32* @_Z12internal_var
+ // CHECK-NOT: @unused
+ // CHECK-NOT: @duplicate_internal
+ // CHECK: @internal_fn = alias internal i32 ()* @_Z11internal_fnv
+ // CHECK-NOT: @unused
+ // CHECK-NOT: @duplicate_internal
+}
diff --git a/test/CodeGenCXX/inheriting-constructor.cpp b/test/CodeGenCXX/inheriting-constructor.cpp
index a99840290a..0f39784929 100644
--- a/test/CodeGenCXX/inheriting-constructor.cpp
+++ b/test/CodeGenCXX/inheriting-constructor.cpp
@@ -1,11 +1,28 @@
// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
-// XFAIL: *
-
// PR12219
struct A { A(int); virtual ~A(); };
struct B : A { using A::A; ~B(); };
B::~B() {}
+
+B b(123);
+
+struct C { template<typename T> C(T); };
+struct D : C { using C::C; };
+D d(123);
+
// CHECK: define void @_ZN1BD0Ev
// CHECK: define void @_ZN1BD1Ev
// CHECK: define void @_ZN1BD2Ev
+
+// CHECK: define linkonce_odr void @_ZN1BC1Ei(
+// CHECK: call void @_ZN1BC2Ei(
+
+// CHECK: define linkonce_odr void @_ZN1DC1IiEET_(
+// CHECK: call void @_ZN1DC2IiEET_(
+
+// CHECK: define linkonce_odr void @_ZN1DC2IiEET_(
+// CHECK: call void @_ZN1CC2IiEET_(
+
+// CHECK: define linkonce_odr void @_ZN1BC2Ei(
+// CHECK: call void @_ZN1AC2Ei(
diff --git a/test/CodeGenCXX/linetable-cleanup.cpp b/test/CodeGenCXX/linetable-cleanup.cpp
new file mode 100644
index 0000000000..4077af6d8e
--- /dev/null
+++ b/test/CodeGenCXX/linetable-cleanup.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -emit-llvm -g -triple x86_64-apple-darwin10 %s -o - | FileCheck %s
+
+// Check the line numbers for cleanup code with EH in combinatin with
+// simple return expressions.
+
+// CHECK: define {{.*}}foo
+// CHECK: call void @_ZN1CD1Ev(%class.C* {{.*}}), !dbg ![[CLEANUP:[0-9]+]]
+// CHECK: ret i32 0, !dbg ![[RET:[0-9]+]]
+
+class C {
+public:
+ ~C() {}
+ int i;
+};
+
+int foo()
+{
+ C c;
+ c.i = 42;
+ // This breakpoint should be at/before the cleanup code.
+ // CHECK: ![[CLEANUP]] = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null}
+ return 0;
+ // CHECK: ![[RET]] = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null}
+}
diff --git a/test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp b/test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp
index 0ac9b3f121..d03ba52649 100644
--- a/test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp
+++ b/test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp
@@ -60,6 +60,51 @@ void foo_pcrbd(const char * volatile* x) {}
void foo_pcrcd(volatile char * volatile* x) {}
// CHECK: "\01?foo_pcrcd@@YAXPCRCD@Z"
+void foo_aad(char &x) {}
+// CHECK: "\01?foo_aad@@YAXAAD@Z"
+
+void foo_abd(const char &x) {}
+// CHECK: "\01?foo_abd@@YAXABD@Z"
+
+void foo_aapad(char *&x) {}
+// CHECK: "\01?foo_aapad@@YAXAAPAD@Z"
+
+void foo_aapbd(const char *&x) {}
+// CHECK: "\01?foo_aapbd@@YAXAAPBD@Z"
+
+void foo_abqad(char * const &x) {}
+// CHECK: "\01?foo_abqad@@YAXABQAD@Z"
+
+void foo_abqbd(const char * const &x) {}
+// CHECK: "\01?foo_abqbd@@YAXABQBD@Z"
+
+void foo_aay144h(int (&x)[5][5]) {}
+// CHECK: "\01?foo_aay144h@@YAXAAY144H@Z"
+
+void foo_aay144cbh(const int (&x)[5][5]) {}
+// CHECK: "\01?foo_aay144cbh@@YAXAAY144$$CBH@Z"
+
+void foo_qay144h(int (&&x)[5][5]) {}
+// CHECK: "\01?foo_qay144h@@YAX$$QAY144H@Z"
+
+void foo_qay144cbh(const int (&&x)[5][5]) {}
+// CHECK: "\01?foo_qay144cbh@@YAX$$QAY144$$CBH@Z"
+
+void foo_p6ahxz(int x()) {}
+// CHECK: "\01?foo_p6ahxz@@YAXP6AHXZ@Z"
+
+void foo_a6ahxz(int (&x)()) {}
+// CHECK: "\01?foo_a6ahxz@@YAXA6AHXZ@Z"
+
+void foo_q6ahxz(int (&&x)()) {}
+// CHECK: "\01?foo_q6ahxz@@YAX$$Q6AHXZ@Z"
+
+void foo_qay04h(int x[5][5]) {}
+// CHECK: "\01?foo_qay04h@@YAXQAY04H@Z"
+
+void foo_qay04cbh(const int x[5][5]) {}
+// CHECK: "\01?foo_qay04cbh@@YAXQAY04$$CBH@Z"
+
typedef double Vector[3];
void foo(Vector*) {}
diff --git a/test/CodeGenCXX/mangle-ms-return-qualifiers.cpp b/test/CodeGenCXX/mangle-ms-return-qualifiers.cpp
index 63bc4a9eb3..87e04c645e 100644
--- a/test/CodeGenCXX/mangle-ms-return-qualifiers.cpp
+++ b/test/CodeGenCXX/mangle-ms-return-qualifiers.cpp
@@ -155,6 +155,15 @@ const volatile struct S* f5() { return 0; }
struct S& f6() { return *(struct S*)0; }
// CHECK: "\01?f6@@YAAAUS@@XZ"
+struct S* const f7() { return 0; }
+// CHECK: "\01?f7@@YAQAUS@@XZ"
+
+int S::* f8() { return 0; }
+// CHECK: "\01?f8@@YAPQS@@HXZ"
+
+int S::* const f9() { return 0; }
+// CHECK: "\01?f9@@YAQQS@@HXZ"
+
typedef int (*function_pointer)(int);
function_pointer g1() { return 0; }
diff --git a/test/CodeGenCXX/mangle-ms-templates.cpp b/test/CodeGenCXX/mangle-ms-templates.cpp
index e16fe936bc..10e68248dc 100644
--- a/test/CodeGenCXX/mangle-ms-templates.cpp
+++ b/test/CodeGenCXX/mangle-ms-templates.cpp
@@ -3,7 +3,7 @@
template<typename T>
class Class {
public:
- void method() {}
+ Class() {}
};
class Typename { };
@@ -32,12 +32,30 @@ class BoolTemplate<true> {
void template_mangling() {
Class<Typename> c1;
- c1.method();
-// CHECK: call {{.*}} @"\01?method@?$Class@VTypename@@@@QAEXXZ"
+// CHECK: call {{.*}} @"\01??0?$Class@VTypename@@@@QAE@XZ"
+
+ Class<const Typename> c1_const;
+// CHECK: call {{.*}} @"\01??0?$Class@$$CBVTypename@@@@QAE@XZ"
+ Class<volatile Typename> c1_volatile;
+// CHECK: call {{.*}} @"\01??0?$Class@$$CCVTypename@@@@QAE@XZ"
+ Class<const volatile Typename> c1_cv;
+// CHECK: call {{.*}} @"\01??0?$Class@$$CDVTypename@@@@QAE@XZ"
Class<Nested<Typename> > c2;
- c2.method();
-// CHECK: call {{.*}} @"\01?method@?$Class@V?$Nested@VTypename@@@@@@QAEXXZ"
+// CHECK: call {{.*}} @"\01??0?$Class@V?$Nested@VTypename@@@@@@QAE@XZ"
+
+ Class<int * const> c_intpc;
+// CHECK: call {{.*}} @"\01??0?$Class@QAH@@QAE@XZ"
+ Class<int()> c_ft;
+// CHECK: call {{.*}} @"\01??0?$Class@$$A6AHXZ@@QAE@XZ"
+ Class<int[]> c_inti;
+// CHECK: call {{.*}} @"\01??0?$Class@$$BY0A@H@@QAE@XZ"
+ Class<int[5]> c_int5;
+// CHECK: call {{.*}} @"\01??0?$Class@$$BY04H@@QAE@XZ"
+ Class<const int[5]> c_intc5;
+// CHECK: call {{.*}} @"\01??0?$Class@$$BY04$$CBH@@QAE@XZ"
+ Class<int * const[5]> c_intpc5;
+// CHECK: call {{.*}} @"\01??0?$Class@$$BY04QAH@@QAE@XZ"
BoolTemplate<false> _false;
// CHECK: call {{.*}} @"\01??0?$BoolTemplate@$0A@@@QAE@XZ"
@@ -78,3 +96,16 @@ namespace space {
void use() {
space::foo(42);
}
+
+// PR13455
+typedef void (*FunctionPointer)(void);
+
+template <FunctionPointer function>
+void FunctionPointerTemplate() {
+ function();
+}
+
+void spam() {
+ FunctionPointerTemplate<spam>();
+// CHECK: "\01??$FunctionPointerTemplate@$1?spam@@YAXXZ@@YAXXZ"
+}
diff --git a/test/CodeGenCXX/mangle-ms-vector-types.cpp b/test/CodeGenCXX/mangle-ms-vector-types.cpp
new file mode 100644
index 0000000000..64cb7250a4
--- /dev/null
+++ b/test/CodeGenCXX/mangle-ms-vector-types.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -fms-extensions -ffreestanding -target-feature +avx -emit-llvm %s -o - -cxx-abi microsoft -triple=i686-pc-win32 | FileCheck %s
+
+#include <xmmintrin.h>
+#include <emmintrin.h>
+#include <immintrin.h>
+
+void foo64(__m64) {}
+// CHECK: define void @"\01?foo64@@YAXT__m64@@@Z"
+
+void foo128(__m128) {}
+// CHECK: define void @"\01?foo128@@YAXT__m128@@@Z"
+
+void foo128d(__m128d) {}
+// CHECK: define void @"\01?foo128d@@YAXU__m128d@@@Z"
+
+void foo128i(__m128i) {}
+// CHECK: define void @"\01?foo128i@@YAXT__m128i@@@Z"
+
+void foo256(__m256) {}
+// CHECK: define void @"\01?foo256@@YAXT__m256@@@Z"
+
+void foo256d(__m256d) {}
+// CHECK: define void @"\01?foo256d@@YAXU__m256d@@@Z"
+
+void foo256i(__m256i) {}
+// CHECK: define void @"\01?foo256i@@YAXT__m256i@@@Z"
+
+// We have a custom mangling for vector types not standardized by Intel.
+void foov8hi(__v8hi) {}
+// CHECK: define void @"\01?foov8hi@@YAXT__clang_vec8_F@@@Z"
+
+// Clang does not support vectors of complex types, so we can't test the
+// mangling of them.
diff --git a/test/CodeGenCXX/mangle-ms.cpp b/test/CodeGenCXX/mangle-ms.cpp
index 6441d67a75..1b98a84823 100644
--- a/test/CodeGenCXX/mangle-ms.cpp
+++ b/test/CodeGenCXX/mangle-ms.cpp
@@ -17,11 +17,8 @@
// CHECK: @"\01?l@@3P8foo@@AEHH@ZA"
// CHECK: @"\01?color1@@3PANA"
// CHECK: @"\01?color2@@3QBNB"
-
-// FIXME: The following three tests currently fail, see http://llvm.org/PR13182
-// Replace "CHECK-NOT" with "CHECK" when it is fixed.
-// CHECK-NOT: @"\01?color3@@3QAY02$$CBNA"
-// CHECK-NOT: @"\01?color4@@3QAY02$$CBNA"
+// CHECK: @"\01?color3@@3QAY02$$CBNA"
+// CHECK: @"\01?color4@@3QAY02$$CBNA"
int a;
diff --git a/test/CodeGenCXX/microsoft-abi-member-pointers.cpp b/test/CodeGenCXX/microsoft-abi-member-pointers.cpp
new file mode 100644
index 0000000000..3fffc9d72c
--- /dev/null
+++ b/test/CodeGenCXX/microsoft-abi-member-pointers.cpp
@@ -0,0 +1,363 @@
+// RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s
+
+struct B1 {
+ void foo();
+ int b;
+};
+struct B2 {
+ void foo();
+};
+struct Single : B1 {
+ void foo();
+};
+struct Multiple : B1, B2 {
+ void foo();
+};
+struct Virtual : virtual B1 {
+ int v;
+ void foo();
+};
+
+struct POD {
+ int a;
+ int b;
+};
+
+struct Polymorphic {
+ virtual void myVirtual();
+ int a;
+ int b;
+};
+
+// This class uses the virtual inheritance model, yet its vbptr offset is not 0.
+// We still use zero for the null field offset, despite it being a valid field
+// offset.
+struct NonZeroVBPtr : POD, Virtual {
+ int n;
+};
+
+struct Unspecified;
+
+// Check that we can lower the LLVM types and get the null initializers right.
+int Single ::*s_d_memptr;
+int Polymorphic::*p_d_memptr;
+int Multiple ::*m_d_memptr;
+int Virtual ::*v_d_memptr;
+int NonZeroVBPtr::*n_d_memptr;
+int Unspecified::*u_d_memptr;
+// CHECK: @"\01?s_d_memptr@@3PQSingle@@HA" = global i32 -1, align 4
+// CHECK: @"\01?p_d_memptr@@3PQPolymorphic@@HA" = global i32 0, align 4
+// CHECK: @"\01?m_d_memptr@@3PQMultiple@@HA" = global i32 -1, align 4
+// CHECK: @"\01?v_d_memptr@@3PQVirtual@@HA" = global { i32, i32 }
+// CHECK: { i32 0, i32 -1 }, align 4
+// CHECK: @"\01?n_d_memptr@@3PQNonZeroVBPtr@@HA" = global { i32, i32 }
+// CHECK: { i32 0, i32 -1 }, align 4
+// CHECK: @"\01?u_d_memptr@@3PQUnspecified@@HA" = global { i32, i32, i32 }
+// CHECK: { i32 0, i32 0, i32 -1 }, align 4
+
+void (Single ::*s_f_memptr)();
+void (Multiple::*m_f_memptr)();
+void (Virtual ::*v_f_memptr)();
+// CHECK: @"\01?s_f_memptr@@3P8Single@@AEXXZA" = global i8* null, align 4
+// CHECK: @"\01?m_f_memptr@@3P8Multiple@@AEXXZA" = global { i8*, i32 } zeroinitializer, align 4
+// CHECK: @"\01?v_f_memptr@@3P8Virtual@@AEXXZA" = global { i8*, i32, i32 } zeroinitializer, align 4
+
+// We can define Unspecified after locking in the inheritance model.
+struct Unspecified : Virtual {
+ void foo();
+ int u;
+};
+
+struct UnspecWithVBPtr;
+int UnspecWithVBPtr::*forceUnspecWithVBPtr;
+struct UnspecWithVBPtr : B1, virtual B2 {
+ int u;
+ void foo();
+};
+
+// Test emitting non-virtual member pointers in a non-constexpr setting.
+void EmitNonVirtualMemberPointers() {
+ void (Single ::*s_f_memptr)() = &Single::foo;
+ void (Multiple ::*m_f_memptr)() = &Multiple::foo;
+ void (Virtual ::*v_f_memptr)() = &Virtual::foo;
+ void (Unspecified::*u_f_memptr)() = &Unspecified::foo;
+ void (UnspecWithVBPtr::*u2_f_memptr)() = &UnspecWithVBPtr::foo;
+// CHECK: define void @"\01?EmitNonVirtualMemberPointers@@YAXXZ"() #0 {
+// CHECK: alloca i8*, align 4
+// CHECK: alloca { i8*, i32 }, align 4
+// CHECK: alloca { i8*, i32, i32 }, align 4
+// CHECK: alloca { i8*, i32, i32, i32 }, align 4
+// CHECK: store i8* bitcast (void (%{{.*}}*)* @"\01?foo@Single@@QAEXXZ" to i8*), i8** %{{.*}}, align 4
+// CHECK: store { i8*, i32 }
+// CHECK: { i8* bitcast (void (%{{.*}}*)* @"\01?foo@Multiple@@QAEXXZ" to i8*), i32 0 },
+// CHECK: { i8*, i32 }* %{{.*}}, align 4
+// CHECK: store { i8*, i32, i32 }
+// CHECK: { i8* bitcast (void (%{{.*}}*)* @"\01?foo@Virtual@@QAEXXZ" to i8*), i32 0, i32 0 },
+// CHECK: { i8*, i32, i32 }* %{{.*}}, align 4
+// CHECK: store { i8*, i32, i32, i32 }
+// CHECK: { i8* bitcast (void (%{{.*}}*)* @"\01?foo@Unspecified@@QAEXXZ" to i8*), i32 0, i32 0, i32 0 },
+// CHECK: { i8*, i32, i32, i32 }* %{{.*}}, align 4
+// CHECK: store { i8*, i32, i32, i32 }
+// CHECK: { i8* bitcast (void (%{{.*}}*)* @"\01?foo@UnspecWithVBPtr@@QAEXXZ" to i8*),
+// CHECK: i32 0, i32 4, i32 0 },
+// CHECK: { i8*, i32, i32, i32 }* %{{.*}}, align 4
+// CHECK: ret void
+// CHECK: }
+}
+
+void podMemPtrs() {
+ int POD::*memptr;
+ memptr = &POD::a;
+ memptr = &POD::b;
+ if (memptr)
+ memptr = 0;
+// Check that member pointers use the right offsets and that null is -1.
+// CHECK: define void @"\01?podMemPtrs@@YAXXZ"() #0 {
+// CHECK: %[[memptr:.*]] = alloca i32, align 4
+// CHECK-NEXT: store i32 0, i32* %[[memptr]], align 4
+// CHECK-NEXT: store i32 4, i32* %[[memptr]], align 4
+// CHECK-NEXT: %[[memptr_val:.*]] = load i32* %[[memptr]], align 4
+// CHECK-NEXT: %{{.*}} = icmp ne i32 %[[memptr_val]], -1
+// CHECK-NEXT: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}
+// CHECK: store i32 -1, i32* %[[memptr]], align 4
+// CHECK: ret void
+// CHECK: }
+}
+
+void polymorphicMemPtrs() {
+ int Polymorphic::*memptr;
+ memptr = &Polymorphic::a;
+ memptr = &Polymorphic::b;
+ if (memptr)
+ memptr = 0;
+// Member pointers for polymorphic classes include the vtable slot in their
+// offset and use 0 to represent null.
+// CHECK: define void @"\01?polymorphicMemPtrs@@YAXXZ"() #0 {
+// CHECK: %[[memptr:.*]] = alloca i32, align 4
+// CHECK-NEXT: store i32 4, i32* %[[memptr]], align 4
+// CHECK-NEXT: store i32 8, i32* %[[memptr]], align 4
+// CHECK-NEXT: %[[memptr_val:.*]] = load i32* %[[memptr]], align 4
+// CHECK-NEXT: %{{.*}} = icmp ne i32 %[[memptr_val]], 0
+// CHECK-NEXT: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}
+// CHECK: store i32 0, i32* %[[memptr]], align 4
+// CHECK: ret void
+// CHECK: }
+}
+
+bool nullTestDataUnspecified(int Unspecified::*mp) {
+ return mp;
+// CHECK: define zeroext i1 @"\01?nullTestDataUnspecified@@YA_NPQUnspecified@@H@Z"{{.*}} {
+// CHECK: %{{.*}} = load { i32, i32, i32 }* %{{.*}}, align 4
+// CHECK: store { i32, i32, i32 } {{.*}} align 4
+// CHECK: %[[mp:.*]] = load { i32, i32, i32 }* %{{.*}}, align 4
+// CHECK: %[[mp0:.*]] = extractvalue { i32, i32, i32 } %[[mp]], 0
+// CHECK: %[[cmp0:.*]] = icmp ne i32 %[[mp0]], 0
+// CHECK: %[[mp1:.*]] = extractvalue { i32, i32, i32 } %[[mp]], 1
+// CHECK: %[[cmp1:.*]] = icmp ne i32 %[[mp1]], 0
+// CHECK: %[[and0:.*]] = and i1 %[[cmp0]], %[[cmp1]]
+// CHECK: %[[mp2:.*]] = extractvalue { i32, i32, i32 } %[[mp]], 2
+// CHECK: %[[cmp2:.*]] = icmp ne i32 %[[mp2]], -1
+// CHECK: %[[and1:.*]] = and i1 %[[and0]], %[[cmp2]]
+// CHECK: ret i1 %[[and1]]
+// CHECK: }
+}
+
+bool nullTestFunctionUnspecified(void (Unspecified::*mp)()) {
+ return mp;
+// CHECK: define zeroext i1 @"\01?nullTestFunctionUnspecified@@YA_NP8Unspecified@@AEXXZ@Z"{{.*}} {
+// CHECK: %{{.*}} = load { i8*, i32, i32, i32 }* %{{.*}}, align 4
+// CHECK: store { i8*, i32, i32, i32 } {{.*}} align 4
+// CHECK: %[[mp:.*]] = load { i8*, i32, i32, i32 }* %{{.*}}, align 4
+// CHECK: %[[mp0:.*]] = extractvalue { i8*, i32, i32, i32 } %[[mp]], 0
+// CHECK: %[[cmp0:.*]] = icmp ne i8* %[[mp0]], null
+// CHECK: ret i1 %[[cmp0]]
+// CHECK: }
+}
+
+int loadDataMemberPointerVirtual(Virtual *o, int Virtual::*memptr) {
+ return o->*memptr;
+// Test that we can unpack this aggregate member pointer and load the member
+// data pointer.
+// CHECK: define i32 @"\01?loadDataMemberPointerVirtual@@YAHPAUVirtual@@PQ1@H@Z"{{.*}} {
+// CHECK: %[[o:.*]] = load %{{.*}}** %{{.*}}, align 4
+// CHECK: %[[memptr:.*]] = load { i32, i32 }* %{{.*}}, align 4
+// CHECK: %[[memptr0:.*]] = extractvalue { i32, i32 } %[[memptr:.*]], 0
+// CHECK: %[[memptr1:.*]] = extractvalue { i32, i32 } %[[memptr:.*]], 1
+// CHECK: %[[v6:.*]] = bitcast %{{.*}}* %[[o]] to i8*
+// CHECK: %[[vbptr:.*]] = getelementptr inbounds i8* %[[v6]], i32 0
+// CHECK: %[[vbptr_a:.*]] = bitcast i8* %[[vbptr]] to i8**
+// CHECK: %[[vbtable:.*]] = load i8** %[[vbptr_a:.*]]
+// CHECK: %[[v7:.*]] = getelementptr inbounds i8* %[[vbtable]], i32 %[[memptr1]]
+// CHECK: %[[v8:.*]] = bitcast i8* %[[v7]] to i32*
+// CHECK: %[[vbase_offs:.*]] = load i32* %[[v8]]
+// CHECK: %[[v10:.*]] = getelementptr inbounds i8* %[[vbptr]], i32 %[[vbase_offs]]
+// CHECK: %[[offset:.*]] = getelementptr inbounds i8* %[[v10]], i32 %[[memptr0]]
+// CHECK: %[[v11:.*]] = bitcast i8* %[[offset]] to i32*
+// CHECK: %[[v12:.*]] = load i32* %[[v11]]
+// CHECK: ret i32 %[[v12]]
+// CHECK: }
+}
+
+int loadDataMemberPointerUnspecified(Unspecified *o, int Unspecified::*memptr) {
+ return o->*memptr;
+// Test that we can unpack this aggregate member pointer and load the member
+// data pointer.
+// CHECK: define i32 @"\01?loadDataMemberPointerUnspecified@@YAHPAUUnspecified@@PQ1@H@Z"{{.*}} {
+// CHECK: %[[o:.*]] = load %{{.*}}** %{{.*}}, align 4
+// CHECK: %[[memptr:.*]] = load { i32, i32, i32 }* %{{.*}}, align 4
+// CHECK: %[[memptr0:.*]] = extractvalue { i32, i32, i32 } %[[memptr:.*]], 0
+// CHECK: %[[memptr1:.*]] = extractvalue { i32, i32, i32 } %[[memptr:.*]], 1
+// CHECK: %[[memptr2:.*]] = extractvalue { i32, i32, i32 } %[[memptr:.*]], 2
+// CHECK: %[[base:.*]] = bitcast %{{.*}}* %[[o]] to i8*
+// CHECK: %[[is_vbase:.*]] = icmp ne i32 %[[memptr2]], 0
+// CHECK: br i1 %[[is_vbase]], label %[[vadjust:.*]], label %[[skip:.*]]
+//
+// CHECK: [[vadjust]]
+// CHECK: %[[vbptr:.*]] = getelementptr inbounds i8* %[[base]], i32 %[[memptr1]]
+// CHECK: %[[vbptr_a:.*]] = bitcast i8* %[[vbptr]] to i8**
+// CHECK: %[[vbtable:.*]] = load i8** %[[vbptr_a:.*]]
+// CHECK: %[[v7:.*]] = getelementptr inbounds i8* %[[vbtable]], i32 %[[memptr2]]
+// CHECK: %[[v8:.*]] = bitcast i8* %[[v7]] to i32*
+// CHECK: %[[vbase_offs:.*]] = load i32* %[[v8]]
+// CHECK: %[[base_adj:.*]] = getelementptr inbounds i8* %[[vbptr]], i32 %[[vbase_offs]]
+//
+// CHECK: [[skip]]
+// CHECK: %[[new_base:.*]] = phi i8* [ %[[base]], %{{.*}} ], [ %[[base_adj]], %[[vadjust]] ]
+// CHECK: %[[offset:.*]] = getelementptr inbounds i8* %[[new_base]], i32 %[[memptr0]]
+// CHECK: %[[v11:.*]] = bitcast i8* %[[offset]] to i32*
+// CHECK: %[[v12:.*]] = load i32* %[[v11]]
+// CHECK: ret i32 %[[v12]]
+// CHECK: }
+}
+
+void callMemberPointerSingle(Single *o, void (Single::*memptr)()) {
+ (o->*memptr)();
+// Just look for an indirect thiscall.
+// CHECK: define void @"\01?callMemberPointerSingle@@{{.*}} #0 {
+// CHECK: call x86_thiscallcc void %{{.*}}(%{{.*}} %{{.*}})
+// CHECK: ret void
+// CHECK: }
+}
+
+void callMemberPointerMultiple(Multiple *o, void (Multiple::*memptr)()) {
+ (o->*memptr)();
+// CHECK: define void @"\01?callMemberPointerMultiple@@{{.*}} #0 {
+// CHECK: %[[memptr0:.*]] = extractvalue { i8*, i32 } %{{.*}}, 0
+// CHECK: %[[memptr1:.*]] = extractvalue { i8*, i32 } %{{.*}}, 1
+// CHECK: %[[this_adjusted:.*]] = getelementptr inbounds i8* %{{.*}}, i32 %[[memptr1]]
+// CHECK: %[[this:.*]] = bitcast i8* %[[this_adjusted]] to {{.*}}
+// CHECK: %[[fptr:.*]] = bitcast i8* %[[memptr0]] to {{.*}}
+// CHECK: call x86_thiscallcc void %[[fptr]](%{{.*}} %[[this]])
+// CHECK: ret void
+// CHECK: }
+}
+
+void callMemberPointerVirtualBase(Virtual *o, void (Virtual::*memptr)()) {
+ (o->*memptr)();
+// This shares a lot with virtual data member pointers.
+// CHECK: define void @"\01?callMemberPointerVirtualBase@@{{.*}} #0 {
+// CHECK: %[[memptr0:.*]] = extractvalue { i8*, i32, i32 } %{{.*}}, 0
+// CHECK: %[[memptr1:.*]] = extractvalue { i8*, i32, i32 } %{{.*}}, 1
+// CHECK: %[[memptr2:.*]] = extractvalue { i8*, i32, i32 } %{{.*}}, 2
+// CHECK: %[[vbptr:.*]] = getelementptr inbounds i8* %{{.*}}, i32 0
+// CHECK: %[[vbptr_a:.*]] = bitcast i8* %[[vbptr]] to i8**
+// CHECK: %[[vbtable:.*]] = load i8** %[[vbptr_a:.*]]
+// CHECK: %[[v7:.*]] = getelementptr inbounds i8* %[[vbtable]], i32 %[[memptr2]]
+// CHECK: %[[v8:.*]] = bitcast i8* %[[v7]] to i32*
+// CHECK: %[[vbase_offs:.*]] = load i32* %[[v8]]
+// CHECK: %[[v10:.*]] = getelementptr inbounds i8* %[[vbptr]], i32 %[[vbase_offs]]
+// CHECK: %[[this_adjusted:.*]] = getelementptr inbounds i8* %[[v10]], i32 %[[memptr1]]
+// CHECK: %[[fptr:.*]] = bitcast i8* %[[memptr0]] to void ({{.*}})
+// CHECK: %[[this:.*]] = bitcast i8* %[[this_adjusted]] to {{.*}}
+// CHECK: call x86_thiscallcc void %[[fptr]](%{{.*}} %[[this]])
+// CHECK: ret void
+// CHECK: }
+}
+
+bool compareSingleFunctionMemptr(void (Single::*l)(), void (Single::*r)()) {
+ return l == r;
+// Should only be one comparison here.
+// CHECK: define zeroext i1 @"\01?compareSingleFunctionMemptr@@YA_NP8Single@@AEXXZ0@Z"{{.*}} {
+// CHECK-NOT: icmp
+// CHECK: %[[r:.*]] = icmp eq
+// CHECK-NOT: icmp
+// CHECK: ret i1 %[[r]]
+// CHECK: }
+}
+
+bool compareNeqSingleFunctionMemptr(void (Single::*l)(), void (Single::*r)()) {
+ return l != r;
+// Should only be one comparison here.
+// CHECK: define zeroext i1 @"\01?compareNeqSingleFunctionMemptr@@YA_NP8Single@@AEXXZ0@Z"{{.*}} {
+// CHECK-NOT: icmp
+// CHECK: %[[r:.*]] = icmp ne
+// CHECK-NOT: icmp
+// CHECK: ret i1 %[[r]]
+// CHECK: }
+}
+
+bool unspecFuncMemptrEq(void (Unspecified::*l)(), void (Unspecified::*r)()) {
+ return l == r;
+// CHECK: define zeroext i1 @"\01?unspecFuncMemptrEq@@YA_NP8Unspecified@@AEXXZ0@Z"{{.*}} {
+// CHECK: %[[lhs0:.*]] = extractvalue { i8*, i32, i32, i32 } %[[l:.*]], 0
+// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[r:.*]], 0
+// CHECK: %[[cmp0:.*]] = icmp eq i8* %[[lhs0]], %{{.*}}
+// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[l]], 1
+// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[r]], 1
+// CHECK: %[[cmp1:.*]] = icmp eq i32
+// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[l]], 2
+// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[r]], 2
+// CHECK: %[[cmp2:.*]] = icmp eq i32
+// CHECK: %[[res12:.*]] = and i1 %[[cmp1]], %[[cmp2]]
+// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[l]], 3
+// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[r]], 3
+// CHECK: %[[cmp3:.*]] = icmp eq i32
+// CHECK: %[[res123:.*]] = and i1 %[[res12]], %[[cmp3]]
+// CHECK: %[[iszero:.*]] = icmp eq i8* %[[lhs0]], null
+// CHECK: %[[bits_or_null:.*]] = or i1 %[[res123]], %[[iszero]]
+// CHECK: %{{.*}} = and i1 %[[bits_or_null]], %[[cmp0]]
+// CHECK: ret i1 %{{.*}}
+// CHECK: }
+}
+
+bool unspecFuncMemptrNeq(void (Unspecified::*l)(), void (Unspecified::*r)()) {
+ return l != r;
+// CHECK: define zeroext i1 @"\01?unspecFuncMemptrNeq@@YA_NP8Unspecified@@AEXXZ0@Z"{{.*}} {
+// CHECK: %[[lhs0:.*]] = extractvalue { i8*, i32, i32, i32 } %[[l:.*]], 0
+// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[r:.*]], 0
+// CHECK: %[[cmp0:.*]] = icmp ne i8* %[[lhs0]], %{{.*}}
+// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[l]], 1
+// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[r]], 1
+// CHECK: %[[cmp1:.*]] = icmp ne i32
+// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[l]], 2
+// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[r]], 2
+// CHECK: %[[cmp2:.*]] = icmp ne i32
+// CHECK: %[[res12:.*]] = or i1 %[[cmp1]], %[[cmp2]]
+// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[l]], 3
+// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[r]], 3
+// CHECK: %[[cmp3:.*]] = icmp ne i32
+// CHECK: %[[res123:.*]] = or i1 %[[res12]], %[[cmp3]]
+// CHECK: %[[iszero:.*]] = icmp ne i8* %[[lhs0]], null
+// CHECK: %[[bits_or_null:.*]] = and i1 %[[res123]], %[[iszero]]
+// CHECK: %{{.*}} = or i1 %[[bits_or_null]], %[[cmp0]]
+// CHECK: ret i1 %{{.*}}
+// CHECK: }
+}
+
+bool unspecDataMemptrEq(int Unspecified::*l, int Unspecified::*r) {
+ return l == r;
+// CHECK: define zeroext i1 @"\01?unspecDataMemptrEq@@YA_NPQUnspecified@@H0@Z"{{.*}} {
+// CHECK: extractvalue { i32, i32, i32 } %{{.*}}, 0
+// CHECK: extractvalue { i32, i32, i32 } %{{.*}}, 0
+// CHECK: icmp eq i32
+// CHECK: extractvalue { i32, i32, i32 } %{{.*}}, 1
+// CHECK: extractvalue { i32, i32, i32 } %{{.*}}, 1
+// CHECK: icmp eq i32
+// CHECK: extractvalue { i32, i32, i32 } %{{.*}}, 2
+// CHECK: extractvalue { i32, i32, i32 } %{{.*}}, 2
+// CHECK: icmp eq i32
+// CHECK: and i1
+// CHECK: and i1
+// CHECK: ret i1
+// CHECK: }
+}
diff --git a/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp b/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
new file mode 100644
index 0000000000..060c172858
--- /dev/null
+++ b/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
@@ -0,0 +1,169 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-linux | FileCheck -check-prefix LINUX %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 -cxx-abi microsoft | FileCheck -check-prefix WIN32 %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-pc-win32 -cxx-abi microsoft | FileCheck -check-prefix WIN64 %s
+
+struct Empty {};
+
+struct EmptyWithCtor {
+ EmptyWithCtor() {}
+};
+
+struct Small {
+ int x;
+};
+
+// This is a C++11 trivial and standard-layout struct but not a C++03 POD.
+struct SmallCpp11NotCpp03Pod : Empty {
+ int x;
+};
+
+struct SmallWithCtor {
+ SmallWithCtor() {}
+ int x;
+};
+
+struct SmallWithVftable {
+ int x;
+ virtual void foo();
+};
+
+struct Medium {
+ int x, y;
+};
+
+struct MediumWithCopyCtor {
+ MediumWithCopyCtor();
+ MediumWithCopyCtor(const struct MediumWithCopyCtor &);
+ int x, y;
+};
+
+struct Big {
+ int a, b, c, d, e, f;
+};
+
+// Returning structs that fit into a register.
+Small small_return() { return Small(); }
+// LINUX: define void @_Z12small_returnv(%struct.Small* noalias sret %agg.result)
+// WIN32: define i32 @"\01?small_return@@YA?AUSmall@@XZ"()
+// WIN64: define i32 @"\01?small_return@@YA?AUSmall@@XZ"()
+
+Medium medium_return() { return Medium(); }
+// LINUX: define void @_Z13medium_returnv(%struct.Medium* noalias sret %agg.result)
+// WIN32: define i64 @"\01?medium_return@@YA?AUMedium@@XZ"()
+// WIN64: define i64 @"\01?medium_return@@YA?AUMedium@@XZ"()
+
+// Returning structs that fit into a register but are not POD.
+SmallCpp11NotCpp03Pod small_non_pod_return() { return SmallCpp11NotCpp03Pod(); }
+// LINUX: define void @_Z20small_non_pod_returnv(%struct.SmallCpp11NotCpp03Pod* noalias sret %agg.result)
+// WIN32: define void @"\01?small_non_pod_return@@YA?AUSmallCpp11NotCpp03Pod@@XZ"(%struct.SmallCpp11NotCpp03Pod* noalias sret %agg.result)
+// WIN64: define void @"\01?small_non_pod_return@@YA?AUSmallCpp11NotCpp03Pod@@XZ"(%struct.SmallCpp11NotCpp03Pod* noalias sret %agg.result)
+
+SmallWithCtor small_with_ctor_return() { return SmallWithCtor(); }
+// LINUX: define void @_Z22small_with_ctor_returnv(%struct.SmallWithCtor* noalias sret %agg.result)
+// WIN32: define void @"\01?small_with_ctor_return@@YA?AUSmallWithCtor@@XZ"(%struct.SmallWithCtor* noalias sret %agg.result)
+// WIN64: define void @"\01?small_with_ctor_return@@YA?AUSmallWithCtor@@XZ"(%struct.SmallWithCtor* noalias sret %agg.result)
+
+SmallWithVftable small_with_vftable_return() { return SmallWithVftable(); }
+// LINUX: define void @_Z25small_with_vftable_returnv(%struct.SmallWithVftable* noalias sret %agg.result)
+// WIN32: define void @"\01?small_with_vftable_return@@YA?AUSmallWithVftable@@XZ"(%struct.SmallWithVftable* noalias sret %agg.result)
+// WIN64: define void @"\01?small_with_vftable_return@@YA?AUSmallWithVftable@@XZ"(%struct.SmallWithVftable* noalias sret %agg.result)
+
+MediumWithCopyCtor medium_with_copy_ctor_return() { return MediumWithCopyCtor(); }
+// LINUX: define void @_Z28medium_with_copy_ctor_returnv(%struct.MediumWithCopyCtor* noalias sret %agg.result)
+// WIN32: define void @"\01?medium_with_copy_ctor_return@@YA?AUMediumWithCopyCtor@@XZ"(%struct.MediumWithCopyCtor* noalias sret %agg.result)
+// WIN64: define void @"\01?medium_with_copy_ctor_return@@YA?AUMediumWithCopyCtor@@XZ"(%struct.MediumWithCopyCtor* noalias sret %agg.result)
+
+// Returning a large struct that doesn't fit into a register.
+Big big_return() { return Big(); }
+// LINUX: define void @_Z10big_returnv(%struct.Big* noalias sret %agg.result)
+// WIN32: define void @"\01?big_return@@YA?AUBig@@XZ"(%struct.Big* noalias sret %agg.result)
+// WIN64: define void @"\01?big_return@@YA?AUBig@@XZ"(%struct.Big* noalias sret %agg.result)
+
+
+void small_arg(Small s) {}
+// LINUX: define void @_Z9small_arg5Small(%struct.Small* byval align 4 %s)
+// WIN32: define void @"\01?small_arg@@YAXUSmall@@@Z"(%struct.Small* byval align 4 %s)
+// WIN64: define void @"\01?small_arg@@YAXUSmall@@@Z"(i32 %s.coerce)
+
+void medium_arg(Medium s) {}
+// LINUX: define void @_Z10medium_arg6Medium(%struct.Medium* byval align 4 %s)
+// WIN32: define void @"\01?medium_arg@@YAXUMedium@@@Z"(%struct.Medium* byval align 4 %s)
+// WIN64: define void @"\01?medium_arg@@YAXUMedium@@@Z"(i64 %s.coerce)
+
+void small_arg_with_ctor(SmallWithCtor s) {}
+// LINUX: define void @_Z19small_arg_with_ctor13SmallWithCtor(%struct.SmallWithCtor* byval align 4 %s)
+// WIN32: define void @"\01?small_arg_with_ctor@@YAXUSmallWithCtor@@@Z"(%struct.SmallWithCtor* byval align 4 %s)
+// WIN64: define void @"\01?small_arg_with_ctor@@YAXUSmallWithCtor@@@Z"(i32 %s.coerce)
+
+void small_arg_with_vftable(SmallWithVftable s) {}
+// LINUX: define void @_Z22small_arg_with_vftable16SmallWithVftable(%struct.SmallWithVftable* %s)
+// WIN32: define void @"\01?small_arg_with_vftable@@YAXUSmallWithVftable@@@Z"(%struct.SmallWithVftable* byval align 4 %s)
+// WIN64: define void @"\01?small_arg_with_vftable@@YAXUSmallWithVftable@@@Z"(%struct.SmallWithVftable* byval %s)
+
+void medium_arg_with_copy_ctor(MediumWithCopyCtor s) {}
+// LINUX: define void @_Z25medium_arg_with_copy_ctor18MediumWithCopyCtor(%struct.MediumWithCopyCtor* %s)
+// WIN32: define void @"\01?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(%struct.MediumWithCopyCtor* byval align 4 %s)
+// WIN64: define void @"\01?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(%struct.MediumWithCopyCtor* byval %s)
+
+void big_arg(Big s) {}
+// LINUX: define void @_Z7big_arg3Big(%struct.Big* byval align 4 %s)
+// WIN32: define void @"\01?big_arg@@YAXUBig@@@Z"(%struct.Big* byval align 4 %s)
+// WIN64: define void @"\01?big_arg@@YAXUBig@@@Z"(%struct.Big* %s)
+
+// FIXME: Add WIN64 tests. Currently, even the method manglings are wrong (sic!).
+class Class {
+ public:
+ Small thiscall_method_small() { return Small(); }
+ // LINUX: define {{.*}} void @_ZN5Class21thiscall_method_smallEv(%struct.Small* noalias sret %agg.result, %class.Class* %this)
+ // WIN32: define {{.*}} x86_thiscallcc void @"\01?thiscall_method_small@Class@@QAE?AUSmall@@XZ"(%struct.Small* noalias sret %agg.result, %class.Class* %this)
+
+ SmallWithCtor thiscall_method_small_with_ctor() { return SmallWithCtor(); }
+ // LINUX: define {{.*}} void @_ZN5Class31thiscall_method_small_with_ctorEv(%struct.SmallWithCtor* noalias sret %agg.result, %class.Class* %this)
+ // WIN32: define {{.*}} x86_thiscallcc void @"\01?thiscall_method_small_with_ctor@Class@@QAE?AUSmallWithCtor@@XZ"(%struct.SmallWithCtor* noalias sret %agg.result, %class.Class* %this)
+
+ Small __cdecl cdecl_method_small() { return Small(); }
+ // LINUX: define {{.*}} void @_ZN5Class18cdecl_method_smallEv(%struct.Small* noalias sret %agg.result, %class.Class* %this)
+ // FIXME: Interesting, cdecl returns structures differently for instance
+ // methods and global functions. This is not supported by Clang yet...
+ // FIXME: Replace WIN32-NOT with WIN32 when this is fixed.
+ // WIN32-NOT: define {{.*}} void @"\01?cdecl_method_small@Class@@QAA?AUSmall@@XZ"(%struct.Small* noalias sret %agg.result, %class.Class* %this)
+
+ Big __cdecl cdecl_method_big() { return Big(); }
+ // LINUX: define {{.*}} void @_ZN5Class16cdecl_method_bigEv(%struct.Big* noalias sret %agg.result, %class.Class* %this)
+ // WIN32: define {{.*}} void @"\01?cdecl_method_big@Class@@QAA?AUBig@@XZ"(%struct.Big* noalias sret %agg.result, %class.Class* %this)
+
+ void thiscall_method_arg(Empty s) {}
+ // LINUX: define {{.*}} void @_ZN5Class19thiscall_method_argE5Empty(%class.Class* %this)
+ // WIN32: define {{.*}} void @"\01?thiscall_method_arg@Class@@QAEXUEmpty@@@Z"(%class.Class* %this, %struct.Empty* byval align 4 %s)
+
+ void thiscall_method_arg(EmptyWithCtor s) {}
+ // LINUX: define {{.*}} void @_ZN5Class19thiscall_method_argE13EmptyWithCtor(%class.Class* %this)
+ // WIN32: define {{.*}} void @"\01?thiscall_method_arg@Class@@QAEXUEmptyWithCtor@@@Z"(%class.Class* %this, %struct.EmptyWithCtor* byval align 4 %s)
+
+ void thiscall_method_arg(Small s) {}
+ // LINUX: define {{.*}} void @_ZN5Class19thiscall_method_argE5Small(%class.Class* %this, %struct.Small* byval align 4 %s)
+ // WIN32: define {{.*}} void @"\01?thiscall_method_arg@Class@@QAEXUSmall@@@Z"(%class.Class* %this, %struct.Small* byval align 4 %s)
+
+ void thiscall_method_arg(SmallWithCtor s) {}
+ // LINUX: define {{.*}} void @_ZN5Class19thiscall_method_argE13SmallWithCtor(%class.Class* %this, %struct.SmallWithCtor* byval align 4 %s)
+ // WIN32: define {{.*}} void @"\01?thiscall_method_arg@Class@@QAEXUSmallWithCtor@@@Z"(%class.Class* %this, %struct.SmallWithCtor* byval align 4 %s)
+
+ void thiscall_method_arg(Big s) {}
+ // LINUX: define {{.*}} void @_ZN5Class19thiscall_method_argE3Big(%class.Class* %this, %struct.Big* byval align 4 %s)
+ // WIN32: define {{.*}} void @"\01?thiscall_method_arg@Class@@QAEXUBig@@@Z"(%class.Class* %this, %struct.Big* byval align 4 %s)
+};
+
+void use_class() {
+ Class c;
+ c.thiscall_method_small();
+ c.thiscall_method_small_with_ctor();
+
+ c.cdecl_method_small();
+ c.cdecl_method_big();
+
+ c.thiscall_method_arg(Empty());
+ c.thiscall_method_arg(EmptyWithCtor());
+ c.thiscall_method_arg(Small());
+ c.thiscall_method_arg(SmallWithCtor());
+ c.thiscall_method_arg(Big());
+}
diff --git a/test/CodeGenCXX/pr15753.cpp b/test/CodeGenCXX/pr15753.cpp
new file mode 100644
index 0000000000..fd2000be6e
--- /dev/null
+++ b/test/CodeGenCXX/pr15753.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
+
+template <typename T> static int Foo(T t);
+template <typename T>
+int Foo(T t) {
+ return t;
+}
+template<> int Foo<int>(int i) {
+ return i;
+}
+
+// CHECK-NOT: define
diff --git a/test/CodeGenCXX/scoped-enums-debug-info.cpp b/test/CodeGenCXX/scoped-enums-debug-info.cpp
new file mode 100644
index 0000000000..d3ef9f7068
--- /dev/null
+++ b/test/CodeGenCXX/scoped-enums-debug-info.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -std=c++11 -emit-llvm -g -o - %s | FileCheck %s
+// Test that we are emitting debug info and base types for scoped enums.
+
+// CHECK: [ DW_TAG_enumeration_type ] [Color] {{.*}} [from int]
+enum class Color { gray };
+
+void f(Color);
+void g() {
+ f(Color::gray);
+}
+
+// CHECK: [ DW_TAG_enumeration_type ] [Colour] {{.*}} [from int]
+enum struct Colour { grey };
+
+void h(Colour);
+void i() {
+ h(Colour::grey);
+}
+
+// CHECK: [ DW_TAG_enumeration_type ] [Couleur] {{.*}} [from unsigned char]
+enum class Couleur : unsigned char { gris };
+
+void j(Couleur);
+void k() {
+ j(Couleur::gris);
+}
diff --git a/test/CodeGenCXX/scoped-enums.cpp b/test/CodeGenCXX/scoped-enums.cpp
index fca0509892..c20faaaf2e 100644
--- a/test/CodeGenCXX/scoped-enums.cpp
+++ b/test/CodeGenCXX/scoped-enums.cpp
@@ -7,3 +7,11 @@ void f(Color);
void g() {
f(Color::red);
}
+
+// See that struct is handled equally.
+enum struct Colour { grey };
+
+void h(Colour);
+void i() {
+ h(Colour::grey);
+}
diff --git a/test/CodeGenCXX/throw-expressions.cpp b/test/CodeGenCXX/throw-expressions.cpp
index f04185b23f..ba8a86881a 100644
--- a/test/CodeGenCXX/throw-expressions.cpp
+++ b/test/CodeGenCXX/throw-expressions.cpp
@@ -1,5 +1,4 @@
-// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -emit-llvm-only -verify %s -Wno-unreachable-code
-// expected-no-diagnostics
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -Wno-unreachable-code -Werror -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s
int val = 42;
int& test1() {
@@ -19,3 +18,28 @@ void test3() {
int test4() {
return 1 ? throw val : val;
}
+
+// PR15923
+int test5(bool x, bool y, int z) {
+ return (x ? throw 1 : y) ? z : throw 2;
+}
+// CHECK: define i32 @_Z5test5bbi(
+// CHECK: br i1
+//
+// x.true:
+// CHECK: call void @__cxa_throw(
+// CHECK-NEXT: unreachable
+//
+// x.false:
+// CHECK: br i1
+//
+// y.true:
+// CHECK: load i32*
+// CHECK: br label
+//
+// y.false:
+// CHECK: call void @__cxa_throw(
+// CHECK-NEXT: unreachable
+//
+// end:
+// CHECK: ret i32
diff --git a/test/CodeGenCXX/tls-init-funcs.cpp b/test/CodeGenCXX/tls-init-funcs.cpp
new file mode 100644
index 0000000000..17299dcb7b
--- /dev/null
+++ b/test/CodeGenCXX/tls-init-funcs.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.8 -std=c++11 -S -emit-llvm %s -o - | FileCheck %s
+
+// CHECK: @a = internal thread_local global
+// CHECK: @_tlv_atexit({{.*}}@_ZN1AD1Ev
+
+struct A {
+ ~A();
+};
+
+thread_local A a;
diff --git a/test/CodeGenCXX/vtable-debug-info.cpp b/test/CodeGenCXX/vtable-debug-info.cpp
index 9294d20e72..8710c76e0b 100644
--- a/test/CodeGenCXX/vtable-debug-info.cpp
+++ b/test/CodeGenCXX/vtable-debug-info.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang -c -g %s -o /dev/null
+// RUN: %clang -emit-llvm -S -g %s -o /dev/null
// Radar 8730409
// XFAIL: win32
diff --git a/test/CodeGenObjC/arc-blocks.m b/test/CodeGenObjC/arc-blocks.m
index 503c7d2a1f..c9ba2f6153 100644
--- a/test/CodeGenObjC/arc-blocks.m
+++ b/test/CodeGenObjC/arc-blocks.m
@@ -80,13 +80,14 @@ void test3(void (^sink)(id*)) {
// CHECK-NEXT: bitcast
// CHECK-NEXT: getelementptr
// CHECK-NEXT: [[BLOCK:%.*]] = bitcast
- // CHECK-NEXT: [[T0:%.*]] = load i8** [[STRONG]]
- // CHECK-NEXT: store i8* [[T0]], i8** [[TEMP]]
+ // CHECK-NEXT: [[V:%.*]] = load i8** [[STRONG]]
+ // CHECK-NEXT: store i8* [[V]], i8** [[TEMP]]
// CHECK-NEXT: [[F0:%.*]] = load i8**
// CHECK-NEXT: [[F1:%.*]] = bitcast i8* [[F0]] to void (i8*, i8**)*
// CHECK-NEXT: call void [[F1]](i8* [[BLOCK]], i8** [[TEMP]])
// CHECK-NEXT: [[T0:%.*]] = load i8** [[TEMP]]
// CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]])
+ // CHECK-NEXT: call void (...)* @clang.arc.use(i8* [[V]]) [[NUW]]
// CHECK-NEXT: [[T2:%.*]] = load i8** [[STRONG]]
// CHECK-NEXT: store i8* [[T1]], i8** [[STRONG]]
// CHECK-NEXT: call void @objc_release(i8* [[T2]])
@@ -127,7 +128,7 @@ void test4(void) {
// CHECK-NEXT: call void @_Block_object_dispose(i8* [[T0]], i32 8)
// CHECK-NEXT: [[T0:%.*]] = load i8** [[SLOT]]
// CHECK-NEXT: call void @objc_release(i8* [[T0]])
- // CHECK-NEXT: ret void
+ // CHECK: ret void
// CHECK: define internal void @__Block_byref_object_copy_
// CHECK: [[T0:%.*]] = getelementptr inbounds [[BYREF_T]]* {{%.*}}, i32 0, i32 6
@@ -206,7 +207,7 @@ void test6(void) {
// CHECK: [[T0:%.*]] = bitcast [[BYREF_T]]* [[VAR]] to i8*
// CHECK-NEXT: call void @_Block_object_dispose(i8* [[T0]], i32 8)
// CHECK-NEXT: call void @objc_destroyWeak(i8** [[SLOT]])
- // CHECK-NEXT: ret void
+ // CHECK: ret void
// CHECK: define internal void @__Block_byref_object_copy_
// CHECK: [[T0:%.*]] = getelementptr inbounds [[BYREF_T]]* {{%.*}}, i32 0, i32 6
@@ -255,14 +256,14 @@ void test7(void) {
// CHECK: call void @test7_helper(
// CHECK-NEXT: call void @objc_destroyWeak(i8** {{%.*}})
// CHECK-NEXT: call void @objc_destroyWeak(i8** [[VAR]])
- // CHECK-NEXT: ret void
+ // CHECK: ret void
// CHECK: define internal void @__test7_block_invoke
// CHECK: [[SLOT:%.*]] = getelementptr inbounds [[BLOCK_T]]* {{%.*}}, i32 0, i32 5
// CHECK-NEXT: [[T0:%.*]] = call i8* @objc_loadWeakRetained(i8** [[SLOT]])
// CHECK-NEXT: call void @test7_consume(i8* [[T0]])
// CHECK-NEXT: call void @objc_release(i8* [[T0]])
- // CHECK-NEXT: ret void
+ // CHECK: ret void
// CHECK: define internal void @__copy_helper_block_
// CHECK: getelementptr
@@ -295,7 +296,7 @@ void test7(void) {
// CHECK-NEXT: [[T1:%.*]] = load [[TEST8]]** [[D0]]
// CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST8]]* [[T1]] to i8*
// CHECK-NEXT: call void @objc_release(i8* [[T2]])
-// CHECK-NEXT: ret void
+// CHECK: ret void
extern void test8_helper(void (^)(void));
test8_helper(^{ (void) self; });
@@ -353,7 +354,7 @@ void test10a(void) {
// CHECK-NEXT: [[T1:%.*]] = load void ()** [[SLOT]]
// CHECK-NEXT: [[T2:%.*]] = bitcast void ()* [[T1]] to i8*
// CHECK-NEXT: call void @objc_release(i8* [[T2]])
- // CHECK-NEXT: ret void
+ // CHECK: ret void
}
// <rdar://problem/10402698>: do this copy and dispose with
@@ -373,7 +374,7 @@ void test10a(void) {
// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainBlock(i8* [[T1]])
// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to void ()*
// CHECK-NEXT: store void ()* [[T3]], void ()** [[D2]], align 8
-// CHECK-NEXT: ret void
+// CHECK: ret void
// CHECK: define internal void @__Block_byref_object_dispose
// CHECK: [[T0:%.*]] = load i8** {{%.*}}
@@ -417,7 +418,7 @@ void test10b(void) {
// CHECK-NEXT: [[T1:%.*]] = load void ()** [[SLOT]]
// CHECK-NEXT: [[T2:%.*]] = bitcast void ()* [[T1]] to i8*
// CHECK-NEXT: call void @objc_release(i8* [[T2]])
- // CHECK-NEXT: ret void
+ // CHECK: ret void
}
// rdar://problem/10088932
@@ -437,7 +438,7 @@ void test11a(void) {
// CHECK-NEXT: call void @test11_helper(i8* [[T4]])
// CHECK-NEXT: [[T5:%.*]] = bitcast void ()* [[T3]] to i8*
// CHECK-NEXT: call void @objc_release(i8* [[T5]])
- // CHECK-NEXT: ret void
+ // CHECK: ret void
}
void test11b(void) {
int x;
@@ -455,7 +456,7 @@ void test11b(void) {
// CHECK-NEXT: store i8* [[T4]], i8** [[B]], align 8
// CHECK-NEXT: [[T5:%.*]] = load i8** [[B]]
// CHECK-NEXT: call void @objc_release(i8* [[T5]])
- // CHECK-NEXT: ret void
+ // CHECK: ret void
}
// rdar://problem/9979150
@@ -649,5 +650,44 @@ void test18(id x) {
// CHECK-UNOPT-NEXT: ret void
}
+// rdar://13588325
+void test19_sink(void (^)(int));
+void test19(void (^b)(void)) {
+// CHECK: define void @test19(
+// Prologue.
+// CHECK: [[B:%.*]] = alloca void ()*,
+// CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
+// CHECK-NEXT: [[T0:%.*]] = bitcast void ()* {{%.*}} to i8*
+// CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]])
+// CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to void ()*
+// CHECK-NEXT: store void ()* [[T2]], void ()** [[B]]
+
+// Block setup. We skip most of this. Note the bare retain.
+// CHECK-NEXT: [[SLOTREL:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
+// CHECK: [[SLOT:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
+// CHECK-NEXT: [[T0:%.*]] = load void ()** [[B]],
+// CHECK-NEXT: [[T1:%.*]] = bitcast void ()* [[T0]] to i8*
+// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]])
+// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to void ()*
+// CHECK-NEXT: store void ()* [[T3]], void ()** [[SLOT]],
+// Call.
+// CHECK-NEXT: [[T0:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to void (i32)*
+// CHECK-NEXT: call void @test19_sink(void (i32)* [[T0]])
+
+ test19_sink(^(int x) { b(); });
+
+// Block teardown.
+// CHECK-NEXT: [[T0:%.*]] = load void ()** [[SLOTREL]]
+// CHECK-NEXT: [[T1:%.*]] = bitcast void ()* [[T0]] to i8*
+// CHECK-NEXT: call void @objc_release(i8* [[T1]])
+
+// Local cleanup.
+// CHECK-NEXT: [[T0:%.*]] = load void ()** [[B]]
+// CHECK-NEXT: [[T1:%.*]] = bitcast void ()* [[T0]] to i8*
+// CHECK-NEXT: call void @objc_release(i8* [[T1]])
+
+// CHECK-NEXT: ret void
+}
+
// CHECK: attributes [[NUW]] = { nounwind }
// CHECK-UNOPT: attributes [[NUW]] = { nounwind }
diff --git a/test/CodeGenObjC/arc-foreach.m b/test/CodeGenObjC/arc-foreach.m
index b81cbbd74a..176b28d3a2 100644
--- a/test/CodeGenObjC/arc-foreach.m
+++ b/test/CodeGenObjC/arc-foreach.m
@@ -84,7 +84,8 @@ void test0(NSArray *array) {
// CHECK-LP64: define internal void @__test0_block_invoke
// CHECK-LP64: [[BLOCK:%.*]] = bitcast i8* {{%.*}} to [[BLOCK_T]]*
-// CHECK-LP64-NEXT: [[T0:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
+// CHECK-LP64-NOT: ret
+// CHECK-LP64: [[T0:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
// CHECK-LP64-NEXT: [[T2:%.*]] = load i8** [[T0]], align 8
// CHECK-LP64-NEXT: call void @use(i8* [[T2]])
diff --git a/test/CodeGenObjC/arc-linetable.m b/test/CodeGenObjC/arc-linetable.m
new file mode 100644
index 0000000000..eac91f1889
--- /dev/null
+++ b/test/CodeGenObjC/arc-linetable.m
@@ -0,0 +1,101 @@
+// RUN: %clang_cc1 -emit-llvm -fblocks -fobjc-arc -g -triple x86_64-apple-darwin10 %s -o - | FileCheck %s
+
+// Legend: EXP = Return expression, RET = ret instruction
+
+// CHECK: define {{.*}}testNoSideEffect
+// CHECK: call void @objc_storeStrong{{.*}}
+// CHECK: call void @objc_storeStrong{{.*}} !dbg ![[ARC1:[0-9]+]]
+// CHECK: ret {{.*}} !dbg ![[RET1:[0-9]+]]
+
+// CHECK: define {{.*}}testNoCleanup
+// CHECK: ret {{.*}} !dbg ![[RET2:[0-9]+]]
+
+// CHECK: define {{.*}}testSideEffect
+// CHECK: @objc_msgSend{{.*}} !dbg ![[MSG3:[0-9]+]]
+// CHECK: ret {{.*}} !dbg ![[RET3:[0-9]+]]
+
+// CHECK: define {{.*}}testMultiline
+// CHECK: @objc_msgSend{{.*}} !dbg ![[MSG4:[0-9]+]]
+// CHECK: load{{.*}} !dbg ![[EXP4:[0-9]+]]
+// CHECK: ret {{.*}} !dbg ![[RET4:[0-9]+]]
+
+// CHECK: define {{.*}}testVoid
+// CHECK: call void @objc_storeStrong{{.*}}
+// CHECK: call void @objc_storeStrong{{.*}} !dbg ![[ARC5:[0-9]+]]
+// CHECK: ret {{.*}} !dbg ![[RET5:[0-9]+]]
+
+// CHECK: define {{.*}}testVoidNoReturn
+// CHECK: @objc_msgSend{{.*}} !dbg ![[MSG6:[0-9]+]]
+// CHECK: ret {{.*}} !dbg ![[RET6:[0-9]+]]
+
+// CHECK: define {{.*}}testNoCleanupSideEffect
+// CHECK: @objc_msgSend{{.*}} !dbg ![[MSG7:[0-9]+]]
+// CHECK: ret {{.*}} !dbg ![[RET7:[0-9]+]]
+
+
+@interface NSObject
++ (id)alloc;
+- (id)init;
+- (id)retain;
+@end
+
+@class NSString;
+
+@interface AppDelegate : NSObject
+
+@end
+
+@implementation AppDelegate : NSObject
+
+- (int)testNoSideEffect:(NSString *)foo {
+ // CHECK: ![[ARC1]] = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null}
+ return 1; // Return expression
+ // CHECK: ![[RET1]] = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null}
+} // Cleanup + Ret
+
+- (int)testNoCleanup {
+ // CHECK: ![[RET2]] = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null}
+ return 1;
+}
+
+- (int)testSideEffect:(NSString *)foo {
+ // CHECK: ![[MSG3]] = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null}
+ return [self testNoSideEffect :foo];
+ // CHECK: ![[RET3]] = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null}
+}
+
+- (int)testMultiline:(NSString *)foo {
+ // CHECK: ![[MSG4]] = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null}
+ int r = [self testSideEffect :foo];
+ // CHECK: ![[EXP4]] = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null}
+ return r;
+ // CHECK: ![[RET4]] = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null}
+}
+
+- (void)testVoid:(NSString *)foo {
+ // CHECK: ![[ARC5]] = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null}
+ return;
+ // CHECK: ![[RET5]] = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null}
+}
+
+- (void)testVoidNoReturn:(NSString *)foo {
+ // CHECK: ![[MSG6]] = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null}
+ [self testVoid :foo];
+ // CHECK: ![[RET6]] = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null}
+}
+
+- (int)testNoCleanupSideEffect {
+ // CHECK: ![[MSG7]] = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null}
+ [self testVoid :@"foo"];
+ // CHECK: ![[RET7]] = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null}
+ return 1;
+}
+
+
+@end
+
+
+int main(int argc, const char** argv) {
+ AppDelegate *o = [[AppDelegate alloc] init];
+ return [o testMultiline :@"foo"];
+}
diff --git a/test/CodeGenObjC/arc-literals.m b/test/CodeGenObjC/arc-literals.m
index 203c2ad1ee..78c5d9d237 100644
--- a/test/CodeGenObjC/arc-literals.m
+++ b/test/CodeGenObjC/arc-literals.m
@@ -35,18 +35,28 @@ void test_numeric() {
// CHECK: define void @test_array
void test_array(id a, id b) {
+ // CHECK: [[A:%.*]] = alloca i8*,
+ // CHECK: [[B:%.*]] = alloca i8*,
+
// Retaining parameters
// CHECK: call i8* @objc_retain(i8*
// CHECK: call i8* @objc_retain(i8*
// Constructing the array
- // CHECK: getelementptr inbounds [2 x i8*]* [[OBJECTS:%[A-Za-z0-9]+]], i32 0, i32 0
- // CHECK: store i8*
- // CHECK: getelementptr inbounds [2 x i8*]* [[OBJECTS]], i32 0, i32 1
- // CHECK: store i8*
-
- // CHECK: {{call i8*.*objc_msgSend.*i64 2}}
- // CHECK: call i8* @objc_retainAutoreleasedReturnValue
+ // CHECK: [[T0:%.*]] = getelementptr inbounds [2 x i8*]* [[OBJECTS:%[A-Za-z0-9]+]], i32 0, i32 0
+ // CHECK-NEXT: [[V0:%.*]] = load i8** [[A]],
+ // CHECK-NEXT: store i8* [[V0]], i8** [[T0]]
+ // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [2 x i8*]* [[OBJECTS]], i32 0, i32 1
+ // CHECK-NEXT: [[V1:%.*]] = load i8** [[B]],
+ // CHECK-NEXT: store i8* [[V1]], i8** [[T0]]
+
+ // CHECK-NEXT: [[T0:%.*]] = load [[CLASS_T:%.*]]** @"\01L_OBJC_CLASSLIST
+ // CHECK-NEXT: [[SEL:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES
+ // CHECK-NEXT: [[T1:%.*]] = bitcast [[CLASS_T]]* [[T0]] to i8*
+ // CHECK-NEXT: [[T2:%.*]] = bitcast [2 x i8*]* [[OBJECTS]] to i8**
+ // CHECK-NEXT: [[T3:%.*]] = call i8* bitcast ({{.*@objc_msgSend.*}})(i8* [[T1]], i8* [[SEL]], i8** [[T2]], i64 2)
+ // CHECK-NEXT: [[T4:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T3]])
+ // CHECK: call void (...)* @clang.arc.use(i8* [[V0]], i8* [[V1]])
id arr = @[a, b];
// CHECK: call void @objc_release
@@ -57,6 +67,11 @@ void test_array(id a, id b) {
// CHECK: define void @test_dictionary
void test_dictionary(id k1, id o1, id k2, id o2) {
+ // CHECK: [[K1:%.*]] = alloca i8*,
+ // CHECK: [[O1:%.*]] = alloca i8*,
+ // CHECK: [[K2:%.*]] = alloca i8*,
+ // CHECK: [[O2:%.*]] = alloca i8*,
+
// Retaining parameters
// CHECK: call i8* @objc_retain(i8*
// CHECK: call i8* @objc_retain(i8*
@@ -64,18 +79,29 @@ void test_dictionary(id k1, id o1, id k2, id o2) {
// CHECK: call i8* @objc_retain(i8*
// Constructing the arrays
- // CHECK: getelementptr inbounds [2 x i8*]* [[KEYS:%[A-Za-z0-9]+]], i32 0, i32 0
- // CHECK: store i8*
- // CHECK: getelementptr inbounds [2 x i8*]* [[OBJECTS:%[A-Za-z0-9]+]], i32 0, i32 0
- // CHECK: store i8*
- // CHECK: getelementptr inbounds [2 x i8*]* [[KEYS]], i32 0, i32 1
- // CHECK: store i8*
- // CHECK: getelementptr inbounds [2 x i8*]* [[OBJECTS]], i32 0, i32 1
- // CHECK: store i8*
+ // CHECK: [[T0:%.*]] = getelementptr inbounds [2 x i8*]* [[KEYS:%[A-Za-z0-9]+]], i32 0, i32 0
+ // CHECK-NEXT: [[V0:%.*]] = load i8** [[K1]],
+ // CHECK-NEXT: store i8* [[V0]], i8** [[T0]]
+ // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [2 x i8*]* [[OBJECTS:%[A-Za-z0-9]+]], i32 0, i32 0
+ // CHECK-NEXT: [[V1:%.*]] = load i8** [[O1]],
+ // CHECK-NEXT: store i8* [[V1]], i8** [[T0]]
+ // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [2 x i8*]* [[KEYS]], i32 0, i32 1
+ // CHECK-NEXT: [[V2:%.*]] = load i8** [[K2]],
+ // CHECK-NEXT: store i8* [[V2]], i8** [[T0]]
+ // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [2 x i8*]* [[OBJECTS]], i32 0, i32 1
+ // CHECK-NEXT: [[V3:%.*]] = load i8** [[O2]],
+ // CHECK-NEXT: store i8* [[V3]], i8** [[T0]]
// Constructing the dictionary
- // CHECK: {{call i8.*@objc_msgSend}}
- // CHECK: call i8* @objc_retainAutoreleasedReturnValue
+ // CHECK-NEXT: [[T0:%.*]] = load [[CLASS_T:%.*]]** @"\01L_OBJC_CLASSLIST
+ // CHECK-NEXT: [[SEL:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES
+ // CHECK-NEXT: [[T1:%.*]] = bitcast [[CLASS_T]]* [[T0]] to i8*
+ // CHECK-NEXT: [[T2:%.*]] = bitcast [2 x i8*]* [[OBJECTS]] to i8**
+ // CHECK-NEXT: [[T3:%.*]] = bitcast [2 x i8*]* [[KEYS]] to i8**
+ // CHECK-NEXT: [[T4:%.*]] = call i8* bitcast ({{.*@objc_msgSend.*}})(i8* [[T1]], i8* [[SEL]], i8** [[T2]], i8** [[T3]], i64 2)
+ // CHECK-NEXT: [[T5:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T4]])
+ // CHECK-NEXT: call void (...)* @clang.arc.use(i8* [[V0]], i8* [[V1]], i8* [[V2]], i8* [[V3]])
+
id dict = @{ k1 : o1, k2 : o2 };
// CHECK: call void @objc_release
@@ -98,19 +124,36 @@ void test_property(B *b) {
// Retain parameter
// CHECK: call i8* @objc_retain
+ // CHECK: [[T0:%.*]] = getelementptr inbounds [1 x i8*]* [[OBJECTS:%.*]], i32 0, i32 0
+
// Invoke 'prop'
- // CHECK: load i8** @"\01L_OBJC_SELECTOR_REFERENCES
- // CHECK: {{call.*@objc_msgSend}}
- // CHECK: call i8* @objc_retainAutoreleasedReturnValue
+ // CHECK: [[SEL:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES
+ // CHECK-NEXT: [[T1:%.*]] = bitcast
+ // CHECK-NEXT: [[T2:%.*]] = call [[B:%.*]]* bitcast ({{.*}} @objc_msgSend to {{.*}})(i8* [[T1]], i8* [[SEL]])
+ // CHECK-NEXT: [[T3:%.*]] = bitcast [[B]]* [[T2]] to i8*
+ // CHECK-NEXT: [[T4:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T3]])
+ // CHECK-NEXT: [[V0:%.*]] = bitcast i8* [[T4]] to [[B]]*
+ // CHECK-NEXT: [[V1:%.*]] = bitcast [[B]]* [[V0]] to i8*
+
+ // Store to array.
+ // CHECK-NEXT: store i8* [[V1]], i8** [[T0]]
// Invoke arrayWithObjects:count:
- // CHECK: load i8** @"\01L_OBJC_SELECTOR_REFERENCES
- // CHECK: {{call.*objc_msgSend}}
- // CHECK: call i8* @objc_retainAutoreleasedReturnValue
+ // CHECK-NEXT: [[T0:%.*]] = load [[CLASS_T]]** @"\01L_OBJC_CLASSLIST
+ // CHECK-NEXT: [[SEL:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES
+ // CHECK-NEXT: [[T1:%.*]] = bitcast [[CLASS_T]]* [[T0]] to i8*
+ // CHECK-NEXT: [[T2:%.*]] = bitcast [1 x i8*]* [[OBJECTS]] to i8**
+ // CHECK-NEXT: [[T3:%.*]] = call i8* bitcast ({{.*}} @objc_msgSend to {{.*}}(i8* [[T1]], i8* [[SEL]], i8** [[T2]], i64 1)
+ // CHECK-NEXT: call i8* @objc_retainAutoreleasedReturnValue(i8* [[T3]])
+ // CHECK-NEXT: call void (...)* @clang.arc.use(i8* [[V1]])
+ // CHECK-NEXT: bitcast
+ // CHECK-NEXT: bitcast
+ // CHECK-NEXT: store
id arr = @[ b.prop ];
// Release b.prop
- // CHECK: call void @objc_release
+ // CHECK-NEXT: [[T0:%.*]] = bitcast [[B]]* [[V0]] to i8*
+ // CHECK-NEXT: call void @objc_release(i8* [[T0]])
// Destroy arr
// CHECK: call void @objc_release
diff --git a/test/CodeGenObjC/arc-precise-lifetime.m b/test/CodeGenObjC/arc-precise-lifetime.m
new file mode 100644
index 0000000000..595a4f9fdf
--- /dev/null
+++ b/test/CodeGenObjC/arc-precise-lifetime.m
@@ -0,0 +1,120 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -O2 -disable-llvm-optzns -o - %s | FileCheck %s
+
+#define PRECISE_LIFETIME __attribute__((objc_precise_lifetime))
+
+id test0_helper(void) __attribute__((ns_returns_retained));
+void test0() {
+ PRECISE_LIFETIME id x = test0_helper();
+ x = 0;
+ // CHECK: [[X:%.*]] = alloca i8*
+ // CHECK-NEXT: [[CALL:%.*]] = call i8* @test0_helper()
+ // CHECK-NEXT: store i8* [[CALL]], i8** [[X]]
+
+ // CHECK-NEXT: [[T1:%.*]] = load i8** [[X]]
+ // CHECK-NEXT: store i8* null, i8** [[X]]
+ // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW:#[0-9]+]]
+ // CHECK-NOT: clang.imprecise_release
+
+ // CHECK-NEXT: [[T1:%.*]] = load i8** [[X]]
+ // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW:#[0-9]+]]
+ // CHECK-NOT: clang.imprecise_release
+
+ // CHECK-NEXT: ret void
+}
+
+// rdar://problem/9821110
+@interface Test1
+- (char*) interior __attribute__((objc_returns_inner_pointer));
+// Should we allow this on properties?
+@end
+extern Test1 *test1_helper(void);
+
+// CHECK: define void @test1a()
+void test1a(void) {
+ // CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper()
+ // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
+ // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]])
+ // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
+ // CHECK-NEXT: store [[TEST1]]* [[T3]]
+ // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]**
+ // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
+ // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutorelease(i8* [[T1]])
+ // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
+ // CHECK-NEXT: [[T4:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_
+ // CHECK-NEXT: [[T5:%.*]] = bitcast [[TEST1]]* [[T3]] to i8*
+ // CHECK-NEXT: [[T6:%.*]] = call i8* bitcast
+ // CHECK-NEXT: store i8* [[T6]], i8**
+ // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]**
+ // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
+ // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]], !clang.imprecise_release
+ // CHECK-NEXT: ret void
+ Test1 *ptr = test1_helper();
+ char *c = [(ptr) interior];
+}
+
+// CHECK: define void @test1b()
+void test1b(void) {
+ // CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper()
+ // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
+ // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]])
+ // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
+ // CHECK-NEXT: store [[TEST1]]* [[T3]]
+ // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]**
+ // CHECK-NEXT: [[T1:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_
+ // CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
+ // CHECK-NEXT: [[T3:%.*]] = call i8* bitcast
+ // CHECK-NEXT: store i8* [[T3]], i8**
+ // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]**
+ // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
+ // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]]
+ // CHECK-NOT: clang.imprecise_release
+ // CHECK-NEXT: ret void
+ __attribute__((objc_precise_lifetime)) Test1 *ptr = test1_helper();
+ char *c = [ptr interior];
+}
+
+@interface Test2 {
+@public
+ id ivar;
+}
+@end
+// CHECK: define void @test2(
+void test2(Test2 *x) {
+ x->ivar = 0;
+ // CHECK: [[X:%.*]] = alloca [[TEST2:%.*]]*
+ // CHECK-NEXT: [[T0:%.*]] = bitcast [[TEST2]]* {{%.*}} to i8*
+ // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]]) [[NUW]]
+ // CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to [[TEST2]]*
+ // CHECK-NEXT: store [[TEST2]]* [[T2]], [[TEST2]]** [[X]],
+
+ // CHECK-NEXT: [[T0:%.*]] = load [[TEST2]]** [[X]],
+ // CHECK-NEXT: [[OFFSET:%.*]] = load i64* @"OBJC_IVAR_$_Test2.ivar"
+ // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST2]]* [[T0]] to i8*
+ // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds i8* [[T1]], i64 [[OFFSET]]
+ // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to i8**
+ // CHECK-NEXT: [[T4:%.*]] = load i8** [[T3]],
+ // CHECK-NEXT: store i8* null, i8** [[T3]],
+ // CHECK-NEXT: call void @objc_release(i8* [[T4]]) [[NUW]]
+ // CHECK-NOT: imprecise
+
+ // CHECK-NEXT: [[T0:%.*]] = load [[TEST2]]** [[X]]
+ // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST2]]* [[T0]] to i8*
+ // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]], !clang.imprecise_release
+
+ // CHECK-NEXT: ret void
+}
+
+// CHECK: define void @test3(i8*
+void test3(PRECISE_LIFETIME id x) {
+ // CHECK: [[X:%.*]] = alloca i8*,
+ // CHECK-NEXT: [[T0:%.*]] = call i8* @objc_retain(i8* {{%.*}}) [[NUW]]
+ // CHECK-NEXT: store i8* [[T0]], i8** [[X]],
+
+ // CHECK-NEXT: [[T0:%.*]] = load i8** [[X]]
+ // CHECK-NEXT: call void @objc_release(i8* [[T0]]) [[NUW]]
+ // CHECK-NOT: imprecise_release
+
+ // CHECK-NEXT: ret void
+}
+
+// CHECK: attributes [[NUW]] = { nounwind }
diff --git a/test/CodeGenObjC/arc-property.m b/test/CodeGenObjC/arc-property.m
index 0e01fb7eda..dde02d7dd7 100644
--- a/test/CodeGenObjC/arc-property.m
+++ b/test/CodeGenObjC/arc-property.m
@@ -86,4 +86,49 @@ static Class theGlobalClass;
// CHECK-NEXT: call void @objc_storeStrong(i8** [[T3]], i8* null) [[NUW]]
// CHECK-NEXT: ret void
+// rdar://13115896
+@interface Test3
+@property id copyMachine;
+@end
+
+void test3(Test3 *t) {
+ id x = t.copyMachine;
+ x = [t copyMachine];
+}
+// CHECK: define void @test3([[TEST3:%.*]]*
+// Prologue.
+// CHECK: [[T:%.*]] = alloca [[TEST3]]*,
+// CHECK-NEXT: [[X:%.*]] = alloca i8*,
+// Property access.
+// CHECK: [[T0:%.*]] = load [[TEST3]]** [[T]],
+// CHECK-NEXT: [[SEL:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES
+// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST3]]* [[T0]] to i8*
+// CHECK-NEXT: [[T2:%.*]] = call i8* bitcast ({{.*}} @objc_msgSend to {{.*}})(i8* [[T1]], i8* [[SEL]])
+// CHECK-NEXT: store i8* [[T2]], i8** [[X]],
+// Message send.
+// CHECK-NEXT: [[T0:%.*]] = load [[TEST3]]** [[T]],
+// CHECK-NEXT: [[SEL:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES
+// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST3]]* [[T0]] to i8*
+// CHECK-NEXT: [[T2:%.*]] = call i8* bitcast ({{.*}} @objc_msgSend to {{.*}})(i8* [[T1]], i8* [[SEL]])
+// CHECK-NEXT: [[T3:%.*]] = load i8** [[X]],
+// CHECK-NEXT: store i8* [[T2]], i8** [[X]],
+// CHECK-NEXT: call void @objc_release(i8* [[T3]])
+// Epilogue.
+// CHECK-NEXT: call void @objc_storeStrong(i8** [[X]], i8* null)
+// CHECK-NEXT: [[T0:%.*]] = bitcast [[TEST3]]** [[T]] to i8**
+// CHECK-NEXT: call void @objc_storeStrong(i8** [[T0]], i8* null)
+// CHECK-NEXT: ret void
+
+@implementation Test3
+- (id) copyMachine {
+ extern id test3_helper(void);
+ return test3_helper();
+}
+// CHECK: define internal i8* @"\01-[Test3 copyMachine]"(
+// CHECK: [[T0:%.*]] = call i8* @test3_helper()
+// CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]])
+// CHECK-NEXT: ret i8* [[T1]]
+- (void) setCopyMachine: (id) x {}
+@end
+
// CHECK: attributes [[NUW]] = { nounwind }
diff --git a/test/CodeGenObjC/arc-ternary-op.m b/test/CodeGenObjC/arc-ternary-op.m
index ed14e9d9df..f70e8864a0 100644
--- a/test/CodeGenObjC/arc-ternary-op.m
+++ b/test/CodeGenObjC/arc-ternary-op.m
@@ -61,11 +61,13 @@ void test1(int cond) {
// CHECK: [[T0:%.*]] = load i8** [[ARG]]
// CHECK-NEXT: store i8* [[T0]], i8** [[TEMP1]]
// CHECK-NEXT: br label
- // CHECK: call void @test1_sink(i8** [[T1]])
+ // CHECK: [[W:%.*]] = phi i8* [ [[T0]], {{%.*}} ], [ undef, {{%.*}} ]
+ // CHECK-NEXT: call void @test1_sink(i8** [[T1]])
// CHECK-NEXT: [[T0:%.*]] = icmp eq i8** [[ARG]], null
// CHECK-NEXT: br i1 [[T0]],
// CHECK: [[T0:%.*]] = load i8** [[TEMP1]]
// CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]])
+ // CHECK-NEXT: call void (...)* @clang.arc.use(i8* [[W]]) [[NUW]]
// CHECK-NEXT: [[T2:%.*]] = load i8** [[ARG]]
// CHECK-NEXT: store i8* [[T1]], i8** [[ARG]]
// CHECK-NEXT: call void @objc_release(i8* [[T2]])
diff --git a/test/CodeGenObjC/arc.m b/test/CodeGenObjC/arc.m
index 48f012a42b..7262dc8d7b 100644
--- a/test/CodeGenObjC/arc.m
+++ b/test/CodeGenObjC/arc.m
@@ -273,27 +273,7 @@ void test8() {
// CHECK: [[X:%.*]] = alloca i8*
// CHECK-NEXT: [[T0:%.*]] = call i8* @test8_helper()
// CHECK-NEXT: store i8* [[T0]], i8** [[X]]
- // CHECK-NEXT: call void @objc_release(i8* [[T0]]) [[NUW]]
- // CHECK-NOT: imprecise_release
- // CHECK-NEXT: ret void
-}
-
-id test9_helper(void) __attribute__((ns_returns_retained));
-void test9() {
- id x __attribute__((objc_precise_lifetime)) = test9_helper();
- x = 0;
- // CHECK: [[X:%.*]] = alloca i8*
- // CHECK-NEXT: [[CALL:%.*]] = call i8* @test9_helper()
- // CHECK-NEXT: store i8* [[CALL]], i8** [[X]]
-
- // CHECK-NEXT: [[T1:%.*]] = load i8** [[X]]
- // CHECK-NEXT: store i8* null, i8** [[X]]
- // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]], !clang.imprecise_release
-
- // CHECK-NEXT: [[T1:%.*]] = load i8** [[X]]
- // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]]
- // CHECK-NOT: clang.imprecise_release
-
+ // CHECK-NEXT: call void @objc_release(i8* [[T0]]) [[NUW]], !clang.imprecise_release
// CHECK-NEXT: ret void
}
@@ -373,7 +353,7 @@ void test12(void) {
// CHECK-NEXT: [[T4:%.*]] = load i8** [[Y]]
// CHECK-NEXT: call void @objc_release(i8* [[T4]]) [[NUW]], !clang.imprecise_release
// CHECK-NEXT: call void @objc_destroyWeak(i8** [[X]])
- // CHECK-NEXT: ret void
+ // CHECK: ret void
}
// Indirect consuming calls.
@@ -480,8 +460,9 @@ void test13(void) {
void test19() {
// CHECK: define void @test19()
// CHECK: [[X:%.*]] = alloca [5 x i8*], align 16
+ // CHECK: call void @llvm.lifetime.start
// CHECK-NEXT: [[T0:%.*]] = bitcast [5 x i8*]* [[X]] to i8*
- // CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[T0]], i8 0, i64 40, i32 16, i1 false)
+ // CHECK: call void @llvm.memset.p0i8.i64(i8* [[T0]], i8 0, i64 40, i32 16, i1 false)
id x[5];
extern id test19_helper(void);
@@ -641,7 +622,9 @@ void test21(unsigned n) {
// CHECK-NEXT: store i8* {{%.*}}, i8** [[CMD]]
// CHECK-NEXT: [[T0:%.*]] = load [[TEST27]]** [[SELF]]
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST27]]* [[T0]] to i8*
-// CHECK-NEXT: [[RET:%.*]] = call i8* @objc_retain(i8* [[T1]])
+// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]])
+// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST27]]*
+// CHECK-NEXT: [[RET:%.*]] = bitcast [[TEST27]]* [[T3]] to i8*
// CHECK-NEXT: store i32 {{[0-9]+}}, i32* [[DEST]]
// CHECK-NEXT: [[T0:%.*]] = load [[TEST27]]** [[SELF]]
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST27]]* [[T0]] to i8*
@@ -705,7 +688,9 @@ static id _test29_allocator = 0;
// Return statement.
// CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[CALL]]
// CHECK-NEXT: [[CALL:%.*]] = bitcast
-// CHECK-NEXT: [[RET:%.*]] = call i8* @objc_retain(i8* [[CALL]]) [[NUW]]
+// CHECK-NEXT: [[T0:%.*]] = call i8* @objc_retain(i8* [[CALL]]) [[NUW]]
+// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[TEST29]]*
+// CHECK-NEXT: [[RET:%.*]] = bitcast [[TEST29]]* [[T1]] to i8*
// CHECK-NEXT: store i32 1, i32* [[CLEANUP]]
// Cleanup.
@@ -759,7 +744,9 @@ static id _test29_allocator = 0;
// Return statement.
// CHECK-NEXT: [[T0:%.*]] = load [[TEST29]]** [[SELF]]
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST29]]* [[T0]] to i8*
-// CHECK-NEXT: [[RET:%.*]] = call i8* @objc_retain(i8* [[T1]]) [[NUW]]
+// CHECK-NEXT: [[T0:%.*]] = call i8* @objc_retain(i8* [[T1]]) [[NUW]]
+// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[TEST29]]*
+// CHECK-NEXT: [[RET:%.*]] = bitcast [[TEST29]]* [[T1]] to i8*
// CHECK-NEXT: store i32 1, i32* [[CLEANUP]]
// Cleanup.
@@ -814,7 +801,9 @@ char *helper;
// Return.
// CHECK-NEXT: [[T0:%.*]] = load [[TEST30]]** [[SELF]]
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST30]]* [[T0]] to i8*
-// CHECK-NEXT: [[RET:%.*]] = call i8* @objc_retain(i8* [[T1]])
+// CHECK-NEXT: [[T0:%.*]] = call i8* @objc_retain(i8* [[T1]])
+// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[TEST30]]*
+// CHECK-NEXT: [[RET:%.*]] = bitcast [[TEST30]]* [[T1]] to i8*
// CHECK-NEXT: store i32 1
// Cleanup.
@@ -877,8 +866,8 @@ void test33(Test33 *ptr) {
// CHECK-NEXT: store [[A_T]]* null, [[A_T]]** [[A]]
// CHECK-NEXT: load [[TEST33]]** [[PTR]]
- // CHECK-NEXT: [[T0:%.*]] = load [[A_T]]** [[A]]
- // CHECK-NEXT: store [[A_T]]* [[T0]], [[A_T]]** [[TEMP0]]
+ // CHECK-NEXT: [[W0:%.*]] = load [[A_T]]** [[A]]
+ // CHECK-NEXT: store [[A_T]]* [[W0]], [[A_T]]** [[TEMP0]]
// CHECK-NEXT: load i8** @"\01L_OBJC_SELECTOR_REFERENCES_
// CHECK-NEXT: bitcast
// CHECK-NEXT: objc_msgSend{{.*}}, [[A_T]]** [[TEMP0]])
@@ -886,14 +875,15 @@ void test33(Test33 *ptr) {
// CHECK-NEXT: [[T1:%.*]] = bitcast [[A_T]]* [[T0]] to i8*
// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]])
// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A_T]]*
+ // CHECK-NEXT: call void (...)* @clang.arc.use([[A_T]]* [[W0]]) [[NUW]]
// CHECK-NEXT: [[T4:%.*]] = load [[A_T]]** [[A]]
// CHECK-NEXT: store [[A_T]]* [[T3]], [[A_T]]** [[A]]
// CHECK-NEXT: [[T5:%.*]] = bitcast [[A_T]]* [[T4]] to i8*
// CHECK-NEXT: call void @objc_release(i8* [[T5]])
// CHECK-NEXT: load [[TEST33]]** [[PTR]]
- // CHECK-NEXT: [[T0:%.*]] = load [[A_T]]** [[A]]
- // CHECK-NEXT: store [[A_T]]* [[T0]], [[A_T]]** [[TEMP1]]
+ // CHECK-NEXT: [[W0:%.*]] = load [[A_T]]** [[A]]
+ // CHECK-NEXT: store [[A_T]]* [[W0]], [[A_T]]** [[TEMP1]]
// CHECK-NEXT: load i8** @"\01L_OBJC_SELECTOR_REFERENCES_
// CHECK-NEXT: bitcast
// CHECK-NEXT: objc_msgSend{{.*}}, [[A_T]]** [[TEMP1]])
@@ -901,6 +891,7 @@ void test33(Test33 *ptr) {
// CHECK-NEXT: [[T1:%.*]] = bitcast [[A_T]]* [[T0]] to i8*
// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]])
// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A_T]]*
+ // CHECK-NEXT: call void (...)* @clang.arc.use([[A_T]]* [[W0]]) [[NUW]]
// CHECK-NEXT: [[T4:%.*]] = load [[A_T]]** [[A]]
// CHECK-NEXT: store [[A_T]]* [[T3]], [[A_T]]** [[A]]
// CHECK-NEXT: [[T5:%.*]] = bitcast [[A_T]]* [[T4]] to i8*
@@ -974,15 +965,16 @@ void test37(void) {
// CHECK-NEXT: [[TEMP:%.*]] = alloca i8*
// CHECK-NEXT: store [[TEST37]]* null, [[TEST37]]** [[VAR]]
- // CHECK-NEXT: [[T0:%.*]] = load [[TEST37]]** [[VAR]]
- // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST37]]* [[T0]] to i8*
- // CHECK-NEXT: store i8* [[T1]], i8** [[TEMP]]
+ // CHECK-NEXT: [[W0:%.*]] = load [[TEST37]]** [[VAR]]
+ // CHECK-NEXT: [[W1:%.*]] = bitcast [[TEST37]]* [[W0]] to i8*
+ // CHECK-NEXT: store i8* [[W1]], i8** [[TEMP]]
// CHECK-NEXT: call void @test37_helper(i8** [[TEMP]])
// CHECK-NEXT: [[T0:%.*]] = load i8** [[TEMP]]
// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[TEST37]]*
// CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST37]]* [[T1]] to i8*
// CHECK-NEXT: [[T3:%.*]] = call i8* @objc_retain(i8* [[T2]])
// CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to [[TEST37]]*
+ // CHECK-NEXT: call void (...)* @clang.arc.use(i8* [[W1]]) [[NUW]]
// CHECK-NEXT: [[T5:%.*]] = load [[TEST37]]** [[VAR]]
// CHECK-NEXT: store [[TEST37]]* [[T4]], [[TEST37]]** [[VAR]]
// CHECK-NEXT: [[T6:%.*]] = bitcast [[TEST37]]* [[T5]] to i8*
@@ -1239,57 +1231,6 @@ void test56_test(void) {
// CHECK-NEXT: [[T5:%.*]] = load i8** [[T4]]
// CHECK-NEXT: ret i8* [[T5]]
-// rdar://problem/9821110
-@interface Test58
-- (char*) interior __attribute__((objc_returns_inner_pointer));
-// Should we allow this on properties?
-@end
-extern Test58 *test58_helper(void);
-
-// CHECK: define void @test58a()
-void test58a(void) {
- // CHECK: [[T0:%.*]] = call [[TEST58:%.*]]* @test58_helper()
- // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST58]]* [[T0]] to i8*
- // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]])
- // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST58]]*
- // CHECK-NEXT: store [[TEST58]]* [[T3]]
- // CHECK-NEXT: [[T0:%.*]] = load [[TEST58]]**
- // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST58]]* [[T0]] to i8*
- // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutorelease(i8* [[T1]])
- // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST58]]*
- // CHECK-NEXT: [[T4:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_
- // CHECK-NEXT: [[T5:%.*]] = bitcast [[TEST58]]* [[T3]] to i8*
- // CHECK-NEXT: [[T6:%.*]] = call i8* bitcast
- // CHECK-NEXT: store i8* [[T6]], i8**
- // CHECK-NEXT: [[T0:%.*]] = load [[TEST58]]**
- // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST58]]* [[T0]] to i8*
- // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]], !clang.imprecise_release
- // CHECK-NEXT: ret void
- Test58 *ptr = test58_helper();
- char *c = [(ptr) interior];
-}
-
-// CHECK: define void @test58b()
-void test58b(void) {
- // CHECK: [[T0:%.*]] = call [[TEST58:%.*]]* @test58_helper()
- // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST58]]* [[T0]] to i8*
- // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]])
- // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST58]]*
- // CHECK-NEXT: store [[TEST58]]* [[T3]]
- // CHECK-NEXT: [[T0:%.*]] = load [[TEST58]]**
- // CHECK-NEXT: [[T1:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_
- // CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST58]]* [[T0]] to i8*
- // CHECK-NEXT: [[T3:%.*]] = call i8* bitcast
- // CHECK-NEXT: store i8* [[T3]], i8**
- // CHECK-NEXT: [[T0:%.*]] = load [[TEST58]]**
- // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST58]]* [[T0]] to i8*
- // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]]
- // CHECK-NOT: clang.imprecise_release
- // CHECK-NEXT: ret void
- __attribute__((objc_precise_lifetime)) Test58 *ptr = test58_helper();
- char *c = [ptr interior];
-}
-
// rdar://problem/9842343
void test59(void) {
extern id test59_getlock(void);
diff --git a/test/CodeGenObjC/autorelease.m b/test/CodeGenObjC/autorelease.m
index 830929afb2..f89b81a8ac 100644
--- a/test/CodeGenObjC/autorelease.m
+++ b/test/CodeGenObjC/autorelease.m
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-arc -fobjc-runtime=macosx-10.7 -o - %s | FileCheck %s
-// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -emit-llvm -fobjc-runtime=macosx-10.7 -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-arc -fobjc-runtime=macosx-10.7 -fexceptions -fobjc-exceptions -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -emit-llvm -fobjc-runtime=macosx-10.7 -fexceptions -fobjc-exceptions -o - %s | FileCheck %s
// rdar://8881826
// rdar://9412038
@@ -28,3 +28,26 @@
// CHECK: call i8* @objc_autoreleasePoolPush
// CHECK: [[T:%.*]] = load i8** [[A:%.*]]
// CHECK: call void @objc_autoreleasePoolPop
+
+// rdar://13660038
+int tryTo(int (*f)(void)) {
+ @try {
+ @autoreleasepool {
+ return f();
+ }
+ } @catch (...) {
+ return 0;
+ }
+}
+// CHECK: define i32 @tryTo(i32 ()*
+// CHECK: [[RET:%.*]] = alloca i32,
+// CHECK: [[T0:%.*]] = call i8* @objc_autoreleasePoolPush()
+// CHECK-NEXT: [[T1:%.*]] = load i32 ()** {{%.*}},
+// CHECK-NEXT: [[T2:%.*]] = invoke i32 [[T1]]()
+// CHECK: store i32 [[T2]], i32* [[RET]]
+// CHECK: invoke void @objc_autoreleasePoolPop(i8* [[T0]])
+// CHECK: landingpad { i8*, i32 } personality
+// CHECK-NEXT: catch i8* null
+// CHECK: call i8* @objc_begin_catch
+// CHECK-NEXT: store i32 0, i32* [[RET]]
+// CHECK: call void @objc_end_catch()
diff --git a/test/CodeGenObjC/blocks.m b/test/CodeGenObjC/blocks.m
index f072c48669..3718ad590a 100644
--- a/test/CodeGenObjC/blocks.m
+++ b/test/CodeGenObjC/blocks.m
@@ -93,7 +93,8 @@ void test2(Test2 *x) {
// doesn't require a read barrier.
// CHECK: define internal void @__test2_block_invoke
// CHECK: [[BLOCK:%.*]] = bitcast i8* {{%.*}} to [[BLOCK_T]]*
-// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
+// CHECK-NOT: bitcast
+// CHECK: [[T0:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
// CHECK-NEXT: [[T1:%.*]] = load i8** [[T0]]
// CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to [[WEAK_T]]{{.*}}*
// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds [[WEAK_T]]{{.*}}* [[T2]], i32 0, i32 1
diff --git a/test/CodeGenObjC/debug-info-block-captured-self.m b/test/CodeGenObjC/debug-info-block-captured-self.m
new file mode 100644
index 0000000000..183e91b6ec
--- /dev/null
+++ b/test/CodeGenObjC/debug-info-block-captured-self.m
@@ -0,0 +1,69 @@
+// RUN: %clang_cc1 -fblocks -g -emit-llvm -triple x86_64-apple-darwin -o - %s | FileCheck %s
+//
+// Test that debug location is generated for a captured "self" inside
+// a block.
+//
+// This test is split into two parts, this one for the frontend, and
+// then llvm/test/DebugInfo/debug-info-block-captured-self.ll to
+// ensure that DW_AT_location is generated for the captured self.
+@class T;
+@interface S
+@end
+@interface Mode
+-(int) count;
+@end
+@interface Context
+@end
+@interface ViewController
+@property (nonatomic, readwrite, strong) Context *context;
+@end
+typedef enum {
+ Unknown = 0,
+} State;
+@interface Main : ViewController
+{
+ T * t1;
+ T * t2;
+}
+@property(readwrite, nonatomic) State state;
+@end
+@implementation Main
+- (id) initWithContext:(Context *) context
+{
+ t1 = [self.context withBlock:^(id obj){
+ id *mode1;
+ t2 = [mode1 withBlock:^(id object){
+ Mode *mode2 = object;
+ if ([mode2 count] != 0) {
+ self.state = 0;
+ }
+ }];
+ }];
+}
+@end
+// The important part of this test is that there is a dbg.value
+// intrinsic associated with the implicit .block_descriptor argument
+// of the block. We also test that this value gets alloca'd, so the
+// register llocator won't accidentally kill it.
+
+// outer block:
+// CHECK: define internal void {{.*}}_block_invoke{{.*}}
+
+// inner block:
+// CHECK: define internal void {{.*}}_block_invoke{{.*}}
+// CHECK: %[[MEM1:.*]] = alloca i8*, align 8
+// CHECK-NEXT: %[[MEM2:.*]] = alloca i8*, align 8
+// CHECK: store i8* [[BLOCK_DESC:%.*]], i8** %[[MEM1]], align 8
+// CHECK: %[[TMP0:.*]] = load i8** %[[MEM1]]
+// CHECK: call void @llvm.dbg.value(metadata !{i8* %[[TMP0]]}, i64 0, metadata ![[BDMD:[0-9]+]])
+// CHECK: call void @llvm.dbg.declare(metadata !{i8* [[BLOCK_DESC]]}, metadata ![[BDMD:[0-9]+]])
+// CHECK: %[[TMP1:.*]] = bitcast
+// CHECK-NEXT: store
+// CHECK: call void @llvm.dbg.declare(metadata !{<{ i8*, i32, i32, i8*, %struct.__block_descriptor*, %0* }>** {{.*}}}, metadata ![[SELF:.*]])
+// make sure we are still in the same function
+// CHECK: define {{.*}}__copy_helper_block_
+// Metadata
+// CHECK: ![[MAIN:.*]] = {{.*}}!"Main"{{.*}}DW_TAG_structure_type{{.*}}line 23
+// CHECK: ![[PMAIN:.*]] = {{.*}}![[MAIN]]} ; [ DW_TAG_pointer_type ]{{.*}}from Main
+// CHECK: ![[BDMD]] = metadata {{.*}}.block_descriptor
+// CHECK: ![[SELF]] = {{.*}}![[PMAIN]]{{.*}}[ DW_TAG_auto_variable ] [self] [line 40]
diff --git a/test/CodeGenObjC/debug-info-block-helper.m b/test/CodeGenObjC/debug-info-block-helper.m
index 5f4a87a565..49c8c5daea 100644
--- a/test/CodeGenObjC/debug-info-block-helper.m
+++ b/test/CodeGenObjC/debug-info-block-helper.m
@@ -2,7 +2,7 @@
// RUN: %clang_cc1 -emit-llvm -fblocks -g -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 %s -o - | FileCheck %s
extern void foo(void(^)(void));
-// CHECK: metadata !{i32 786478, i32 0, metadata ![[FILE:.*]], metadata !"__destroy_helper_block_", metadata !"__destroy_helper_block_", metadata !"", metadata ![[FILE]], i32 24, metadata !{{.*}}, i1 true, i1 true, i32 0, i32 0, null, i32 0, i1 false, void (i8*)* @__destroy_helper_block_, null, null, metadata !{{.*}}, i32 24} ; [ DW_TAG_subprogram ]
+// CHECK: [ DW_TAG_subprogram ] {{.*}} [__destroy_helper_block_]
@interface NSObject {
struct objc_object *isa;
diff --git a/test/CodeGenObjC/debug-info-block-line.m b/test/CodeGenObjC/debug-info-block-line.m
index c913a972e1..2192575bb7 100644
--- a/test/CodeGenObjC/debug-info-block-line.m
+++ b/test/CodeGenObjC/debug-info-block-line.m
@@ -64,13 +64,16 @@ typedef enum : NSUInteger {
// CHECK: define internal void @"__39-[TServer serverConnection:getCommand:]_block_invoke"
// CHECK: call void @objc_storeStrong(i8** [[ZERO:%.*]], i8* [[ONE:%.*]]) [[NUW:#[0-9]+]]
// CHECK: call void @objc_storeStrong(i8** [[TWO:%.*]], i8* [[THREE:%.*]]) [[NUW]]
+// CHECK: call {{.*}}@objc_msgSend{{.*}}, !dbg ![[LINE_ABOVE:[0-9]+]]
+// CHECK: getelementptr
+// CHECK-NOT: !dbg, ![[LINE_ABOVE]]
// CHECK: bitcast %5** [[TMP:%.*]] to i8**
-// CHECK: call void @objc_storeStrong(i8** [[VAL1:%.*]], i8* null) [[NUW]], !dbg ![[MD1:.*]]
-// CHECK: bitcast %4** [[TMP:%.*]] to i8**
-// CHECK: call void @objc_storeStrong(i8** [[VAL2:%.*]], i8* null) [[NUW]], !dbg ![[MD1]]
+// CHECK-NOT: !dbg, ![[LINE_ABOVE]]
+// CHECK: call void @objc_storeStrong(i8** [[VAL1:%.*]], i8* null) [[NUW]]
+// CHECK-NEXT: bitcast %4** [[TMP:%.*]] to i8**
+// CHECK-NEXT: call void @objc_storeStrong(i8** [[VAL2:%.*]], i8* null) [[NUW]]
// CHECK-NEXT: ret
// CHECK: attributes [[NUW]] = { nounwind }
-// CHECK: ![[MD1]] = metadata !{i32 87
[map dataWithCompletionBlock:^(NSData *data, NSError *error) {
if (data) {
NSString *encoded = [[data compressedData] encodedString:18];
diff --git a/test/CodeGenObjC/debug-info-blocks.m b/test/CodeGenObjC/debug-info-blocks.m
index 71ae8a610e..3d91c9ea5c 100644
--- a/test/CodeGenObjC/debug-info-blocks.m
+++ b/test/CodeGenObjC/debug-info-blocks.m
@@ -1,9 +1,16 @@
-// REQUIRES: x86-64-registered-target
-// RUN: %clang_cc1 -masm-verbose -S -fblocks -g -triple x86_64-apple-darwin10 -fobjc-dispatch-method=mixed %s -o - | FileCheck %s
-
-//Radar 9279956
-//CHECK: ## DW_OP_deref
-//CHECK-NEXT: ## DW_OP_plus_uconst
+// RUN: %clang_cc1 -emit-llvm -fblocks -g -triple x86_64-apple-darwin10 -fobjc-dispatch-method=mixed %s -o - | FileCheck %s
+
+// rdar://problem/9279956
+// Test that we generate the proper debug location for a captured self.
+// The second half of this patch is in llvm/tests/DebugInfo/debug-info-blocks.ll
+
+// CHECK: define {{.*}}_block_invoke
+// CHECK: %[[BLOCK:.*]] = bitcast i8* %.block_descriptor to <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, %0* }>*, !dbg
+// CHECK-NEXT: store <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, %0* }>* %[[BLOCK]], <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, %0* }>** %[[ALLOCA:.*]], align
+// CHECK-NEXT: call void @llvm.dbg.declare(metadata !{<{ i8*, i32, i32, i8*, %struct.__block_descriptor*, %0* }>** %[[ALLOCA]]}, metadata ![[SELF:[0-9]+]])
+// CHECK-NEXT: call void @llvm.dbg.declare(metadata !{%1** %d}, metadata ![[D:[0-9]+]])
+// CHECK: ![[SELF]] = {{.*}} [ DW_TAG_auto_variable ] [self] [line 51]
+// CHECK: ![[D]] = {{.*}} [d] [line 49]
typedef unsigned int NSUInteger;
diff --git a/test/CodeGenObjC/debug-info-fwddecl.m b/test/CodeGenObjC/debug-info-fwddecl.m
index 8f2860c7d8..b41c485e19 100644
--- a/test/CodeGenObjC/debug-info-fwddecl.m
+++ b/test/CodeGenObjC/debug-info-fwddecl.m
@@ -2,4 +2,4 @@
@class ForwardObjcClass;
ForwardObjcClass *ptr = 0;
-// CHECK: metadata !{i32 {{.*}}, null, metadata !"ForwardObjcClass", metadata !{{.*}}, i32 2, i64 0, i64 0, i32 0, i32 4, null, null, i32 16} ; [ DW_TAG_structure_type ]
+// CHECK: {{.*}} [ DW_TAG_structure_type ] [ForwardObjcClass] [line 2, size 0, align 0, offset 0] [fwd]
diff --git a/test/CodeGenObjC/debug-info-impl.m b/test/CodeGenObjC/debug-info-impl.m
index 51d111454f..8991a88962 100644
--- a/test/CodeGenObjC/debug-info-impl.m
+++ b/test/CodeGenObjC/debug-info-impl.m
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -g -S -emit-llvm %s -o - | FileCheck %s
-// CHECK: metadata !{i32 {{.*}}, metadata {{.*}}, metadata !"Circle", metadata {{.*}}, i32 11, i64 64, i64 64, i32 0, i32 512, null, metadata {{.*}}, i32 16, null, null} ; [ DW_TAG_structure_type ]
+// CHECK: {{.*}} [ DW_TAG_structure_type ] [Circle] [line 11,
@interface NSObject {
struct objc_object *isa;
}
diff --git a/test/CodeGenObjC/debug-info-ivars-extension.m b/test/CodeGenObjC/debug-info-ivars-extension.m
index 733d146875..e43b598f70 100644
--- a/test/CodeGenObjC/debug-info-ivars-extension.m
+++ b/test/CodeGenObjC/debug-info-ivars-extension.m
@@ -24,10 +24,10 @@ void gorf (I* pg) {
int _b = pg->b;
}
-// CHECK: metadata !{i32 {{[0-9]*}}, metadata !{{[0-9]*}}, metadata !"I", {{.*}}} ; [ DW_TAG_structure_type ]
+// CHECK: {{.*}} [ DW_TAG_structure_type ] [I]
// Check for "a".
-// CHECK: metadata !{i32 {{[0-9]*}}, metadata !{{[0-9]*}}, metadata !"a", metadata !{{[0-9]*}}, i32 7, i64 32, i64 32, i64 0, i32 0, metadata !{{[0-9]*}}, null} ; [ DW_TAG_member ] [a] [line 7, size 32, align 32, offset 0] [from int]
+// CHECK: {{.*}} [ DW_TAG_member ] [a] [line 7, size 32, align 32, offset 0] [from int]
// Make sure we don't output the same type twice.
-// CHECK-NOT: metadata !{i32 {{[0-9]*}}, metadata !{{[0-9]*}}, metadata !"I", {{.*}}} ; [ DW_TAG_structure_type ]
+// CHECK-NOT: {{.*}} [ DW_TAG_structure_type ] [I]
// Check for "b".
-// CHECK: metadata !{i32 {{[0-9]*}}, metadata !{{[0-9]*}}, metadata !"b", metadata !{{[0-9]*}}, i32 18, i64 32, i64 32, i64 0, i32 0, metadata !{{[0-9]*}}, null} ; [ DW_TAG_member ] [b] [line 18, size 32, align 32, offset 0] [from int]
+// CHECK: {{.*}} [ DW_TAG_member ] [b] [line 18, size 32, align 32, offset 0] [from int]
diff --git a/test/CodeGenObjC/debug-info-ivars-indirect.m b/test/CodeGenObjC/debug-info-ivars-indirect.m
index 9f7f940133..1548ddd0bb 100644
--- a/test/CodeGenObjC/debug-info-ivars-indirect.m
+++ b/test/CodeGenObjC/debug-info-ivars-indirect.m
@@ -29,4 +29,4 @@ void gorf (struct S* s) {
int _b = s->i->b;
}
-// CHECK: metadata !{i32 {{[0-9]*}}, metadata !{{[0-9]*}}, metadata !"b", metadata !{{[0-9]*}}, i32 24, i64 32, i64 32, i64 0, i32 0, metadata !{{[0-9]*}}, null} ; [ DW_TAG_member ] [b] [line 24, size 32, align 32, offset 0] [from int]
+// CHECK: {{.*}} [ DW_TAG_member ] [b] [line 24, size 32, align 32, offset 0] [from int]
diff --git a/test/CodeGenObjC/debug-info-ivars-private.m b/test/CodeGenObjC/debug-info-ivars-private.m
index 0a555c2a8b..8505da17bb 100644
--- a/test/CodeGenObjC/debug-info-ivars-private.m
+++ b/test/CodeGenObjC/debug-info-ivars-private.m
@@ -32,5 +32,5 @@ __attribute((objc_root_class)) @interface NSObject {
}
@end
-// CHECK: metadata !{i32 {{[0-9]*}}, metadata !{{[0-9]*}}, metadata !"foo", metadata !{{[0-9]*}}, i32 14, i64 32, i64 32, i64 0, i32 2, metadata !{{[0-9]*}}, null} ; [ DW_TAG_member ] [foo] [line 14, size 32, align 32, offset 0] [protected] [from int]
-// CHECK: metadata !{i32 {{[0-9]*}}, metadata !{{[0-9]*}}, metadata !"bar", metadata !{{[0-9]*}}, i32 27, i64 32, i64 32, i64 0, i32 1, metadata !{{[0-9]*}}, null} ; [ DW_TAG_member ] [bar] [line 27, size 32, align 32, offset 0] [private] [from int]
+// CHECK: {{.*}} [ DW_TAG_member ] [foo] [line 14, size 32, align 32, offset 0] [protected] [from int]
+// CHECK: {{.*}} [ DW_TAG_member ] [bar] [line 27, size 32, align 32, offset 0] [private] [from int]
diff --git a/test/CodeGenObjC/debug-info-ivars.m b/test/CodeGenObjC/debug-info-ivars.m
index 24705e1ad6..a0f2963f5d 100644
--- a/test/CodeGenObjC/debug-info-ivars.m
+++ b/test/CodeGenObjC/debug-info-ivars.m
@@ -1,7 +1,7 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -g %s -o - | FileCheck %s
__attribute((objc_root_class)) @interface NSObject {
- id isa;
+ id isa;
}
@end
@@ -10,15 +10,15 @@ __attribute((objc_root_class)) @interface NSObject {
int i;
unsigned flag_1 : 9;
unsigned flag_2 : 9;
- unsigned : 1;
- unsigned flag_3 : 9;
+ unsigned : 1;
+ unsigned flag_3 : 9;
}
@end
@implementation BaseClass
@end
-// CHECK: metadata !{i32 786445, metadata !{{[0-9]*}}, metadata !"i", metadata !{{[0-9]*}}, i32 10, i64 32, i64 32, i64 0, i32 2, metadata !{{[0-9]*}}, null} ; [ DW_TAG_member ] [i] [line 10, size 32, align 32, offset 0] [protected] [from int]
-// CHECK: metadata !{i32 786445, metadata !{{[0-9]*}}, metadata !"flag_1", metadata !{{[0-9]*}}, i32 11, i64 9, i64 32, i64 0, i32 2, metadata !{{[0-9]*}}, null} ; [ DW_TAG_member ] [flag_1] [line 11, size 9, align 32, offset 0] [protected] [from unsigned int]
-// CHECK: metadata !{i32 786445, metadata !{{[0-9]*}}, metadata !"flag_2", metadata !{{[0-9]*}}, i32 12, i64 9, i64 32, i64 1, i32 2, metadata !{{[0-9]*}}, null} ; [ DW_TAG_member ] [flag_2] [line 12, size 9, align 32, offset 1] [protected] [from unsigned int]
-// CHECK: metadata !{i32 786445, metadata !{{[0-9]*}}, metadata !"flag_3", metadata !{{[0-9]*}}, i32 14, i64 9, i64 32, i64 3, i32 2, metadata !{{[0-9]*}}, null} ; [ DW_TAG_member ] [flag_3] [line 14, size 9, align 32, offset 3] [protected] [from unsigned int] \ No newline at end of file
+// CHECK: {{.*}} [ DW_TAG_member ] [i] [line 10, size 32, align 32, offset 0] [protected] [from int]
+// CHECK: {{.*}} [ DW_TAG_member ] [flag_1] [line 11, size 9, align 32, offset 0] [protected] [from unsigned int]
+// CHECK: {{.*}} [ DW_TAG_member ] [flag_2] [line 12, size 9, align 32, offset 1] [protected] [from unsigned int]
+// CHECK: {{.*}} [ DW_TAG_member ] [flag_3] [line 14, size 9, align 32, offset 3] [protected] [from unsigned int]
diff --git a/test/CodeGenObjC/debug-info-pubtypes.m b/test/CodeGenObjC/debug-info-pubtypes.m
index ebe87d40f7..8b7dfadfd9 100644
--- a/test/CodeGenObjC/debug-info-pubtypes.m
+++ b/test/CodeGenObjC/debug-info-pubtypes.m
@@ -1,7 +1,7 @@
// REQUIRES: x86-64-registered-target
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -g -emit-llvm %s -o - | FileCheck %s
-// CHECK: !{{.*}} = metadata !{i32 {{.*}}, metadata ![[FILE:.*]], metadata !"H", metadata ![[FILE]], i32 6, i64 0, i64 8, i32 0, i32 512, null, metadata !{{.*}}, i32 16, null, null} ; [ DW_TAG_structure_type ]
+// CHECK: {{.*}} [ DW_TAG_structure_type ] [H] [line 6,
@interface H
-(void) foo;
diff --git a/test/CodeGenObjC/debug-info-synthesis.m b/test/CodeGenObjC/debug-info-synthesis.m
index fac9eca4a1..1bf7576d88 100644
--- a/test/CodeGenObjC/debug-info-synthesis.m
+++ b/test/CodeGenObjC/debug-info-synthesis.m
@@ -30,5 +30,5 @@ int main(int argc, char *argv[]) {
}
}
-// CHECK: ![[FILE:.*]] = metadata !{i32 {{.*}}, metadata !"./foo.h"
-// CHECK: !{{.*}} = metadata !{i32 {{.*}}, i32 0, metadata ![[FILE]], metadata !"-[Foo dict]", metadata !"-[Foo dict]", metadata !"", metadata ![[FILE]], i32 8, metadata !{{.*}}, i1 true, i1 true, i32 0, i32 0, null, i32 320, i1 false, %1* (%0*, i8*)* @"\01-[Foo dict]", null, null, metadata !{{.*}}, i32 8} ; [ DW_TAG_subprogram ]
+// CHECK: ![[FILE:.*]] = {{.*}}[ DW_TAG_file_type ] [{{.*}}/foo.h]
+// CHECK: metadata ![[FILE]], {{.*}} ; [ DW_TAG_subprogram ] [line 8] [local] [def] [-[Foo dict]]
diff --git a/test/CodeGenObjC/encode-test-3.m b/test/CodeGenObjC/encode-test-3.m
index 4b39cd718e..b76063ffd3 100644
--- a/test/CodeGenObjC/encode-test-3.m
+++ b/test/CodeGenObjC/encode-test-3.m
@@ -1,12 +1,14 @@
-// RUN: %clang_cc1 -triple=i686-apple-darwin9 -emit-llvm -o %t %s
-// RUN: grep -e "\^i" %t | count 1
-// RUN: grep -e "\[0i\]" %t | count 1
+// RUN: %clang_cc1 -triple=i686-apple-darwin9 -emit-llvm -o - %s | FileCheck %s
int main() {
int n;
const char * inc = @encode(int[]);
+// CHECK: ^i
+// CHECK-NOT: ^i
const char * vla = @encode(int[n]);
+// CHECK: [0i]
+// CHECK-NOT: [0i]
}
// PR3648
diff --git a/test/CodeGenObjC/exceptions.m b/test/CodeGenObjC/exceptions.m
index 551e67c2e6..408b94d385 100644
--- a/test/CodeGenObjC/exceptions.m
+++ b/test/CodeGenObjC/exceptions.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -fexceptions -fobjc-exceptions -O2 -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -fobjc-exceptions -O2 -o - %s | FileCheck %s
//
// <rdar://problem/7471679> [irgen] [eh] Exception code built with clang (x86_64) crashes
@@ -28,7 +28,7 @@ void f1() {
// CHECK: call void asm sideeffect "", "*m"
// CHECK-NEXT: call void @foo()
foo();
- // CHECK-NEXT: call void @objc_exception_try_exit
+ // CHECK: call void @objc_exception_try_exit
// CHECK: call void asm sideeffect "", "=*m"
} @finally {
diff --git a/test/CodeGenObjC/metadata-symbols-32.m b/test/CodeGenObjC/metadata-symbols-32.m
index e8d25129a7..fda909ca74 100644
--- a/test/CodeGenObjC/metadata-symbols-32.m
+++ b/test/CodeGenObjC/metadata-symbols-32.m
@@ -1,32 +1,32 @@
-// RUN: %clang_cc1 -triple i386-apple-darwin9 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -o %t %s
-
-// RUN: grep '@"\\01L_OBJC_CATEGORY_A_Cat" = internal global .*section "__OBJC,__category,regular,no_dead_strip", align 4' %t
-// RUN: grep '@"\\01L_OBJC_CATEGORY_CLASS_METHODS_A_Cat" = internal global .*section "__OBJC,__cat_cls_meth,regular,no_dead_strip", align 4' %t
-// RUN: grep '@"\\01L_OBJC_CATEGORY_INSTANCE_METHODS_A_Cat" = internal global .*section "__OBJC,__cat_inst_meth,regular,no_dead_strip", align 4' %t
-// RUN: grep '@"\\01L_OBJC_CLASSEXT_A" = internal global .*section "__OBJC,__class_ext,regular,no_dead_strip", align 4' %t
-// RUN: grep '@"\\01L_OBJC_CLASS_A" = internal global .*section "__OBJC,__class,regular,no_dead_strip", align 4' %t
-// RUN: grep '@"\\01L_OBJC_CLASS_METHODS_A" = internal global .*section "__OBJC,__cls_meth,regular,no_dead_strip", align 4' %t
-// RUN: grep '@"\\01L_OBJC_CLASS_NAME_[0-9]*" = internal global .*section "__TEXT,__cstring,cstring_literals", align 1' %t
-// RUN: grep '@"\\01L_OBJC_CLASS_PROTOCOLS_A" = internal global .*section "__OBJC,__cat_cls_meth,regular,no_dead_strip", align 4' %t
-// RUN: grep '@"\\01L_OBJC_CLASS_REFERENCES_[0-9]*" = internal global .*section "__OBJC,__cls_refs,literal_pointers,no_dead_strip", align 4' %t
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -o - %s | FileCheck %s
+
+// CHECK: .lazy_reference .objc_class_name_J0
+
+// CHECK: @"\01L_OBJC_METH_VAR_NAME_{{[0-9]*}}" = internal global {{.*}}section "__TEXT,__cstring,cstring_literals", align 1
+// CHECK: @"\01L_OBJC_METH_VAR_TYPE_{{[0-9]*}}" = internal global {{.*}}section "__TEXT,__cstring,cstring_literals", align 1
+// CHECK: @"\01L_OBJC_CLASS_NAME_{{[0-9]*}}" = internal global {{.*}}section "__TEXT,__cstring,cstring_literals", align 1
+// CHECK: @"\01L_OBJC_PROTOCOL_INSTANCE_METHODS_P" = internal global {{.*}}section "__OBJC,__cat_inst_meth,regular,no_dead_strip", align 4
+// CHECK: @"\01L_OBJC_PROTOCOL_CLASS_METHODS_P" = internal global {{.*}}section "__OBJC,__cat_cls_meth,regular,no_dead_strip", align 4
+// CHECK: @"\01L_OBJC_PROTOCOL_P" = internal global {{.*}}section "__OBJC,__protocol,regular,no_dead_strip", align 4
+// CHECK: @"\01L_OBJC_CLASS_PROTOCOLS_A" = internal global {{.*}}section "__OBJC,__cat_cls_meth,regular,no_dead_strip", align 4
+// CHECK: @"\01L_OBJC_CLASS_METHODS_A" = internal global {{.*}}section "__OBJC,__cls_meth,regular,no_dead_strip", align 4
+// CHECK: @"\01L_OBJC_METACLASS_A" = internal global {{.*}}section "__OBJC,__meta_class,regular,no_dead_strip", align 4
+// CHECK: @"\01L_OBJC_INSTANCE_VARIABLES_A" = internal global {{.*}}section "__OBJC,__instance_vars,regular,no_dead_strip", align 4
+// CHECK: @"\01L_OBJC_INSTANCE_METHODS_A" = internal global {{.*}}section "__OBJC,__inst_meth,regular,no_dead_strip", align 4
+// CHECK: @"\01L_OBJC_PROP_NAME_ATTR_{{[0-9]*}}" = internal global {{.*}}section "__TEXT,__cstring,cstring_literals", align 1
+// CHECK: @"\01l_OBJC_$_PROP_LIST_A" = internal global {{.*}}section "__OBJC,__property,regular,no_dead_strip", align 4
+// CHECK: @"\01L_OBJC_CLASSEXT_A" = internal global {{.*}}section "__OBJC,__class_ext,regular,no_dead_strip", align 4
+// CHECK: @"\01L_OBJC_CLASS_A" = internal global {{.*}}section "__OBJC,__class,regular,no_dead_strip", align 4
+// CHECK: @"\01L_OBJC_CATEGORY_INSTANCE_METHODS_A_Cat" = internal global {{.*}}section "__OBJC,__cat_inst_meth,regular,no_dead_strip", align 4
+// CHECK: @"\01L_OBJC_CATEGORY_CLASS_METHODS_A_Cat" = internal global {{.*}}section "__OBJC,__cat_cls_meth,regular,no_dead_strip", align 4
+// CHECK: @"\01L_OBJC_CATEGORY_A_Cat" = internal global {{.*}}section "__OBJC,__category,regular,no_dead_strip", align 4
+// CHECK: @"\01L_OBJC_CLASS_REFERENCES_{{[0-9]*}}" = internal global {{.*}}section "__OBJC,__cls_refs,literal_pointers,no_dead_strip", align 4
+// CHECK: @"\01L_OBJC_SELECTOR_REFERENCES_{{[0-9]*}}" = internal externally_initialized global {{.*}}section "__OBJC,__message_refs,literal_pointers,no_dead_strip", align 4
+// CHECK: @"\01L_OBJC_SYMBOLS" = internal global {{.*}}section "__OBJC,__symbols,regular,no_dead_strip", align 4
+// CHECK: @"\01L_OBJC_MODULES" = internal global {{.*}}section "__OBJC,__module_info,regular,no_dead_strip", align 4
// Clang's Obj-C 32-bit doesn't emit ivars for the root class.
-// RUNX: grep '@"\\01L_OBJC_CLASS_VARIABLES_A" = internal global .*section "__OBJC,__class_vars,regular,no_dead_strip", align 4' %t &&
-
-// RUN: grep '@"\\01L_OBJC_INSTANCE_METHODS_A" = internal global .*section "__OBJC,__inst_meth,regular,no_dead_strip", align 4' %t
-// RUN: grep '@"\\01L_OBJC_INSTANCE_VARIABLES_A" = internal global .*section "__OBJC,__instance_vars,regular,no_dead_strip", align 4' %t
-// RUN: grep '@"\\01L_OBJC_METACLASS_A" = internal global .*section "__OBJC,__meta_class,regular,no_dead_strip", align 4' %t
-// RUN: grep '@"\\01L_OBJC_METH_VAR_NAME_[0-9]*" = internal global .*section "__TEXT,__cstring,cstring_literals", align 1' %t
-// RUN: grep '@"\\01L_OBJC_METH_VAR_TYPE_[0-9]*" = internal global .*section "__TEXT,__cstring,cstring_literals", align 1' %t
-// RUN: grep '@"\\01L_OBJC_MODULES" = internal global .*section "__OBJC,__module_info,regular,no_dead_strip", align 4' %t
-// RUN: grep '@"\\01L_OBJC_PROP_NAME_ATTR_[0-9]*" = internal global .*section "__TEXT,__cstring,cstring_literals", align 1' %t
-// RUN: grep '@"\\01L_OBJC_PROTOCOL_CLASS_METHODS_P" = internal global .*section "__OBJC,__cat_cls_meth,regular,no_dead_strip", align 4' %t
-// RUN: grep '@"\\01L_OBJC_PROTOCOL_INSTANCE_METHODS_P" = internal global .*section "__OBJC,__cat_inst_meth,regular,no_dead_strip", align 4' %t
-// RUN: grep '@"\\01L_OBJC_PROTOCOL_P" = internal global .*section "__OBJC,__protocol,regular,no_dead_strip", align 4' %t
-// RUN: grep '@"\\01L_OBJC_SELECTOR_REFERENCES_[0-9]*" = internal externally_initialized global .*section "__OBJC,__message_refs,literal_pointers,no_dead_strip", align 4' %t
-// RUN: grep '@"\\01L_OBJC_SYMBOLS" = internal global .*section "__OBJC,__symbols,regular,no_dead_strip", align 4' %t
-// RUN: grep '@"\\01l_OBJC_$_PROP_LIST_A" = internal global .*section "__OBJC,__property,regular,no_dead_strip", align 4' %t
-// RUN: grep "\.lazy_reference \.objc_class_name_J0" %t
+// CHECKX: @"\01L_OBJC_CLASS_VARIABLES_A" = internal global {{.*}}section "__OBJC,__class_vars,regular,no_dead_strip", align 4
/*
diff --git a/test/CodeGenObjC/metadata-symbols-64.m b/test/CodeGenObjC/metadata-symbols-64.m
index 27017b76a8..a89fec56de 100644
--- a/test/CodeGenObjC/metadata-symbols-64.m
+++ b/test/CodeGenObjC/metadata-symbols-64.m
@@ -1,37 +1,38 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-dispatch-method=mixed -emit-llvm -o %t %s
-
-// RUN: grep '@"OBJC_CLASS_$_A" = global' %t
-// RUN: grep '@"OBJC_CLASS_$_B" = external global' %t
-// RUN: grep '@"OBJC_IVAR_$_A._ivar" = global .* section "__DATA, __objc_ivar", align 8' %t
-// RUN: grep '@"OBJC_METACLASS_$_A" = global .* section "__DATA, __objc_data", align 8' %t
-// RUN: grep '@"\\01L_OBJC_CLASSLIST_REFERENCES_$_[0-9]*" = internal global .* section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8' %t
-// RUN: grep '@"\\01L_OBJC_CLASSLIST_SUP_REFS_$_[0-9]*" = internal global .* section "__DATA, __objc_superrefs, regular, no_dead_strip", align 8' %t | count 2
-// RUN: grep '@"\\01L_OBJC_CLASS_NAME_[0-9]*" = internal global .* section "__TEXT,__objc_classname,cstring_literals", align 1' %t
-// RUN: grep '@"\\01L_OBJC_LABEL_CATEGORY_$" = internal global .* section "__DATA, __objc_catlist, regular, no_dead_strip", align 8' %t
-// RUN: grep '@"\\01L_OBJC_LABEL_CLASS_$" = internal global .* section "__DATA, __objc_classlist, regular, no_dead_strip", align 8' %t
-// RUN: grep '@"\\01L_OBJC_METH_VAR_NAME_[0-9]*" = internal global .* section "__TEXT,__objc_methname,cstring_literals", align 1' %t
-// RUN: grep '@"\\01L_OBJC_METH_VAR_TYPE_[0-9]*" = internal global .* section "__TEXT,__objc_methtype,cstring_literals", align 1' %t
-// RUN: grep '@"\\01L_OBJC_PROP_NAME_ATTR_[0-9]*" = internal global .* section "__TEXT,__cstring,cstring_literals", align 1' %t
-// RUN: grep '@"\\01L_OBJC_SELECTOR_REFERENCES_*" = internal externally_initialized global .* section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"' %t
-// RUN: grep '@"\\01l_OBJC_$_CATEGORY_A_$_Cat" = internal global .* section "__DATA, __objc_const", align 8' %t
-// RUN: grep '@"\\01l_OBJC_$_CATEGORY_CLASS_METHODS_A_$_Cat" = internal global .* section "__DATA, __objc_const", align 8' %t
-// RUN: grep '@"\\01l_OBJC_$_CATEGORY_INSTANCE_METHODS_A_$_Cat" = internal global .* section "__DATA, __objc_const", align 8' %t
-// RUN: grep '@"\\01l_OBJC_$_CLASS_METHODS_A" = internal global .* section "__DATA, __objc_const", align 8' %t
-// RUN: grep '@"\\01l_OBJC_$_INSTANCE_METHODS_A" = internal global .* section "__DATA, __objc_const", align 8' %t
-// RUN: grep '@"\\01l_OBJC_$_INSTANCE_VARIABLES_A" = internal global .* section "__DATA, __objc_const", align 8' %t
-// RUN: grep '@"\\01l_OBJC_$_PROP_LIST_A" = internal global .* section "__DATA, __objc_const", align 8' %t
-// RUN: grep '@"\\01l_OBJC_$_PROTOCOL_CLASS_METHODS_P" = internal global .* section "__DATA, __objc_const", align 8' %t
-// RUN: grep '@"\\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_P" = internal global .* section "__DATA, __objc_const", align 8' %t
-// RUN: grep '@"\\01l_OBJC_CLASS_PROTOCOLS_$_A" = internal global .* section "__DATA, __objc_const", align 8' %t
-// RUN: grep '@"\\01l_OBJC_CLASS_RO_$_A" = internal global .* section "__DATA, __objc_const", align 8' %t
-// RUN: grep '@"\\01l_OBJC_LABEL_PROTOCOL_$_P" = weak hidden global .* section "__DATA, __objc_protolist, coalesced, no_dead_strip", align 8' %t
-// RUN: grep '@"\\01l_OBJC_METACLASS_RO_$_A" = internal global .* section "__DATA, __objc_const", align 8' %t
-// RUN: grep '@"\\01l_OBJC_PROTOCOL_$_P" = weak hidden global .* section "__DATA,__datacoal_nt,coalesced", align 8' %t
-// RUN: grep '@"\\01l_objc_msgSend_fixup_alloc" = weak hidden global .* section "__DATA, __objc_msgrefs, coalesced", align 16' %t
-// RUN: grep '@_objc_empty_cache = external global' %t
-// RUN: grep '@_objc_empty_vtable = external global' %t
-// RUN: grep '@objc_msgSend_fixup(' %t
-// RUN: grep '@objc_msgSend_fpret(' %t
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-dispatch-method=mixed -emit-llvm -o - %s | FileCheck %s
+
+// CHECK: @"OBJC_IVAR_$_A._ivar" = global {{.*}} section "__DATA, __objc_ivar", align 8
+// CHECK: @_objc_empty_cache = external global
+// CHECK: @_objc_empty_vtable = external global
+// CHECK: @"OBJC_CLASS_$_A" = global
+// CHECK: @"OBJC_METACLASS_$_A" = global {{.*}} section "__DATA, __objc_data", align 8
+// CHECK: @"\01L_OBJC_CLASS_NAME_{{[0-9]*}}" = internal global {{.*}} section "__TEXT,__objc_classname,cstring_literals", align 1
+// CHECK: @"\01L_OBJC_METH_VAR_NAME_{{[0-9]*}}" = internal global {{.*}} section "__TEXT,__objc_methname,cstring_literals", align 1
+// CHECK: @"\01L_OBJC_METH_VAR_TYPE_{{[0-9]*}}" = internal global {{.*}} section "__TEXT,__objc_methtype,cstring_literals", align 1
+// CHECK: @"\01l_OBJC_$_CLASS_METHODS_A" = internal global {{.*}} section "__DATA, __objc_const", align 8
+// CHECK: @"\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_P" = internal global {{.*}} section "__DATA, __objc_const", align 8
+// CHECK: @"\01l_OBJC_$_PROTOCOL_CLASS_METHODS_P" = internal global {{.*}} section "__DATA, __objc_const", align 8
+// CHECK: @"\01l_OBJC_PROTOCOL_$_P" = weak hidden global {{.*}} section "__DATA,__datacoal_nt,coalesced", align 8
+// CHECK: @"\01l_OBJC_LABEL_PROTOCOL_$_P" = weak hidden global {{.*}} section "__DATA, __objc_protolist, coalesced, no_dead_strip", align 8
+// CHECK: @"\01l_OBJC_CLASS_PROTOCOLS_$_A" = internal global {{.*}} section "__DATA, __objc_const", align 8
+// CHECK: @"\01l_OBJC_METACLASS_RO_$_A" = internal global {{.*}} section "__DATA, __objc_const", align 8
+// CHECK: @"\01l_OBJC_$_INSTANCE_METHODS_A" = internal global {{.*}} section "__DATA, __objc_const", align 8
+// CHECK: @"\01l_OBJC_$_INSTANCE_VARIABLES_A" = internal global {{.*}} section "__DATA, __objc_const", align 8
+// CHECK: @"\01L_OBJC_PROP_NAME_ATTR_{{[0-9]*}}" = internal global {{.*}} section "__TEXT,__cstring,cstring_literals", align 1
+// CHECK: @"\01l_OBJC_$_PROP_LIST_A" = internal global {{.*}} section "__DATA, __objc_const", align 8
+// CHECK: @"\01l_OBJC_CLASS_RO_$_A" = internal global {{.*}} section "__DATA, __objc_const", align 8
+// CHECK: @"\01l_OBJC_$_CATEGORY_INSTANCE_METHODS_A_$_Cat" = internal global {{.*}} section "__DATA, __objc_const", align 8
+// CHECK: @"\01l_OBJC_$_CATEGORY_CLASS_METHODS_A_$_Cat" = internal global {{.*}} section "__DATA, __objc_const", align 8
+// CHECK: @"\01l_OBJC_$_CATEGORY_A_$_Cat" = internal global {{.*}} section "__DATA, __objc_const", align 8
+// CHECK: @"\01L_OBJC_CLASSLIST_SUP_REFS_$_{{[0-9]*}}" = internal global {{.*}} section "__DATA, __objc_superrefs, regular, no_dead_strip", align 8
+// CHECK: @"\01L_OBJC_SELECTOR_REFERENCES_" = internal externally_initialized global {{.*}} section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
+// CHECK: @"\01L_OBJC_CLASSLIST_SUP_REFS_$_{{[0-9]*}}" = internal global {{.*}} section "__DATA, __objc_superrefs, regular, no_dead_strip", align 8
+// CHECK: @"OBJC_CLASS_$_B" = external global
+// CHECK: @"\01L_OBJC_CLASSLIST_REFERENCES_$_{{[0-9]*}}" = internal global {{.*}} section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8
+// CHECK: @"\01l_objc_msgSend_fixup_alloc" = weak hidden global {{.*}} section "__DATA, __objc_msgrefs, coalesced", align 16
+// CHECK: @"\01L_OBJC_LABEL_CLASS_$" = internal global {{.*}} section "__DATA, __objc_classlist, regular, no_dead_strip", align 8
+// CHECK: @"\01L_OBJC_LABEL_CATEGORY_$" = internal global {{.*}} section "__DATA, __objc_catlist, regular, no_dead_strip", align 8
+// CHECK: @objc_msgSend_fpret(
+// CHECK: @objc_msgSend_fixup(
/*
diff --git a/test/CodeGenObjC/metadata_symbols.m b/test/CodeGenObjC/metadata_symbols.m
index 576a55b136..eedcf16627 100644
--- a/test/CodeGenObjC/metadata_symbols.m
+++ b/test/CodeGenObjC/metadata_symbols.m
@@ -1,6 +1,12 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fexceptions -fobjc-exceptions -o %t %s
// RUN: FileCheck -check-prefix=CHECK-X86_64 < %t %s
-// RUN: grep '@"OBJC_EHTYPE_$_EH3"' %t | count 3
+// RUN: FileCheck -check-prefix=CHECK-EHTYPE < %t %s
+
+// We need exactly 3 of these.
+// CHECK-EHTYPE: @"OBJC_EHTYPE_$_EH3"
+// CHECK-EHTYPE: @"OBJC_EHTYPE_$_EH3"
+// CHECK-EHTYPE: @"OBJC_EHTYPE_$_EH3"
+// CHECK-EHTYPE-NOT: @"OBJC_EHTYPE_$_EH3"
// CHECK-X86_64: @"OBJC_CLASS_$_A" = global {{.*}}, section "__DATA, __objc_data", align 8
// CHECK-X86_64: @"OBJC_METACLASS_$_A" = global {{.*}}, section "__DATA, __objc_data", align 8
diff --git a/test/CodeGenObjC/objc-align.m b/test/CodeGenObjC/objc-align.m
index 1a9e882a13..1a96f34c5d 100644
--- a/test/CodeGenObjC/objc-align.m
+++ b/test/CodeGenObjC/objc-align.m
@@ -1,14 +1,14 @@
// 32-bit
-// RUN: %clang_cc1 -triple i386-apple-darwin9 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -o %t %s
-// RUN: grep '@"\\01L_OBJC_CATEGORY_A_Cat" = internal global .*, section "__OBJC,__category,regular,no_dead_strip", align 4' %t
-// RUN: grep '@"\\01L_OBJC_CLASS_A" = internal global .*, section "__OBJC,__class,regular,no_dead_strip", align 4' %t
-// RUN: grep '@"\\01L_OBJC_CLASS_C" = internal global .*, section "__OBJC,__class,regular,no_dead_strip", align 4' %t
-// RUN: grep '@"\\01L_OBJC_CLASS_PROTOCOLS_C" = internal global .*, section "__OBJC,__cat_cls_meth,regular,no_dead_strip", align 4' %t
-// RUN: grep '@"\\01L_OBJC_METACLASS_A" = internal global .*, section "__OBJC,__meta_class,regular,no_dead_strip", align 4' %t
-// RUN: grep '@"\\01L_OBJC_METACLASS_C" = internal global .*, section "__OBJC,__meta_class,regular,no_dead_strip", align 4' %t
-// RUN: grep '@"\\01L_OBJC_MODULES" = internal global .*, section "__OBJC,__module_info,regular,no_dead_strip", align 4' %t
-// RUN: grep '@"\\01L_OBJC_PROTOCOL_P" = internal global .*, section "__OBJC,__protocol,regular,no_dead_strip", align 4' %t
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -o - %s | FileCheck %s
+// CHECK: @"\01L_OBJC_METACLASS_A" = internal global {{.*}}, section "__OBJC,__meta_class,regular,no_dead_strip", align 4
+// CHECK: @"\01L_OBJC_CLASS_A" = internal global {{.*}}, section "__OBJC,__class,regular,no_dead_strip", align 4
+// CHECK: @"\01L_OBJC_CATEGORY_A_Cat" = internal global {{.*}}, section "__OBJC,__category,regular,no_dead_strip", align 4
+// CHECK: @"\01L_OBJC_PROTOCOL_P" = internal global {{.*}}, section "__OBJC,__protocol,regular,no_dead_strip", align 4
+// CHECK: @"\01L_OBJC_CLASS_PROTOCOLS_C" = internal global {{.*}}, section "__OBJC,__cat_cls_meth,regular,no_dead_strip", align 4
+// CHECK: @"\01L_OBJC_METACLASS_C" = internal global {{.*}}, section "__OBJC,__meta_class,regular,no_dead_strip", align 4
+// CHECK: @"\01L_OBJC_CLASS_C" = internal global {{.*}}, section "__OBJC,__class,regular,no_dead_strip", align 4
+// CHECK: @"\01L_OBJC_MODULES" = internal global {{.*}}, section "__OBJC,__module_info,regular,no_dead_strip", align 4
// 64-bit
diff --git a/test/CodeGenObjC/objc-fixed-enum.m b/test/CodeGenObjC/objc-fixed-enum.m
new file mode 100644
index 0000000000..55c2a7c103
--- /dev/null
+++ b/test/CodeGenObjC/objc-fixed-enum.m
@@ -0,0 +1,64 @@
+// RUN: %clang_cc1 -g -emit-llvm -o - %s | FileCheck %s
+// The DWARF standard says the underlying data type of an enum may be
+// stored in an DW_AT_type entry in the enum DIE. This is useful to have
+// so the debugger knows about the signedness of the underlying type.
+
+typedef long NSInteger;
+#define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type
+
+// Enum with no specified underlying type
+typedef enum {
+ Enum0One,
+ Enum0Two
+} Enum0;
+
+// Enum declared with the NS_ENUM macro
+typedef NS_ENUM(NSInteger, Enum1) {
+ Enum1One = -1,
+ Enum1Two
+};
+
+// Enum declared with a fixed underlying type
+typedef enum : NSInteger {
+ Enum2One = -1,
+ Enum2Two
+} Enum2;
+
+// Typedef and declaration separately
+enum : NSInteger
+{
+ Enum3One = -1,
+ Enum3Two
+};
+typedef NSInteger Enum3;
+
+int main() {
+ Enum0 e0 = Enum0One;
+ // CHECK: call void @llvm.dbg.declare(metadata !{{.*}}, metadata ![[ENUM0:[0-9]+]])
+ Enum1 e1 = Enum1One;
+ // CHECK: call void @llvm.dbg.declare(metadata !{{.*}}, metadata ![[ENUM1:[0-9]+]])
+ Enum2 e2 = Enum2One;
+ // CHECK: call void @llvm.dbg.declare(metadata !{{.*}}, metadata ![[ENUM2:[0-9]+]])
+ Enum3 e3 = Enum3One;
+ // CHECK: call void @llvm.dbg.declare(metadata !{{.*}}, metadata ![[ENUM3:[0-9]+]])
+
+ // -Werror and the following line ensures that these enums are not
+ // -treated as C++11 strongly typed enums.
+ return e0 != e1 && e1 == e2 && e2 == e3;
+}
+// CHECK: ![[ENUMERATOR0:[0-9]+]] = {{.*}}; [ DW_TAG_enumeration_type ] [line 10
+// CHECK: ![[ENUMERATOR1:[0-9]+]] = {{.*}}; [ DW_TAG_enumeration_type ] [Enum1] [line 16{{.*}}] [from NSInteger]
+// CHECK: ![[ENUMERATOR3:[0-9]+]] = {{.*}}; [ DW_TAG_typedef ] [NSInteger] [line 6{{.*}}] [from long int]
+// CHECK: ![[ENUMERATOR2:[0-9]+]] = {{.*}}; [ DW_TAG_enumeration_type ] [line 22{{.*}}] [from NSInteger]
+
+// CHECK: ![[ENUM0]] = metadata !{{{.*}}!"e0", metadata !{{[0-9]+}}, i32 {{[0-9]+}}, metadata ![[TYPE0:[0-9]+]]
+// CHECK: ![[TYPE0]] = metadata !{{{.*}}!"Enum0", {{.*}} metadata ![[ENUMERATOR0]]} ; [ DW_TAG_typedef ] [Enum0]
+
+// CHECK: ![[ENUM1]] = metadata !{{{.*}}!"e1", metadata !{{[0-9]+}}, i32 {{[0-9]+}}, metadata ![[TYPE1:[0-9]+]]
+// CHECK: ![[TYPE1]] = metadata !{{{.*}}!"Enum1", {{.*}} metadata ![[ENUMERATOR1]]} ; [ DW_TAG_typedef ] [Enum1]
+
+// CHECK: ![[ENUM2]] = metadata !{{{.*}}!"e2", metadata !{{[0-9]+}}, i32 {{[0-9]+}}, metadata ![[TYPE2:[0-9]+]]
+// CHECK: ![[TYPE2]] = metadata !{{{.*}}!"Enum2", {{.*}} metadata ![[ENUMERATOR2]]} ; [ DW_TAG_typedef ] [Enum2]
+
+// CHECK: ![[ENUM3]] = metadata !{{{.*}}!"e3", metadata !{{[0-9]+}}, i32 {{[0-9]+}}, metadata ![[TYPE3:[0-9]+]]
+// CHECK: ![[TYPE3]] = metadata !{{{.*}}!"Enum3", {{.*}} metadata ![[ENUMERATOR3]]} ; [ DW_TAG_typedef ] [Enum3]
diff --git a/test/CodeGenObjC/synthesize_ivar-cont-class.m b/test/CodeGenObjC/synthesize_ivar-cont-class.m
index 9822702331..393ec3650c 100644
--- a/test/CodeGenObjC/synthesize_ivar-cont-class.m
+++ b/test/CodeGenObjC/synthesize_ivar-cont-class.m
@@ -1,5 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm -o %t %s
-// RUN: grep '@"OBJC_IVAR_$_XCOrganizerDeviceNodeInfo.viewController"' %t
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
// PR13820
// REQUIRES: LP64
@@ -17,5 +16,6 @@
@implementation XCOrganizerDeviceNodeInfo
@synthesize viewController;
+// CHECK: @"OBJC_IVAR_$_XCOrganizerDeviceNodeInfo.viewController"
@end
diff --git a/test/CodeGenObjC/tentative-cfconstantstring.m b/test/CodeGenObjC/tentative-cfconstantstring.m
new file mode 100644
index 0000000000..b7e1c4601f
--- /dev/null
+++ b/test/CodeGenObjC/tentative-cfconstantstring.m
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
+// rdar://13598026
+
+@interface NSObject @end
+
+@class NSString;
+
+int __CFConstantStringClassReference[24];
+
+@interface Bar : NSObject
++(void)format:(NSString *)format,...;
+@end
+
+@interface Foo : NSObject
+@end
+
+
+static inline void _inlineFunction() {
+ [Bar format:@" "];
+}
+
+@implementation Foo
+
+
++(NSString *)someMethod {
+ return @"";
+}
+
+-(void)someMethod {
+ _inlineFunction();
+}
+@end
+
+// CHECK: @__CFConstantStringClassReference = common global [24 x i32] zeroinitializer, align 16
+// CHECK: @_unnamed_cfstring_{{.*}} = private constant %struct.NSConstantString { i32* getelementptr inbounds ([24 x i32]* @__CFConstantStringClassReference, i32 0, i32 0)
+
+// CHECK: define internal void @_inlineFunction()
+// CHECK: [[ZERO:%.*]] = load %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_
+// CHECK-NEXT: [[ONE:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_"
+// CHECK-NEXT: [[TWO:%.*]] = bitcast %struct._class_t* [[ZERO]] to i8*
+// CHECK-NEXT: call void (i8*, i8*, [[T:%.*]]*, ...)* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, [[T:%.*]]*, ...)*)(i8* [[TWO]], i8* [[ONE]], [[T:%.*]]* bitcast (%struct.NSConstantString* @_unnamed_cfstring_{{.*}} to [[T:%.*]]*))
+// CHECK-NEXT: ret void
+
diff --git a/test/CodeGenObjCXX/arc.mm b/test/CodeGenObjCXX/arc.mm
index aa40f930ca..e3e86a0b0d 100644
--- a/test/CodeGenObjCXX/arc.mm
+++ b/test/CodeGenObjCXX/arc.mm
@@ -76,11 +76,13 @@ void test34(int cond) {
// CHECK: [[T0:%.*]] = load i8** [[ARG]]
// CHECK-NEXT: store i8* [[T0]], i8** [[TEMP1]]
// CHECK-NEXT: br label
+ // CHECK: [[W0:%.*]] = phi i8* [ [[T0]], {{%.*}} ], [ undef, {{%.*}} ]
// CHECK: call void @_Z11test34_sinkPU15__autoreleasingP11objc_object(i8** [[T1]])
// CHECK-NEXT: [[T0:%.*]] = icmp eq i8** [[ARG]], null
// CHECK-NEXT: br i1 [[T0]],
// CHECK: [[T0:%.*]] = load i8** [[TEMP1]]
// CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]])
+ // CHECK-NEXT: call void (...)* @clang.arc.use(i8* [[W0]])
// CHECK-NEXT: [[T2:%.*]] = load i8** [[ARG]]
// CHECK-NEXT: store i8* [[T1]], i8** [[ARG]]
// CHECK-NEXT: call void @objc_release(i8* [[T2]])
@@ -273,3 +275,25 @@ id Test39::bar() { return 0; }
// CHECK: define i8* @_ZThn8_N6Test393barEv(
// CHECK: call i8* @_ZN6Test393barEv(
// CHECK-NEXT: ret i8*
+
+// rdar://13617051
+// Just a basic sanity-check that IR-gen still works after instantiating
+// a non-dependent message send that requires writeback.
+@interface Test40
++ (void) foo:(id *)errorPtr;
+@end
+template <class T> void test40_helper() {
+ id x;
+ [Test40 foo: &x];
+};
+template void test40_helper<int>();
+// CHECK: define weak_odr void @_Z13test40_helperIiEvv()
+// CHECK: [[X:%.*]] = alloca i8*
+// CHECK-NEXT: [[TEMP:%.*]] = alloca i8*
+// CHECK-NEXT: store i8* null, i8** [[X]]
+// CHECK: [[T0:%.*]] = load i8** [[X]]
+// CHECK-NEXT: store i8* [[T0]], i8** [[TEMP]]
+// CHECK: @objc_msgSend
+// CHECK-NEXT: [[T0:%.*]] = load i8** [[TEMP]]
+// CHECK-NEXT: call i8* @objc_retain(i8* [[T0]])
+
diff --git a/test/CodeGenObjCXX/exceptions-legacy.mm b/test/CodeGenObjCXX/exceptions-legacy.mm
new file mode 100644
index 0000000000..a31ba36660
--- /dev/null
+++ b/test/CodeGenObjCXX/exceptions-legacy.mm
@@ -0,0 +1,80 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -fexceptions -fobjc-exceptions -O2 -o - %s | FileCheck %s
+
+// Test we maintain at least a basic amount of interoperation between
+// ObjC and C++ exceptions in the legacy runtime.
+
+// rdar://12364847
+
+void foo(void);
+
+void test0(id obj) {
+ @synchronized(obj) {
+ foo();
+ }
+}
+// CHECK: define void @_Z5test0P11objc_object(
+// Enter the @synchronized block.
+// CHECK: call i32 @objc_sync_enter(i8* [[OBJ:%.*]])
+// CHECK: call void @objc_exception_try_enter([[BUF_T:%.*]]* [[BUF:%.*]])
+// CHECK-NEXT: [[T0:%.*]] = getelementptr [[BUF_T]]* [[BUF]], i32 0, i32 0, i32 0
+// CHECK-NEXT: [[T1:%.*]] = call i32 @_setjmp(i32* [[T0]])
+// CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0
+// CHECK-NEXT: br i1 [[T2]],
+
+// Body.
+// CHECK: invoke void @_Z3foov()
+
+// Leave the @synchronized. The reload of obj here is unnecessary.
+// CHECK: call void @objc_exception_try_exit([[BUF_T]]* [[BUF]])
+// CHECK-NEXT: [[T0:%.*]] = load i8**
+// CHECK-NEXT: call i32 @objc_sync_exit(i8* [[T0]])
+// CHECK-NEXT: ret void
+
+// Real EH cleanup.
+// CHECK: [[T0:%.*]] = landingpad
+// CHECK-NEXT: cleanup
+// CHECK-NEXT: call void @objc_exception_try_exit([[BUF_T]]* [[BUF]])
+// CHECK-NEXT: [[T0:%.*]] = load i8**
+// CHECK-NEXT: call i32 @objc_sync_exit(i8* [[T0]])
+// CHECK-NEXT: resume
+
+// ObjC EH "cleanup".
+// CHECK: [[T0:%.*]] = load i8**
+// CHECK-NEXT: call i32 @objc_sync_exit(i8* [[T0]])
+// CHECK-NEXT: [[T0:%.*]] = call i8* @objc_exception_extract([[BUF_T]]* [[BUF]])
+// CHECK-NEXT: call void @objc_exception_throw(i8* [[T0]])
+// CHECK-NEXT: unreachable
+
+void test1(id obj, bool *failed) {
+ @try {
+ foo();
+ } @catch (...) {
+ *failed = true;
+ }
+}
+// CHECK: define void @_Z5test1P11objc_objectPb(
+// Enter the @try block.
+// CHECK: call void @objc_exception_try_enter([[BUF_T]]* [[BUF:%.*]])
+// CHECK-NEXT: [[T0:%.*]] = getelementptr [[BUF_T]]* [[BUF]], i32 0, i32 0, i32 0
+// CHECK-NEXT: [[T1:%.*]] = call i32 @_setjmp(i32* [[T0]])
+// CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0
+// CHECK-NEXT: br i1 [[T2]],
+
+// Body.
+// CHECK: invoke void @_Z3foov()
+
+// Leave the @try.
+// CHECK: call void @objc_exception_try_exit([[BUF_T]]* [[BUF]])
+// CHECK-NEXT: br label
+// CHECK: ret void
+
+// Real EH cleanup.
+// CHECK: [[T0:%.*]] = landingpad
+// CHECK-NEXT: cleanup
+// CHECK-NEXT: call void @objc_exception_try_exit([[BUF_T]]* [[BUF]])
+// CHECK-NEXT: resume
+
+// Catch handler. Reload of 'failed' address is unnecessary.
+// CHECK: [[T0:%.*]] = load i8**
+// CHECK-NEXT: store i8 1, i8* [[T0]],
+// CHECK-NEXT: br label
diff --git a/test/CodeGenObjCXX/lambda-expressions.mm b/test/CodeGenObjCXX/lambda-expressions.mm
index 7c1e2e4f57..c73e1727d6 100644
--- a/test/CodeGenObjCXX/lambda-expressions.mm
+++ b/test/CodeGenObjCXX/lambda-expressions.mm
@@ -38,6 +38,28 @@ void f2() { global = []{ return 3; }; }
// ARC: define internal i32 @___Z2f2v_block_invoke
// ARC: call i32 @"_ZZ2f2vENK3$_1clEv
+template <class T> void take_lambda(T &&lambda) { lambda(); }
+void take_block(void (^block)()) { block(); }
+
+// rdar://13800041
+@interface A
+- (void) test;
+@end
+@interface B : A @end
+@implementation B
+- (void) test {
+ take_block(^{
+ take_lambda([=]{
+ take_block(^{
+ take_lambda([=] {
+ [super test];
+ });
+ });
+ });
+ });
+}
+@end
+
// ARC: attributes [[NUW]] = { nounwind{{.*}} }
// MRC: attributes [[NUW]] = { nounwind{{.*}} }
diff --git a/test/CodeGenObjCXX/mangle.mm b/test/CodeGenObjCXX/mangle.mm
index 2521c6076a..45a93a196d 100644
--- a/test/CodeGenObjCXX/mangle.mm
+++ b/test/CodeGenObjCXX/mangle.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -std=c++11 -emit-llvm -o - | FileCheck %s
// CHECK: @"_ZZ11+[A shared]E1a" = internal global
// CHECK: @"_ZZ11-[A(Foo) f]E1a" = internal global
@@ -54,3 +54,27 @@
uiIsVisible();
}
@end
+
+// rdar://13434937
+//
+// Don't crash when mangling an enum whose semantic context
+// is a class extension (which looks anonymous in the AST).
+// The other tests here are just for coverage.
+@interface Test2 @end
+@interface Test2 ()
+@property (assign) enum { T2x, T2y, T2z } axis;
+@end
+@interface Test2 (a)
+@property (assign) enum { T2i, T2j, T2k } dimension;
+@end
+@implementation Test2 {
+@public
+ enum { T2a, T2b, T2c } alt_axis;
+}
+@end
+template <class T> struct Test2Template { Test2Template() {} }; // must have a member that we'll instantiate and mangle
+void test2(Test2 *t) {
+ Test2Template<decltype(t.axis)> t0;
+ Test2Template<decltype(t.dimension)> t1;
+ Test2Template<decltype(t->alt_axis)> t2;
+}
diff --git a/test/CodeGenOpenCL/kernel-arg-info.cl b/test/CodeGenOpenCL/kernel-arg-info.cl
index 7e35a33564..c7e20491a9 100644
--- a/test/CodeGenOpenCL/kernel-arg-info.cl
+++ b/test/CodeGenOpenCL/kernel-arg-info.cl
@@ -1,7 +1,20 @@
-// RUN: %clang_cc1 %s -cl-kernel-arg-info -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -cl-kernel-arg-info -emit-llvm -o - -triple spir-unknown-unknown | FileCheck %s
-kernel void foo(global int *X, int Y, int anotherArg) {
+kernel void foo(__global int * restrict X, const int Y,
+ volatile int anotherArg, __constant float * restrict Z) {
*X = Y + anotherArg;
}
-// CHECK: metadata !{metadata !"kernel_arg_name", metadata !"X", metadata !"Y", metadata !"anotherArg"}
+// CHECK: metadata !{metadata !"kernel_arg_addr_space", i32 1, i32 0, i32 0, i32 2}
+// CHECK: metadata !{metadata !"kernel_arg_access_qual", metadata !"none", metadata !"none", metadata !"none", metadata !"none"}
+// CHECK: metadata !{metadata !"kernel_arg_type", metadata !"int*", metadata !"int", metadata !"int", metadata !"float*"}
+// CHECK: metadata !{metadata !"kernel_arg_type_qual", metadata !"restrict", metadata !"const", metadata !"volatile", metadata !"restrict const"}
+// CHECK: metadata !{metadata !"kernel_arg_name", metadata !"X", metadata !"Y", metadata !"anotherArg", metadata !"Z"}
+
+kernel void foo2(read_only image1d_t img1, image2d_t img2, write_only image2d_array_t img3) {
+}
+// CHECK: metadata !{metadata !"kernel_arg_addr_space", i32 0, i32 0, i32 0}
+// CHECK: metadata !{metadata !"kernel_arg_access_qual", metadata !"read_only", metadata !"read_only", metadata !"write_only"}
+// CHECK: metadata !{metadata !"kernel_arg_type", metadata !"image1d_t", metadata !"image2d_t", metadata !"image2d_array_t"}
+// CHECK: metadata !{metadata !"kernel_arg_type_qual", metadata !"", metadata !"", metadata !""}
+// CHECK: metadata !{metadata !"kernel_arg_name", metadata !"img1", metadata !"img2", metadata !"img3"}
diff --git a/test/CodeGenOpenCL/ptx-calls.cl b/test/CodeGenOpenCL/ptx-calls.cl
index 34a21c6c1d..d9904513e5 100644
--- a/test/CodeGenOpenCL/ptx-calls.cl
+++ b/test/CodeGenOpenCL/ptx-calls.cl
@@ -2,11 +2,12 @@
void device_function() {
}
-// CHECK: define ptx_device void @device_function()
+// CHECK: define void @device_function()
__kernel void kernel_function() {
device_function();
}
-// CHECK: define ptx_kernel void @kernel_function()
-// CHECK: call ptx_device void @device_function()
+// CHECK: define void @kernel_function()
+// CHECK: call void @device_function()
+// CHECK: !{{[0-9]+}} = metadata !{void ()* @kernel_function, metadata !"kernel", i32 1}
diff --git a/test/CodeGenOpenCL/ptx-kernels.cl b/test/CodeGenOpenCL/ptx-kernels.cl
index 1d7e497b7c..07648e4015 100644
--- a/test/CodeGenOpenCL/ptx-kernels.cl
+++ b/test/CodeGenOpenCL/ptx-kernels.cl
@@ -2,9 +2,10 @@
void device_function() {
}
-// CHECK: define ptx_device void @device_function()
+// CHECK: define void @device_function()
__kernel void kernel_function() {
}
-// CHECK: define ptx_kernel void @kernel_function()
+// CHECK: define void @kernel_function()
+// CHECK: !{{[0-9]+}} = metadata !{void ()* @kernel_function, metadata !"kernel", i32 1}
diff --git a/test/Driver/Inputs/fedora_18_tree/lib/.keep b/test/Driver/Inputs/fedora_18_tree/lib/.keep
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/fedora_18_tree/lib/.keep
diff --git a/test/Driver/Inputs/fedora_18_tree/usr/lib/crt1.o b/test/Driver/Inputs/fedora_18_tree/usr/lib/crt1.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/fedora_18_tree/usr/lib/crt1.o
diff --git a/test/Driver/Inputs/fedora_18_tree/usr/lib/crti.o b/test/Driver/Inputs/fedora_18_tree/usr/lib/crti.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/fedora_18_tree/usr/lib/crti.o
diff --git a/test/Driver/Inputs/fedora_18_tree/usr/lib/crtn.o b/test/Driver/Inputs/fedora_18_tree/usr/lib/crtn.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/fedora_18_tree/usr/lib/crtn.o
diff --git a/test/Driver/Inputs/fedora_18_tree/usr/lib/gcc/armv7hl-redhat-linux-gnueabi/4.7.2/crtbegin.o b/test/Driver/Inputs/fedora_18_tree/usr/lib/gcc/armv7hl-redhat-linux-gnueabi/4.7.2/crtbegin.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/fedora_18_tree/usr/lib/gcc/armv7hl-redhat-linux-gnueabi/4.7.2/crtbegin.o
diff --git a/test/Driver/Inputs/fedora_18_tree/usr/lib/gcc/armv7hl-redhat-linux-gnueabi/4.7.2/crtend.o b/test/Driver/Inputs/fedora_18_tree/usr/lib/gcc/armv7hl-redhat-linux-gnueabi/4.7.2/crtend.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/fedora_18_tree/usr/lib/gcc/armv7hl-redhat-linux-gnueabi/4.7.2/crtend.o
diff --git a/test/Driver/Inputs/mips_cs_tree/bin/.keep b/test/Driver/Inputs/mips_cs_tree/bin/.keep
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/bin/.keep
diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/64/crtbegin.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/64/crtbegin.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/64/crtbegin.o
diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/64/crtend.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/64/crtend.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/64/crtend.o
diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/crtbegin.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/crtbegin.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/crtbegin.o
diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/crtend.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/crtend.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/crtend.o
diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/el/64/crtbegin.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/el/64/crtbegin.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/el/64/crtbegin.o
diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/el/64/crtend.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/el/64/crtend.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/el/64/crtend.o
diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/el/crtbegin.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/el/crtbegin.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/el/crtbegin.o
diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/el/crtend.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/el/crtend.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/el/crtend.o
diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/64/.keep b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/64/.keep
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/64/.keep
diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/el/64/.keep b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/el/64/.keep
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/el/64/.keep
diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/micromips/el/.keep b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/micromips/el/.keep
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/micromips/el/.keep
diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/micromips/soft-float/el/.keep b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/micromips/soft-float/el/.keep
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/micromips/soft-float/el/.keep
diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/mips16/el/.keep b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/mips16/el/.keep
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/mips16/el/.keep
diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/mips16/soft-float/el/.keep b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/mips16/soft-float/el/.keep
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/mips16/soft-float/el/.keep
diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/soft-float/64/.keep b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/soft-float/64/.keep
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/soft-float/64/.keep
diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/soft-float/el/64/.keep b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/soft-float/el/64/.keep
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/soft-float/el/64/.keep
diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include/.keep b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include/.keep
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include/.keep
diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/crtbegin.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/crtbegin.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/crtbegin.o
diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/crtend.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/crtend.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/crtend.o
diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/el/crtbegin.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/el/crtbegin.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/el/crtbegin.o
diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/el/crtend.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/el/crtend.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/el/crtend.o
diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/soft-float/crtbegin.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/soft-float/crtbegin.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/soft-float/crtbegin.o
diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/soft-float/crtend.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/soft-float/crtend.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/soft-float/crtend.o
diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/soft-float/el/crtbegin.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/soft-float/el/crtbegin.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/soft-float/el/crtbegin.o
diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/soft-float/el/crtend.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/soft-float/el/crtend.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/micromips/soft-float/el/crtend.o
diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/crtbegin.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/crtbegin.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/crtbegin.o
diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/crtend.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/crtend.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/crtend.o
diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/el/crtbegin.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/el/crtbegin.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/el/crtbegin.o
diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/el/crtend.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/el/crtend.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/el/crtend.o
diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/soft-float/crtbegin.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/soft-float/crtbegin.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/soft-float/crtbegin.o
diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/soft-float/crtend.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/soft-float/crtend.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/soft-float/crtend.o
diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/soft-float/el/crtbegin.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/soft-float/el/crtbegin.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/soft-float/el/crtbegin.o
diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/soft-float/el/crtend.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/soft-float/el/crtend.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/mips16/soft-float/el/crtend.o
diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/64/crtbegin.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/64/crtbegin.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/64/crtbegin.o
diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/64/crtend.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/64/crtend.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/64/crtend.o
diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/crtbegin.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/crtbegin.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/crtbegin.o
diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/crtend.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/crtend.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/crtend.o
diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/el/64/crtbegin.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/el/64/crtbegin.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/el/64/crtbegin.o
diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/el/64/crtend.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/el/64/crtend.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/el/64/crtend.o
diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/el/crtbegin.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/el/crtbegin.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/el/crtbegin.o
diff --git a/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/el/crtend.o b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/el/crtend.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/soft-float/el/crtend.o
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/.keep
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/.keep
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib/el/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib/el/.keep
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib/el/.keep
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib/micromips/el/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib/micromips/el/.keep
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib/micromips/el/.keep
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib/micromips/soft-float/el/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib/micromips/soft-float/el/.keep
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib/micromips/soft-float/el/.keep
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib/mips16/el/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib/mips16/el/.keep
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib/mips16/el/.keep
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib/mips16/soft-float/el/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib/mips16/soft-float/el/.keep
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib/mips16/soft-float/el/.keep
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib/soft-float/el/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib/soft-float/el/.keep
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib/soft-float/el/.keep
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib64/el/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib64/el/.keep
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib64/el/.keep
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib64/soft-float/el/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib64/soft-float/el/.keep
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib64/soft-float/el/.keep
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/lib/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/lib/.keep
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/lib/.keep
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/lib64/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/lib64/.keep
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/lib64/.keep
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/usr/lib/crt1.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/usr/lib/crt1.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/usr/lib/crt1.o
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/usr/lib/crti.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/usr/lib/crti.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/usr/lib/crti.o
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/usr/lib/crtn.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/usr/lib/crtn.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/usr/lib/crtn.o
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/usr/lib64/crt1.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/usr/lib64/crt1.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/usr/lib64/crt1.o
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/usr/lib64/crti.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/usr/lib64/crti.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/usr/lib64/crti.o
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/usr/lib64/crtn.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/usr/lib64/crtn.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/el/usr/lib64/crtn.o
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/lib/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/lib/.keep
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/lib/.keep
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/lib64/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/lib64/.keep
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/lib64/.keep
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/el/lib/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/el/lib/.keep
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/el/lib/.keep
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/el/usr/lib/crt1.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/el/usr/lib/crt1.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/el/usr/lib/crt1.o
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/el/usr/lib/crti.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/el/usr/lib/crti.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/el/usr/lib/crti.o
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/el/usr/lib/crtn.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/el/usr/lib/crtn.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/el/usr/lib/crtn.o
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/lib/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/lib/.keep
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/lib/.keep
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/el/lib/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/el/lib/.keep
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/el/lib/.keep
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/el/usr/lib/crt1.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/el/usr/lib/crt1.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/el/usr/lib/crt1.o
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/el/usr/lib/crti.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/el/usr/lib/crti.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/el/usr/lib/crti.o
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/el/usr/lib/crtn.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/el/usr/lib/crtn.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/el/usr/lib/crtn.o
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/lib/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/lib/.keep
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/lib/.keep
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/usr/lib/crt1.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/usr/lib/crt1.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/usr/lib/crt1.o
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/usr/lib/crti.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/usr/lib/crti.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/usr/lib/crti.o
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/usr/lib/crtn.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/usr/lib/crtn.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/soft-float/usr/lib/crtn.o
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/usr/lib/crt1.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/usr/lib/crt1.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/usr/lib/crt1.o
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/usr/lib/crti.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/usr/lib/crti.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/usr/lib/crti.o
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/usr/lib/crtn.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/usr/lib/crtn.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/micromips/usr/lib/crtn.o
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/el/lib/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/el/lib/.keep
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/el/lib/.keep
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/el/usr/lib/crt1.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/el/usr/lib/crt1.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/el/usr/lib/crt1.o
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/el/usr/lib/crti.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/el/usr/lib/crti.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/el/usr/lib/crti.o
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/el/usr/lib/crtn.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/el/usr/lib/crtn.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/el/usr/lib/crtn.o
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/lib/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/lib/.keep
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/lib/.keep
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/el/lib/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/el/lib/.keep
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/el/lib/.keep
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/el/usr/lib/crt1.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/el/usr/lib/crt1.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/el/usr/lib/crt1.o
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/el/usr/lib/crti.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/el/usr/lib/crti.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/el/usr/lib/crti.o
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/el/usr/lib/crtn.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/el/usr/lib/crtn.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/el/usr/lib/crtn.o
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/lib/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/lib/.keep
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/lib/.keep
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/usr/lib/crt1.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/usr/lib/crt1.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/usr/lib/crt1.o
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/usr/lib/crti.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/usr/lib/crti.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/usr/lib/crti.o
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/usr/lib/crtn.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/usr/lib/crtn.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/soft-float/usr/lib/crtn.o
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/usr/lib/crt1.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/usr/lib/crt1.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/usr/lib/crt1.o
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/usr/lib/crti.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/usr/lib/crti.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/usr/lib/crti.o
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/usr/lib/crtn.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/usr/lib/crtn.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/mips16/usr/lib/crtn.o
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/lib/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/lib/.keep
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/lib/.keep
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/lib64/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/lib64/.keep
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/lib64/.keep
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/usr/lib/crt1.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/usr/lib/crt1.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/usr/lib/crt1.o
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/usr/lib/crti.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/usr/lib/crti.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/usr/lib/crti.o
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/usr/lib/crtn.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/usr/lib/crtn.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/usr/lib/crtn.o
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/usr/lib64/crt1.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/usr/lib64/crt1.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/usr/lib64/crt1.o
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/usr/lib64/crti.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/usr/lib64/crti.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/usr/lib64/crti.o
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/usr/lib64/crtn.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/usr/lib64/crtn.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/el/usr/lib64/crtn.o
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/lib/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/lib/.keep
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/lib/.keep
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/lib64/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/lib64/.keep
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/lib64/.keep
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/usr/lib/crt1.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/usr/lib/crt1.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/usr/lib/crt1.o
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/usr/lib/crti.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/usr/lib/crti.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/usr/lib/crti.o
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/usr/lib/crtn.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/usr/lib/crtn.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/usr/lib/crtn.o
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/usr/lib64/crt1.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/usr/lib64/crt1.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/usr/lib64/crt1.o
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/usr/lib64/crti.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/usr/lib64/crti.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/usr/lib64/crti.o
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/usr/lib64/crtn.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/usr/lib64/crtn.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/soft-float/usr/lib64/crtn.o
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/usr/include/.keep b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/usr/include/.keep
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/usr/include/.keep
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/usr/lib/crt1.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/usr/lib/crt1.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/usr/lib/crt1.o
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/usr/lib/crti.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/usr/lib/crti.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/usr/lib/crti.o
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/usr/lib/crtn.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/usr/lib/crtn.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/usr/lib/crtn.o
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/usr/lib64/crt1.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/usr/lib64/crt1.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/usr/lib64/crt1.o
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/usr/lib64/crti.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/usr/lib64/crti.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/usr/lib64/crti.o
diff --git a/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/usr/lib64/crtn.o b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/usr/lib64/crtn.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/usr/lib64/crtn.o
diff --git a/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.asan-i386.a.syms b/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.asan-i386.a.syms
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.asan-i386.a.syms
diff --git a/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.asan-x86_64.a.syms b/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.asan-x86_64.a.syms
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.asan-x86_64.a.syms
diff --git a/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.msan-x86_64.a.syms b/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.msan-x86_64.a.syms
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.msan-x86_64.a.syms
diff --git a/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.tsan-x86_64.a.syms b/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.tsan-x86_64.a.syms
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.tsan-x86_64.a.syms
diff --git a/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.ubsan-i386.a.syms b/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.ubsan-i386.a.syms
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.ubsan-i386.a.syms
diff --git a/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.ubsan-x86_64.a.syms b/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.ubsan-x86_64.a.syms
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.ubsan-x86_64.a.syms
diff --git a/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.ubsan_cxx-i386.a.syms b/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.ubsan_cxx-i386.a.syms
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.ubsan_cxx-i386.a.syms
diff --git a/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.ubsan_cxx-x86_64.a.syms b/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.ubsan_cxx-x86_64.a.syms
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.ubsan_cxx-x86_64.a.syms
diff --git a/test/Driver/Ofast.c b/test/Driver/Ofast.c
new file mode 100644
index 0000000000..1f9fc78ec1
--- /dev/null
+++ b/test/Driver/Ofast.c
@@ -0,0 +1,39 @@
+// RUN: %clang -Ofast -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST %s
+// RUN: %clang -O2 -Ofast -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST %s
+// RUN: %clang -fno-fast-math -Ofast -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST %s
+// RUN: %clang -fno-strict-aliasing -Ofast -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST %s
+// RUN: %clang -fno-vectorize -Ofast -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST %s
+// RUN: %clang -Ofast -O2 -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST-O2 %s
+// RUN: %clang -Ofast -fno-fast-math -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST-NO-FAST-MATH %s
+// RUN: %clang -Ofast -fno-strict-aliasing -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST-NO-STRICT-ALIASING %s
+// RUN: %clang -Ofast -fno-vectorize -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST-NO-VECTORIZE %s
+
+// CHECK-OFAST: -cc1
+// CHECK-OFAST-NOT: -relaxed-aliasing
+// CHECK-OFAST: -ffast-math
+// CHECK-OFAST: -Ofast
+// CHECK-OFAST: -vectorize-loops
+
+// CHECK-OFAST-O2: -cc1
+// CHECK-OFAST-O2-NOT: -relaxed-aliasing
+// CHECK-OFAST-O2-NOT: -ffast-math
+// CHECK-OFAST-O2-NOT: -Ofast
+// CHECK-OFAST-O2: -vectorize-loops
+
+// CHECK-OFAST-NO-FAST-MATH: -cc1
+// CHECK-OFAST-NO-FAST-MATH-NOT: -relaxed-aliasing
+// CHECK-OFAST-NO-FAST-MATH-NOT: -ffast-math
+// CHECK-OFAST-NO-FAST-MATH: -Ofast
+// CHECK-OFAST-NO-FAST-MATH: -vectorize-loops
+
+// CHECK-OFAST-NO-STRICT-ALIASING: -cc1
+// CHECK-OFAST-NO-STRICT-ALIASING: -relaxed-aliasing
+// CHECK-OFAST-NO-STRICT-ALIASING: -ffast-math
+// CHECK-OFAST-NO-STRICT-ALIASING: -Ofast
+// CHECK-OFAST-NO-STRICT-ALIASING: -vectorize-loops
+
+// CHECK-OFAST-NO-VECTORIZE: -cc1
+// CHECK-OFAST-NO-VECTORIZE-NOT: -relaxed-aliasing
+// CHECK-OFAST-NO-VECTORIZE: -ffast-math
+// CHECK-OFAST-NO-VECTORIZE: -Ofast
+// CHECK-OFAST-NO-VECTORIZE-NOT: -vectorize-loops
diff --git a/test/Driver/autolink_integrated_as.c b/test/Driver/autolink_integrated_as.c
new file mode 100644
index 0000000000..f1e710222a
--- /dev/null
+++ b/test/Driver/autolink_integrated_as.c
@@ -0,0 +1,6 @@
+// RUN: %clang -target x86_64-apple-darwin -fsyntax-only %s -no-integrated-as -### 2>&1 | FileCheck %s
+
+// Test that the autolinking feature is disabled with *not* using the
+// integrated assembler.
+
+// CHECK: -fno-autolink
diff --git a/test/Driver/clang_cpp.c b/test/Driver/clang_cpp.c
index 79b2f55131..bf31800566 100644
--- a/test/Driver/clang_cpp.c
+++ b/test/Driver/clang_cpp.c
@@ -1,4 +1,5 @@
// Verify that -include isn't included twice with -save-temps.
// RUN: %clang -S -o - %s -include %t.h -save-temps -### 2> %t.log
-// RUN: grep '"-include' %t.log | count 1
-
+// RUN: FileCheck %s < %t.log
+// CHECK: "-include
+// CHECK-NOT: "-include
diff --git a/test/Driver/clang_f_opts.c b/test/Driver/clang_f_opts.c
index 1bd2e140b2..5451945515 100644
--- a/test/Driver/clang_f_opts.c
+++ b/test/Driver/clang_f_opts.c
@@ -1,6 +1,7 @@
-// RUN: %clang -### -S -fasm -fblocks -fbuiltin -fno-math-errno -fcommon -fpascal-strings -fno-blocks -fno-builtin -fmath-errno -fno-common -fno-pascal-strings -fblocks -fbuiltin -fmath-errno -fcommon -fpascal-strings %s 2>&1 | FileCheck -check-prefix=CHECK-OPTIONS1 %s
+// RUN: %clang -### -S -fasm -fblocks -fbuiltin -fno-math-errno -fcommon -fpascal-strings -fno-blocks -fno-builtin -fmath-errno -fno-common -fno-pascal-strings -fblocks -fbuiltin -fmath-errno -fcommon -fpascal-strings -fsplit-stack %s 2>&1 | FileCheck -check-prefix=CHECK-OPTIONS1 %s
// RUN: %clang -### -S -fasm -fblocks -fbuiltin -fno-math-errno -fcommon -fpascal-strings -fno-asm -fno-blocks -fno-builtin -fmath-errno -fno-common -fno-pascal-strings -fno-show-source-location -fshort-enums -fshort-wchar %s 2>&1 | FileCheck -check-prefix=CHECK-OPTIONS2 %s
+// CHECK-OPTIONS1: -split-stacks
// CHECK-OPTIONS1: -fgnu-keywords
// CHECK-OPTIONS1: -fblocks
// CHECK-OPTIONS1: -fpascal-strings
@@ -55,8 +56,15 @@
// RUN: %clang -### -S -fno-tree-slp-vectorize -fslp-vectorize %s 2>&1 | FileCheck -check-prefix=CHECK-SLP-VECTORIZE %s
// RUN: %clang -### -S -fno-tree-slp-vectorize %s 2>&1 | FileCheck -check-prefix=CHECK-NO-SLP-VECTORIZE %s
// RUN: %clang -### -S -ftree-slp-vectorize -fno-slp-vectorize %s 2>&1 | FileCheck -check-prefix=CHECK-NO-SLP-VECTORIZE %s
-// CHECK-SLP-VECTORIZE: "-vectorize"
-// CHECK-NO-SLP-VECTORIZE-NOT: "-vectorize"
+// CHECK-SLP-VECTORIZE: "-vectorize-slp"
+// CHECK-NO-SLP-VECTORIZE-NOT: "-vectorize-slp"
+
+// RUN: %clang -### -S -fslp-vectorize-aggressive %s 2>&1 | FileCheck -check-prefix=CHECK-SLP-VECTORIZE-AGG %s
+// RUN: %clang -### -S -fno-slp-vectorize-aggressive -fslp-vectorize-aggressive %s 2>&1 | FileCheck -check-prefix=CHECK-SLP-VECTORIZE-AGG %s
+// RUN: %clang -### -S -fno-slp-vectorize-aggressive %s 2>&1 | FileCheck -check-prefix=CHECK-NO-SLP-VECTORIZE-AGG %s
+// RUN: %clang -### -S -fslp-vectorize-aggressive -fno-slp-vectorize-aggressive %s 2>&1 | FileCheck -check-prefix=CHECK-NO-SLP-VECTORIZE-AGG %s
+// CHECK-SLP-VECTORIZE-AGG: "-vectorize-slp-aggressive"
+// CHECK-NO-SLP-VECTORIZE-AGG-NOT: "-vectorize-slp-aggressive"
// RUN: %clang -### -S -fextended-identifiers %s 2>&1 | FileCheck -check-prefix=CHECK-EXTENDED-IDENTIFIERS %s
// RUN: %clang -### -S -fno-extended-identifiers %s 2>&1 | FileCheck -check-prefix=CHECK-NO-EXTENDED-IDENTIFIERS %s
diff --git a/test/Driver/color-diagnostics.c b/test/Driver/color-diagnostics.c
new file mode 100644
index 0000000000..deff5119a0
--- /dev/null
+++ b/test/Driver/color-diagnostics.c
@@ -0,0 +1,53 @@
+// RUN: %clang -fcolor-diagnostics -### -c %s 2>&1 \
+// RUN: | FileCheck --check-prefix=CD %s
+// CHECK-CD: clang{{.*}}" "-fcolor-diagnostics"
+
+// RUN: %clang -fno-color-diagnostics -### -c %s 2>&1 \
+// RUN: | FileCheck --check-prefix=NCD %s
+// CHECK-NCD-NOT: clang{{.*}}" "-fcolor-diagnostics"
+
+// RUN: %clang -fdiagnostics-color -### -c %s 2>&1 \
+// RUN: | FileCheck --check-prefix=DC %s
+// CHECK-DC: clang{{.*}}" "-fcolor-diagnostics"
+
+// RUN: %clang -fno-diagnostics-color -### -c %s 2>&1 \
+// RUN: | FileCheck --check-prefix=NDC %s
+// CHECK-NDC-NOT: clang{{.*}}" "-fcolor-diagnostics"
+
+// RUN: %clang -fdiagnostics-color=always -### -c %s 2>&1 \
+// RUN: | FileCheck --check-prefix=DCE_A %s
+// CHECK-DCE_A: clang{{.*}}" "-fcolor-diagnostics"
+
+// RUN: %clang -fdiagnostics-color=never -### -c %s 2>&1 \
+// RUN: | FileCheck --check-prefix=DCE_N %s
+// CHECK-DCE_N-NOT: clang{{.*}}" "-fcolor-diagnostics"
+
+// The test doesn't run in a PTY, so "auto" defaults to off.
+// RUN: %clang -fdiagnostics-color=auto -### -c %s 2>&1 \
+// RUN: | FileCheck --check-prefix=DCE_AUTO %s
+// CHECK-DCE_AUTO-NOT: clang{{.*}}" "-fcolor-diagnostics"
+
+// RUN: %clang -fdiagnostics-color=foo -### -c %s 2>&1 \
+// RUN: | FileCheck --check-prefix=DCE_FOO %s
+// CHECK-DCE_FOO: error: the clang compiler does not support '-fdiagnostics-color=foo'
+
+// Check that the last flag wins.
+// RUN: %clang -fno-color-diagnostics -fdiagnostics-color -### -c %s 2>&1 \
+// RUN: | FileCheck --check-prefix=NCD_DC_S %s
+// CHECK-NCD_DC_S: clang{{.*}}" "-fcolor-diagnostics"
+
+// RUN: %clang -fcolor-diagnostics -fno-diagnostics-color -### -c %s 2>&1 \
+// RUN: | FileCheck --check-prefix=CD_NDC_S %s
+// CHECK-CD_NDC_S-NOT: clang{{.*}}" "-fcolor-diagnostics"
+
+// RUN: %clang -fdiagnostics-color -fno-color-diagnostics -### -c %s 2>&1 \
+// RUN: | FileCheck --check-prefix=DC_NCD_S %s
+// CHECK-DC_NCD_S-NOT: clang{{.*}}" "-fcolor-diagnostics"
+
+// RUN: %clang -fno-diagnostics-color -fcolor-diagnostics -### -c %s 2>&1 \
+// RUN: | FileCheck --check-prefix=NDC_CD_S %s
+// CHECK-NDC_CD_S: clang{{.*}}" "-fcolor-diagnostics"
+
+// RUN: %clang -fcolor-diagnostics -fdiagnostics-color=auto -### -c %s 2>&1 \
+// RUN: | FileCheck --check-prefix=CD_DCE_AUTO_S %s
+// CHECK-CD_DCE_AUTO_S-NOT: clang{{.*}}" "-fcolor-diagnostics"
diff --git a/test/Driver/debug-comp-dir.S b/test/Driver/debug-comp-dir.S
index ca1ca30ae6..daf895c18a 100644
--- a/test/Driver/debug-comp-dir.S
+++ b/test/Driver/debug-comp-dir.S
@@ -1,9 +1,6 @@
// RUN: cd %S && %clang -### -g %s -c 2>&1 | FileCheck -check-prefix=CHECK-PWD %s
// CHECK-PWD: {{"-fdebug-compilation-dir" ".*Driver.*"}}
-// RUN: env PWD=/foo %clang -### -g %s -c 2>&1 | FileCheck -check-prefix=CHECK-FOO %s
-// CHECK-FOO: {{"-fdebug-compilation-dir" ".*foo"}}
-
// "PWD=/foo gcc" wouldn't necessarily work. You would need to pick a different
// path to the same directory (try a symlink).
diff --git a/test/Driver/debug.c b/test/Driver/debug.c
index ca1ca30ae6..daf895c18a 100644
--- a/test/Driver/debug.c
+++ b/test/Driver/debug.c
@@ -1,9 +1,6 @@
// RUN: cd %S && %clang -### -g %s -c 2>&1 | FileCheck -check-prefix=CHECK-PWD %s
// CHECK-PWD: {{"-fdebug-compilation-dir" ".*Driver.*"}}
-// RUN: env PWD=/foo %clang -### -g %s -c 2>&1 | FileCheck -check-prefix=CHECK-FOO %s
-// CHECK-FOO: {{"-fdebug-compilation-dir" ".*foo"}}
-
// "PWD=/foo gcc" wouldn't necessarily work. You would need to pick a different
// path to the same directory (try a symlink).
diff --git a/test/Driver/dragonfly.c b/test/Driver/dragonfly.c
index 8a629da817..4be2aadd7a 100644
--- a/test/Driver/dragonfly.c
+++ b/test/Driver/dragonfly.c
@@ -1,7 +1,7 @@
-// RUN: %clang -no-canonical-prefixes -target amd64-pc-dragonfly %s -### 2> %t.log
+// RUN: %clang -no-canonical-prefixes -target x86_64-pc-dragonfly %s -### 2> %t.log
// RUN: FileCheck -input-file %t.log %s
-// CHECK: clang{{.*}}" "-cc1" "-triple" "amd64-pc-dragonfly"
-// CHECK: ld{{.*}}" "-dynamic-linker" "{{.*}}ld-elf.{{.*}}" "-o" "a.out" "{{.*}}crt1.o" "{{.*}}crti.o" "{{.*}}crtbegin.o" "{{.*}}.o" "-L{{.*}}/gcc{{.*}}" {{.*}} "-lc" "-lgcc" "{{.*}}crtend.o" "{{.*}}crtn.o"
+// CHECK: clang{{.*}}" "-cc1" "-triple" "x86_64-pc-dragonfly"
+// CHECK: ld{{.*}}" "--eh-frame-hdr" "-dynamic-linker" "/usr/libexec/ld-elf.so.{{.*}}" "--hash-style=both" "-o" "a.out" "{{.*}}crt1.o" "{{.*}}crti.o" "{{.*}}crtbegin.o" "{{.*}}.o" "-L{{.*}}gcc4{{.*}}" "-rpath" "{{.*}}gcc4{{.*}}" "-lc" "-lgcc" "{{.*}}crtend.o" "{{.*}}crtn.o"
diff --git a/test/Driver/flags.c b/test/Driver/flags.c
index 27862316f8..ff60caf2e0 100644
--- a/test/Driver/flags.c
+++ b/test/Driver/flags.c
@@ -1,20 +1,26 @@
-// RUN: %clang -target i386-apple-darwin9 -### -S -msoft-float %s 2> %t.log
-// RUN: grep '"-no-implicit-float"' %t.log
+// RUN: %clang -target i386-apple-darwin9 -### -S -msoft-float %s 2>&1 | FileCheck -check-prefix=TEST1 %s
+// TEST1: "-no-implicit-float"
-// RUN: %clang -target i386-apple-darwin9 -### -S -msoft-float -mno-soft-float %s 2> %t.log
-// RUN: grep '"-no-implicit-float"' %t.log | count 0
+// RUN: %clang -target i386-apple-darwin9 -### -S -msoft-float -mno-soft-float %s 2>&1 | FileCheck -check-prefix=TEST2 %s
+// TEST2-NOT: "-no-implicit-float"
-// RUN: %clang -target i386-apple-darwin9 -### -S -mno-soft-float %s -msoft-float 2> %t.log
-// RUN: grep '"-no-implicit-float"' %t.log
+// RUN: %clang -target i386-apple-darwin9 -### -S -mno-soft-float %s -msoft-float 2>&1 | FileCheck -check-prefix=TEST3 %s
+// TEST3: "-no-implicit-float"
-// RUN: %clang -target i386-apple-darwin9 -### -S -mno-implicit-float %s 2> %t.log
-// RUN: grep '"-no-implicit-float"' %t.log
+// RUN: %clang -target i386-apple-darwin9 -### -S -mno-implicit-float %s 2>&1 | FileCheck -check-prefix=TEST4 %s
+// TEST4: "-no-implicit-float"
-// RUN: %clang -target i386-apple-darwin9 -### -S -mkernel %s 2> %t.log
-// RUN: grep '"-no-implicit-float"' %t.log
+// RUN: %clang -target i386-apple-darwin9 -### -S -mno-implicit-float -mimplicit-float %s 2>&1 | FileCheck -check-prefix=TEST4A %s
+// TEST4A-NOT: "-no-implicit-float"
-// RUN: %clang -target i386-apple-darwin9 -### -S -mkernel -mno-soft-float %s 2> %t.log
-// RUN: grep '"-no-implicit-float"' %t.log | count 0
+// RUN: %clang -target i386-apple-darwin9 -### -S -mkernel %s 2>&1 | FileCheck -check-prefix=TEST5 %s
+// TEST5: "-no-implicit-float"
-// RUN: %clang -target armv7-apple-darwin10 -### -S -mno-implicit-float %s 2> %t.log
-// RUN: grep '"-no-implicit-float"' %t.log
+// RUN: %clang -target i386-apple-darwin9 -### -S -mkernel -mno-soft-float %s 2>&1 | FileCheck -check-prefix=TEST6 %s
+// TEST6-NOT: "-no-implicit-float"
+
+// RUN: %clang -target armv7-apple-darwin10 -### -S -mno-implicit-float %s 2>&1 | FileCheck -check-prefix=TEST7 %s
+// TEST7: "-no-implicit-float"
+
+// RUN: %clang -target armv7-apple-darwin10 -### -S -mno-implicit-float -mimplicit-float %s 2>&1 | FileCheck -check-prefix=TEST8 %s
+// TEST8-NOT: "-no-implicit-float"
diff --git a/test/Driver/fparse-all-comments.c b/test/Driver/fparse-all-comments.c
new file mode 100644
index 0000000000..5f825d0429
--- /dev/null
+++ b/test/Driver/fparse-all-comments.c
@@ -0,0 +1,5 @@
+// Check that we pass -fparse-all-comments to frontend.
+//
+// RUN: %clang -c %s -fparse-all-comments -### 2>&1 | FileCheck %s --check-prefix=CHECK-ARG
+//
+// CHECK-ARG: -fparse-all-comments
diff --git a/test/Driver/frame-pointer-elim.c b/test/Driver/frame-pointer-elim.c
new file mode 100644
index 0000000000..286cd6e61f
--- /dev/null
+++ b/test/Driver/frame-pointer-elim.c
@@ -0,0 +1,30 @@
+// For these next two tests when optimized we should omit the leaf frame
+// pointer, for unoptimized we should have a leaf frame pointer.
+// RUN: %clang -### -target i386-pc-linux-gnu -S -O1 %s 2>&1 | \
+// RUN: FileCheck --check-prefix=LINUX-OPT %s
+// LINUX-OPT: "-momit-leaf-frame-pointer"
+
+// RUN: %clang -### -target i386-pc-linux-gnu -S %s 2>&1 | \
+// RUN: FileCheck --check-prefix=LINUX %s
+// LINUX-NOT: "-momit-leaf-frame-pointer"
+
+// Darwin disables omitting the leaf frame pointer even under optimization
+// unless the command lines are given.
+// RUN: %clang -### -target i386-apple-darwin -S %s 2>&1 | \
+// RUN: FileCheck --check-prefix=DARWIN %s
+// DARWIN: "-mdisable-fp-elim"
+
+// RUN: %clang -### -target i386-apple-darwin -S -O1 %s 2>&1 | \
+// RUN: FileCheck --check-prefix=DARWIN-OPT %s
+// DARWIN-OPT-NOT: "-momit-leaf-frame-pointer"
+
+// RUN: %clang -### -target i386-darwin -S -fomit-frame-pointer %s 2>&1 | \
+// RUN: FileCheck --check-prefix=OMIT_ALL %s
+// OMIT_ALL-NOT: "-mdisable-fp-elim"
+
+// RUN: %clang -### -target i386-darwin -S -momit-leaf-frame-pointer %s 2>&1 | \
+// RUN: FileCheck --check-prefix=OMIT_LEAF %s
+// OMIT_LEAF: "-momit-leaf-frame-pointer"
+
+void f0() {}
+void f1() { f0(); }
diff --git a/test/Driver/freebsd.c b/test/Driver/freebsd.c
index d0e608cd31..cc72443961 100644
--- a/test/Driver/freebsd.c
+++ b/test/Driver/freebsd.c
@@ -105,5 +105,5 @@
// RUN: %clang %s -### -o %t.o -target arm-gnueabi-freebsd10.0 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-ARM-EABI %s
// CHECK-ARM-EABI-NOT: clang{{.*}}" "-cc1"{{.*}}" "-fsjlj-exceptions"
-// CHECK-ARM-EABI: as{{.*}}" "-mfpu=softvfp"
+// CHECK-ARM-EABI: as{{.*}}" "-mfpu=softvfp" "-meabi=5"
// CHECK-ARM-EABI-NOT: as{{.*}}" "-matpcs"
diff --git a/test/Driver/fsanitize.c b/test/Driver/fsanitize.c
index efb289f6a7..0e7522b548 100644
--- a/test/Driver/fsanitize.c
+++ b/test/Driver/fsanitize.c
@@ -16,6 +16,12 @@
// RUN: %clang -target x86_64-linux-gnu -fsanitize=address-full %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-FULL
// CHECK-ASAN-FULL: "-fsanitize={{((address|init-order|use-after-return|use-after-scope),?){4}"}}
+// RUN: %clang -target x86_64-linux-gnu -fno-sanitize=init-order -fsanitize=address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-IMPLIED-INIT-ORDER
+// CHECK-ASAN-IMPLIED-INIT-ORDER: "-fsanitize={{((address|init-order),?){2}"}}
+
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fno-sanitize=init-order %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-NO-IMPLIED-INIT-ORDER
+// CHECK-ASAN-NO-IMPLIED-INIT-ORDER-NOT: init-order
+
// RUN: %clang -target x86_64-linux-gnu -fcatch-undefined-behavior -fno-sanitize-undefined-trap-on-error %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-NO-TRAP-ERROR
// CHECK-UNDEFINED-NO-TRAP-ERROR: '-fcatch-undefined-behavior' not allowed with '-fno-sanitize-undefined-trap-on-error'
@@ -89,19 +95,30 @@
// CHECK-DEPRECATED: argument '-fbounds-checking' is deprecated, use '-fsanitize=bounds' instead
// RUN: %clang -target x86_64-linux-gnu -fsanitize=thread %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-NO-PIE
-// CHECK-TSAN-NO-PIE: invalid argument '-fsanitize=thread' only allowed with '-pie'
+// CHECK-TSAN-NO-PIE: "-mrelocation-model" "pic" "-pic-level" "2" "-pie-level" "2"
+// CHECK-TSAN-NO-PIE: "-pie"
// RUN: %clang -target x86_64-linux-gnu -fsanitize=memory %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-MSAN-NO-PIE
-// CHECK-MSAN-NO-PIE: invalid argument '-fsanitize=memory' only allowed with '-pie'
+// CHECK-MSAN-NO-PIE: "-mrelocation-model" "pic" "-pic-level" "2" "-pie-level" "2"
+// CHECK-MSAN-NO-PIE: "-pie"
// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-address-zero-base-shadow %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-ZERO-BASE-SHADOW-NO-PIE
-// CHECK-ASAN-ZERO-BASE-SHADOW-NO-PIE: invalid argument '-fsanitize-address-zero-base-shadow' only allowed with '-pie'
+// CHECK-ASAN-ZERO-BASE-SHADOW-NO-PIE: "-mrelocation-model" "pic" "-pic-level" "2" "-pie-level" "2"
+// CHECK-ASAN-ZERO-BASE-SHADOW-NO-PIE: "-pie"
// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-address-zero-base-shadow -fno-sanitize-address-zero-base-shadow %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-ZERO-BASE-SHADOW-CANCEL
-// CHECK-ASAN-ZERO-BASE-SHADOW-CANCEL-NOT: '-fsanitize-address-zero-base-shadow' only allowed with '-pie'
+// CHECK-ASAN-ZERO-BASE-SHADOW-CANCEL-NOT: "-mrelocation-model" "pic" "-pic-level" "2" "-pie-level" "2"
+// CHECK-ASAN-ZERO-BASE-SHADOW-CANCEL-NOT: "-pie"
// RUN: %clang -target arm-linux-androideabi -fsanitize=address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ANDROID-ASAN-NO-PIE
-// CHECK-ANDROID-ASAN-NO-PIE: AddressSanitizer on Android requires '-pie'
+// CHECK-ANDROID-ASAN-NO-PIE: "-mrelocation-model" "pic" "-pic-level" "2" "-pie-level" "2"
+// CHECK-ANDROID-ASAN-NO-PIE: "-pie"
+
+// RUN: %clang -target arm-linux-androideabi -fsanitize=address -fsanitize-address-zero-base-shadow %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ANDROID-ASAN-ZERO-BASE
+// CHECK-ANDROID-ASAN-ZERO-BASE-NOT: argument unused during compilation
+
+// RUN: %clang -target arm-linux-androideabi -fsanitize=address -fno-sanitize-address-zero-base-shadow %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ANDROID-ASAN-NO-ZERO-BASE
+// CHECK-ANDROID-ASAN-NO-ZERO-BASE: '-fno-sanitize-address-zero-base-shadow' not allowed with '-fsanitize=address'
// RUN: %clang -target x86_64-linux-gnu %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RECOVER
// RUN: %clang -target x86_64-linux-gnu %s -fsanitize-recover -### 2>&1 | FileCheck %s --check-prefix=CHECK-RECOVER
diff --git a/test/Driver/hexagon-toolchain-elf.c b/test/Driver/hexagon-toolchain-elf.c
new file mode 100644
index 0000000000..1a2650d16e
--- /dev/null
+++ b/test/Driver/hexagon-toolchain-elf.c
@@ -0,0 +1,564 @@
+// REQUIRES: hexagon-registered-target
+
+// -----------------------------------------------------------------------------
+// Test standard include paths
+// -----------------------------------------------------------------------------
+
+// RUN: %clang -### -target hexagon-unknown-elf \
+// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
+// RUN: %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECK001 %s
+// CHECK001: "-cc1" {{.*}} "-internal-externc-isystem" "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/lib/gcc/hexagon/4.4.0/include"
+// CHECK001: "-internal-externc-isystem" "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/lib/gcc/hexagon/4.4.0/include-fixed"
+// CHECK001: "-internal-externc-isystem" "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/hexagon/include"
+// CHECK001-NEXT: "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/bin/hexagon-as"
+
+// RUN: %clang -ccc-cxx -x c++ -### -target hexagon-unknown-elf \
+// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
+// RUN: %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECK002 %s
+// CHECK002: "-cc1" {{.*}} "-internal-isystem" "[[INSTALL_DIR:.*]]/Inputs/hexagon_tree/qc/bin/../../gnu/hexagon/include/c++/4.4.0"
+// CHECK002: "-internal-externc-isystem" "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/lib/gcc/hexagon/4.4.0/include"
+// CHECK002: "-internal-externc-isystem" "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/lib/gcc/hexagon/4.4.0/include-fixed"
+// CHECK002: "-internal-externc-isystem" "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/hexagon/include"
+// CHECK002-NEXT: "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/bin/hexagon-as"
+
+// -----------------------------------------------------------------------------
+// Test -nostdinc, -nostdlibinc, -nostdinc++
+// -----------------------------------------------------------------------------
+
+// RUN: %clang -### -target hexagon-unknown-elf \
+// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
+// RUN: -nostdinc \
+// RUN: %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECK003 %s
+// CHECK003: "-cc1"
+// CHECK003-NOT: "-internal-externc-isystem" "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/lib/gcc/hexagon/4.4.0/include"
+// CHECK003-NOT: "-internal-externc-isystem" "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/lib/gcc/hexagon/4.4.0/include-fixed"
+// CHECK003-NOT: "-internal-externc-isystem" "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/hexagon/include"
+// CHECK003-NEXT: "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/bin/hexagon-as"
+
+// RUN: %clang -### -target hexagon-unknown-elf \
+// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
+// RUN: -nostdlibinc \
+// RUN: %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECK004 %s
+// CHECK004: "-cc1"
+// CHECK004-NOT: "-internal-externc-isystem" "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/lib/gcc/hexagon/4.4.0/include"
+// CHECK004-NOT: "-internal-externc-isystem" "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/lib/gcc/hexagon/4.4.0/include-fixed"
+// CHECK004-NOT: "-internal-externc-isystem" "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/hexagon/include"
+// CHECK004-NEXT: "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/bin/hexagon-as"
+
+// RUN: %clang -ccc-cxx -x c++ -### -target hexagon-unknown-elf \
+// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
+// RUN: -nostdlibinc \
+// RUN: %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECK005 %s
+// CHECK005: "-cc1"
+// CHECK005-NOT: "-internal-isystem" "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/hexagon/include/c++/4.4.0"
+// CHECK005-NOT: "-internal-externc-isystem" "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/lib/gcc/hexagon/4.4.0/include"
+// CHECK005-NOT: "-internal-externc-isystem" "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/lib/gcc/hexagon/4.4.0/include-fixed"
+// CHECK005-NOT: "-internal-externc-isystem" "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/hexagon/include"
+// CHECK005-NEXT: "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/bin/hexagon-as"
+
+// RUN: %clang -ccc-cxx -x c++ -### -target hexagon-unknown-elf \
+// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
+// RUN: -nostdinc++ \
+// RUN: %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECK006 %s
+// CHECK006: "-cc1"
+// CHECK006-NOT: "-internal-isystem" "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/hexagon/include/c++/4.4.0"
+// CHECK006-NEXT: "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/bin/hexagon-as"
+
+// -----------------------------------------------------------------------------
+// Test -march=<archname> -mcpu=<archname> -mv<number>
+// -----------------------------------------------------------------------------
+// RUN: %clang -### -target hexagon-unknown-elf \
+// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
+// RUN: -march=hexagonv3 \
+// RUN: %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECK007 %s
+// CHECK007: "-cc1" {{.*}} "-target-cpu" "hexagonv3"
+// CHECK007-NEXT: "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/bin/hexagon-as"{{.*}} "-march=v3"
+// CHECK007-NEXT: "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/bin/hexagon-ld"{{.*}} "-mv3"
+
+// RUN: %clang -### -target hexagon-unknown-elf \
+// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
+// RUN: -mcpu=hexagonv5 \
+// RUN: %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECK008 %s
+// CHECK008: "-cc1" {{.*}} "-target-cpu" "hexagonv5"
+// CHECK008-NEXT: "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/bin/hexagon-as"{{.*}} "-march=v5"
+// CHECK008-NEXT: "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/bin/hexagon-ld"{{.*}} "-mv5"
+
+// RUN: %clang -### -target hexagon-unknown-elf \
+// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
+// RUN: -mv2 \
+// RUN: %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECK009 %s
+// CHECK009: "-cc1" {{.*}} "-target-cpu" "hexagonv2"
+// CHECK009-NEXT: "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/bin/hexagon-as"{{.*}} "-march=v2"
+// CHECK009-NEXT: "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/bin/hexagon-ld"{{.*}} "-mv2"
+
+// RUN: %clang -### -target hexagon-unknown-elf \
+// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
+// RUN: %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECK010 %s
+// CHECK010: "-cc1" {{.*}} "-target-cpu" "hexagonv4"
+// CHECK010-NEXT: "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/bin/hexagon-as"{{.*}} "-march=v4"
+// CHECK010-NEXT: "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/bin/hexagon-ld"{{.*}} "-mv4"
+
+// RUN: %clang -march=hexagonv2 -target hexagon-unknown-elf \
+// RUN: %s 2>&1 | FileCheck -check-prefix=CHECK-UNKNOWN-V2 %s
+// RUN: %clang -mcpu=hexagonv2 -target hexagon-unknown-elf \
+// RUN: %s 2>&1 | FileCheck -check-prefix=CHECK-UNKNOWN-V2 %s
+// RUN: %clang -mv2 -target hexagon-unknown-elf \
+// RUN: %s 2>&1 | FileCheck -check-prefix=CHECK-UNKNOWN-V2 %s
+// CHECK-UNKNOWN-V2: error: unknown target CPU 'hexagonv2'
+
+// RUN: %clang -march=hexagonv3 -target hexagon-unknown-elf \
+// RUN: %s 2>&1 | FileCheck -check-prefix=CHECK-UNKNOWN-V3 %s
+// RUN: %clang -mcpu=hexagonv3 -target hexagon-unknown-elf \
+// RUN: %s 2>&1 | FileCheck -check-prefix=CHECK-UNKNOWN-V3 %s
+// RUN: %clang -mv3 -target hexagon-unknown-elf \
+// RUN: %s 2>&1 | FileCheck -check-prefix=CHECK-UNKNOWN-V3 %s
+// CHECK-UNKNOWN-V3: error: unknown target CPU 'hexagonv3'
+
+// -----------------------------------------------------------------------------
+// Test Linker related args
+// -----------------------------------------------------------------------------
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+// Defaults for C
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+// RUN: %clang -### -target hexagon-unknown-elf \
+// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
+// RUN: %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECK011 %s
+// CHECK011: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK011-NEXT: "{{.*}}/bin/hexagon-as"{{.*}}
+// CHECK011-NEXT: "{{.*}}/bin/hexagon-ld"
+// CHECK011-NOT: "-static"
+// CHECK011-NOT: "-shared"
+// CHECK011: "{{.*}}/hexagon/lib/v4/crt0_standalone.o"
+// CHECK011: "{{.*}}/hexagon/lib/v4/crt0.o"
+// CHECK011: "{{.*}}/hexagon/lib/v4/init.o"
+// CHECK011: "-L{{.*}}/lib/gcc/hexagon/4.4.0/v4"
+// CHECK011: "-L{{.*}}/lib/gcc/hexagon/4.4.0"
+// CHECK011: "-L{{.*}}/lib/gcc"
+// CHECK011: "-L{{.*}}/hexagon/lib/v4"
+// CHECK011: "-L{{.*}}/hexagon/lib"
+// CHECK011: "{{[^"]+}}.o"
+// CHECK011: "--start-group" "-lstandalone" "-lc" "-lgcc" "--end-group"
+// CHECK011: "{{.*}}/hexagon/lib/v4/fini.o"
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+// Defaults for C++
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+// RUN: %clang -ccc-cxx -x c++ -### -target hexagon-unknown-elf \
+// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
+// RUN: %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECK012 %s
+// CHECK012: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK012-NEXT: "{{.*}}/bin/hexagon-as"{{.*}}
+// CHECK012-NEXT: "{{.*}}/bin/hexagon-ld"
+// CHECK012-NOT: "-static"
+// CHECK012-NOT: "-shared"
+// CHECK012: "{{.*}}/hexagon/lib/v4/crt0_standalone.o"
+// CHECK012: "{{.*}}/hexagon/lib/v4/crt0.o"
+// CHECK012: "{{.*}}/hexagon/lib/v4/init.o"
+// CHECK012: "-L{{.*}}/lib/gcc/hexagon/4.4.0/v4"
+// CHECK012: "-L{{.*}}/lib/gcc/hexagon/4.4.0"
+// CHECK012: "-L{{.*}}/lib/gcc"
+// CHECK012: "-L{{.*}}/hexagon/lib/v4"
+// CHECK012: "-L{{.*}}/hexagon/lib"
+// CHECK012: "{{[^"]+}}.o"
+// CHECK012: "-lstdc++" "-lm"
+// CHECK012: "--start-group" "-lstandalone" "-lc" "-lgcc" "--end-group"
+// CHECK012: "{{.*}}/hexagon/lib/v4/fini.o"
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+// Additional Libraries (-L)
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+// RUN: %clang -### -target hexagon-unknown-elf \
+// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
+// RUN: -Lone -L two -L three \
+// RUN: %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECK013 %s
+// CHECK013: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK013-NEXT: "{{.*}}/bin/hexagon-as"{{.*}}
+// CHECK013-NEXT: "{{.*}}/bin/hexagon-ld"
+// CHECK013: "{{.*}}/hexagon/lib/v4/crt0_standalone.o"
+// CHECK013: "{{.*}}/hexagon/lib/v4/crt0.o"
+// CHECK013: "{{.*}}/hexagon/lib/v4/init.o"
+// CHECK013: "-Lone" "-Ltwo" "-Lthree"
+// CHECK013: "-L{{.*}}/lib/gcc/hexagon/4.4.0/v4"
+// CHECK013: "-L{{.*}}/lib/gcc/hexagon/4.4.0"
+// CHECK013: "-L{{.*}}/lib/gcc"
+// CHECK013: "-L{{.*}}/hexagon/lib/v4"
+// CHECK013: "-L{{.*}}/hexagon/lib"
+// CHECK013: "{{[^"]+}}.o"
+// CHECK013: "--start-group" "-lstandalone" "-lc" "-lgcc" "--end-group"
+// CHECK013: "{{.*}}/hexagon/lib/v4/fini.o"
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+// -static, -shared
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+// RUN: %clang -### -target hexagon-unknown-elf \
+// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
+// RUN: -static \
+// RUN: %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECK014 %s
+// CHECK014: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK014-NEXT: "{{.*}}/bin/hexagon-as"{{.*}}
+// CHECK014-NEXT: "{{.*}}/bin/hexagon-ld"
+// CHECK014: "-static"
+// CHECK014: "{{.*}}/hexagon/lib/v4/crt0_standalone.o"
+// CHECK014: "{{.*}}/hexagon/lib/v4/crt0.o"
+// CHECK014: "{{.*}}/hexagon/lib/v4/init.o"
+// CHECK014: "-L{{.*}}/lib/gcc/hexagon/4.4.0/v4"
+// CHECK014: "-L{{.*}}/lib/gcc/hexagon/4.4.0"
+// CHECK014: "-L{{.*}}/lib/gcc"
+// CHECK014: "-L{{.*}}/hexagon/lib/v4"
+// CHECK014: "-L{{.*}}/hexagon/lib"
+// CHECK014: "{{[^"]+}}.o"
+// CHECK014: "--start-group" "-lstandalone" "-lc" "-lgcc" "--end-group"
+// CHECK014: "{{.*}}/hexagon/lib/v4/fini.o"
+
+// RUN: %clang -### -target hexagon-unknown-elf \
+// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
+// RUN: -shared \
+// RUN: %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECK015 %s
+// CHECK015: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK015-NEXT: "{{.*}}/bin/hexagon-as"{{.*}}
+// CHECK015-NEXT: "{{.*}}/bin/hexagon-ld"
+// CHECK015: "-shared" "-call_shared"
+// CHECK015-NOT: crt0_standalone.o
+// CHECK015-NOT: crt0.o
+// CHECK015: "{{.*}}/hexagon/lib/v4/G0/initS.o"
+// CHECK015: "-L{{.*}}/lib/gcc/hexagon/4.4.0/v4/G0"
+// CHECK015: "-L{{.*}}/lib/gcc/hexagon/4.4.0/G0"
+// CHECK015: "-L{{.*}}/lib/gcc/hexagon/4.4.0/v4"
+// CHECK015: "-L{{.*}}/lib/gcc/hexagon/4.4.0"
+// CHECK015: "-L{{.*}}/lib/gcc"
+// CHECK015: "-L{{.*}}/hexagon/lib/v4/G0"
+// CHECK015: "-L{{.*}}/hexagon/lib/G0"
+// CHECK015: "-L{{.*}}/hexagon/lib/v4"
+// CHECK015: "-L{{.*}}/hexagon/lib"
+// CHECK015: "{{[^"]+}}.o"
+// CHECK015: "--start-group"
+// CHECK015-NOT: "-lstandalone"
+// CHECK015-NOT: "-lc"
+// CHECK015: "-lgcc"
+// CHECK015: "--end-group"
+// CHECK015: "{{.*}}/hexagon/lib/v4/G0/finiS.o"
+
+// RUN: %clang -### -target hexagon-unknown-elf \
+// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
+// RUN: -shared \
+// RUN: -static \
+// RUN: %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECK016 %s
+// CHECK016: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK016-NEXT: "{{.*}}/bin/hexagon-as"{{.*}}
+// CHECK016-NEXT: "{{.*}}/bin/hexagon-ld"
+// CHECK016: "-shared" "-call_shared" "-static"
+// CHECK016-NOT: crt0_standalone.o
+// CHECK016-NOT: crt0.o
+// CHECK016: "{{.*}}/hexagon/lib/v4/G0/init.o"
+// CHECK016: "-L{{.*}}/lib/gcc/hexagon/4.4.0/v4/G0"
+// CHECK016: "-L{{.*}}/lib/gcc/hexagon/4.4.0/G0"
+// CHECK016: "-L{{.*}}/lib/gcc/hexagon/4.4.0/v4"
+// CHECK016: "-L{{.*}}/lib/gcc/hexagon/4.4.0"
+// CHECK016: "-L{{.*}}/lib/gcc"
+// CHECK016: "-L{{.*}}/hexagon/lib/v4/G0"
+// CHECK016: "-L{{.*}}/hexagon/lib/G0"
+// CHECK016: "-L{{.*}}/hexagon/lib/v4"
+// CHECK016: "-L{{.*}}/hexagon/lib"
+// CHECK016: "{{[^"]+}}.o"
+// CHECK016: "--start-group"
+// CHECK016-NOT: "-lstandalone"
+// CHECK016-NOT: "-lc"
+// CHECK016: "-lgcc"
+// CHECK016: "--end-group"
+// CHECK016: "{{.*}}/hexagon/lib/v4/G0/fini.o"
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+// -nostdlib, -nostartfiles, -nodefaultlibs
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+// RUN: %clang -ccc-cxx -x c++ -### -target hexagon-unknown-elf \
+// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
+// RUN: -nostdlib \
+// RUN: %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECK017 %s
+// CHECK017: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK017-NEXT: "{{.*}}/bin/hexagon-as"{{.*}}
+// CHECK017-NEXT: "{{.*}}/bin/hexagon-ld"
+// CHECK017-NOT: crt0_standalone.o
+// CHECK017-NOT: crt0.o
+// CHECK017-NOT: init.o
+// CHECK017: "-L{{.*}}/lib/gcc/hexagon/4.4.0/v4"
+// CHECK017: "-L{{.*}}/lib/gcc/hexagon/4.4.0"
+// CHECK017: "-L{{.*}}/lib/gcc"
+// CHECK017: "-L{{.*}}/hexagon/lib/v4"
+// CHECK017: "-L{{.*}}/hexagon/lib"
+// CHECK017: "{{[^"]+}}.o"
+// CHECK017-NOT: "-lstdc++"
+// CHECK017-NOT: "-lm"
+// CHECK017-NOT: "--start-group"
+// CHECK017-NOT: "-lstandalone"
+// CHECK017-NOT: "-lc"
+// CHECK017-NOT: "-lgcc"
+// CHECK017-NOT: "--end-group"
+// CHECK017-NOT: fini.o
+
+// RUN: %clang -ccc-cxx -x c++ -### -target hexagon-unknown-elf \
+// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
+// RUN: -nostartfiles \
+// RUN: %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECK018 %s
+// CHECK018: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK018-NEXT: "{{.*}}/bin/hexagon-as"{{.*}}
+// CHECK018-NEXT: "{{.*}}/bin/hexagon-ld"
+// CHECK018-NOT: crt0_standalone.o
+// CHECK018-NOT: crt0.o
+// CHECK018-NOT: init.o
+// CHECK018: "-L{{.*}}/lib/gcc/hexagon/4.4.0/v4"
+// CHECK018: "-L{{.*}}/lib/gcc/hexagon/4.4.0"
+// CHECK018: "-L{{.*}}/lib/gcc"
+// CHECK018: "-L{{.*}}/hexagon/lib/v4"
+// CHECK018: "-L{{.*}}/hexagon/lib"
+// CHECK018: "{{[^"]+}}.o"
+// CHECK018: "-lstdc++"
+// CHECK018: "-lm"
+// CHECK018: "--start-group"
+// CHECK018: "-lstandalone"
+// CHECK018: "-lc"
+// CHECK018: "-lgcc"
+// CHECK018: "--end-group"
+// CHECK018-NOT: fini.o
+
+// RUN: %clang -ccc-cxx -x c++ -### -target hexagon-unknown-elf \
+// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
+// RUN: -nodefaultlibs \
+// RUN: %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECK019 %s
+// CHECK019: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK019-NEXT: "{{.*}}/bin/hexagon-as"{{.*}}
+// CHECK019-NEXT: "{{.*}}/bin/hexagon-ld"
+// CHECK019: "{{.*}}/hexagon/lib/v4/crt0_standalone.o"
+// CHECK019: "{{.*}}/hexagon/lib/v4/crt0.o"
+// CHECK019: "{{.*}}/hexagon/lib/v4/init.o"
+// CHECK019: "-L{{.*}}/lib/gcc/hexagon/4.4.0/v4"
+// CHECK019: "-L{{.*}}/lib/gcc/hexagon/4.4.0"
+// CHECK019: "-L{{.*}}/lib/gcc"
+// CHECK019: "-L{{.*}}/hexagon/lib/v4"
+// CHECK019: "-L{{.*}}/hexagon/lib"
+// CHECK019: "{{[^"]+}}.o"
+// CHECK019-NOT: "-lstdc++"
+// CHECK019-NOT: "-lm"
+// CHECK019-NOT: "--start-group"
+// CHECK019-NOT: "-lstandalone"
+// CHECK019-NOT: "-lc"
+// CHECK019-NOT: "-lgcc"
+// CHECK019-NOT: "--end-group"
+// CHECK019: "{{.*}}/hexagon/lib/v4/fini.o"
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+// -moslib
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+// RUN: %clang -### -target hexagon-unknown-elf \
+// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
+// RUN: -moslib=first -moslib=second \
+// RUN: %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECK020 %s
+// CHECK020: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK020-NEXT: "{{.*}}/bin/hexagon-as"{{.*}}
+// CHECK020-NEXT: "{{.*}}/bin/hexagon-ld"
+// CHECK020-NOT: "-static"
+// CHECK020-NOT: "-shared"
+// CHECK020-NOT: crt0_standalone.o
+// CHECK020: "{{.*}}/hexagon/lib/v4/crt0.o"
+// CHECK020: "{{.*}}/hexagon/lib/v4/init.o"
+// CHECK020: "-L{{.*}}/lib/gcc/hexagon/4.4.0/v4"
+// CHECK020: "-L{{.*}}/lib/gcc/hexagon/4.4.0"
+// CHECK020: "-L{{.*}}/lib/gcc"
+// CHECK020: "-L{{.*}}/hexagon/lib/v4"
+// CHECK020: "-L{{.*}}/hexagon/lib"
+// CHECK020: "{{[^"]+}}.o"
+// CHECK020: "--start-group"
+// CHECK020: "-lfirst" "-lsecond"
+// CHECK020-NOT: "-lstandalone"
+// CHECK020: "-lc" "-lgcc" "--end-group"
+// CHECK020: "{{.*}}/hexagon/lib/v4/fini.o"
+
+// RUN: %clang -### -target hexagon-unknown-elf \
+// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
+// RUN: -moslib=first -moslib=second -moslib=standalone\
+// RUN: %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECK021 %s
+// CHECK021: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK021-NEXT: "{{.*}}/bin/hexagon-as"{{.*}}
+// CHECK021-NEXT: "{{.*}}/bin/hexagon-ld"
+// CHECK021-NOT: "-static"
+// CHECK021-NOT: "-shared"
+// CHECK021: "{{.*}}/hexagon/lib/v4/crt0_standalone.o"
+// CHECK021: "{{.*}}/hexagon/lib/v4/crt0.o"
+// CHECK021: "{{.*}}/hexagon/lib/v4/init.o"
+// CHECK021: "-L{{.*}}/lib/gcc/hexagon/4.4.0/v4"
+// CHECK021: "-L{{.*}}/lib/gcc/hexagon/4.4.0"
+// CHECK021: "-L{{.*}}/lib/gcc"
+// CHECK021: "-L{{.*}}/hexagon/lib/v4"
+// CHECK021: "-L{{.*}}/hexagon/lib"
+// CHECK021: "{{[^"]+}}.o"
+// CHECK021: "--start-group"
+// CHECK021: "-lfirst" "-lsecond"
+// CHECK021: "-lstandalone"
+// CHECK021: "-lc" "-lgcc" "--end-group"
+// CHECK021: "{{.*}}/hexagon/lib/v4/fini.o"
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+// Other args to pass to linker
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+// RUN: %clang -ccc-cxx -x c++ -### -target hexagon-unknown-elf \
+// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
+// RUN: -s \
+// RUN: -Tbss 0xdead -Tdata 0xbeef -Ttext 0xcafe \
+// RUN: -t \
+// RUN: -e start_here \
+// RUN: -uFoo -undefined Bar \
+// RUN: %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECK022 %s
+// CHECK022: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK022-NEXT: "{{.*}}/bin/hexagon-as"{{.*}}
+// CHECK022-NEXT: "{{.*}}/bin/hexagon-ld"
+// CHECK022: "{{.*}}/hexagon/lib/v4/crt0_standalone.o"
+// CHECK022: "{{.*}}/hexagon/lib/v4/crt0.o"
+// CHECK022: "{{.*}}/hexagon/lib/v4/init.o"
+// CHECK022: "-L{{.*}}/lib/gcc/hexagon/4.4.0/v4"
+// CHECK022: "-L{{.*}}/lib/gcc/hexagon/4.4.0"
+// CHECK022: "-L{{.*}}/lib/gcc"
+// CHECK022: "-L{{.*}}/hexagon/lib/v4"
+// CHECK022: "-L{{.*}}/hexagon/lib"
+// CHECK022: "-Tbss" "0xdead" "-Tdata" "0xbeef" "-Ttext" "0xcafe"
+// CHECK022: "-s"
+// CHECK022: "-t"
+// CHECK022: "-u" "Foo" "-undefined" "Bar"
+// CHECK022: "{{[^"]+}}.o"
+// CHECK022: "-lstdc++" "-lm"
+// CHECK022: "--start-group" "-lstandalone" "-lc" "-lgcc" "--end-group"
+// CHECK022: "{{.*}}/hexagon/lib/v4/fini.o"
+
+// -----------------------------------------------------------------------------
+// pic, small data threshold
+// -----------------------------------------------------------------------------
+// RUN: %clang -### -target hexagon-unknown-elf \
+// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
+// RUN: %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECK023 %s
+// CHECK023: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK023: "-mrelocation-model" "static"
+// CHECK023-NEXT: "{{.*}}/bin/hexagon-as"
+// CHECK023-NOT: "-G{{[0-9]+}}"
+// CHECK023-NEXT: "{{.*}}/bin/hexagon-ld"
+// CHECK023-NOT: "-G{{[0-9]+}}"
+
+// RUN: %clang -### -target hexagon-unknown-elf \
+// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
+// RUN: -fpic \
+// RUN: %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECK024 %s
+// RUN: %clang -### -target hexagon-unknown-elf \
+// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
+// RUN: -fPIC \
+// RUN: %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECK024 %s
+// RUN: %clang -### -target hexagon-unknown-elf \
+// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
+// RUN: -fPIC \
+// RUN: -msmall_data_threshold=8 \
+// RUN: %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECK024 %s
+// CHECK024: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK024-NOT: "-mrelocation-model" "static"
+// CHECK024: "-pic-level" "{{[12]}}"
+// CHECK024: "-mllvm" "-hexagon-small-data-threshold=0"
+// CHECK024-NEXT: "{{.*}}/bin/hexagon-as"
+// CHECK024: "-G0"
+// CHECK024-NEXT: "{{.*}}/bin/hexagon-ld"
+// CHECK024: "-G0"
+
+// RUN: %clang -### -target hexagon-unknown-elf \
+// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
+// RUN: -G=8 \
+// RUN: %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECK025 %s
+// RUN: %clang -### -target hexagon-unknown-elf \
+// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
+// RUN: -G 8 \
+// RUN: %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECK025 %s
+// RUN: %clang -### -target hexagon-unknown-elf \
+// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
+// RUN: -msmall-data-threshold=8 \
+// RUN: %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECK025 %s
+// CHECK025: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK025: "-mrelocation-model" "static"
+// CHECK025: "-mllvm" "-hexagon-small-data-threshold=8"
+// CHECK025-NEXT: "{{.*}}/bin/hexagon-as"
+// CHECK025: "-G8"
+// CHECK025-NEXT: "{{.*}}/bin/hexagon-ld"
+// CHECK025: "-G8"
+
+// -----------------------------------------------------------------------------
+// pie
+// -----------------------------------------------------------------------------
+// RUN: %clang -### -target hexagon-unknown-elf \
+// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
+// RUN: -pie \
+// RUN: %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECK026 %s
+// CHECK026: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK026-NEXT: "{{.*}}/bin/hexagon-as"
+// CHECK026-NEXT: "{{.*}}/bin/hexagon-ld"
+// CHECK026: "-pie"
+
+// RUN: %clang -### -target hexagon-unknown-elf \
+// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
+// RUN: -pie -shared \
+// RUN: %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECK027 %s
+// CHECK027: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK027-NEXT: "{{.*}}/bin/hexagon-as"
+// CHECK027-NEXT: "{{.*}}/bin/hexagon-ld"
+// CHECK027-NOT: "-pie"
+
+// -----------------------------------------------------------------------------
+// Misc Defaults
+// -----------------------------------------------------------------------------
+// RUN: %clang -### -target hexagon-unknown-elf \
+// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
+// RUN: %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECK028 %s
+// CHECK028: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK028: "-mqdsp6-compat"
+// CHECK028: "-Wreturn-type"
+// CHECK028-NEXT: "{{.*}}/bin/hexagon-as"
+// CHECK028-NEXT: "{{.*}}/bin/hexagon-ld"
+
+// -----------------------------------------------------------------------------
+// Test Assembler related args
+// -----------------------------------------------------------------------------
+// RUN: %clang -### -target hexagon-unknown-elf \
+// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
+// RUN: -gdwarf-2 \
+// RUN: -Wa,--noexecstack,--trap \
+// RUN: -Xassembler --keep-locals \
+// RUN: %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECK029 %s
+// CHECK029: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK029-NEXT: "{{.*}}/bin/hexagon-as"
+// CHECK029: "--noexecstack" "--trap" "--keep-locals"
+// CHECK029-NEXT: "{{.*}}/bin/hexagon-ld"
diff --git a/test/Driver/hexagon-toolchain.c b/test/Driver/hexagon-toolchain.c
index bfa627c421..3e66f354c4 100644
--- a/test/Driver/hexagon-toolchain.c
+++ b/test/Driver/hexagon-toolchain.c
@@ -560,5 +560,5 @@
// RUN: | FileCheck -check-prefix=CHECK029 %s
// CHECK029: "{{.*}}clang{{.*}}" "-cc1"
// CHECK029-NEXT: "{{.*}}/bin/hexagon-as"
-// CHECK029: "-gdwarf-2" "--noexecstack" "--trap" "--keep-locals"
+// CHECK029: "--noexecstack" "--trap" "--keep-locals"
// CHECK029-NEXT: "{{.*}}/bin/hexagon-ld"
diff --git a/test/Driver/inhibit-downstream-commands.c b/test/Driver/inhibit-downstream-commands.c
index e06fdb1a3d..5e46708cfe 100644
--- a/test/Driver/inhibit-downstream-commands.c
+++ b/test/Driver/inhibit-downstream-commands.c
@@ -2,4 +2,5 @@
// CHECK: error: unknown type name 'invalid'
// CHECK-NOT: clang: error: assembler command failed
// CHECK-NOT: clang: error: linker command failed
+// XFAIL: win32
invalid C code!
diff --git a/test/Driver/linux-ld.c b/test/Driver/linux-ld.c
index 79282cbf41..ebac718b33 100644
--- a/test/Driver/linux-ld.c
+++ b/test/Driver/linux-ld.c
@@ -245,6 +245,22 @@
// CHECK-UBUNTU-12-04-ARM-HF: "{{.*}}/usr/lib/gcc/arm-linux-gnueabihf/4.6.3/crtend.o"
// CHECK-UBUNTU-12-04-ARM-HF: "{{.*}}/usr/lib/gcc/arm-linux-gnueabihf/4.6.3/../../../arm-linux-gnueabihf/crtn.o"
//
+// Check fedora 18 on arm.
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN: -target armv7-unknown-linux-gnueabihf \
+// RUN: --sysroot=%S/Inputs/fedora_18_tree \
+// RUN: | FileCheck --check-prefix=CHECK-FEDORA-18-ARM-HF %s
+// CHECK-FEDORA-18-ARM-HF: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
+// CHECK-FEDORA-18-ARM-HF: "{{.*}}/usr/lib/gcc/armv7hl-redhat-linux-gnueabi/4.7.2/../../../crt1.o"
+// CHECK-FEDORA-18-ARM-HF: "{{.*}}/usr/lib/gcc/armv7hl-redhat-linux-gnueabi/4.7.2/../../../crti.o"
+// CHECK-FEDORA-18-ARM-HF: "{{.*}}/usr/lib/gcc/armv7hl-redhat-linux-gnueabi/4.7.2/crtbegin.o"
+// CHECK-FEDORA-18-ARM-HF: "-L[[SYSROOT]]/usr/lib/gcc/armv7hl-redhat-linux-gnueabi/4.7.2"
+// CHECK-FEDORA-18-ARM-HF: "-L[[SYSROOT]]/usr/lib/gcc/armv7hl-redhat-linux-gnueabi/4.7.2/../../.."
+// CHECK-FEDORA-18-ARM-HF: "-L[[SYSROOT]]/lib"
+// CHECK-FEDORA-18-ARM-HF: "-L[[SYSROOT]]/usr/lib"
+// CHECK-FEDORA-18-ARM-HF: "{{.*}}/usr/lib/gcc/armv7hl-redhat-linux-gnueabi/4.7.2/crtend.o"
+// CHECK-FEDORA-18-ARM-HF: "{{.*}}/usr/lib/gcc/armv7hl-redhat-linux-gnueabi/4.7.2/../../../crtn.o"
+//
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
// RUN: -target arm-unknown-linux-gnueabi \
// RUN: --sysroot=%S/Inputs/ubuntu_12.04_LTS_multiarch_tree \
diff --git a/test/Driver/mips-abi.c b/test/Driver/mips-abi.c
new file mode 100644
index 0000000000..fd2b46f41b
--- /dev/null
+++ b/test/Driver/mips-abi.c
@@ -0,0 +1,36 @@
+// Check passing Mips ABI options to the backend.
+//
+// RUN: %clang -target mips-linux-gnu -### -c %s \
+// RUN: -mabi=32 2>&1 \
+// RUN: | FileCheck -check-prefix=MIPS-ABI-32 %s
+// MIPS-ABI-32: "-target-abi" "o32"
+//
+// RUN: %clang -target mips-linux-gnu -### -c %s \
+// RUN: -mabi=o32 2>&1 \
+// RUN: | FileCheck -check-prefix=MIPS-ABI-O32 %s
+// MIPS-ABI-O32: "-target-abi" "o32"
+//
+// RUN: %clang -target mips-linux-gnu -### -c %s \
+// RUN: -mabi=n32 2>&1 \
+// RUN: | FileCheck -check-prefix=MIPS-ABI-N32 %s
+// MIPS-ABI-N32: "-target-abi" "n32"
+//
+// RUN: %clang -target mips64-linux-gnu -### -c %s \
+// RUN: -mabi=64 2>&1 \
+// RUN: | FileCheck -check-prefix=MIPS-ABI-64 %s
+// MIPS-ABI-64: "-target-abi" "n64"
+//
+// RUN: %clang -target mips64-linux-gnu -### -c %s \
+// RUN: -mabi=n64 2>&1 \
+// RUN: | FileCheck -check-prefix=MIPS-ABI-N64 %s
+// MIPS-ABI-N64: "-target-abi" "n64"
+//
+// RUN: %clang -target mips64-linux-gnu -### -c %s \
+// RUN: -mabi=o64 2>&1 \
+// RUN: | FileCheck -check-prefix=MIPS-ABI-O64 %s
+// MIPS-ABI-O64: "-target-abi" "o64"
+//
+// RUN: %clang -target mips-linux-gnu -### -c %s \
+// RUN: -mabi=eabi 2>&1 \
+// RUN: | FileCheck -check-prefix=MIPS-ABI-EABI %s
+// MIPS-ABI-EABI: "-target-abi" "eabi"
diff --git a/test/Driver/mips-as.c b/test/Driver/mips-as.c
index 146b1930c6..216b65607e 100644
--- a/test/Driver/mips-as.c
+++ b/test/Driver/mips-as.c
@@ -1,5 +1,3 @@
-// REQUIRES: mips-registered-target
-//
// Check passing options to the assembler for MIPS targets.
//
// RUN: %clang -target mips-linux-gnu -### \
@@ -73,3 +71,47 @@
// RUN: -no-integrated-as -c %s 2>&1 \
// RUN: | FileCheck -check-prefix=MIPS-ALIAS-64R2 %s
// MIPS-ALIAS-64R2: as{{(.exe)?}}" "-march" "mips64r2" "-mabi" "64" "-EB"
+//
+// RUN: %clang -target mips-linux-gnu -mno-mips16 -mips16 -### \
+// RUN: -no-integrated-as -c %s 2>&1 \
+// RUN: | FileCheck -check-prefix=MIPS-16 %s
+// MIPS-16: as{{(.exe)?}}" "-march" "mips32" "-mabi" "32" "-EB" "-mips16"
+//
+// RUN: %clang -target mips-linux-gnu -mips16 -mno-mips16 -### \
+// RUN: -no-integrated-as -c %s 2>&1 \
+// RUN: | FileCheck -check-prefix=MIPS-N16 %s
+// MIPS-N16: as{{(.exe)?}}"
+// MIPS-N16-NOT: "-mips16"
+//
+// RUN: %clang -target mips-linux-gnu -mno-micromips -mmicromips -### \
+// RUN: -no-integrated-as -c %s 2>&1 \
+// RUN: | FileCheck -check-prefix=MIPS-MICRO %s
+// MIPS-MICRO: as{{(.exe)?}}" "-march" "mips32" "-mabi" "32" "-EB" "-mmicromips"
+//
+// RUN: %clang -target mips-linux-gnu -mmicromips -mno-micromips -### \
+// RUN: -no-integrated-as -c %s 2>&1 \
+// RUN: | FileCheck -check-prefix=MIPS-NMICRO %s
+// MIPS-NMICRO: as{{(.exe)?}}"
+// MIPS-NMICRO-NOT: "-mmicromips"
+//
+// RUN: %clang -target mips-linux-gnu -mno-dsp -mdsp -### \
+// RUN: -no-integrated-as -c %s 2>&1 \
+// RUN: | FileCheck -check-prefix=MIPS-DSP %s
+// MIPS-DSP: as{{(.exe)?}}" "-march" "mips32" "-mabi" "32" "-EB" "-mdsp"
+//
+// RUN: %clang -target mips-linux-gnu -mdsp -mno-dsp -### \
+// RUN: -no-integrated-as -c %s 2>&1 \
+// RUN: | FileCheck -check-prefix=MIPS-NDSP %s
+// MIPS-NDSP: as{{(.exe)?}}"
+// MIPS-NDSP-NOT: "-mdsp"
+//
+// RUN: %clang -target mips-linux-gnu -mno-dspr2 -mdspr2 -### \
+// RUN: -no-integrated-as -c %s 2>&1 \
+// RUN: | FileCheck -check-prefix=MIPS-DSPR2 %s
+// MIPS-DSPR2: as{{(.exe)?}}" "-march" "mips32" "-mabi" "32" "-EB" "-mdspr2"
+//
+// RUN: %clang -target mips-linux-gnu -mdspr2 -mno-dspr2 -### \
+// RUN: -no-integrated-as -c %s 2>&1 \
+// RUN: | FileCheck -check-prefix=MIPS-NDSPR2 %s
+// MIPS-NDSPR2: as{{(.exe)?}}"
+// MIPS-NDSPR2-NOT: "-mdspr2"
diff --git a/test/Driver/mips-cs-header-search.cpp b/test/Driver/mips-cs-header-search.cpp
new file mode 100644
index 0000000000..e59fadca58
--- /dev/null
+++ b/test/Driver/mips-cs-header-search.cpp
@@ -0,0 +1,257 @@
+// Check frontend invocations on Mentor Graphics MIPS toolchain.
+//
+// = Big-endian, hard float
+// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \
+// RUN: -target mips-linux-gnu \
+// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \
+// RUN: | FileCheck --check-prefix=CHECK-BE-HF-32 %s
+// CHECK-BE-HF-32: "-internal-isystem"
+// CHECK-BE-HF-32: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3"
+// CHECK-BE-HF-32: "-internal-isystem"
+// CHECK-BE-HF-32: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu"
+// CHECK-BE-HF-32: "-internal-isystem"
+// CHECK-BE-HF-32: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward"
+// CHECK-BE-HF-32: "-internal-externc-isystem"
+// CHECK-BE-HF-32: "[[TC]]/include"
+// CHECK-BE-HF-32: "-internal-externc-isystem"
+// CHECK-BE-HF-32: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include"
+//
+// = Big-endian, hard float, mips16
+// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \
+// RUN: -target mips-linux-gnu -mips16 \
+// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \
+// RUN: | FileCheck --check-prefix=CHECK-BE-HF-16 %s
+// CHECK-BE-HF-16: "-internal-isystem"
+// CHECK-BE-HF-16: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3"
+// CHECK-BE-HF-16: "-internal-isystem"
+// CHECK-BE-HF-16: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/mips16"
+// CHECK-BE-HF-16: "-internal-isystem"
+// CHECK-BE-HF-16: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward"
+// CHECK-BE-HF-16: "-internal-externc-isystem"
+// CHECK-BE-HF-16: "[[TC]]/include"
+// CHECK-BE-HF-16: "-internal-externc-isystem"
+// CHECK-BE-HF-16: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include"
+//
+// = Big-endian, hard float, micromips
+// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \
+// RUN: -target mips-linux-gnu -mmicromips \
+// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \
+// RUN: | FileCheck --check-prefix=CHECK-BE-HF-MICRO %s
+// CHECK-BE-HF-MICRO: "-internal-isystem"
+// CHECK-BE-HF-MICRO: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3"
+// CHECK-BE-HF-MICRO: "-internal-isystem"
+// CHECK-BE-HF-MICRO: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/micromips"
+// CHECK-BE-HF-MICRO: "-internal-isystem"
+// CHECK-BE-HF-MICRO: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward"
+// CHECK-BE-HF-MICRO: "-internal-externc-isystem"
+// CHECK-BE-HF-MICRO: "[[TC]]/include"
+// CHECK-BE-HF-MICRO: "-internal-externc-isystem"
+// CHECK-BE-HF-MICRO: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include"
+//
+// = Big-endian, soft float
+// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \
+// RUN: -target mips-linux-gnu -msoft-float \
+// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \
+// RUN: | FileCheck --check-prefix=CHECK-BE-SF-32 %s
+// CHECK-BE-SF-32: "-internal-isystem"
+// CHECK-BE-SF-32: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3"
+// CHECK-BE-SF-32: "-internal-isystem"
+// CHECK-BE-SF-32: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/soft-float"
+// CHECK-BE-SF-32: "-internal-isystem"
+// CHECK-BE-SF-32: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward"
+// CHECK-BE-SF-32: "-internal-externc-isystem"
+// CHECK-BE-SF-32: "[[TC]]/include"
+// CHECK-BE-SF-32: "-internal-externc-isystem"
+// CHECK-BE-SF-32: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include"
+//
+// = Big-endian, soft float, mips16
+// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \
+// RUN: -target mips-linux-gnu -msoft-float -mips16 \
+// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \
+// RUN: | FileCheck --check-prefix=CHECK-BE-SF-16 %s
+// CHECK-BE-SF-16: "-internal-isystem"
+// CHECK-BE-SF-16: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3"
+// CHECK-BE-SF-16: "-internal-isystem"
+// CHECK-BE-SF-16: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/mips16/soft-float"
+// CHECK-BE-SF-16: "-internal-isystem"
+// CHECK-BE-SF-16: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward"
+// CHECK-BE-SF-16: "-internal-externc-isystem"
+// CHECK-BE-SF-16: "[[TC]]/include"
+// CHECK-BE-SF-16: "-internal-externc-isystem"
+// CHECK-BE-SF-16: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include"
+//
+// = Big-endian, soft float, micromips
+// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \
+// RUN: -target mips-linux-gnu -msoft-float -mmicromips \
+// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \
+// RUN: | FileCheck --check-prefix=CHECK-BE-SF-MICRO %s
+// CHECK-BE-SF-MICRO: "-internal-isystem"
+// CHECK-BE-SF-MICRO: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3"
+// CHECK-BE-SF-MICRO: "-internal-isystem"
+// CHECK-BE-SF-MICRO: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/micromips/soft-float"
+// CHECK-BE-SF-MICRO: "-internal-isystem"
+// CHECK-BE-SF-MICRO: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward"
+// CHECK-BE-SF-MICRO: "-internal-externc-isystem"
+// CHECK-BE-SF-MICRO: "[[TC]]/include"
+// CHECK-BE-SF-MICRO: "-internal-externc-isystem"
+// CHECK-BE-SF-MICRO: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include"
+//
+// = Big-endian, hard float, 64-bit
+// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \
+// RUN: -target mips64-linux-gnu \
+// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \
+// RUN: | FileCheck --check-prefix=CHECK-BE-HF-64 %s
+// CHECK-BE-HF-64: "-internal-isystem"
+// CHECK-BE-HF-64: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3"
+// CHECK-BE-HF-64: "-internal-isystem"
+// CHECK-BE-HF-64: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/64"
+// CHECK-BE-HF-64: "-internal-isystem"
+// CHECK-BE-HF-64: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward"
+// CHECK-BE-HF-64: "-internal-externc-isystem"
+// CHECK-BE-HF-64: "[[TC]]/include"
+// CHECK-BE-HF-64: "-internal-externc-isystem"
+// CHECK-BE-HF-64: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include"
+//
+// = Big-endian, soft float, 64-bit
+// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \
+// RUN: -target mips64-linux-gnu -msoft-float \
+// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \
+// RUN: | FileCheck --check-prefix=CHECK-BE-SF-64 %s
+// CHECK-BE-SF-64: "-internal-isystem"
+// CHECK-BE-SF-64: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3"
+// CHECK-BE-SF-64: "-internal-isystem"
+// CHECK-BE-SF-64: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/soft-float/64"
+// CHECK-BE-SF-64: "-internal-isystem"
+// CHECK-BE-SF-64: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward"
+// CHECK-BE-SF-64: "-internal-externc-isystem"
+// CHECK-BE-SF-64: "[[TC]]/include"
+// CHECK-BE-SF-64: "-internal-externc-isystem"
+// CHECK-BE-SF-64: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include"
+//
+// = Little-endian, hard float
+// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \
+// RUN: -target mipsel-linux-gnu -mhard-float \
+// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \
+// RUN: | FileCheck --check-prefix=CHECK-EL-HF-32 %s
+// CHECK-EL-HF-32: "-internal-isystem"
+// CHECK-EL-HF-32: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3"
+// CHECK-EL-HF-32: "-internal-isystem"
+// CHECK-EL-HF-32: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/el"
+// CHECK-EL-HF-32: "-internal-isystem"
+// CHECK-EL-HF-32: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward"
+// CHECK-EL-HF-32: "-internal-externc-isystem"
+// CHECK-EL-HF-32: "[[TC]]/include"
+// CHECK-EL-HF-32: "-internal-externc-isystem"
+// CHECK-EL-HF-32: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include"
+//
+// = Little-endian, hard float, mips16
+// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \
+// RUN: -target mipsel-linux-gnu -mips16 \
+// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \
+// RUN: | FileCheck --check-prefix=CHECK-EL-HF-16 %s
+// CHECK-EL-HF-16: "-internal-isystem"
+// CHECK-EL-HF-16: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3"
+// CHECK-EL-HF-16: "-internal-isystem"
+// CHECK-EL-HF-16: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/mips16/el"
+// CHECK-EL-HF-16: "-internal-isystem"
+// CHECK-EL-HF-16: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward"
+// CHECK-EL-HF-16: "-internal-externc-isystem"
+// CHECK-EL-HF-16: "[[TC]]/include"
+// CHECK-EL-HF-16: "-internal-externc-isystem"
+// CHECK-EL-HF-16: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include"
+//
+// = Little-endian, hard float, micromips
+// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \
+// RUN: -target mipsel-linux-gnu -mmicromips \
+// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \
+// RUN: | FileCheck --check-prefix=CHECK-EL-HF-MICRO %s
+// CHECK-EL-HF-MICRO: "-internal-isystem"
+// CHECK-EL-HF-MICRO: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3"
+// CHECK-EL-HF-MICRO: "-internal-isystem"
+// CHECK-EL-HF-MICRO: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/micromips/el"
+// CHECK-EL-HF-MICRO: "-internal-isystem"
+// CHECK-EL-HF-MICRO: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward"
+// CHECK-EL-HF-MICRO: "-internal-externc-isystem"
+// CHECK-EL-HF-MICRO: "[[TC]]/include"
+// CHECK-EL-HF-MICRO: "-internal-externc-isystem"
+// CHECK-EL-HF-MICRO: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include"
+//
+// = Little-endian, soft float
+// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \
+// RUN: -target mipsel-linux-gnu -mfloat-abi=soft \
+// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \
+// RUN: | FileCheck --check-prefix=CHECK-EL-SF-32 %s
+// CHECK-EL-SF-32: "-internal-isystem"
+// CHECK-EL-SF-32: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3"
+// CHECK-EL-SF-32: "-internal-isystem"
+// CHECK-EL-SF-32: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/soft-float/el"
+// CHECK-EL-SF-32: "-internal-isystem"
+// CHECK-EL-SF-32: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward"
+// CHECK-EL-SF-32: "-internal-externc-isystem"
+// CHECK-EL-SF-32: "[[TC]]/include"
+// CHECK-EL-SF-32: "-internal-externc-isystem"
+// CHECK-EL-SF-32: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include"
+//
+// = Little-endian, soft float, mips16
+// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \
+// RUN: -target mipsel-linux-gnu -mips16 -msoft-float \
+// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \
+// RUN: | FileCheck --check-prefix=CHECK-EL-SF-16 %s
+// CHECK-EL-SF-16: "-internal-isystem"
+// CHECK-EL-SF-16: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3"
+// CHECK-EL-SF-16: "-internal-isystem"
+// CHECK-EL-SF-16: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/mips16/soft-float/el"
+// CHECK-EL-SF-16: "-internal-isystem"
+// CHECK-EL-SF-16: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward"
+// CHECK-EL-SF-16: "-internal-externc-isystem"
+// CHECK-EL-SF-16: "[[TC]]/include"
+// CHECK-EL-SF-16: "-internal-externc-isystem"
+// CHECK-EL-SF-16: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include"
+//
+// = Little-endian, soft float, micromips
+// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \
+// RUN: -target mipsel-linux-gnu -mmicromips -msoft-float \
+// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \
+// RUN: | FileCheck --check-prefix=CHECK-EL-SF-MICRO %s
+// CHECK-EL-SF-MICRO: "-internal-isystem"
+// CHECK-EL-SF-MICRO: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3"
+// CHECK-EL-SF-MICRO: "-internal-isystem"
+// CHECK-EL-SF-MICRO: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/micromips/soft-float/el"
+// CHECK-EL-SF-MICRO: "-internal-isystem"
+// CHECK-EL-SF-MICRO: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward"
+// CHECK-EL-SF-MICRO: "-internal-externc-isystem"
+// CHECK-EL-SF-MICRO: "[[TC]]/include"
+// CHECK-EL-SF-MICRO: "-internal-externc-isystem"
+// CHECK-EL-SF-MICRO: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include"
+//
+// = Little-endian, hard float, 64-bit
+// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \
+// RUN: -target mips64el-linux-gnu \
+// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \
+// RUN: | FileCheck --check-prefix=CHECK-EL-HF-64 %s
+// CHECK-EL-HF-64: "-internal-isystem"
+// CHECK-EL-HF-64: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3"
+// CHECK-EL-HF-64: "-internal-isystem"
+// CHECK-EL-HF-64: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/el/64"
+// CHECK-EL-HF-64: "-internal-isystem"
+// CHECK-EL-HF-64: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward"
+// CHECK-EL-HF-64: "-internal-externc-isystem"
+// CHECK-EL-HF-64: "[[TC]]/include"
+// CHECK-EL-HF-64: "-internal-externc-isystem"
+// CHECK-EL-HF-64: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include"
+//
+// = Little-endian, soft float, 64-bit
+// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \
+// RUN: -target mips64el-linux-gnu -msoft-float \
+// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \
+// RUN: | FileCheck --check-prefix=CHECK-EL-SF-64 %s
+// CHECK-EL-SF-64: "-internal-isystem"
+// CHECK-EL-SF-64: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3"
+// CHECK-EL-SF-64: "-internal-isystem"
+// CHECK-EL-SF-64: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/soft-float/el/64"
+// CHECK-EL-SF-64: "-internal-isystem"
+// CHECK-EL-SF-64: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward"
+// CHECK-EL-SF-64: "-internal-externc-isystem"
+// CHECK-EL-SF-64: "[[TC]]/include"
+// CHECK-EL-SF-64: "-internal-externc-isystem"
+// CHECK-EL-SF-64: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include"
diff --git a/test/Driver/mips-cs-ld.c b/test/Driver/mips-cs-ld.c
new file mode 100644
index 0000000000..ac3adfd910
--- /dev/null
+++ b/test/Driver/mips-cs-ld.c
@@ -0,0 +1,288 @@
+// Check ld invocations on Mentor Graphics MIPS toolchain.
+//
+// = Big-endian, hard float
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN: -target mips-linux-gnu \
+// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \
+// RUN: | FileCheck --check-prefix=CHECK-BE-HF-32 %s
+// CHECK-BE-HF-32: "{{.*}}ld{{(.exe)?}}"
+// CHECK-BE-HF-32: "--sysroot=[[TC:[^"]+]]/../../../../mips-linux-gnu/libc"
+// CHECK-BE-HF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/usr/lib/../lib/crt1.o"
+// CHECK-BE-HF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/usr/lib/../lib/crti.o"
+// CHECK-BE-HF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/crtbegin.o"
+// CHECK-BE-HF-32: "-L[[TC]]"
+// CHECK-BE-HF-32: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib"
+// CHECK-BE-HF-32: "-L[[TC]]/../../../../mips-linux-gnu/libc/lib"
+// CHECK-BE-HF-32: "-L[[TC]]/../../../../mips-linux-gnu/libc/usr/lib"
+// CHECK-BE-HF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/crtend.o"
+// CHECK-BE-HF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/usr/lib/../lib/crtn.o"
+//
+// = Big-endian, hard float, mips16
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN: -target mips-linux-gnu -mips16 \
+// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \
+// RUN: | FileCheck --check-prefix=CHECK-BE-HF-16 %s
+// CHECK-BE-HF-16: "{{.*}}ld{{(.exe)?}}"
+// CHECK-BE-HF-16: "--sysroot=[[TC:[^"]+]]/../../../../mips-linux-gnu/libc/mips16"
+// CHECK-BE-HF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/mips16/usr/lib/../lib/crt1.o"
+// CHECK-BE-HF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/mips16/usr/lib/../lib/crti.o"
+// CHECK-BE-HF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/mips16/crtbegin.o"
+// CHECK-BE-HF-16: "-L[[TC]]/mips16"
+// CHECK-BE-HF-16: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib/mips16"
+// CHECK-BE-HF-16: "-L[[TC]]"
+// CHECK-BE-HF-16: "-L[[TC]]/../../../../mips-linux-gnu/libc/mips16/lib"
+// CHECK-BE-HF-16: "-L[[TC]]/../../../../mips-linux-gnu/libc/mips16/usr/lib"
+// CHECK-BE-HF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/mips16/crtend.o"
+// CHECK-BE-HF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/mips16/usr/lib/../lib/crtn.o"
+//
+// = Big-endian, hard float, mmicromips
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN: -target mips-linux-gnu -mmicromips \
+// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \
+// RUN: | FileCheck --check-prefix=CHECK-BE-HF-MICRO %s
+// CHECK-BE-HF-MICRO: "{{.*}}ld{{(.exe)?}}"
+// CHECK-BE-HF-MICRO: "--sysroot=[[TC:[^"]+]]/../../../../mips-linux-gnu/libc/micromips"
+// CHECK-BE-HF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/micromips/usr/lib/../lib/crt1.o"
+// CHECK-BE-HF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/micromips/usr/lib/../lib/crti.o"
+// CHECK-BE-HF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/micromips/crtbegin.o"
+// CHECK-BE-HF-MICRO: "-L[[TC]]/micromips"
+// CHECK-BE-HF-MICRO: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib/micromips"
+// CHECK-BE-HF-MICRO: "-L[[TC]]"
+// CHECK-BE-HF-MICRO: "-L[[TC]]/../../../../mips-linux-gnu/libc/micromips/lib"
+// CHECK-BE-HF-MICRO: "-L[[TC]]/../../../../mips-linux-gnu/libc/micromips/usr/lib"
+// CHECK-BE-HF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/micromips/crtend.o"
+// CHECK-BE-HF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/micromips/usr/lib/../lib/crtn.o"
+//
+// = Big-endian, soft float
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN: -target mips-linux-gnu -msoft-float \
+// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \
+// RUN: | FileCheck --check-prefix=CHECK-BE-SF-32 %s
+// CHECK-BE-SF-32: "{{.*}}ld{{(.exe)?}}"
+// CHECK-BE-SF-32: "--sysroot=[[TC:[^"]+]]/../../../../mips-linux-gnu/libc/soft-float"
+// CHECK-BE-SF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/soft-float/usr/lib/../lib/crt1.o"
+// CHECK-BE-SF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/soft-float/usr/lib/../lib/crti.o"
+// CHECK-BE-SF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/soft-float/crtbegin.o"
+// CHECK-BE-SF-32: "-L[[TC]]/soft-float"
+// CHECK-BE-SF-32: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib/soft-float"
+// CHECK-BE-SF-32: "-L[[TC]]"
+// CHECK-BE-SF-32: "-L[[TC]]/../../../../mips-linux-gnu/libc/soft-float/lib"
+// CHECK-BE-SF-32: "-L[[TC]]/../../../../mips-linux-gnu/libc/soft-float/usr/lib"
+// CHECK-BE-SF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/soft-float/crtend.o"
+// CHECK-BE-SF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/soft-float/usr/lib/../lib/crtn.o"
+//
+// = Big-endian, soft float, mips16
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN: -target mips-linux-gnu -msoft-float -mips16 \
+// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \
+// RUN: | FileCheck --check-prefix=CHECK-BE-SF-16 %s
+// CHECK-BE-SF-16: "{{.*}}ld{{(.exe)?}}"
+// CHECK-BE-SF-16: "--sysroot=[[TC:[^"]+]]/../../../../mips-linux-gnu/libc/mips16/soft-float"
+// CHECK-BE-SF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/mips16/soft-float/usr/lib/../lib/crt1.o"
+// CHECK-BE-SF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/mips16/soft-float/usr/lib/../lib/crti.o"
+// CHECK-BE-SF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/mips16/soft-float/crtbegin.o"
+// CHECK-BE-SF-16: "-L[[TC]]/mips16/soft-float"
+// CHECK-BE-SF-16: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib/mips16/soft-float"
+// CHECK-BE-SF-16: "-L[[TC]]"
+// CHECK-BE-SF-16: "-L[[TC]]/../../../../mips-linux-gnu/libc/mips16/soft-float/lib"
+// CHECK-BE-SF-16: "-L[[TC]]/../../../../mips-linux-gnu/libc/mips16/soft-float/usr/lib"
+// CHECK-BE-SF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/mips16/soft-float/crtend.o"
+// CHECK-BE-SF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/mips16/soft-float/usr/lib/../lib/crtn.o"
+//
+// = Big-endian, soft float, micromips
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN: -target mips-linux-gnu -msoft-float -mmicromips \
+// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \
+// RUN: | FileCheck --check-prefix=CHECK-BE-SF-MICRO %s
+// CHECK-BE-SF-MICRO: "{{.*}}ld{{(.exe)?}}"
+// CHECK-BE-SF-MICRO: "--sysroot=[[TC:[^"]+]]/../../../../mips-linux-gnu/libc/micromips/soft-float"
+// CHECK-BE-SF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/micromips/soft-float/usr/lib/../lib/crt1.o"
+// CHECK-BE-SF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/micromips/soft-float/usr/lib/../lib/crti.o"
+// CHECK-BE-SF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/micromips/soft-float/crtbegin.o"
+// CHECK-BE-SF-MICRO: "-L[[TC]]/micromips/soft-float"
+// CHECK-BE-SF-MICRO: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib/micromips/soft-float"
+// CHECK-BE-SF-MICRO: "-L[[TC]]"
+// CHECK-BE-SF-MICRO: "-L[[TC]]/../../../../mips-linux-gnu/libc/micromips/soft-float/lib"
+// CHECK-BE-SF-MICRO: "-L[[TC]]/../../../../mips-linux-gnu/libc/micromips/soft-float/usr/lib"
+// CHECK-BE-SF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/micromips/soft-float/crtend.o"
+// CHECK-BE-SF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/micromips/soft-float/usr/lib/../lib/crtn.o"
+//
+// = Big-endian, hard float, 64-bit
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN: -target mips64-linux-gnu \
+// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \
+// RUN: | FileCheck --check-prefix=CHECK-BE-HF-64 %s
+// CHECK-BE-HF-64: "{{.*}}ld{{(.exe)?}}"
+// CHECK-BE-HF-64: "--sysroot=[[TC:[^"]+]]/../../../../mips-linux-gnu/libc"
+// CHECK-BE-HF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/usr/lib/../lib64/crt1.o"
+// CHECK-BE-HF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/usr/lib/../lib64/crti.o"
+// CHECK-BE-HF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/64/crtbegin.o"
+// CHECK-BE-HF-64: "-L[[TC]]/64"
+// CHECK-BE-HF-64: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib64"
+// CHECK-BE-HF-64: "-L[[TC]]/../../../../mips-linux-gnu/libc/lib/../lib64"
+// CHECK-BE-HF-64: "-L[[TC]]/../../../../mips-linux-gnu/libc/usr/lib/../lib64"
+// CHECK-BE-HF-64: "-L[[TC]]"
+// CHECK-BE-HF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/64/crtend.o"
+// CHECK-BE-HF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/usr/lib/../lib64/crtn.o"
+//
+// = Big-endian, soft float, 64-bit
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN: -target mips64-linux-gnu -msoft-float \
+// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \
+// RUN: | FileCheck --check-prefix=CHECK-BE-SF-64 %s
+// CHECK-BE-SF-64: "{{.*}}ld{{(.exe)?}}"
+// CHECK-BE-SF-64: "--sysroot=[[TC:[^"]+]]/../../../../mips-linux-gnu/libc/soft-float"
+// CHECK-BE-SF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/soft-float/usr/lib/../lib64/crt1.o"
+// CHECK-BE-SF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/soft-float/usr/lib/../lib64/crti.o"
+// CHECK-BE-SF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/soft-float/64/crtbegin.o"
+// CHECK-BE-SF-64: "-L[[TC]]/soft-float/64"
+// CHECK-BE-SF-64: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib64/soft-float"
+// CHECK-BE-SF-64: "-L[[TC]]/../../../../mips-linux-gnu/libc/soft-float/lib/../lib64"
+// CHECK-BE-SF-64: "-L[[TC]]/../../../../mips-linux-gnu/libc/soft-float/usr/lib/../lib64"
+// CHECK-BE-SF-64: "-L[[TC]]"
+// CHECK-BE-SF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/soft-float/64/crtend.o"
+// CHECK-BE-SF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/soft-float/usr/lib/../lib64/crtn.o"
+//
+// = Little-endian, hard float
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN: -target mipsel-linux-gnu -mhard-float \
+// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \
+// RUN: | FileCheck --check-prefix=CHECK-EL-HF-32 %s
+// CHECK-EL-HF-32: "{{.*}}ld{{(.exe)?}}"
+// CHECK-EL-HF-32: "--sysroot=[[TC:[^"]+]]/../../../../mips-linux-gnu/libc/el"
+// CHECK-EL-HF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/el/usr/lib/../lib/crt1.o"
+// CHECK-EL-HF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/el/usr/lib/../lib/crti.o"
+// CHECK-EL-HF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/el/crtbegin.o"
+// CHECK-EL-HF-32: "-L[[TC]]/el"
+// CHECK-EL-HF-32: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib/el"
+// CHECK-EL-HF-32: "-L[[TC]]"
+// CHECK-EL-HF-32: "-L[[TC]]/../../../../mips-linux-gnu/libc/el/lib"
+// CHECK-EL-HF-32: "-L[[TC]]/../../../../mips-linux-gnu/libc/el/usr/lib"
+// CHECK-EL-HF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/el/crtend.o"
+// CHECK-EL-HF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/el/usr/lib/../lib/crtn.o"
+//
+// = Little-endian, hard float, mips16
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN: -target mipsel-linux-gnu -mips16 \
+// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \
+// RUN: | FileCheck --check-prefix=CHECK-EL-HF-16 %s
+// CHECK-EL-HF-16: "{{.*}}ld{{(.exe)?}}"
+// CHECK-EL-HF-16: "--sysroot=[[TC:[^"]+]]/../../../../mips-linux-gnu/libc/mips16/el"
+// CHECK-EL-HF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/mips16/el/usr/lib/../lib/crt1.o"
+// CHECK-EL-HF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/mips16/el/usr/lib/../lib/crti.o"
+// CHECK-EL-HF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/mips16/el/crtbegin.o"
+// CHECK-EL-HF-16: "-L[[TC]]/mips16/el"
+// CHECK-EL-HF-16: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib/mips16/el"
+// CHECK-EL-HF-16: "-L[[TC]]"
+// CHECK-EL-HF-16: "-L[[TC]]/../../../../mips-linux-gnu/libc/mips16/el/lib"
+// CHECK-EL-HF-16: "-L[[TC]]/../../../../mips-linux-gnu/libc/mips16/el/usr/lib"
+// CHECK-EL-HF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/mips16/el/crtend.o"
+// CHECK-EL-HF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/mips16/el/usr/lib/../lib/crtn.o"
+//
+// = Little-endian, hard float, micromips
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN: -target mipsel-linux-gnu -mmicromips \
+// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \
+// RUN: | FileCheck --check-prefix=CHECK-EL-HF-MICRO %s
+// CHECK-EL-HF-MICRO: "{{.*}}ld{{(.exe)?}}"
+// CHECK-EL-HF-MICRO: "--sysroot=[[TC:[^"]+]]/../../../../mips-linux-gnu/libc/micromips/el"
+// CHECK-EL-HF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/micromips/el/usr/lib/../lib/crt1.o"
+// CHECK-EL-HF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/micromips/el/usr/lib/../lib/crti.o"
+// CHECK-EL-HF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/micromips/el/crtbegin.o"
+// CHECK-EL-HF-MICRO: "-L[[TC]]/micromips/el"
+// CHECK-EL-HF-MICRO: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib/micromips/el"
+// CHECK-EL-HF-MICRO: "-L[[TC]]"
+// CHECK-EL-HF-MICRO: "-L[[TC]]/../../../../mips-linux-gnu/libc/micromips/el/lib"
+// CHECK-EL-HF-MICRO: "-L[[TC]]/../../../../mips-linux-gnu/libc/micromips/el/usr/lib"
+// CHECK-EL-HF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/micromips/el/crtend.o"
+// CHECK-EL-HF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/micromips/el/usr/lib/../lib/crtn.o"
+//
+// = Little-endian, soft float
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN: -target mipsel-linux-gnu -mfloat-abi=soft \
+// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \
+// RUN: | FileCheck --check-prefix=CHECK-EL-SF-32 %s
+// CHECK-EL-SF-32: "{{.*}}ld{{(.exe)?}}"
+// CHECK-EL-SF-32: "--sysroot=[[TC:[^"]+]]/../../../../mips-linux-gnu/libc/soft-float/el"
+// CHECK-EL-SF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/soft-float/el/usr/lib/../lib/crt1.o"
+// CHECK-EL-SF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/soft-float/el/usr/lib/../lib/crti.o"
+// CHECK-EL-SF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/soft-float/el/crtbegin.o"
+// CHECK-EL-SF-32: "-L[[TC]]/soft-float/el"
+// CHECK-EL-SF-32: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib/soft-float/el"
+// CHECK-EL-SF-32: "-L[[TC]]"
+// CHECK-EL-SF-32: "-L[[TC]]/../../../../mips-linux-gnu/libc/soft-float/el/lib"
+// CHECK-EL-SF-32: "-L[[TC]]/../../../../mips-linux-gnu/libc/soft-float/el/usr/lib"
+// CHECK-EL-SF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/soft-float/el/crtend.o"
+// CHECK-EL-SF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/soft-float/el/usr/lib/../lib/crtn.o"
+//
+// = Little-endian, soft float, mips16
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN: -target mipsel-linux-gnu -mips16 -msoft-float \
+// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \
+// RUN: | FileCheck --check-prefix=CHECK-EL-SF-16 %s
+// CHECK-EL-SF-16: "{{.*}}ld{{(.exe)?}}"
+// CHECK-EL-SF-16: "--sysroot=[[TC:[^"]+]]/../../../../mips-linux-gnu/libc/mips16/soft-float/el"
+// CHECK-EL-SF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/mips16/soft-float/el/usr/lib/../lib/crt1.o"
+// CHECK-EL-SF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/mips16/soft-float/el/usr/lib/../lib/crti.o"
+// CHECK-EL-SF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/mips16/soft-float/el/crtbegin.o"
+// CHECK-EL-SF-16: "-L[[TC]]/mips16/soft-float/el"
+// CHECK-EL-SF-16: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib/mips16/soft-float/el"
+// CHECK-EL-SF-16: "-L[[TC]]"
+// CHECK-EL-SF-16: "-L[[TC]]/../../../../mips-linux-gnu/libc/mips16/soft-float/el/lib"
+// CHECK-EL-SF-16: "-L[[TC]]/../../../../mips-linux-gnu/libc/mips16/soft-float/el/usr/lib"
+// CHECK-EL-SF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/mips16/soft-float/el/crtend.o"
+// CHECK-EL-SF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/mips16/soft-float/el/usr/lib/../lib/crtn.o"
+//
+// = Little-endian, soft float, micromips
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN: -target mipsel-linux-gnu -mmicromips -msoft-float \
+// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \
+// RUN: | FileCheck --check-prefix=CHECK-EL-SF-MICRO %s
+// CHECK-EL-SF-MICRO: "{{.*}}ld{{(.exe)?}}"
+// CHECK-EL-SF-MICRO: "--sysroot=[[TC:[^"]+]]/../../../../mips-linux-gnu/libc/micromips/soft-float/el"
+// CHECK-EL-SF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/micromips/soft-float/el/usr/lib/../lib/crt1.o"
+// CHECK-EL-SF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/micromips/soft-float/el/usr/lib/../lib/crti.o"
+// CHECK-EL-SF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/micromips/soft-float/el/crtbegin.o"
+// CHECK-EL-SF-MICRO: "-L[[TC]]/micromips/soft-float/el"
+// CHECK-EL-SF-MICRO: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib/micromips/soft-float/el"
+// CHECK-EL-SF-MICRO: "-L[[TC]]"
+// CHECK-EL-SF-MICRO: "-L[[TC]]/../../../../mips-linux-gnu/libc/micromips/soft-float/el/lib"
+// CHECK-EL-SF-MICRO: "-L[[TC]]/../../../../mips-linux-gnu/libc/micromips/soft-float/el/usr/lib"
+// CHECK-EL-SF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/micromips/soft-float/el/crtend.o"
+// CHECK-EL-SF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/micromips/soft-float/el/usr/lib/../lib/crtn.o"
+//
+// = Little-endian, hard float, 64-bit
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN: -target mips64el-linux-gnu \
+// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \
+// RUN: | FileCheck --check-prefix=CHECK-EL-HF-64 %s
+// CHECK-EL-HF-64: "{{.*}}ld{{(.exe)?}}"
+// CHECK-EL-HF-64: "--sysroot=[[TC:[^"]+]]/../../../../mips-linux-gnu/libc/el"
+// CHECK-EL-HF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/el/usr/lib/../lib64/crt1.o"
+// CHECK-EL-HF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/el/usr/lib/../lib64/crti.o"
+// CHECK-EL-HF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/el/64/crtbegin.o"
+// CHECK-EL-HF-64: "-L[[TC]]/el/64"
+// CHECK-EL-HF-64: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib64/el"
+// CHECK-EL-HF-64: "-L[[TC]]/../../../../mips-linux-gnu/libc/el/lib/../lib64"
+// CHECK-EL-HF-64: "-L[[TC]]/../../../../mips-linux-gnu/libc/el/usr/lib/../lib64"
+// CHECK-EL-HF-64: "-L[[TC]]"
+// CHECK-EL-HF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/el/64/crtend.o"
+// CHECK-EL-HF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/el/usr/lib/../lib64/crtn.o"
+//
+// = Little-endian, soft float, 64-bit
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN: -target mips64el-linux-gnu -msoft-float \
+// RUN: -gcc-toolchain %S/Inputs/mips_cs_tree \
+// RUN: | FileCheck --check-prefix=CHECK-EL-SF-64 %s
+// CHECK-EL-SF-64: "{{.*}}ld{{(.exe)?}}"
+// CHECK-EL-SF-64: "--sysroot=[[TC:[^"]+]]/../../../../mips-linux-gnu/libc/soft-float/el"
+// CHECK-EL-SF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/soft-float/el/usr/lib/../lib64/crt1.o"
+// CHECK-EL-SF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/soft-float/el/usr/lib/../lib64/crti.o"
+// CHECK-EL-SF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/soft-float/el/64/crtbegin.o"
+// CHECK-EL-SF-64: "-L[[TC]]/soft-float/el/64"
+// CHECK-EL-SF-64: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib64/soft-float/el"
+// CHECK-EL-SF-64: "-L[[TC]]/../../../../mips-linux-gnu/libc/soft-float/el/lib/../lib64"
+// CHECK-EL-SF-64: "-L[[TC]]/../../../../mips-linux-gnu/libc/soft-float/el/usr/lib/../lib64"
+// CHECK-EL-SF-64: "-L[[TC]]"
+// CHECK-EL-SF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/soft-float/el/64/crtend.o"
+// CHECK-EL-SF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/soft-float/el/usr/lib/../lib64/crtn.o"
diff --git a/test/Driver/mips-eleb.c b/test/Driver/mips-eleb.c
new file mode 100644
index 0000000000..6ea49be3c3
--- /dev/null
+++ b/test/Driver/mips-eleb.c
@@ -0,0 +1,29 @@
+// Check that -EL/-EB options adjust the toolchain flags.
+//
+// RUN: %clang -no-canonical-prefixes -target mips-unknown-linux-gnu -### \
+// RUN: -EL -no-integrated-as %s 2>&1 \
+// RUN: | FileCheck -check-prefix=MIPS32-EL %s
+// MIPS32-EL: "{{.*}}clang{{.*}}" "-cc1" "-triple" "mipsel-unknown-linux-gnu"
+// MIPS32-EL: "{{.*}}as{{(.exe)?}}" "-march" "mips32" "-mabi" "32" "-EL"
+// MIPS32-EL: "{{.*}}ld{{(.exe)?}}" {{.*}} "-m" "elf32ltsmip"
+//
+// RUN: %clang -no-canonical-prefixes -target mips64-unknown-linux-gnu -### \
+// RUN: -EL -no-integrated-as %s 2>&1 \
+// RUN: | FileCheck -check-prefix=MIPS64-EL %s
+// MIPS64-EL: "{{.*}}clang{{.*}}" "-cc1" "-triple" "mips64el-unknown-linux-gnu"
+// MIPS64-EL: "{{.*}}as{{(.exe)?}}" "-march" "mips64" "-mabi" "64" "-EL"
+// MIPS64-EL: "{{.*}}ld{{(.exe)?}}" {{.*}} "-m" "elf64ltsmip"
+//
+// RUN: %clang -no-canonical-prefixes -target mipsel-unknown-linux-gnu -### \
+// RUN: -EB -no-integrated-as %s 2>&1 \
+// RUN: | FileCheck -check-prefix=MIPS32-EB %s
+// MIPS32-EB: "{{.*}}clang{{.*}}" "-cc1" "-triple" "mips-unknown-linux-gnu"
+// MIPS32-EB: "{{.*}}as{{(.exe)?}}" "-march" "mips32" "-mabi" "32" "-EB"
+// MIPS32-EB: "{{.*}}ld{{(.exe)?}}" {{.*}} "-m" "elf32btsmip"
+//
+// RUN: %clang -no-canonical-prefixes -target mips64el-unknown-linux-gnu -### \
+// RUN: -EB -no-integrated-as %s 2>&1 \
+// RUN: | FileCheck -check-prefix=MIPS64-EB %s
+// MIPS64-EB: "{{.*}}clang{{.*}}" "-cc1" "-triple" "mips64-unknown-linux-gnu"
+// MIPS64-EB: "{{.*}}as{{(.exe)?}}" "-march" "mips64" "-mabi" "64" "-EB"
+// MIPS64-EB: "{{.*}}ld{{(.exe)?}}" {{.*}} "-m" "elf64btsmip"
diff --git a/test/Driver/mips-features.c b/test/Driver/mips-features.c
index 3bebffc11b..31bf1935ea 100644
--- a/test/Driver/mips-features.c
+++ b/test/Driver/mips-features.c
@@ -1,5 +1,3 @@
-// REQUIRES: mips-registered-target
-//
// Check handling MIPS specific features options.
//
// -mips16
@@ -14,6 +12,18 @@
// RUN: | FileCheck --check-prefix=CHECK-NOMIPS16 %s
// CHECK-NOMIPS16: "-target-feature" "-mips16"
//
+// -mmicromips
+// RUN: %clang -target mips-linux-gnu -### -c %s \
+// RUN: -mno-micromips -mmicromips 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-MICROMIPS %s
+// CHECK-MICROMIPS: "-target-feature" "+micromips"
+//
+// -mno-micromips
+// RUN: %clang -target mips-linux-gnu -### -c %s \
+// RUN: -mmicromips -mno-micromips 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-NOMICROMIPS %s
+// CHECK-NOMICROMIPS: "-target-feature" "-micromips"
+//
// -mdsp
// RUN: %clang -target mips-linux-gnu -### -c %s \
// RUN: -mno-dsp -mdsp 2>&1 \
diff --git a/test/Driver/mips-float.c b/test/Driver/mips-float.c
index 5c16b9b063..9e62c0a95e 100644
--- a/test/Driver/mips-float.c
+++ b/test/Driver/mips-float.c
@@ -1,4 +1,3 @@
-// REQUIRES: mips-registered-target
// Check handling -mhard-float / -msoft-float / -mfloat-abi options
// when build for MIPS platforms.
//
@@ -36,12 +35,27 @@
// CHECK-ABI-SOFT: "-mfloat-abi" "soft"
// CHECK-ABI-SOFT: "-target-feature" "+soft-float"
//
-// -mfloat-abi=single
+// -mdouble-float
// RUN: %clang -c %s -### -o %t.o 2>&1 \
-// RUN: -target mips-linux-gnu -mfloat-abi=single \
+// RUN: -target mips-linux-gnu -msingle-float -mdouble-float \
+// RUN: | FileCheck --check-prefix=CHECK-ABI-DOUBLE %s
+// CHECK-ABI-DOUBLE: "-mfloat-abi" "hard"
+// CHECK-ABI-DOUBLE-NOT: "+single-float"
+//
+// -msingle-float
+// RUN: %clang -c %s -### -o %t.o 2>&1 \
+// RUN: -target mips-linux-gnu -mdouble-float -msingle-float \
// RUN: | FileCheck --check-prefix=CHECK-ABI-SINGLE %s
+// CHECK-ABI-SINGLE: "-mfloat-abi" "hard"
// CHECK-ABI-SINGLE: "-target-feature" "+single-float"
//
+// -msoft-float -msingle-float
+// RUN: %clang -c %s -### -o %t.o 2>&1 \
+// RUN: -target mips-linux-gnu -msoft-float -msingle-float \
+// RUN: | FileCheck --check-prefix=CHECK-ABI-SOFT-SINGLE %s
+// CHECK-ABI-SOFT-SINGLE: "-mfloat-abi" "soft"
+// CHECK-ABI-SOFT-SINGLE: "-target-feature" "+single-float"
+//
// Default -mips16
// RUN: %clang -c %s -### -o %t.o 2>&1 \
// RUN: -target mips-linux-gnu -mips16 \
diff --git a/test/Driver/modules.m b/test/Driver/modules.m
index 7752e22b7e..b93054dbf8 100644
--- a/test/Driver/modules.m
+++ b/test/Driver/modules.m
@@ -4,9 +4,3 @@
// RUN: %clang -fmodules -fno-modules -fmodules -### %s 2>&1 | FileCheck -check-prefix=CHECK-HAS-MODULES %s
// CHECK-HAS-MODULES: -fmodules
-// RUN: %clang -fmodules -fno-modules -fmodules -### %s 2>&1 | FileCheck -check-prefix=CHECK-HAS-AUTOLINK %s
-// CHECK-HAS-AUTOLINK: -fmodules-autolink
-
-// RUN: %clang -fmodules -fno-modules -fno-modules-autolink -fmodules -### %s 2>&1 | FileCheck -check-prefix=CHECK-NO-AUTOLINK %s
-// CHECK-NO-AUTOLINK-NOT: -fmodules-autolink
-
diff --git a/test/Driver/modules_integrated_as.c b/test/Driver/modules_integrated_as.c
deleted file mode 100644
index 037cdd0c3c..0000000000
--- a/test/Driver/modules_integrated_as.c
+++ /dev/null
@@ -1,4 +0,0 @@
-// RUN: %clang -fmodules -no-integrated-as -fsyntax-only %s 2>&1 | FileCheck %s
-
-// CHECK: error: modules can only be used with the compiler's integrated assembler
-// CHECK note: '-no-integrated-as' cannot be used with '-fmodules'
diff --git a/test/Driver/no-integrated-as-win.c b/test/Driver/no-integrated-as-win.c
new file mode 100644
index 0000000000..0d6c2958e5
--- /dev/null
+++ b/test/Driver/no-integrated-as-win.c
@@ -0,0 +1,3 @@
+// RUN: %clang -target x86_64-pc-win32 -### -no-integrated-as %s -c 2>&1 | FileCheck %s
+
+// CHECK: there is no external assembler we can use on windows
diff --git a/test/Driver/objc++-cpp-output.mm b/test/Driver/objc++-cpp-output.mm
index 63b15d8c18..a42f7b2557 100644
--- a/test/Driver/objc++-cpp-output.mm
+++ b/test/Driver/objc++-cpp-output.mm
@@ -1,5 +1,5 @@
-// RUN: %clang -x objc++-cpp-output -c %s -o /dev/null
-// RUN: %clang -x objc++-cpp-output -c %s -o /dev/null -### 2>&1 | FileCheck %s
+// RUN: %clang -emit-llvm -x objc++-cpp-output -S %s -o /dev/null
+// RUN: %clang -emit-llvm -x objc++-cpp-output -S %s -o /dev/null -### 2>&1 | FileCheck %s
// PR13820
// REQUIRES: LP64
diff --git a/test/Driver/objc-cpp-output.m b/test/Driver/objc-cpp-output.m
index 8c174f7732..293bbc7ef2 100644
--- a/test/Driver/objc-cpp-output.m
+++ b/test/Driver/objc-cpp-output.m
@@ -1,4 +1,4 @@
-// RUN: %clang -x objc-cpp-output -c %s -o /dev/null
+// RUN: %clang -emit-llvm -x objc-cpp-output -S %s -o /dev/null
// PR13820
// REQUIRES: LP64
diff --git a/test/Driver/output-file-is-dir.c b/test/Driver/output-file-is-dir.c
index c1fec56eac..042ae3d40c 100644
--- a/test/Driver/output-file-is-dir.c
+++ b/test/Driver/output-file-is-dir.c
@@ -1,7 +1,6 @@
// RUN: rm -rf %t.dir
-// RUN: mkdir -p %t.dir/a.out
-// RUN: cd %t.dir && not %clang %s
-// RUN: test -d %t.dir/a.out
-// REQUIRES: shell
+// RUN: mkdir -p %t.dir
+// RUN: not %clang %s -c -emit-llvm -o %t.dir
+// RUN: test -d %t.dir
int main() { return 0; }
diff --git a/test/Driver/pic.c b/test/Driver/pic.c
index 8ba931954b..3faed2d18f 100644
--- a/test/Driver/pic.c
+++ b/test/Driver/pic.c
@@ -36,6 +36,8 @@
//
// CHECK-NO-PIE-NOT: "-pie"
//
+// CHECK-NO-UNUSED-ARG-NOT: argument unused during compilation
+//
// RUN: %clang -c %s -target i386-unknown-unknown -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-NO-PIC
// RUN: %clang -c %s -target i386-unknown-unknown -fpic -### 2>&1 \
@@ -164,6 +166,8 @@
// RUN: | FileCheck %s --check-prefix=CHECK-PIC2
// RUN: %clang -c %s -target x86_64-apple-darwin -fPIE -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-PIC2
+// RUN: %clang -c %s -target x86_64-apple-darwin -fPIC -### 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-NO-UNUSED-ARG
//
// Darwin gets even more special with '-mdynamic-no-pic'. This flag is only
// valid on Darwin, and it's behavior is very strange but needs to remain
diff --git a/test/Driver/ppc-features.cpp b/test/Driver/ppc-features.cpp
index 1918ed7d76..be78e19861 100644
--- a/test/Driver/ppc-features.cpp
+++ b/test/Driver/ppc-features.cpp
@@ -68,3 +68,21 @@
// RUN: %clang -target powerpc64-unknown-linux-gnu %s -mno-qpx -mqpx -### -o %t.o 2>&1 | FileCheck -check-prefix=CHECK-QPX %s
// CHECK-QPX-NOT: "-target-feature" "-qpx"
+// RUN: %clang -target powerpc64-unknown-linux-gnu %s -mno-mfcrf -### -o %t.o 2>&1 | FileCheck -check-prefix=CHECK-NOMFCRF %s
+// CHECK-NOMFCRF: "-target-feature" "-mfocrf"
+
+// RUN: %clang -target powerpc64-unknown-linux-gnu %s -mno-mfcrf -mmfcrf -### -o %t.o 2>&1 | FileCheck -check-prefix=CHECK-MFCRF %s
+// CHECK-MFCRF: "-target-feature" "+mfocrf"
+
+// RUN: %clang -target powerpc64-unknown-linux-gnu %s -mno-popcntd -### -o %t.o 2>&1 | FileCheck -check-prefix=CHECK-NOPOPCNTD %s
+// CHECK-NOPOPCNTD: "-target-feature" "-popcntd"
+
+// RUN: %clang -target powerpc64-unknown-linux-gnu %s -mno-popcntd -mpopcntd -### -o %t.o 2>&1 | FileCheck -check-prefix=CHECK-POPCNTD %s
+// CHECK-POPCNTD: "-target-feature" "+popcntd"
+
+// RUN: %clang -target powerpc64-unknown-linux-gnu %s -mno-fprnd -### -o %t.o 2>&1 | FileCheck -check-prefix=CHECK-NOFPRND %s
+// CHECK-NOFPRND: "-target-feature" "-fprnd"
+
+// RUN: %clang -target powerpc64-unknown-linux-gnu %s -mno-fprnd -mfprnd -### -o %t.o 2>&1 | FileCheck -check-prefix=CHECK-FPRND %s
+// CHECK-FPRND: "-target-feature" "+fprnd"
+
diff --git a/test/Driver/r600-mcpu.cl b/test/Driver/r600-mcpu.cl
new file mode 100644
index 0000000000..1c5e76225b
--- /dev/null
+++ b/test/Driver/r600-mcpu.cl
@@ -0,0 +1,52 @@
+// Check that -mcpu works for all supported GPUs
+
+// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=r600 %s -o - 2>&1 | FileCheck --check-prefix=R600-CHECK %s
+// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=rv630 %s -o - 2>&1 | FileCheck --check-prefix=R600-CHECK %s
+// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=rv635 %s -o - 2>&1 | FileCheck --check-prefix=R600-CHECK %s
+// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=rv610 %s -o - 2>&1 | FileCheck --check-prefix=RS880-CHECK %s
+// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=rv620 %s -o - 2>&1 | FileCheck --check-prefix=RS880-CHECK %s
+// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=rs780 %s -o - 2>&1 | FileCheck --check-prefix=RS880-CHECK %s
+// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=rs880 %s -o - 2>&1 | FileCheck --check-prefix=RS880-CHECK %s
+// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=rv670 %s -o - 2>&1 | FileCheck --check-prefix=RV670-CHECK %s
+// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=rv710 %s -o - 2>&1 | FileCheck --check-prefix=RV710-CHECK %s
+// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=rv730 %s -o - 2>&1 | FileCheck --check-prefix=RV730-CHECK %s
+// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=rv740 %s -o - 2>&1 | FileCheck --check-prefix=RV770-CHECK %s
+// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=rv770 %s -o - 2>&1 | FileCheck --check-prefix=RV770-CHECK %s
+// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=palm %s -o - 2>&1 | FileCheck --check-prefix=CEDAR-CHECK %s
+// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=cedar %s -o - 2>&1 | FileCheck --check-prefix=CEDAR-CHECK %s
+// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=sumo %s -o - 2>&1 | FileCheck --check-prefix=SUMO-CHECK %s
+// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=sumo2 %s -o - 2>&1 | FileCheck --check-prefix=SUMO-CHECK %s
+// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=redwood %s -o - 2>&1 | FileCheck --check-prefix=REDWOOD-CHECK %s
+// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=juniper %s -o - 2>&1 | FileCheck --check-prefix=JUNIPER-CHECK %s
+// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=juniper %s -o - 2>&1 | FileCheck --check-prefix=JUNIPER-CHECK %s
+// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=hemlock %s -o - 2>&1 | FileCheck --check-prefix=CYPRESS-CHECK %s
+// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=cypress %s -o - 2>&1 | FileCheck --check-prefix=CYPRESS-CHECK %s
+// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=barts %s -o - 2>&1 | FileCheck --check-prefix=BARTS-CHECK %s
+// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=turks %s -o - 2>&1 | FileCheck --check-prefix=TURKS-CHECK %s
+// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=caicos %s -o - 2>&1 | FileCheck --check-prefix=CAICOS-CHECK %s
+// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=cayman %s -o - 2>&1 | FileCheck --check-prefix=CAYMAN-CHECK %s
+// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=aruba %s -o - 2>&1 | FileCheck --check-prefix=CAYMAN-CHECK %s
+// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=tahiti %s -o - 2>&1 | FileCheck --check-prefix=TAHITI-CHECK %s
+// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=pitcairn %s -o - 2>&1 | FileCheck --check-prefix=PITCAIRN-CHECK %s
+// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=verde %s -o - 2>&1 | FileCheck --check-prefix=VERDE-CHECK %s
+// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=oland %s -o - 2>&1 | FileCheck --check-prefix=OLAND-CHECK %s
+
+// R600-CHECK: "-target-cpu" "r600"
+// RS880-CHECK: "-target-cpu" "rs880"
+// RV670-CHECK: "-target-cpu" "rv670"
+// RV710-CHECK: "-target-cpu" "rv710"
+// RV730-CHECK: "-target-cpu" "rv730"
+// RV770-CHECK: "-target-cpu" "rv770"
+// CEDAR-CHECK: "-target-cpu" "cedar"
+// REDWOOD-CHECK: "-target-cpu" "redwood"
+// SUMO-CHECK: "-target-cpu" "sumo"
+// JUNIPER-CHECK: "-target-cpu" "juniper"
+// CYPRESS-CHECK: "-target-cpu" "cypress"
+// BARTS-CHECK: "-target-cpu" "barts"
+// TURKS-CHECK: "-target-cpu" "turks"
+// CAICOS-CHECK: "-target-cpu" "caicos"
+// CAYMAN-CHECK: "-target-cpu" "cayman"
+// TAHITI-CHECK: "-target-cpu" "tahiti"
+// PITCAIRN-CHECK: "-target-cpu" "pitcairn"
+// VERDE-CHECK: "-target-cpu" "verde"
+// OLAND-CHECK: "-target-cpu" "oland"
diff --git a/test/Driver/sanitizer-ld.c b/test/Driver/sanitizer-ld.c
index 9bb2eab29a..fd7e97fc20 100644
--- a/test/Driver/sanitizer-ld.c
+++ b/test/Driver/sanitizer-ld.c
@@ -2,6 +2,7 @@
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
// RUN: -target i386-unknown-linux -fsanitize=address \
+// RUN: -resource-dir=%S/Inputs/resource_dir \
// RUN: --sysroot=%S/Inputs/basic_linux_tree \
// RUN: | FileCheck --check-prefix=CHECK-ASAN-LINUX %s
//
@@ -9,11 +10,14 @@
// CHECK-ASAN-LINUX-NOT: "-lc"
// CHECK-ASAN-LINUX: libclang_rt.asan-i386.a"
// CHECK-ASAN-LINUX: "-lpthread"
+// CHECK-ASAN-LINUX: "-lrt"
// CHECK-ASAN-LINUX: "-ldl"
-// CHECK-ASAN-LINUX: "-export-dynamic"
+// CHECK-ASAN-LINUX-NOT: "-export-dynamic"
+// CHECK-ASAN-LINUX: "--dynamic-list={{.*}}libclang_rt.asan-i386.a.syms"
// RUN: %clangxx -no-canonical-prefixes %s -### -o %t.o 2>&1 \
// RUN: -target i386-unknown-linux -fsanitize=address \
+// RUN: -resource-dir=%S/Inputs/empty_resource_dir \
// RUN: --sysroot=%S/Inputs/basic_linux_tree \
// RUN: | FileCheck --check-prefix=CHECK-ASAN-LINUX-CXX %s
//
@@ -21,8 +25,10 @@
// CHECK-ASAN-LINUX-CXX-NOT: "-lc"
// CHECK-ASAN-LINUX-CXX: "-whole-archive" "{{.*}}libclang_rt.asan-i386.a" "-no-whole-archive"
// CHECK-ASAN-LINUX-CXX: "-lpthread"
+// CHECK-ASAN-LINUX-CXX: "-lrt"
// CHECK-ASAN-LINUX-CXX: "-ldl"
// CHECK-ASAN-LINUX-CXX: "-export-dynamic"
+// CHECK-ASAN-LINUX-CXX-NOT: "--dynamic-list"
// CHECK-ASAN-LINUX-CXX: stdc++
// RUN: %clang -no-canonical-prefixes %s -### -o /dev/null -fsanitize=address \
@@ -58,6 +64,7 @@
// RUN: %clangxx -no-canonical-prefixes %s -### -o %t.o 2>&1 \
// RUN: -target x86_64-unknown-linux -lstdc++ -fsanitize=thread \
+// RUN: -resource-dir=%S/Inputs/resource_dir \
// RUN: --sysroot=%S/Inputs/basic_linux_tree \
// RUN: | FileCheck --check-prefix=CHECK-TSAN-LINUX-CXX %s
//
@@ -65,12 +72,15 @@
// CHECK-TSAN-LINUX-CXX-NOT: stdc++
// CHECK-TSAN-LINUX-CXX: "-whole-archive" "{{.*}}libclang_rt.tsan-x86_64.a" "-no-whole-archive"
// CHECK-TSAN-LINUX-CXX: "-lpthread"
+// CHECK-TSAN-LINUX-CXX: "-lrt"
// CHECK-TSAN-LINUX-CXX: "-ldl"
-// CHECK-TSAN-LINUX-CXX: "-export-dynamic"
+// CHECK-TSAN-LINUX-CXX-NOT: "-export-dynamic"
+// CHECK-TSAN-LINUX-CXX: "--dynamic-list={{.*}}libclang_rt.tsan-x86_64.a.syms"
// CHECK-TSAN-LINUX-CXX: stdc++
// RUN: %clangxx -no-canonical-prefixes %s -### -o %t.o 2>&1 \
// RUN: -target x86_64-unknown-linux -lstdc++ -fsanitize=memory \
+// RUN: -resource-dir=%S/Inputs/resource_dir \
// RUN: --sysroot=%S/Inputs/basic_linux_tree \
// RUN: | FileCheck --check-prefix=CHECK-MSAN-LINUX-CXX %s
//
@@ -78,8 +88,10 @@
// CHECK-MSAN-LINUX-CXX-NOT: stdc++
// CHECK-MSAN-LINUX-CXX: "-whole-archive" "{{.*}}libclang_rt.msan-x86_64.a" "-no-whole-archive"
// CHECK-MSAN-LINUX-CXX: "-lpthread"
+// CHECK-MSAN-LINUX-CXX: "-lrt"
// CHECK-MSAN-LINUX-CXX: "-ldl"
-// CHECK-MSAN-LINUX-CXX: "-export-dynamic"
+// CHECK-MSAN-LINUX-CXX-NOT: "-export-dynamic"
+// CHECK-MSAN-LINUX-CXX: "--dynamic-list={{.*}}libclang_rt.msan-x86_64.a.syms"
// CHECK-MSAN-LINUX-CXX: stdc++
// RUN: %clang -fsanitize=undefined %s -### -o %t.o 2>&1 \
@@ -87,9 +99,52 @@
// RUN: --sysroot=%S/Inputs/basic_linux_tree \
// RUN: | FileCheck --check-prefix=CHECK-UBSAN-LINUX %s
// CHECK-UBSAN-LINUX: "{{.*}}ld{{(.exe)?}}"
-// CHECK-UBSAN-LINUX-NOT: "-lc"
-// CHECK-UBSAN-LINUX: libclang_rt.ubsan-i386.a"
+// CHECK-UBSAN-LINUX-NOT: libclang_rt.asan
+// CHECK-UBSAN-LINUX: "-whole-archive" "{{.*}}libclang_rt.san-i386.a" "-no-whole-archive"
+// CHECK-UBSAN-LINUX-NOT: libclang_rt.asan
+// CHECK-UBSAN-LINUX: "-whole-archive" "{{.*}}libclang_rt.ubsan-i386.a" "-no-whole-archive"
+// CHECK-UBSAN-LINUX-NOT: libclang_rt.ubsan_cxx
// CHECK-UBSAN-LINUX: "-lpthread"
+// CHECK-UBSAN-LINUX-NOT: "-lstdc++"
+
+// RUN: %clangxx -fsanitize=undefined %s -### -o %t.o 2>&1 \
+// RUN: -target i386-unknown-linux \
+// RUN: --sysroot=%S/Inputs/basic_linux_tree \
+// RUN: | FileCheck --check-prefix=CHECK-UBSAN-LINUX-CXX %s
+// CHECK-UBSAN-LINUX-CXX: "{{.*}}ld{{(.exe)?}}"
+// CHECK-UBSAN-LINUX-CXX-NOT: libclang_rt.asan
+// CHECK-UBSAN-LINUX-CXX: "-whole-archive" "{{.*}}libclang_rt.san-i386.a" "-no-whole-archive"
+// CHECK-UBSAN-LINUX-CXX-NOT: libclang_rt.asan
+// CHECK-UBSAN-LINUX-CXX: "-whole-archive" "{{.*}}libclang_rt.ubsan-i386.a" "-no-whole-archive"
+// CHECK-UBSAN-LINUX-CXX: "-whole-archive" "{{.*}}libclang_rt.ubsan_cxx-i386.a" "-no-whole-archive"
+// CHECK-UBSAN-LINUX-CXX: "-lpthread"
+// CHECK-UBSAN-LINUX-CXX: "-lstdc++"
+
+// RUN: %clang -fsanitize=address,undefined %s -### -o %t.o 2>&1 \
+// RUN: -target i386-unknown-linux \
+// RUN: --sysroot=%S/Inputs/basic_linux_tree \
+// RUN: | FileCheck --check-prefix=CHECK-ASAN-UBSAN-LINUX %s
+// CHECK-ASAN-UBSAN-LINUX: "{{.*}}ld{{(.exe)?}}"
+// CHECK-ASAN-UBSAN-LINUX-NOT: libclang_rt.san
+// CHECK-ASAN-UBSAN-LINUX: "-whole-archive" "{{.*}}libclang_rt.asan-i386.a" "-no-whole-archive"
+// CHECK-ASAN-UBSAN-LINUX-NOT: libclang_rt.san
+// CHECK-ASAN-UBSAN-LINUX: "-whole-archive" "{{.*}}libclang_rt.ubsan-i386.a" "-no-whole-archive"
+// CHECK-ASAN-UBSAN-LINUX-NOT: libclang_rt.ubsan_cxx
+// CHECK-ASAN-UBSAN-LINUX: "-lpthread"
+// CHECK-ASAN-UBSAN-LINUX-NOT: "-lstdc++"
+
+// RUN: %clangxx -fsanitize=address,undefined %s -### -o %t.o 2>&1 \
+// RUN: -target i386-unknown-linux \
+// RUN: --sysroot=%S/Inputs/basic_linux_tree \
+// RUN: | FileCheck --check-prefix=CHECK-ASAN-UBSAN-LINUX-CXX %s
+// CHECK-ASAN-UBSAN-LINUX-CXX: "{{.*}}ld{{(.exe)?}}"
+// CHECK-ASAN-UBSAN-LINUX-CXX-NOT: libclang_rt.san
+// CHECK-ASAN-UBSAN-LINUX-CXX: "-whole-archive" "{{.*}}libclang_rt.asan-i386.a" "-no-whole-archive"
+// CHECK-ASAN-UBSAN-LINUX-CXX-NOT: libclang_rt.san
+// CHECK-ASAN-UBSAN-LINUX-CXX: "-whole-archive" "{{.*}}libclang_rt.ubsan-i386.a" "-no-whole-archive"
+// CHECK-ASAN-UBSAN-LINUX-CXX: "-whole-archive" "{{.*}}libclang_rt.ubsan_cxx-i386.a" "-no-whole-archive"
+// CHECK-ASAN-UBSAN-LINUX-CXX: "-lpthread"
+// CHECK-ASAN-UBSAN-LINUX-CXX: "-lstdc++"
// RUN: %clang -fsanitize=undefined %s -### -o %t.o 2>&1 \
// RUN: -target i386-unknown-linux \
@@ -97,6 +152,4 @@
// RUN: -shared \
// RUN: | FileCheck --check-prefix=CHECK-UBSAN-LINUX-SHARED %s
// CHECK-UBSAN-LINUX-SHARED: "{{.*}}ld{{(.exe)?}}"
-// CHECK-UBSAN-LINUX-SHARED-NOT: "-lc"
-// CHECK-UBSAN-LINUX-SHARED: libclang_rt.ubsan-i386.a"
-// CHECK-UBSAN-LINUX-SHARED: "-lpthread"
+// CHECK-UBSAN-LINUX-SHARED-NOT: libclang_rt.ubsan-i386.a"
diff --git a/test/Driver/save-temps.c b/test/Driver/save-temps.c
new file mode 100644
index 0000000000..a4ca3b2664
--- /dev/null
+++ b/test/Driver/save-temps.c
@@ -0,0 +1,19 @@
+// RUN: %clang -target x86_64-apple-darwin -save-temps -arch x86_64 %s -### 2>&1 \
+// RUN: | FileCheck %s
+// CHECK: "-o" "save-temps.i"
+// CHECK: "-o" "save-temps.s"
+// CHECK: "-o" "save-temps.o"
+// CHECK: "-o" "a.out"
+
+// RUN: %clang -target x86_64-apple-darwin -save-temps -arch i386 -arch x86_64 %s -### 2>&1 \
+// RUN: | FileCheck %s -check-prefix=MULT-ARCH
+// MULT-ARCH: "-o" "save-temps-i386.i"
+// MULT-ARCH: "-o" "save-temps-i386.s"
+// MULT-ARCH: "-o" "save-temps-i386.o"
+// MULT-ARCH: "-o" "a.out-i386"
+// MULT-ARCH: "-o" "save-temps-x86_64.i"
+// MULT-ARCH: "-o" "save-temps-x86_64.s"
+// MULT-ARCH: "-o" "save-temps-x86_64.o"
+// MULT-ARCH: "-o" "a.out-x86_64"
+// MULT-ARCH: lipo
+// MULT-ARCH: "-create" "-output" "a.out" "a.out-i386" "a.out-x86_64"
diff --git a/test/Driver/split-debug.s b/test/Driver/split-debug.s
new file mode 100644
index 0000000000..d5f077af13
--- /dev/null
+++ b/test/Driver/split-debug.s
@@ -0,0 +1,21 @@
+// Check that we split debug output properly
+//
+// REQUIRES: asserts
+// RUN: %clang -target x86_64-unknown-linux-gnu -gsplit-dwarf -c -### %s 2> %t
+// RUN: FileCheck -check-prefix=CHECK-ACTIONS < %t %s
+//
+// CHECK-ACTIONS: objcopy{{.*}}--extract-dwo{{.*}}"split-debug.dwo"
+// CHECK-ACTIONS: objcopy{{.*}}--strip-dwo{{.*}}"split-debug.o"
+
+
+// RUN: %clang -target x86_64-macosx -gsplit-dwarf -c -### %s 2> %t
+// RUN: FileCheck -check-prefix=CHECK-NO-ACTIONS < %t %s
+//
+// CHECK-NO-ACTIONS-NOT: -split-dwarf
+
+
+// RUN: %clang -target x86_64-unknown-linux-gnu -gsplit-dwarf -o Bad.x -### %s 2> %t
+// RUN: FileCheck -check-prefix=CHECK-BAD < %t %s
+//
+// CHECK-BAD-NOT: "Bad.dwo"
+
diff --git a/test/Driver/unknown-gcc-arch.c b/test/Driver/unknown-gcc-arch.c
index 5e4746babd..dcd17d4f46 100644
--- a/test/Driver/unknown-gcc-arch.c
+++ b/test/Driver/unknown-gcc-arch.c
@@ -1,8 +1,32 @@
-// RUN: %clang -target x86_64-unknown-unknown -c -x assembler %s -### 2> %t.log
-// RUN: grep '.*gcc.*"-m64"' %t.log
-// RUN: %clang -target x86_64-unknown-unknown -c -x assembler %s -### -m32 2> %t.log
-// RUN: grep '.*gcc.*"-m32"' %t.log
-// RUN: %clang -target i386-unknown-unknown -c -x assembler %s -### 2> %t.log
-// RUN: grep '.*gcc.*"-m32"' %t.log
-// RUN: %clang -target i386-unknown-unknown -c -x assembler %s -### -m64 2> %t.log
-// RUN: grep '.*gcc.*"-m64"' %t.log
+// RUN: %clang -target x86_64-unknown-unknown -c -x assembler %s -### 2>&1 \
+// RUN: | FileCheck -check-prefix=X86_64 %s
+// X86_64: {{.*gcc.*-m64}}
+
+// RUN: %clang -target x86_64-unknown-unknown -c -x assembler %s -### -m32 2>&1 \
+// RUN: | FileCheck -check-prefix=X86_64-M32 %s
+// X86_64-M32: {{.*gcc.*-m32}}
+
+// RUN: %clang -target i386-unknown-unknown -c -x assembler %s -### 2>&1 \
+// RUN: | FileCheck -check-prefix=I386 %s
+// I386: {{.*gcc.*-m32}}
+
+// RUN: %clang -target i386-unknown-unknown -c -x assembler %s -### -m64 2>&1 \
+// RUN: | FileCheck -check-prefix=I386-M64 %s
+// I386-M64: {{.*gcc.*-m64}}
+
+
+// RUN: %clang -target powerpc64-unknown-unknown -c -x assembler %s -### 2>&1 \
+// RUN: | FileCheck -check-prefix=PPC64 %s
+// PPC64: {{.*gcc.*-m64}}
+
+// RUN: %clang -target powerpc64-unknown-unknown -c -x assembler %s -### -m32 2>&1 \
+// RUN: | FileCheck -check-prefix=PPC64-M32 %s
+// PPC64-M32: {{.*gcc.*-m32}}
+
+// RUN: %clang -target powerpc-unknown-unknown -c -x assembler %s -### 2>&1 \
+// RUN: | FileCheck -check-prefix=PPC %s
+// PPC: {{.*gcc.*-m32}}
+
+// RUN: %clang -target powerpc-unknown-unknown -c -x assembler %s -### -m64 2>&1 \
+// RUN: | FileCheck -check-prefix=PPC-M64 %s
+// PPC-M64: {{.*gcc.*-m64}}
diff --git a/test/FixIt/auto-isa-fixit.m b/test/FixIt/auto-isa-fixit.m
new file mode 100644
index 0000000000..3f22c1838a
--- /dev/null
+++ b/test/FixIt/auto-isa-fixit.m
@@ -0,0 +1,66 @@
+// RUN: cp %s %t
+// RUN: %clang_cc1 -x objective-c -fixit %t
+// RUN: %clang_cc1 -x objective-c -Werror %t
+// rdar://13503456
+
+void object_setClass(id, id);
+Class object_getClass(id);
+
+id rhs();
+
+Class pr6302(id x123) {
+ x123->isa = 0;
+ x123->isa = rhs();
+ x123->isa = (id)(x123->isa);
+ x123->isa = (id)x123->isa;
+ x123->isa = (x123->isa);
+ x123->isa = (id)(x123->isa);
+ return x123->isa;
+}
+
+
+@interface BaseClass {
+@public
+ Class isa; // expected-note 3 {{instance variable is declared here}}
+}
+@end
+
+@interface OtherClass {
+@public
+ id firstIvar;
+ Class isa; // note, not first ivar;
+}
+@end
+
+@interface Subclass : BaseClass @end
+
+@interface SiblingClass : BaseClass @end
+
+@interface Root @end
+
+@interface hasIsa : Root {
+@public
+ Class isa; // note, isa is not in root class
+}
+@end
+
+@implementation Subclass
+-(void)method {
+ hasIsa *u;
+ id v;
+ BaseClass *w;
+ Subclass *x;
+ SiblingClass *y;
+ OtherClass *z;
+ (void)v->isa;
+ (void)w->isa;
+ (void)x->isa;
+ (void)y->isa;
+ (void)z->isa;
+ (void)u->isa;
+ y->isa = 0;
+ y->isa = w->isa;
+ x->isa = rhs();
+}
+@end
+
diff --git a/test/FixIt/bridge-in-non-arc.m b/test/FixIt/bridge-in-non-arc.m
index 948fa8ebcc..b4d2677be0 100644
--- a/test/FixIt/bridge-in-non-arc.m
+++ b/test/FixIt/bridge-in-non-arc.m
@@ -4,9 +4,9 @@
@end
void foo(void *p) {
- I *i = (__bridge I*)p;
- I *i2 = (__bridge/*cake*/I*)p;
+ I *i = (__bridge_transfer I*)p;
+ I *i2 = (__bridge_transfer/*cake*/I*)p;
}
-// CHECK: {7:11-7:20}:""
-// CHECK: {8:12-8:20}:""
+// CHECK: {7:11-7:29}:""
+// CHECK: {8:12-8:29}:""
diff --git a/test/FixIt/fixit-cxx1y-compat.cpp b/test/FixIt/fixit-cxx1y-compat.cpp
new file mode 100644
index 0000000000..9fd5ff26e5
--- /dev/null
+++ b/test/FixIt/fixit-cxx1y-compat.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -verify -std=c++11 %s
+// RUN: cp %s %t
+// RUN: %clang_cc1 -x c++ -std=c++11 -fixit %t
+// RUN: %clang_cc1 -Wall -pedantic-errors -Werror -x c++ -std=c++11 %t
+// RUN: %clang_cc1 -Wall -pedantic-errors -Werror -x c++ -std=c++1y %t
+
+// This is a test of the code modification hints for C++1y-compatibility problems.
+
+struct S {
+ constexpr int &f(); // expected-warning {{'constexpr' non-static member function will not be implicitly 'const' in C++1y; add 'const' to avoid a change in behavior}}
+ int &f();
+};
diff --git a/test/FixIt/fixit.cpp b/test/FixIt/fixit.cpp
index 253abd0f4e..fca596b715 100644
--- a/test/FixIt/fixit.cpp
+++ b/test/FixIt/fixit.cpp
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -pedantic -Wall -Wno-comment -verify -fcxx-exceptions -x c++ %s
+// RUN: %clang_cc1 -fsyntax-only -fdiagnostics-parseable-fixits -x c++ %s 2>&1 | FileCheck %s
// RUN: cp %s %t
// RUN: not %clang_cc1 -pedantic -Wall -Wno-comment -fcxx-exceptions -fixit -x c++ %t
// RUN: %clang_cc1 -fsyntax-only -pedantic -Wall -Werror -Wno-comment -fcxx-exceptions -x c++ %t
@@ -299,3 +300,10 @@ class foo {
}
int i();
};
+
+namespace dtor_fixit {
+ class foo {
+ ~bar() { } // expected-error {{expected the class name after '~' to name a destructor}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:6-[[@LINE-1]]:9}:"foo"
+ };
+}
diff --git a/test/FixIt/format-darwin.m b/test/FixIt/format-darwin.m
index cfaac29e90..f520564348 100644
--- a/test/FixIt/format-darwin.m
+++ b/test/FixIt/format-darwin.m
@@ -23,6 +23,8 @@ typedef long SInt32;
typedef unsigned long UInt32;
#endif
+typedef SInt32 OSStatus;
+
NSInteger getNSInteger();
NSUInteger getNSUInteger();
SInt32 getSInt32();
@@ -210,3 +212,9 @@ void testCapitals() {
// CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:13-[[@LINE-3]]:14}:"d"
// CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:11-[[@LINE-4]]:14}:"%D"
}
+
+void testLayeredTypedefs(OSStatus i) {
+ printf("%s", i); // expected-warning {{values of type 'OSStatus' should not be used as format arguments}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%d"
+}
+
diff --git a/test/Format/basic.cpp b/test/Format/basic.cpp
new file mode 100644
index 0000000000..a12866b9c1
--- /dev/null
+++ b/test/Format/basic.cpp
@@ -0,0 +1,6 @@
+// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp
+// RUN: clang-format -style=LLVM -i %t.cpp
+// RUN: FileCheck -strict-whitespace -input-file=%t.cpp %s
+
+// CHECK: {{^int\ \*i;}}
+ int * i ;
diff --git a/test/Format/diagnostic.cpp b/test/Format/diagnostic.cpp
new file mode 100644
index 0000000000..2e930ee5b7
--- /dev/null
+++ b/test/Format/diagnostic.cpp
@@ -0,0 +1,4 @@
+// RUN: clang-format 2>&1 >/dev/null %s |FileCheck %s
+
+}
+// CHECK: diagnostic.cpp:[[@LINE-1]]:1: error: unexpected '}'
diff --git a/test/Format/multiple-inputs-error.cpp b/test/Format/multiple-inputs-error.cpp
new file mode 100644
index 0000000000..71f87e0b15
--- /dev/null
+++ b/test/Format/multiple-inputs-error.cpp
@@ -0,0 +1,6 @@
+// RUN: cp %s %t-1.cpp
+// RUN: cp %s %t-2.cpp
+// RUN: clang-format 2>&1 >/dev/null -offset=1 -length=0 %t-1.cpp %t-2.cpp |FileCheck %s
+// CHECK: error: "-offset" and "-length" can only be used for single file.
+
+int i ;
diff --git a/test/Format/multiple-inputs-inplace.cpp b/test/Format/multiple-inputs-inplace.cpp
new file mode 100644
index 0000000000..74c30db71e
--- /dev/null
+++ b/test/Format/multiple-inputs-inplace.cpp
@@ -0,0 +1,8 @@
+// RUN: cp %s %t-1.cpp
+// RUN: cp %s %t-2.cpp
+// RUN: clang-format -style=LLVM -i %t-1.cpp %t-2.cpp
+// RUN: FileCheck -strict-whitespace -input-file=%t-1.cpp %s
+// RUN: FileCheck -strict-whitespace -input-file=%t-2.cpp %s
+
+// CHECK: {{^int\ \*i;}}
+ int * i ;
diff --git a/test/Format/multiple-inputs.cpp b/test/Format/multiple-inputs.cpp
new file mode 100644
index 0000000000..df267149fe
--- /dev/null
+++ b/test/Format/multiple-inputs.cpp
@@ -0,0 +1,7 @@
+// RUN: cp %s %t-1.cpp
+// RUN: cp %s %t-2.cpp
+// RUN: clang-format -style=LLVM %t-1.cpp %t-2.cpp|FileCheck -strict-whitespace %s
+
+// CHECK: {{^int\ \*i;}}
+// CHECK: {{^int\ \*i;}}
+ int * i ;
diff --git a/test/Format/ranges.cpp b/test/Format/ranges.cpp
new file mode 100644
index 0000000000..c7fdd4b97a
--- /dev/null
+++ b/test/Format/ranges.cpp
@@ -0,0 +1,11 @@
+// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp
+// RUN: clang-format -style=LLVM -offset=2 -length=0 -offset=28 -length=0 -i %t.cpp
+// RUN: FileCheck -strict-whitespace -input-file=%t.cpp %s
+// CHECK: {{^int\ \*i;$}}
+ int*i;
+
+// CHECK: {{^\ \ int\ \ \*\ \ i;$}}
+ int * i;
+
+// CHECK: {{^\ \ int\ \*i;$}}
+ int * i;
diff --git a/test/Frontend/Inputs/rewrite-includes8.h b/test/Frontend/Inputs/rewrite-includes8.h
new file mode 100644
index 0000000000..e827ad99cf
--- /dev/null
+++ b/test/Frontend/Inputs/rewrite-includes8.h
@@ -0,0 +1,5 @@
+#if __has_include_next(<rewrite-includes8.h>)
+#elif __has_include(<rewrite-includes8.hfail>)
+#endif
+#if !__has_include("rewrite-includes8.h")
+#endif
diff --git a/test/Frontend/ast-main.cpp b/test/Frontend/ast-main.cpp
new file mode 100644
index 0000000000..4bddbe1372
--- /dev/null
+++ b/test/Frontend/ast-main.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang -emit-llvm -S -o %t1.ll -x c++ - < %s
+// RUN: %clang -fno-delayed-template-parsing -emit-ast -o %t.ast %s
+// RUN: %clang -emit-llvm -S -o %t2.ll -x ast - < %t.ast
+// RUN: diff %t1.ll %t2.ll
+
+// http://llvm.org/bugs/show_bug.cgi?id=15377
+template<typename T>
+struct S {
+ T *mf();
+};
+template<typename T>
+T *S<T>::mf() {
+ // warning: control reaches end of non-void function [-Wreturn-type]
+}
+
+void f() {
+ S<int>().mf();
+}
+
+int main() {
+ return 0;
+}
diff --git a/test/Frontend/dependency-gen-escaping.c b/test/Frontend/dependency-gen-escaping.c
new file mode 100644
index 0000000000..84eb242ec3
--- /dev/null
+++ b/test/Frontend/dependency-gen-escaping.c
@@ -0,0 +1,17 @@
+// REQUIRES: shell
+// PR15642
+// RUN: rm -rf %t.dir
+// RUN: mkdir -p %t.dir
+// RUN: echo > '%t.dir/ .h'
+// RUN: echo > '%t.dir/$$.h'
+// RUN: echo > '%t.dir/##.h'
+// RUN: cd %t.dir
+// RUN: %clang -MD -MF - %s -fsyntax-only -I. | FileCheck -strict-whitespace %s
+
+// CHECK: \ \ \ \ .h
+// CHECK: $$$$.h
+// CHECK: \#\#.h
+
+#include " .h"
+#include "$$.h"
+#include "##.h"
diff --git a/test/Frontend/rewrite-includes-invalid-hasinclude.c b/test/Frontend/rewrite-includes-invalid-hasinclude.c
new file mode 100644
index 0000000000..e32d6ad8a3
--- /dev/null
+++ b/test/Frontend/rewrite-includes-invalid-hasinclude.c
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -E -frewrite-includes -DFIRST -I %S/Inputs %s -o - | FileCheck -strict-whitespace %s
+
+#if __has_include bar.h
+#endif
+
+#if __has_include(bar.h)
+#endif
+
+#if __has_include(<bar.h)
+#endif
+
+// CHECK: #if __has_include bar.h
+// CHECK: #endif
+// CHECK: #if __has_include(bar.h)
+// CHECK: #endif
+// CHECK: #if __has_include(<bar.h)
+// CHECK: #endif
diff --git a/test/Frontend/rewrite-includes-missing.c b/test/Frontend/rewrite-includes-missing.c
index b79bbd9ca8..da4e209bc1 100644
--- a/test/Frontend/rewrite-includes-missing.c
+++ b/test/Frontend/rewrite-includes-missing.c
@@ -4,4 +4,4 @@
// CHECK: {{^}}#if 0 /* expanded by -frewrite-includes */{{$}}
// CHECK-NEXT: {{^}}#include "foobar.h"
// CHECK-NEXT: {{^}}#endif /* expanded by -frewrite-includes */{{$}}
-// CHECK-NEXT: {{^}}# 4 "{{.*}}rewrite-includes-missing.c" 2{{$}}
+// CHECK-NEXT: {{^}}# 4 "{{.*}}rewrite-includes-missing.c"{{$}}
diff --git a/test/Frontend/rewrite-includes-modules.c b/test/Frontend/rewrite-includes-modules.c
new file mode 100644
index 0000000000..783a96739a
--- /dev/null
+++ b/test/Frontend/rewrite-includes-modules.c
@@ -0,0 +1,20 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -x objective-c %s -F %S/../Modules/Inputs -E -frewrite-includes -o - | FileCheck %s
+
+int bar();
+#include <Module/Module.h>
+int foo();
+#include <Module/Module.h>
+
+// CHECK: int bar();{{$}}
+// CHECK-NEXT: #if 0 /* expanded by -frewrite-includes */{{$}}
+// CHECK-NEXT: #include <Module/Module.h>{{$}}
+// CHECK-NEXT: #endif /* expanded by -frewrite-includes */{{$}}
+// CHECK-NEXT: @import Module; /* clang -frewrite-includes: implicit import */{{$}}
+// CHECK-NEXT: # 6 "{{.*[/\\]}}rewrite-includes-modules.c"{{$}}
+// CHECK-NEXT: int foo();{{$}}
+// CHECK-NEXT: #if 0 /* expanded by -frewrite-includes */{{$}}
+// CHECK-NEXT: #include <Module/Module.h>{{$}}
+// CHECK-NEXT: #endif /* expanded by -frewrite-includes */{{$}}
+// CHECK-NEXT: @import Module; /* clang -frewrite-includes: implicit import */{{$}}
+// CHECK-NEXT: # 8 "{{.*[/\\]}}rewrite-includes-modules.c"{{$}}
diff --git a/test/Frontend/rewrite-includes.c b/test/Frontend/rewrite-includes.c
index 546a2c44af..bf330a60a3 100644
--- a/test/Frontend/rewrite-includes.c
+++ b/test/Frontend/rewrite-includes.c
@@ -18,6 +18,7 @@ A(1,2)
continues */
#include "rewrite-includes7.h"
#include "rewrite-includes7.h"
+#include "rewrite-includes8.h"
// ENDCOMPARE
// CHECK: {{^}}// STARTCOMPARE{{$}}
// CHECK-NEXT: {{^}}#define A(a,b) a ## b{{$}}
@@ -88,6 +89,16 @@ A(1,2)
// CHECK-NEXT: {{^}}#include "rewrite-includes7.h"{{$}}
// CHECK-NEXT: {{^}}#endif /* expanded by -frewrite-includes */{{$}}
// CHECK-NEXT: {{^}}# 21 "{{.*}}rewrite-includes.c"{{$}}
+// CHECK-NEXT: {{^}}#if 0 /* expanded by -frewrite-includes */{{$}}
+// CHECK-NEXT: {{^}}#include "rewrite-includes8.h"{{$}}
+// CHECK-NEXT: {{^}}#endif /* expanded by -frewrite-includes */{{$}}
+// CHECK-NEXT: {{^}}# 1 "{{.*[/\\]Inputs[/\\]}}rewrite-includes8.h" 1{{$}}
+// CHECK-NEXT: {{^}}#if (1)/*__has_include_next(<rewrite-includes8.h>)*/{{$}}
+// CHECK-NEXT: {{^}}#elif (0)/*__has_include(<rewrite-includes8.hfail>)*/{{$}}
+// CHECK-NEXT: {{^}}#endif{{$}}
+// CHECK-NEXT: {{^}}#if !(1)/*__has_include("rewrite-includes8.h")*/{{$}}
+// CHECK-NEXT: {{^}}#endif{{$}}
+// CHECK-NEXT: {{^}}# 22 "{{.*}}rewrite-includes.c" 2{{$}}
// CHECK-NEXT: {{^}}// ENDCOMPARE{{$}}
// CHECKNL: {{^}}// STARTCOMPARE{{$}}
@@ -142,4 +153,12 @@ A(1,2)
// CHECKNL-NEXT: {{^}}#if 0 /* expanded by -frewrite-includes */{{$}}
// CHECKNL-NEXT: {{^}}#include "rewrite-includes7.h"{{$}}
// CHECKNL-NEXT: {{^}}#endif /* expanded by -frewrite-includes */{{$}}
+// CHECKNL-NEXT: {{^}}#if 0 /* expanded by -frewrite-includes */{{$}}
+// CHECKNL-NEXT: {{^}}#include "rewrite-includes8.h"{{$}}
+// CHECKNL-NEXT: {{^}}#endif /* expanded by -frewrite-includes */{{$}}
+// CHECKNL-NEXT: {{^}}#if (1)/*__has_include_next(<rewrite-includes8.h>)*/{{$}}
+// CHECKNL-NEXT: {{^}}#elif (0)/*__has_include(<rewrite-includes8.hfail>)*/{{$}}
+// CHECKNL-NEXT: {{^}}#endif{{$}}
+// CHECKNL-NEXT: {{^}}#if !(1)/*__has_include("rewrite-includes8.h")*/{{$}}
+// CHECKNL-NEXT: {{^}}#endif{{$}}
// CHECKNL-NEXT: {{^}}// ENDCOMPARE{{$}}
diff --git a/test/Frontend/rewrite-macros.c b/test/Frontend/rewrite-macros.c
index bc7479693b..eab66571b8 100644
--- a/test/Frontend/rewrite-macros.c
+++ b/test/Frontend/rewrite-macros.c
@@ -1,17 +1,21 @@
-// RUN: %clang_cc1 -verify -rewrite-macros -o %t %s
+// RUN: %clang_cc1 %s -verify -rewrite-macros -o %t
+// RUN: FileCheck %s < %t
+
+// Any CHECK line comments are included in the output, so we use some extra
+// regex brackets to make sure we don't match the CHECK lines themselves.
#define A(a,b) a ## b
-// RUN: grep '12 */\*A\*/ /\*(1,2)\*/' %t
+// CHECK: {{^}} 12 /*A*/ /*(1,2)*/{{$}}
A(1,2)
-// RUN: grep '/\*_Pragma("mark")\*/' %t
+// CHECK: {{^}} /*_Pragma("mark")*/{{$}}
_Pragma("mark")
-// RUN: grep "//#warning eek" %t
+// CHECK: /*#warning eek*/{{$}}
/* expected-warning {{eek}} */ #warning eek
-// RUN: grep "//#pragma mark mark" %t
+// CHECK: {{^}}//#pragma mark mark{{$}}
#pragma mark mark
diff --git a/test/Frontend/verify.c b/test/Frontend/verify.c
index 062e6bd861..3d71e04980 100644
--- a/test/Frontend/verify.c
+++ b/test/Frontend/verify.c
@@ -124,3 +124,19 @@ unexpected b; // expected-error@33 1-1 {{unknown type}}
// CHECK7-NEXT: Line 2: 2
// CHECK7-NEXT: 2 errors generated.
#endif
+
+#ifdef TEST8
+// RUN: %clang_cc1 -DTEST8 -verify %s 2>&1 | FileCheck -check-prefix=CHECK8 %s
+
+// expected-warning@nonexistant-file:1 {{ }}
+// expected-error@-1 {{file 'nonexistant-file' could not be located}}
+
+// expected-warning@verify-directive.h: {{ }}
+// expected-error@-1 {{missing or invalid line number}}
+
+// expected-warning@verify-directive.h:1 {{diagnostic}}
+
+// CHECK8: error: 'warning' diagnostics expected but not seen:
+// CHECK8-NEXT: File {{.*}}verify-directive.h Line 1 (directive at {{.*}}verify.c:137): diagnostic
+// CHECK8-NEXT: 1 error generated.
+#endif
diff --git a/test/Headers/c11.c b/test/Headers/c11.c
index 24a1c2a60d..21f2e4f222 100644
--- a/test/Headers/c11.c
+++ b/test/Headers/c11.c
@@ -1,4 +1,6 @@
// RUN: %clang -fsyntax-only -Xclang -verify -std=c11 %s
+// RUN: %clang -fsyntax-only -Xclang -verify -std=c11 -fmodules %s
+// RUN: %clang -fsyntax-only -Xclang -verify -std=c11 -ffreestanding %s
noreturn int f(); // expected-error 1+{{}}
@@ -16,3 +18,15 @@ _Static_assert(__alignas_is_defined, "");
_Static_assert(__alignof_is_defined, "");
alignas(alignof(int)) char c[4];
_Static_assert(__alignof(c) == 4, "");
+
+#define __STDC_WANT_LIB_EXT1__ 1
+#include <stddef.h>
+rsize_t x = 0;
+
+// If we are freestanding, then also check RSIZE_MAX (in a hosted implementation
+// we will use the host stdint.h, which may not yet have C11 support).
+#ifndef __STDC_HOSTED__
+#include <stdint.h>
+rsize_t x2 = RSIZE_MAX;
+#endif
+
diff --git a/test/Headers/cxx11.cpp b/test/Headers/cxx11.cpp
index 995fc6528d..54fe350ea5 100644
--- a/test/Headers/cxx11.cpp
+++ b/test/Headers/cxx11.cpp
@@ -1,4 +1,5 @@
// RUN: %clang -fsyntax-only -std=c++11 %s
+// RUN: %clang -fsyntax-only -std=c++11 -fmodules %s
#include <stdalign.h>
@@ -12,3 +13,10 @@
static_assert(__alignas_is_defined, "");
static_assert(__alignof_is_defined, "");
+
+
+#include <stdint.h>
+
+#ifndef SIZE_MAX
+#error SIZE_MAX should be defined in C++
+#endif
diff --git a/test/Headers/ms-wchar.c b/test/Headers/ms-wchar.c
new file mode 100644
index 0000000000..f015fc77ee
--- /dev/null
+++ b/test/Headers/ms-wchar.c
@@ -0,0 +1,15 @@
+// RUN: %clang -fsyntax-only -target i386-pc-win32 %s
+
+#if defined(_WCHAR_T_DEFINED)
+#error "_WCHAR_T_DEFINED should not be defined in C99"
+#endif
+
+#include <stddef.h>
+
+#if !defined(_WCHAR_T_DEFINED)
+#error "_WCHAR_T_DEFINED should have been set by stddef.h"
+#endif
+
+#if defined(_NATIVE_WCHAR_T_DEFINED)
+#error "_NATIVE_WCHAR_T_DEFINED should not be defined"
+#endif
diff --git a/test/Index/annotate-deep-statements.cpp b/test/Index/annotate-deep-statements.cpp
index 32a48b7d6a..79f2d39ae5 100644
--- a/test/Index/annotate-deep-statements.cpp
+++ b/test/Index/annotate-deep-statements.cpp
@@ -3,6 +3,9 @@
// rdar://11979525
// Check that we don't get stack overflow trying to annotate an extremely deep AST.
+// AddressSanitizer increases stack usage.
+// XFAIL: asan
+
struct S {
S &operator()();
};
diff --git a/test/Index/annotate-module.m b/test/Index/annotate-module.m
index 33ca3f8324..55e21d235e 100644
--- a/test/Index/annotate-module.m
+++ b/test/Index/annotate-module.m
@@ -40,3 +40,10 @@ int glob;
// CHECK-MOD-NEXT: Punctuation: "*" [2:5 - 2:6] VarDecl=Module_Sub:2:6
// CHECK-MOD-NEXT: Identifier: "Module_Sub" [2:6 - 2:16] VarDecl=Module_Sub:2:6
// CHECK-MOD-NEXT: Punctuation: ";" [2:16 - 2:17]
+
+// RUN: c-index-test -cursor-at=%s:3:11 %s -fmodules-cache-path=%t.cache -fmodules -F %S/../Modules/Inputs \
+// RUN: | FileCheck %s -check-prefix=CHECK-CURSOR
+
+// CHECK-CURSOR: 3:1 ModuleImport=DependsOnModule:3:1 (Definition) Extent=[3:1 - 3:24] Spelling=DependsOnModule ([3:9 - 3:24]) ModuleName=DependsOnModule ({{.*}}DependsOnModule.pcm) Headers(2):
+// CHECK-CURSOR-NEXT: {{.*}}other.h
+// CHECK-CURSOR-NEXT: {{.*}}DependsOnModule.h
diff --git a/test/Index/annotate-tokens.cpp b/test/Index/annotate-tokens.cpp
index 3062901b7c..16726547a2 100644
--- a/test/Index/annotate-tokens.cpp
+++ b/test/Index/annotate-tokens.cpp
@@ -20,7 +20,15 @@ void test3(S2 s2) {
X foo;
}
-// RUN: c-index-test -test-annotate-tokens=%s:1:1:21:1 %s | FileCheck %s
+template <bool (*tfn)(X*)>
+struct TS {
+ void foo();
+};
+
+template <bool (*tfn)(X*)>
+void TS<tfn>::foo() {}
+
+// RUN: c-index-test -test-annotate-tokens=%s:1:1:30:1 %s -fno-delayed-template-parsing | FileCheck %s
// CHECK: Keyword: "struct" [1:1 - 1:7] StructDecl=bonk:1:8 (Definition)
// CHECK: Identifier: "bonk" [1:8 - 1:12] StructDecl=bonk:1:8 (Definition)
// CHECK: Punctuation: "{" [1:13 - 1:14] StructDecl=bonk:1:8 (Definition)
@@ -120,3 +128,48 @@ void test3(S2 s2) {
// CHECK: Identifier: "foo" [20:5 - 20:8] VarDecl=foo:20:5 (Definition)
// CHECK: Punctuation: ";" [20:8 - 20:9] DeclStmt=
// CHECK: Punctuation: "}" [21:1 - 21:2] CompoundStmt=
+// CHECK: Keyword: "template" [23:1 - 23:9] ClassTemplate=TS:24:8 (Definition)
+// CHECK: Punctuation: "<" [23:10 - 23:11] ClassTemplate=TS:24:8 (Definition)
+// CHECK: Keyword: "bool" [23:11 - 23:15] NonTypeTemplateParameter=tfn:23:18 (Definition)
+// CHECK: Punctuation: "(" [23:16 - 23:17] NonTypeTemplateParameter=tfn:23:18 (Definition)
+// CHECK: Punctuation: "*" [23:17 - 23:18] NonTypeTemplateParameter=tfn:23:18 (Definition)
+// CHECK: Identifier: "tfn" [23:18 - 23:21] NonTypeTemplateParameter=tfn:23:18 (Definition)
+// CHECK: Punctuation: ")" [23:21 - 23:22] NonTypeTemplateParameter=tfn:23:18 (Definition)
+// CHECK: Punctuation: "(" [23:22 - 23:23] NonTypeTemplateParameter=tfn:23:18 (Definition)
+// CHECK: Identifier: "X" [23:23 - 23:24] TypeRef=struct X:7:8
+// CHECK: Punctuation: "*" [23:24 - 23:25] ParmDecl=:23:25 (Definition)
+// CHECK: Punctuation: ")" [23:25 - 23:26] ParmDecl=:23:25 (Definition)
+// CHECK: Punctuation: ">" [23:26 - 23:27] ClassTemplate=TS:24:8 (Definition)
+// CHECK: Keyword: "struct" [24:1 - 24:7] ClassTemplate=TS:24:8 (Definition)
+// CHECK: Identifier: "TS" [24:8 - 24:10] ClassTemplate=TS:24:8 (Definition)
+// CHECK: Punctuation: "{" [24:11 - 24:12] ClassTemplate=TS:24:8 (Definition)
+// CHECK: Keyword: "void" [25:3 - 25:7] CXXMethod=foo:25:8
+// CHECK: Identifier: "foo" [25:8 - 25:11] CXXMethod=foo:25:8
+// CHECK: Punctuation: "(" [25:11 - 25:12] CXXMethod=foo:25:8
+// CHECK: Punctuation: ")" [25:12 - 25:13] CXXMethod=foo:25:8
+// CHECK: Punctuation: ";" [25:13 - 25:14] ClassTemplate=TS:24:8 (Definition)
+// CHECK: Punctuation: "}" [26:1 - 26:2] ClassTemplate=TS:24:8 (Definition)
+// CHECK: Punctuation: ";" [26:2 - 26:3]
+// CHECK: Keyword: "template" [28:1 - 28:9] CXXMethod=foo:29:15 (Definition)
+// CHECK: Punctuation: "<" [28:10 - 28:11] CXXMethod=foo:29:15 (Definition)
+// CHECK: Keyword: "bool" [28:11 - 28:15] NonTypeTemplateParameter=tfn:28:18 (Definition)
+// CHECK: Punctuation: "(" [28:16 - 28:17] NonTypeTemplateParameter=tfn:28:18 (Definition)
+// CHECK: Punctuation: "*" [28:17 - 28:18] NonTypeTemplateParameter=tfn:28:18 (Definition)
+// CHECK: Identifier: "tfn" [28:18 - 28:21] NonTypeTemplateParameter=tfn:28:18 (Definition)
+// CHECK: Punctuation: ")" [28:21 - 28:22] NonTypeTemplateParameter=tfn:28:18 (Definition)
+// CHECK: Punctuation: "(" [28:22 - 28:23] NonTypeTemplateParameter=tfn:28:18 (Definition)
+// CHECK: Identifier: "X" [28:23 - 28:24] TypeRef=struct X:7:8
+// CHECK: Punctuation: "*" [28:24 - 28:25] ParmDecl=:28:25 (Definition)
+// CHECK: Punctuation: ")" [28:25 - 28:26] ParmDecl=:28:25 (Definition)
+// CHECK: Punctuation: ">" [28:26 - 28:27] CXXMethod=foo:29:15 (Definition)
+// CHECK: Keyword: "void" [29:1 - 29:5] CXXMethod=foo:29:15 (Definition)
+// CHECK: Identifier: "TS" [29:6 - 29:8] TemplateRef=TS:24:8
+// CHECK: Punctuation: "<" [29:8 - 29:9] CXXMethod=foo:29:15 (Definition)
+// CHECK: Identifier: "tfn" [29:9 - 29:12] DeclRefExpr=tfn:28:18
+// CHECK: Punctuation: ">" [29:12 - 29:13] CXXMethod=foo:29:15 (Definition)
+// CHECK: Punctuation: "::" [29:13 - 29:15] CXXMethod=foo:29:15 (Definition)
+// CHECK: Identifier: "foo" [29:15 - 29:18] CXXMethod=foo:29:15 (Definition)
+// CHECK: Punctuation: "(" [29:18 - 29:19] CXXMethod=foo:29:15 (Definition)
+// CHECK: Punctuation: ")" [29:19 - 29:20] CXXMethod=foo:29:15 (Definition)
+// CHECK: Punctuation: "{" [29:21 - 29:22] CompoundStmt=
+// CHECK: Punctuation: "}" [29:22 - 29:23] CompoundStmt=
diff --git a/test/Index/annotate-tokens.m b/test/Index/annotate-tokens.m
index 7e888e394c..40c66a18b8 100644
--- a/test/Index/annotate-tokens.m
+++ b/test/Index/annotate-tokens.m
@@ -281,7 +281,7 @@ static Rdar8595462_A * Rdar8595462_staticVar;
// CHECK: Punctuation: ")" [40:19 - 40:20] CallExpr=ibaction_test:36:12
// CHECK: Punctuation: ";" [40:20 - 40:21] CompoundStmt=
// CHECK: Punctuation: "[" [41:5 - 41:6] ObjCMessageExpr=foo::34:9
-// CHECK: Identifier: "self" [41:6 - 41:10] DeclRefExpr=self:0:0
+// CHECK: Identifier: "self" [41:6 - 41:10] ObjCSelfExpr=self:0:0
// CHECK: Identifier: "foo" [41:11 - 41:14] ObjCMessageExpr=foo::34:9
// CHECK: Punctuation: ":" [41:14 - 41:15] ObjCMessageExpr=foo::34:9
// CHECK: Literal: "0" [41:15 - 41:16] IntegerLiteral=
@@ -391,7 +391,7 @@ static Rdar8595462_A * Rdar8595462_staticVar;
// CHECK: Identifier: "local" [76:9 - 76:14] VarDecl=local:76:9 (Definition)
// CHECK: Punctuation: "=" [76:15 - 76:16] VarDecl=local:76:9 (Definition)
// CHECK: Punctuation: "[" [76:17 - 76:18] ObjCMessageExpr=foo::66:9
-// CHECK: Identifier: "self" [76:18 - 76:22] DeclRefExpr=self:0:0
+// CHECK: Identifier: "self" [76:18 - 76:22] ObjCSelfExpr=self:0:0
// CHECK: Identifier: "foo" [76:23 - 76:26] ObjCMessageExpr=foo::66:9
// CHECK: Punctuation: ":" [76:26 - 76:27] ObjCMessageExpr=foo::66:9
// CHECK: Identifier: "VAL" [76:27 - 76:30] macro expansion=VAL:63:9
@@ -401,7 +401,7 @@ static Rdar8595462_A * Rdar8595462_staticVar;
// CHECK: Identifier: "second" [77:9 - 77:15] VarDecl=second:77:9 (Definition)
// CHECK: Punctuation: "=" [77:16 - 77:17] VarDecl=second:77:9 (Definition)
// CHECK: Punctuation: "[" [77:18 - 77:19] ObjCMessageExpr=foo::66:9
-// CHECK: Identifier: "self" [77:19 - 77:23] DeclRefExpr=self:0:0
+// CHECK: Identifier: "self" [77:19 - 77:23] ObjCSelfExpr=self:0:0
// CHECK: Identifier: "foo" [77:24 - 77:27] ObjCMessageExpr=foo::66:9
// CHECK: Punctuation: ":" [77:27 - 77:28] ObjCMessageExpr=foo::66:9
// CHECK: Literal: "0" [77:28 - 77:29] IntegerLiteral=
@@ -518,7 +518,7 @@ static Rdar8595462_A * Rdar8595462_staticVar;
// CHECK-INSIDE_BLOCK: Identifier: "result" [127:9 - 127:15] VarDecl=result:127:9 (Definition)
// CHECK-INSIDE_BLOCK: Punctuation: "=" [127:16 - 127:17] VarDecl=result:127:9 (Definition)
// CHECK-INSIDE_BLOCK: Punctuation: "[" [127:18 - 127:19] ObjCMessageExpr=blah::124:8
-// CHECK-INSIDE_BLOCK: Identifier: "self" [127:19 - 127:23] DeclRefExpr=self:0:0
+// CHECK-INSIDE_BLOCK: Identifier: "self" [127:19 - 127:23] ObjCSelfExpr=self:0:0
// CHECK-INSIDE_BLOCK: Identifier: "blah" [127:24 - 127:28] ObjCMessageExpr=blah::124:8
// CHECK-INSIDE_BLOCK: Punctuation: ":" [127:28 - 127:29] ObjCMessageExpr=blah::124:8
// CHECK-INSIDE_BLOCK: Literal: "5" [127:29 - 127:30] IntegerLiteral=
@@ -530,7 +530,7 @@ static Rdar8595462_A * Rdar8595462_staticVar;
// CHECK-INSIDE_BLOCK: Punctuation: "*" [128:17 - 128:18] VarDecl=a:128:18 (Definition)
// CHECK-INSIDE_BLOCK: Identifier: "a" [128:18 - 128:19] VarDecl=a:128:18 (Definition)
// CHECK-INSIDE_BLOCK: Punctuation: "=" [128:20 - 128:21] VarDecl=a:128:18 (Definition)
-// CHECK-INSIDE_BLOCK: Identifier: "self" [128:22 - 128:26] DeclRefExpr=self:0:0
+// CHECK-INSIDE_BLOCK: Identifier: "self" [128:22 - 128:26] ObjCSelfExpr=self:0:0
// RUN: c-index-test -test-annotate-tokens=%s:134:1:138:1 %s -DIBOutlet='__attribute__((iboutlet))' -DIBAction='void)__attribute__((ibaction)' | FileCheck -check-prefix=CHECK-PROP-AFTER-METHOD %s
// CHECK-PROP-AFTER-METHOD: Punctuation: "@" [134:1 - 134:2] ObjCInterfaceDecl=Rdar8062781:134:12
diff --git a/test/Index/c-index-api-loadTU-test.m b/test/Index/c-index-api-loadTU-test.m
index b0fb71e419..61d82a6cde 100644
--- a/test/Index/c-index-api-loadTU-test.m
+++ b/test/Index/c-index-api-loadTU-test.m
@@ -169,7 +169,7 @@ struct X0 {};
// CHECK: c-index-api-loadTU-test.m:71:8: StructDecl=X0:71:8 (Definition) Extent=[71:1 - 71:14]
// CHECK: c-index-api-loadTU-test.m:73:12: ObjCCategoryDecl=:73:12 Extent=[73:1 - 76:5]
// CHECK: c-index-api-loadTU-test.m:73:12: ObjCClassRef=TestAttributes:62:12 Extent=[73:12 - 73:26]
-// CHECK: c-index-api-loadTU-test.m:75:32: ObjCPropertyDecl=anotherOutlet:75:32 Extent=[75:1 - 75:45]
+// CHECK: c-index-api-loadTU-test.m:75:32: ObjCPropertyDecl=anotherOutlet:75:32 [retain,] Extent=[75:1 - 75:45]
// CHECK: <invalid loc>:0:0: attribute(iboutlet)= Extent=[75:20 - 75:28]
// CHECK: c-index-api-loadTU-test.m:75:29: TypeRef=id:0:0 Extent=[75:29 - 75:31]
// CHECK: c-index-api-loadTU-test.m:75:32: ObjCInstanceMethodDecl=anotherOutlet:75:32 Extent=[75:32 - 75:45]
diff --git a/test/Index/comment-cplus11-specific.cpp b/test/Index/comment-cplus11-specific.cpp
new file mode 100644
index 0000000000..fa0db914cd
--- /dev/null
+++ b/test/Index/comment-cplus11-specific.cpp
@@ -0,0 +1,27 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: c-index-test -test-load-source all -comments-xml-schema=%S/../../bindings/xml/comment-xml-schema.rng std=c++11 %s > %t/out
+// RUN: FileCheck %s < %t/out
+// rdar://13752382
+
+namespace inner {
+ //! This documentation should be inherited.
+ struct Opaque;
+}
+// CHECK: (CXComment_Text Text=[ This documentation should be inherited.])))]
+
+namespace borrow {
+ //! This is documentation for the typedef (which shows up).
+ typedef inner::Opaque Typedef;
+// CHECK: (CXComment_Text Text=[ This is documentation for the typedef (which shows up).])))]
+
+ //! This is documentation for the alias (which shows up).
+ using Alias = inner::Opaque;
+// CHECK: (CXComment_Text Text=[ This is documentation for the alias (which shows up).])))]
+
+ typedef inner::Opaque NoDocTypedef;
+// CHECK: (CXComment_Text Text=[ This documentation should be inherited.])))]
+
+ using NoDocAlias = inner::Opaque;
+// CHECK: (CXComment_Text Text=[ This documentation should be inherited.])))]
+}
diff --git a/test/Index/comment-misc-tags.m b/test/Index/comment-misc-tags.m
new file mode 100644
index 0000000000..9eae5489fc
--- /dev/null
+++ b/test/Index/comment-misc-tags.m
@@ -0,0 +1,110 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: c-index-test -test-load-source all -comments-xml-schema=%S/../../bindings/xml/comment-xml-schema.rng %s > %t/out
+// RUN: FileCheck %s < %t/out
+// rdar://12379114
+
+/*!
+ @interface IOCommandGate
+ @brief This is a brief
+ @abstract Single-threaded work-loop client request mechanism.
+ @discussion An IOCommandGate instance is an extremely light weight mechanism that
+ executes an action on the driver's work-loop...
+ @textblock
+ Many discussions about text
+ Many1 discussions about text
+ Many2 discussions about text
+ @/textblock
+ @link //un_ref/c/func/function_name link text goes here @/link
+ @see //un_ref/doc/uid/XX0000011 I/O Kit Fundamentals
+ @seealso //k_ref/doc/uid/XX30000905-CH204 Programming
+ */
+@interface IOCommandGate
+@end
+
+// CHECK: (CXComment_BlockCommand CommandName=[abstract]
+// CHECK-NEXT: (CXComment_Paragraph
+// CHECK-NEXT: (CXComment_Text Text=[ Single-threaded work-loop client request mechanism.] HasTrailingNewline)
+// CHECK: (CXComment_BlockCommand CommandName=[discussion]
+// CHECK-NEXT: (CXComment_Paragraph
+// CHECK-NEXT: (CXComment_Text Text=[ An IOCommandGate instance is an extremely light weight mechanism that] HasTrailingNewline)
+// CHECK-NEXT: (CXComment_Text Text=[ executes an action on the driver's work-loop...] HasTrailingNewline)
+// CHECK: (CXComment_VerbatimBlockCommand CommandName=[textblock]
+// CHECK-NEXT: (CXComment_VerbatimBlockLine Text=[ Many discussions about text])
+// CHECK-NEXT: (CXComment_VerbatimBlockLine Text=[ Many1 discussions about text])
+// CHECK-NEXT: (CXComment_VerbatimBlockLine Text=[ Many2 discussions about text]))
+// CHECK-NEXT: (CXComment_Paragraph IsWhitespace
+
+// CHECK: (CXComment_VerbatimBlockCommand CommandName=[link]
+// CHECK-NEXT: (CXComment_VerbatimBlockLine Text=[ //un_ref/c/func/function_name link text goes here ]))
+// CHECK-NEXT: (CXComment_Paragraph IsWhitespace
+// CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace))
+// CHECK: (CXComment_BlockCommand CommandName=[see]
+// CHECK-NEXT: (CXComment_Paragraph
+// CHECK-NEXT: (CXComment_Text Text=[ //un_ref/doc/uid/XX0000011 I/O Kit Fundamentals] HasTrailingNewline)
+// CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace)))
+// CHECK: (CXComment_BlockCommand CommandName=[seealso]
+// CHECK-NEXT: (CXComment_Paragraph
+// CHECK-NEXT: (CXComment_Text Text=[ //k_ref/doc/uid/XX30000905-CH204 Programming] HasTrailingNewline)
+
+// rdar://12379053
+/*!
+\arg \c AlignLeft left alignment.
+\li \c AlignRight right alignment.
+
+ No other types of alignment are supported.
+*/
+struct S {
+ int AlignLeft;
+ int AlignRight;
+};
+
+// CHECK: (CXComment_BlockCommand CommandName=[arg]
+// CHECK-NEXT: (CXComment_Paragraph
+// CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace)
+// CHECK-NEXT: (CXComment_InlineCommand CommandName=[c] RenderMonospaced Arg[0]=AlignLeft)
+// CHECK-NEXT: (CXComment_Text Text=[ left alignment.] HasTrailingNewline)))
+// CHECK: (CXComment_BlockCommand CommandName=[li]
+// CHECK-NEXT: (CXComment_Paragraph
+// CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace)
+// CHECK-NEXT: (CXComment_InlineCommand CommandName=[c] RenderMonospaced Arg[0]=AlignRight)
+// CHECK-NEXT: (CXComment_Text Text=[ right alignment.])))
+// CHECK: (CXComment_Paragraph
+// CHECK-NEXT: (CXComment_Text Text=[ No other types of alignment are supported.]))
+
+// rdar://12379053
+/*! \struct Test
+ * Normal text.
+ *
+ * \par User defined paragraph:
+ * Contents of the paragraph.
+ *
+ * \par
+ * New paragraph under the same heading.
+ *
+ * \note
+ * This note consists of two paragraphs.
+ * This is the first paragraph.
+ *
+ * \par
+ * And this is the second paragraph.
+ *
+ * More normal text.
+ */
+
+struct Test {int filler;};
+
+// CHECK: (CXComment_BlockCommand CommandName=[par]
+// CHECK-NEXT: (CXComment_Paragraph
+// CHECK-NEXT: (CXComment_Text Text=[ User defined paragraph:] HasTrailingNewline)
+// CHECK-NEXT: (CXComment_Text Text=[ Contents of the paragraph.])))
+// CHECK: (CXComment_BlockCommand CommandName=[par]
+// CHECK-NEXT: (CXComment_Paragraph
+// CHECK-NEXT: (CXComment_Text Text=[ New paragraph under the same heading.])))
+// CHECK: (CXComment_BlockCommand CommandName=[note]
+// CHECK-NEXT: (CXComment_Paragraph
+// CHECK-NEXT: (CXComment_Text Text=[ This note consists of two paragraphs.] HasTrailingNewline)
+// CHECK-NEXT: (CXComment_Text Text=[ This is the first paragraph.])))
+// CHECK: (CXComment_BlockCommand CommandName=[par]
+// CHECK-NEXT: (CXComment_Paragraph
+// CHECK-NEXT: (CXComment_Text Text=[ And this is the second paragraph.])))
diff --git a/test/Index/comment-to-html-xml-conversion.cpp b/test/Index/comment-to-html-xml-conversion.cpp
index b33fa4ace4..c770ca8d30 100644
--- a/test/Index/comment-to-html-xml-conversion.cpp
+++ b/test/Index/comment-to-html-xml-conversion.cpp
@@ -19,6 +19,7 @@
// RUN: FileCheck %s < %t/out.c-index-direct
// RUN: FileCheck %s < %t/out.c-index-pch
+// XFAIL: msan
// XFAIL: valgrind
#ifndef HEADER
diff --git a/test/Index/comment-unqualified-objc-pointer.m b/test/Index/comment-unqualified-objc-pointer.m
new file mode 100644
index 0000000000..546d4fa9f0
--- /dev/null
+++ b/test/Index/comment-unqualified-objc-pointer.m
@@ -0,0 +1,36 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: c-index-test -test-load-source all -comments-xml-schema=%S/../../bindings/xml/comment-xml-schema.rng -target x86_64-apple-darwin10 -fobjc-default-synthesize-properties -fobjc-arc %s > %t/out
+// RUN: FileCheck %s < %t/out
+// rdar://13757500
+
+@class NSString;
+
+@interface NSArray @end
+
+@interface NSMutableArray : NSArray
+{
+//! This is the name.
+ NSString *Name;
+}
+//! This is WithLabel comment.
+- (NSString *)WithLabel:(NSString * const)label;
+// CHECK: <Declaration>- (NSString *)WithLabel:(NSString *const)label;</Declaration>
+
+//! This is a property to get the Name.
+@property (copy) NSString *Name;
+// CHECK: <Declaration>@property(readwrite, copy, atomic) NSString *Name;</Declaration>
+@end
+
+@implementation NSMutableArray
+{
+//! This is private ivar
+ NSString *NickName;
+// CHECK: <Declaration>NSString *NickName</Declaration>
+}
+
+- (NSString *)WithLabel:(NSString * const)label {
+ return 0;
+}
+@synthesize Name = Name;
+@end
diff --git a/test/Index/comment-with-preamble.c b/test/Index/comment-with-preamble.c
new file mode 100644
index 0000000000..72e6140d12
--- /dev/null
+++ b/test/Index/comment-with-preamble.c
@@ -0,0 +1,13 @@
+// Make sure the preable does not truncate comments.
+
+#ifndef BAZ
+#define BAZ 3
+#endif
+
+//! Foo’s description.
+void Foo();
+
+// RUN: c-index-test -test-load-source-reparse 1 local %s | FileCheck %s
+// RUN: env CINDEXTEST_EDITING=1 c-index-test -test-load-source-reparse 1 local %s | FileCheck %s
+
+// CHECK: FunctionDecl=Foo:8:6 RawComment=[//! Foo’s description.] RawCommentRange=[7:1 - 7:25] BriefComment=[Foo’s description.]
diff --git a/test/Index/complete-declarators.m b/test/Index/complete-declarators.m
index d42a3c7a6c..b3a60ded11 100644
--- a/test/Index/complete-declarators.m
+++ b/test/Index/complete-declarators.m
@@ -22,6 +22,7 @@
static P *p = 0;
}
+- (boid)method2 {}
@end
// RUN: c-index-test -code-completion-at=%s:7:4 %s | FileCheck -check-prefix=CHECK-CC0 %s
@@ -81,3 +82,8 @@
// CHECK-CC5: NotImplemented:{TypedText unsigned} (50)
// CHECK-CC5: NotImplemented:{TypedText void} (50)
// CHECK-CC5: NotImplemented:{TypedText volatile} (50)
+
+// Check that there are no duplicate entries if we code-complete after an @implementation
+// RUN: c-index-test -code-completion-at=%s:27:1 %s | FileCheck -check-prefix=CHECK-CC6 %s
+// CHECK-CC6: ObjCInterfaceDecl:{TypedText A}
+// CHECK-CC6-NOT: ObjCInterfaceDecl:{TypedText A}
diff --git a/test/Index/complete-documentation-properties.m b/test/Index/complete-documentation-properties.m
index d423f84d22..774a02021e 100644
--- a/test/Index/complete-documentation-properties.m
+++ b/test/Index/complete-documentation-properties.m
@@ -49,6 +49,7 @@
p = [self PropertyInPrimaryClass];
p = [self Record];
[self setThisRecord : (id)0 ];
+ p = self.GetterInClassExtension;
return 0;
}
@end
@@ -66,3 +67,26 @@
// RUN: env CINDEXTEST_COMPLETION_BRIEF_COMMENTS=1 c-index-test -code-completion-at=%s:51:9 %s | FileCheck -check-prefix=CC5 %s
// CHECK-CC5: {TypedText setThisRecord:}{Placeholder (id)}{{.*}}(brief comment: This is Record)
+
+// RUN: env CINDEXTEST_COMPLETION_BRIEF_COMMENTS=1 c-index-test -code-completion-at=%s:52:12 %s | FileCheck -check-prefix=CC6 %s
+// CHECK-CC6: {TypedText GetterInClassExtension}{{.*}}(brief comment: This is PropertyInClassExtension)
+
+@interface AnotherAppDelegate
+/**
+ \brief This is ReadonlyProperty
+*/
+@property (getter = ReadonlyGetter) int MyProperty;
+/**
+ \brief This is getter = ReadonlyGetter
+*/
+- (int) ReadonlyGetter;
+@end
+
+@implementation AnotherAppDelegate
+- (int) PropertyInPrimaryClass {
+self.ReadonlyGetter;
+}
+@end
+// RUN: env CINDEXTEST_COMPLETION_BRIEF_COMMENTS=1 c-index-test -code-completion-at=%s:87:6 %s | FileCheck -check-prefix=CC7 %s
+// CHECK-CC7: {TypedText ReadonlyGetter}{{.*}}(brief comment: This is getter = ReadonlyGetter)
+
diff --git a/test/Index/crash-recovery-code-complete.c b/test/Index/crash-recovery-code-complete.c
index f001578f78..c502ce5186 100644
--- a/test/Index/crash-recovery-code-complete.c
+++ b/test/Index/crash-recovery-code-complete.c
@@ -8,4 +8,7 @@
//
// REQUIRES: crash-recovery
+// FIXME: Please investigate abnormal path in MemoryBuffer.
+// XFAIL: mingw32,win32
+
#warning parsing original file
diff --git a/test/Index/get-cursor.cpp b/test/Index/get-cursor.cpp
index 8b70216dd1..996ecc25ef 100644
--- a/test/Index/get-cursor.cpp
+++ b/test/Index/get-cursor.cpp
@@ -47,6 +47,24 @@ void test() {
};
}
+template <bool (*tfn)(X*)>
+struct TS {
+ void foo();
+};
+
+template <bool (*tfn)(X*)>
+void TS<tfn>::foo() {}
+
+template <typename T>
+class TC {
+ void init();
+};
+
+template<> void TC<char>::init();
+
+#define EXTERN_TEMPLATE(...) extern template __VA_ARGS__;
+EXTERN_TEMPLATE(class TC<char>)
+
// RUN: c-index-test -cursor-at=%s:6:4 %s | FileCheck -check-prefix=CHECK-COMPLETION-1 %s
// CHECK-COMPLETION-1: CXXConstructor=X:6:3
// CHECK-COMPLETION-1-NEXT: Completion string: {TypedText X}{LeftParen (}{Placeholder int}{Comma , }{Placeholder int}{RightParen )}
@@ -103,3 +121,10 @@ void test() {
// RUN: c-index-test -cursor-at=%s:45:9 %s | FileCheck -check-prefix=CHECK-LOCALCLASS %s
// CHECK-LOCALCLASS: 45:9 DeclRefExpr=x:44:11 Extent=[45:9 - 45:10] Spelling=x ([45:9 - 45:10])
+
+// RUN: c-index-test -cursor-at=%s:50:23 -cursor-at=%s:55:23 %s | FileCheck -check-prefix=CHECK-TEMPLPARAM %s
+// CHECK-TEMPLPARAM: 50:23 TypeRef=struct X:3:8 Extent=[50:23 - 50:24] Spelling=struct X ([50:23 - 50:24])
+// CHECK-TEMPLPARAM: 55:23 TypeRef=struct X:3:8 Extent=[55:23 - 55:24] Spelling=struct X ([55:23 - 55:24])
+
+// RUN: c-index-test -cursor-at=%s:66:23 %s | FileCheck -check-prefix=CHECK-TEMPLSPEC %s
+// CHECK-TEMPLSPEC: 66:23 ClassDecl=TC:66:23 (Definition) [Specialization of TC:59:7] Extent=[66:1 - 66:31] Spelling=TC ([66:23 - 66:25])
diff --git a/test/Index/index-refs.m b/test/Index/index-refs.m
index b82345f9c6..f25013b882 100644
--- a/test/Index/index-refs.m
+++ b/test/Index/index-refs.m
@@ -13,6 +13,15 @@ void foo() {
@encode(struct FooS);
}
+@interface I
++(void)clsMeth;
+@end
+
+void foo2() {
+ [I clsMeth];
+}
+
// RUN: c-index-test -index-file %s | FileCheck %s
// CHECK: [indexEntityReference]: kind: objc-protocol | name: Prot | {{.*}} | loc: 12:27
// CHECK: [indexEntityReference]: kind: struct | name: FooS | {{.*}} | loc: 13:18
+// CHECK: [indexEntityReference]: kind: objc-class | name: I | {{.*}} | loc: 21:4
diff --git a/test/Index/load-classes.cpp b/test/Index/load-classes.cpp
index 58770191ea..db7b48f7ef 100644
--- a/test/Index/load-classes.cpp
+++ b/test/Index/load-classes.cpp
@@ -3,7 +3,9 @@
struct X {
X(int value);
X(const X& x);
+protected:
~X();
+private:
operator X*();
};
@@ -11,18 +13,18 @@ X::X(int value) {
}
// RUN: c-index-test -test-load-source all %s | FileCheck %s
-// CHECK: load-classes.cpp:3:8: StructDecl=X:3:8 (Definition) Extent=[3:1 - 8:2]
-// CHECK: load-classes.cpp:4:3: CXXConstructor=X:4:3 Extent=[4:3 - 4:15]
+// CHECK: load-classes.cpp:3:8: StructDecl=X:3:8 (Definition) Extent=[3:1 - 10:2]
+// CHECK: load-classes.cpp:4:3: CXXConstructor=X:4:3 Extent=[4:3 - 4:15] [access=public]
// FIXME: missing TypeRef in the constructor name
// CHECK: load-classes.cpp:4:9: ParmDecl=value:4:9 (Definition) Extent=[4:5 - 4:14]
-// CHECK: load-classes.cpp:5:3: CXXConstructor=X:5:3 Extent=[5:3 - 5:16]
+// CHECK: load-classes.cpp:5:3: CXXConstructor=X:5:3 Extent=[5:3 - 5:16] [access=public]
// FIXME: missing TypeRef in the constructor name
// CHECK: load-classes.cpp:5:14: ParmDecl=x:5:14 (Definition) Extent=[5:5 - 5:15]
// CHECK: load-classes.cpp:5:11: TypeRef=struct X:3:8 Extent=[5:11 - 5:12]
-// CHECK: load-classes.cpp:6:3: CXXDestructor=~X:6:3 Extent=[6:3 - 6:7]
+// CHECK: load-classes.cpp:7:3: CXXDestructor=~X:7:3 Extent=[7:3 - 7:7] [access=protected]
// FIXME: missing TypeRef in the destructor name
-// CHECK: load-classes.cpp:7:3: CXXConversion=operator struct X *:7:3 Extent=[7:3 - 7:16]
-// CHECK: load-classes.cpp:7:12: TypeRef=struct X:3:8 Extent=[7:12 - 7:13]
-// CHECK: load-classes.cpp:10:4: CXXConstructor=X:10:4 (Definition) Extent=[10:1 - 11:2]
-// CHECK: load-classes.cpp:10:1: TypeRef=struct X:3:8 Extent=[10:1 - 10:2]
-// CHECK: load-classes.cpp:10:10: ParmDecl=value:10:10 (Definition) Extent=[10:6 - 10:15]
+// CHECK: load-classes.cpp:9:3: CXXConversion=operator struct X *:9:3 Extent=[9:3 - 9:16] [access=private]
+// CHECK: load-classes.cpp:9:12: TypeRef=struct X:3:8 Extent=[9:12 - 9:13]
+// CHECK: load-classes.cpp:12:4: CXXConstructor=X:12:4 (Definition) Extent=[12:1 - 13:2] [access=public]
+// CHECK: load-classes.cpp:12:1: TypeRef=struct X:3:8 Extent=[12:1 - 12:2]
+// CHECK: load-classes.cpp:12:10: ParmDecl=value:12:10 (Definition) Extent=[12:6 - 12:15]
diff --git a/test/Index/modules-objc-categories.m b/test/Index/modules-objc-categories.m
new file mode 100644
index 0000000000..4d0fd260d4
--- /dev/null
+++ b/test/Index/modules-objc-categories.m
@@ -0,0 +1,10 @@
+@import category_top;
+@import category_left;
+
+@interface Sub : Foo
+- (void)left_sub;
+@end
+
+// RUN: rm -rf %t
+// RUN: c-index-test -test-load-source local -fmodules -fmodules-cache-path=%t %s -I%S/../Modules/Inputs | FileCheck %s
+// CHECK: modules-objc-categories.m:5:9: ObjCInstanceMethodDecl=left_sub:5:9 [Overrides @2:9]
diff --git a/test/Index/parse-all-comments.c b/test/Index/parse-all-comments.c
new file mode 100644
index 0000000000..f8b0449f20
--- /dev/null
+++ b/test/Index/parse-all-comments.c
@@ -0,0 +1,62 @@
+// Run lines are sensitive to line numbers and come below the code.
+
+#ifndef HEADER
+#define HEADER
+
+// Not a Doxygen comment. notdoxy1 NOT_DOXYGEN
+void notdoxy1(void);
+
+/* Not a Doxygen comment. notdoxy2 NOT_DOXYGEN */
+void notdoxy2(void);
+
+/*/ Not a Doxygen comment. notdoxy3 NOT_DOXYGEN */
+void notdoxy3(void);
+
+/** Doxygen comment. isdoxy4 IS_DOXYGEN_SINGLE */
+void isdoxy4(void);
+
+/*! Doxygen comment. isdoxy5 IS_DOXYGEN_SINGLE */
+void isdoxy5(void);
+
+/// Doxygen comment. isdoxy6 IS_DOXYGEN_SINGLE
+void isdoxy6(void);
+
+/* BLOCK_ORDINARY_COMMENT */
+// ORDINARY COMMENT
+/// This is a BCPL comment. IS_DOXYGEN_START
+/// It has only two lines.
+/** But there are other blocks that are part of the comment, too. IS_DOXYGEN_END */
+void multi_line_comment_plus_ordinary(int);
+
+// MULTILINE COMMENT
+//
+// WITH EMPTY LINE
+void multi_line_comment_empty_line(int);
+
+#endif
+
+// RUN: rm -rf %t
+// RUN: mkdir %t
+
+// RUN: %clang_cc1 -fparse-all-comments -x c++ -std=c++11 -emit-pch -o %t/out.pch %s
+
+// RUN: c-index-test -test-load-source all -comments-xml-schema=%S/../../bindings/xml/comment-xml-schema.rng %s -std=c++11 -fparse-all-comments > %t/out.c-index-direct
+// RUN: c-index-test -test-load-tu %t/out.pch all > %t/out.c-index-pch
+
+// RUN: FileCheck %s -check-prefix=WRONG < %t/out.c-index-direct
+// RUN: FileCheck %s -check-prefix=WRONG < %t/out.c-index-pch
+
+// Ensure that XML is not invalid
+// WRONG-NOT: CommentXMLInvalid
+
+// RUN: FileCheck %s < %t/out.c-index-direct
+// RUN: FileCheck %s < %t/out.c-index-pch
+
+// CHECK: parse-all-comments.c:7:6: FunctionDecl=notdoxy1:{{.*}} notdoxy1 NOT_DOXYGEN
+// CHECK: parse-all-comments.c:10:6: FunctionDecl=notdoxy2:{{.*}} notdoxy2 NOT_DOXYGEN
+// CHECK: parse-all-comments.c:13:6: FunctionDecl=notdoxy3:{{.*}} notdoxy3 NOT_DOXYGEN
+// CHECK: parse-all-comments.c:16:6: FunctionDecl=isdoxy4:{{.*}} isdoxy4 IS_DOXYGEN_SINGLE
+// CHECK: parse-all-comments.c:19:6: FunctionDecl=isdoxy5:{{.*}} isdoxy5 IS_DOXYGEN_SINGLE
+// CHECK: parse-all-comments.c:22:6: FunctionDecl=isdoxy6:{{.*}} isdoxy6 IS_DOXYGEN_SINGLE
+// CHECK: parse-all-comments.c:29:6: FunctionDecl=multi_line_comment_plus_ordinary:{{.*}} BLOCK_ORDINARY_COMMENT {{.*}} ORDINARY COMMENT {{.*}} IS_DOXYGEN_START {{.*}} IS_DOXYGEN_END
+// CHECK: parse-all-comments.c:34:6: FunctionDecl=multi_line_comment_empty_line:{{.*}} MULTILINE COMMENT{{.*}}\n{{.*}}\n{{.*}} WITH EMPTY LINE
diff --git a/test/Index/print-type-size.cpp b/test/Index/print-type-size.cpp
new file mode 100644
index 0000000000..698d96705b
--- /dev/null
+++ b/test/Index/print-type-size.cpp
@@ -0,0 +1,428 @@
+// from SemaCXX/class-layout.cpp
+// RUN: c-index-test -test-print-type-size %s -target x86_64-pc-linux-gnu | FileCheck -check-prefix=CHECK64 %s
+// RUN: c-index-test -test-print-type-size %s -target i386-apple-darwin9 | FileCheck -check-prefix=CHECK32 %s
+
+namespace basic {
+
+// CHECK64: VarDecl=v:[[@LINE+2]]:6 (Definition) [type=void] [typekind=Void]
+// CHECK32: VarDecl=v:[[@LINE+1]]:6 (Definition) [type=void] [typekind=Void]
+void v;
+
+// CHECK64: VarDecl=v1:[[@LINE+2]]:7 (Definition) [type=void *] [typekind=Pointer] [sizeof=8] [alignof=8]
+// CHECK32: VarDecl=v1:[[@LINE+1]]:7 (Definition) [type=void *] [typekind=Pointer] [sizeof=4] [alignof=4]
+void *v1;
+
+// offsetof
+// CHECK64: StructDecl=simple:[[@LINE+2]]:8 (Definition) [type=basic::simple] [typekind=Record] [sizeof=48] [alignof=8]
+// CHECK32: StructDecl=simple:[[@LINE+1]]:8 (Definition) [type=basic::simple] [typekind=Record] [sizeof=36] [alignof=4]
+struct simple {
+ int a;
+ char b;
+// CHECK64: FieldDecl=c:[[@LINE+1]]:7 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=40] [BitFieldSize=3]
+ int c:3;
+ long d;
+ int e:5;
+// CHECK64: FieldDecl=f:[[@LINE+1]]:7 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=133] [BitFieldSize=4]
+ int f:4;
+// CHECK64: FieldDecl=g:[[@LINE+2]]:13 (Definition) [type=long long] [typekind=LongLong] [sizeof=8] [alignof=8] [offsetof=192]
+// CHECK32: FieldDecl=g:[[@LINE+1]]:13 (Definition) [type=long long] [typekind=LongLong] [sizeof=8] [alignof=4] [offsetof=128]
+ long long g;
+// CHECK64: FieldDecl=h:[[@LINE+1]]:8 (Definition) [type=char] [typekind=Char_S] [sizeof=1] [alignof=1] [offsetof=256] [BitFieldSize=3]
+ char h:3;
+ char i:3;
+ float j;
+// CHECK64: FieldDecl=k:[[@LINE+2]]:10 (Definition) [type=char *] [typekind=Pointer] [sizeof=8] [alignof=8] [offsetof=320]
+// CHECK32: FieldDecl=k:[[@LINE+1]]:10 (Definition) [type=char *] [typekind=Pointer] [sizeof=4] [alignof=4] [offsetof=256]
+ char * k;
+};
+
+
+// CHECK64: UnionDecl=u:[[@LINE+2]]:7 (Definition) [type=basic::u] [typekind=Record] [sizeof=48] [alignof=8]
+// CHECK32: UnionDecl=u:[[@LINE+1]]:7 (Definition) [type=basic::u] [typekind=Record] [sizeof=36] [alignof=4]
+union u {
+ int u1;
+ long long u2;
+ struct simple s1;
+};
+
+// CHECK64: VarDecl=s1:[[@LINE+2]]:8 (Definition) [type=basic::simple] [typekind=Record] [sizeof=48] [alignof=8]
+// CHECK32: VarDecl=s1:[[@LINE+1]]:8 (Definition) [type=basic::simple] [typekind=Record] [sizeof=36] [alignof=4]
+simple s1;
+
+struct Test {
+ struct {
+ union {
+//CHECK64: FieldDecl=foo:[[@LINE+1]]:11 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=0]
+ int foo;
+ };
+ };
+};
+
+struct Test2 {
+ struct {
+ struct {
+//CHECK64: FieldDecl=foo:[[@LINE+1]]:11 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=0]
+ int foo;
+ };
+ struct {
+//CHECK64: FieldDecl=bar:[[@LINE+1]]:11 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=32]
+ int bar;
+ };
+ struct {
+ struct {
+//CHECK64: FieldDecl=foobar:[[@LINE+1]]:15 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=64]
+ int foobar;
+ };
+ };
+ struct inner {
+ struct {
+//CHECK64: FieldDecl=mybar:[[@LINE+1]]:15 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=0]
+ int mybar;
+ };
+//CHECK64: FieldDecl=mole:[[@LINE+1]]:7 (Definition) [type=struct inner] [typekind=Unexposed] [sizeof=4] [alignof=4] [offsetof=96]
+ } mole;
+ };
+};
+
+}
+
+// these are test crash. Offsetof return values are not important.
+namespace Incomplete {
+// test that fields in incomplete named record do not crash
+union named {
+ struct forward_decl f1;
+//CHECK64: FieldDecl=f2:[[@LINE+1]]:7 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=-2]
+ int f2;
+ struct x {
+//CHECK64: FieldDecl=g1:[[@LINE+1]]:9 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=0]
+ int g1;
+//CHECK64: FieldDecl=f3:[[@LINE+1]]:5 (Definition) [type=struct x] [typekind=Unexposed] [sizeof=4] [alignof=4] [offsetof=-2]
+ } f3;
+ struct forward_decl f4;
+ struct x2{
+ int g2;
+ struct forward_decl g3;
+ } f5;
+};
+
+// test that fields in incomplete anonymous record do not crash
+union f {
+//CHECK64: FieldDecl=f1:[[@LINE+1]]:23 (Definition) [type=struct forward_decl] [typekind=Unexposed] [sizeof=-2] [alignof=-2] [offsetof=-2]
+ struct forward_decl f1;
+//CHECK64: FieldDecl=f2:[[@LINE+1]]:7 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=-2]
+ int f2;
+ struct {
+//CHECK64: FieldDecl=e1:[[@LINE+1]]:9 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=-2]
+ int e1;
+ struct {
+//CHECK64: FieldDecl=g1:[[@LINE+1]]:28 (Definition) [type=struct forward_decl2] [typekind=Unexposed] [sizeof=-2] [alignof=-2] [offsetof=-2]
+ struct forward_decl2 g1;
+ };
+//CHECK64: FieldDecl=e3:[[@LINE+1]]:9 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=-2]
+ int e3;
+ };
+};
+
+
+// incomplete not in root level, in named record
+struct s1 {
+ struct {
+ struct forward_decl2 s1_g1;
+//CHECK64: FieldDecl=s1_e1:[[@LINE+1]]:9 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=-2]
+ int s1_e1;
+ } s1_x; // named record shows in s1->field_iterator
+//CHECK64: FieldDecl=s1_e3:[[@LINE+1]]:7 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=-2]
+ int s1_e3;
+};
+
+// incomplete not in root level, in anonymous record
+struct s1b {
+ struct {
+ struct forward_decl2 s1b_g1;
+ }; // erroneous anonymous record does not show in s1b->field_iterator
+//CHECK64: FieldDecl=s1b_e2:[[@LINE+1]]:7 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=0]
+ int s1b_e2;
+};
+
+struct s2 {
+ struct {
+ struct forward_decl2 s2_g1;
+//CHECK64: FieldDecl=s2_e1:[[@LINE+1]]:9 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=-5]
+ int s2_e1;
+ }; // erroneous anonymous record does not show in s1b->field_iterator
+//CHECK64: FieldDecl=s2_e3:[[@LINE+1]]:7 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=0]
+ int s2_e3;
+};
+
+//deep anonymous with deep level incomplete
+struct s3 {
+ struct {
+ int s3_e1;
+ struct {
+ struct {
+ struct {
+ struct {
+ struct forward_decl2 s3_g1;
+ };
+ };
+ };
+ };
+//CHECK64: FieldDecl=s3_e3:[[@LINE+1]]:9 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=64]
+ int s3_e3;
+ };
+};
+
+//deep anonymous with first level incomplete
+struct s4a {
+ struct forward_decl2 g1;
+ struct {
+ struct forward_decl2 g2;
+ struct {
+ struct {
+ struct {
+ struct {
+//CHECK64: FieldDecl=s4_e1:[[@LINE+1]]:17 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=-2]
+ int s4_e1;
+ };
+ };
+ };
+ };
+//CHECK64: FieldDecl=s4_e3:[[@LINE+1]]:9 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=-2]
+ int s4_e3;
+ };
+};
+
+//deep anonymous with sub-first-level incomplete
+struct s4b {
+ struct {
+ struct forward_decl2 g1;
+ struct {
+ struct {
+ struct {
+ struct {
+//CHECK64: FieldDecl=s4b_e1:[[@LINE+1]]:17 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=-5]
+ int s4b_e1;
+ };
+ };
+ };
+ };
+//CHECK64: FieldDecl=s4b_e3:[[@LINE+1]]:9 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=-5]
+ int s4b_e3;
+ };
+};
+
+// CHECK64: StructDecl=As:[[@LINE+1]]:8 [type=Incomplete::As] [typekind=Record]
+struct As;
+
+// undefined class. Should not crash
+// CHECK64: ClassDecl=A:[[@LINE+1]]:7 [type=Incomplete::A] [typekind=Record]
+class A;
+// CHECK64: ClassDecl=B:[[@LINE+1]]:7 (Definition) [type=Incomplete::B] [typekind=Record] [sizeof=16] [alignof=8]
+class B {
+// CHECK64: FieldDecl=a1:[[@LINE+2]]:6 (Definition) [type=Incomplete::A *] [typekind=Pointer] [sizeof=8] [alignof=8] [offsetof=0]
+// CHECK32: FieldDecl=a1:[[@LINE+1]]:6 (Definition) [type=Incomplete::A *] [typekind=Pointer] [sizeof=4] [alignof=4] [offsetof=0]
+ A* a1;
+// CHECK64: FieldDecl=a2:[[@LINE+2]]:6 (Definition) [type=Incomplete::A &] [typekind=LValueReference] [sizeof=-2] [alignof=-2] [offsetof=64]
+// CHECK32: FieldDecl=a2:[[@LINE+1]]:6 (Definition) [type=Incomplete::A &] [typekind=LValueReference] [sizeof=-2] [alignof=-2] [offsetof=32]
+ A& a2;
+};
+
+}
+
+namespace Sizes {
+
+// CHECK64: StructDecl=A:[[@LINE+2]]:8 (Definition) [type=Sizes::A] [typekind=Record] [sizeof=8] [alignof=4]
+// CHECK32: StructDecl=A:[[@LINE+1]]:8 (Definition) [type=Sizes::A] [typekind=Record] [sizeof=8] [alignof=4]
+struct A {
+ int a;
+ char b;
+};
+
+// CHECK64: StructDecl=B:[[@LINE+2]]:8 (Definition) [type=Sizes::B] [typekind=Record] [sizeof=12] [alignof=4]
+// CHECK32: StructDecl=B:[[@LINE+1]]:8 (Definition) [type=Sizes::B] [typekind=Record] [sizeof=12] [alignof=4]
+struct B : A {
+ char c;
+};
+
+// CHECK64: StructDecl=C:[[@LINE+2]]:8 (Definition) [type=Sizes::C] [typekind=Record] [sizeof=8] [alignof=4]
+// CHECK32: StructDecl=C:[[@LINE+1]]:8 (Definition) [type=Sizes::C] [typekind=Record] [sizeof=8] [alignof=4]
+struct C {
+// Make fields private so C won't be a POD type.
+private:
+ int a;
+ char b;
+};
+
+// CHECK64: StructDecl=D:[[@LINE+2]]:8 (Definition) [type=Sizes::D] [typekind=Record] [sizeof=8] [alignof=4]
+// CHECK32: StructDecl=D:[[@LINE+1]]:8 (Definition) [type=Sizes::D] [typekind=Record] [sizeof=8] [alignof=4]
+struct D : C {
+ char c;
+};
+
+// CHECK64: StructDecl=E:[[@LINE+2]]:32 (Definition) [type=Sizes::E] [typekind=Record] [sizeof=5] [alignof=1]
+// CHECK32: StructDecl=E:[[@LINE+1]]:32 (Definition) [type=Sizes::E] [typekind=Record] [sizeof=5] [alignof=1]
+struct __attribute__((packed)) E {
+ char b;
+ int a;
+};
+
+// CHECK64: StructDecl=F:[[@LINE+2]]:32 (Definition) [type=Sizes::F] [typekind=Record] [sizeof=6] [alignof=1]
+// CHECK32: StructDecl=F:[[@LINE+1]]:32 (Definition) [type=Sizes::F] [typekind=Record] [sizeof=6] [alignof=1]
+struct __attribute__((packed)) F : E {
+ char d;
+};
+
+struct G { G(); };
+// CHECK64: StructDecl=H:[[@LINE+2]]:8 (Definition) [type=Sizes::H] [typekind=Record] [sizeof=1] [alignof=1]
+// CHECK32: StructDecl=H:[[@LINE+1]]:8 (Definition) [type=Sizes::H] [typekind=Record] [sizeof=1] [alignof=1]
+struct H : G { };
+
+// CHECK64: StructDecl=I:[[@LINE+2]]:8 (Definition) [type=Sizes::I] [typekind=Record] [sizeof=5] [alignof=1]
+// CHECK32: StructDecl=I:[[@LINE+1]]:8 (Definition) [type=Sizes::I] [typekind=Record] [sizeof=5] [alignof=1]
+struct I {
+ char b;
+ int a;
+} __attribute__((packed));
+
+}
+
+namespace Test1 {
+
+// Test complex class hierarchy
+struct A { };
+struct B : A { virtual void b(); };
+class C : virtual A { int c; };
+struct D : virtual B { };
+struct E : C, virtual D { };
+class F : virtual E { };
+// CHECK64: StructDecl=G:[[@LINE+2]]:8 (Definition) [type=Test1::G] [typekind=Record] [sizeof=24] [alignof=8]
+// CHECK32: StructDecl=G:[[@LINE+1]]:8 (Definition) [type=Test1::G] [typekind=Record] [sizeof=16] [alignof=4]
+struct G : virtual E, F { };
+
+}
+
+namespace Test2 {
+
+// Test that this somewhat complex class structure is laid out correctly.
+struct A { };
+struct B : A { virtual void b(); };
+struct C : virtual B { };
+struct D : virtual A { };
+struct E : virtual B, D { };
+struct F : E, virtual C { };
+struct G : virtual F, A { };
+// CHECK64: StructDecl=H:[[@LINE+2]]:8 (Definition) [type=Test2::H] [typekind=Record] [sizeof=24] [alignof=8]
+// CHECK32: StructDecl=H:[[@LINE+1]]:8 (Definition) [type=Test2::H] [typekind=Record] [sizeof=12] [alignof=4]
+struct H { G g; };
+
+}
+
+namespace Test3 {
+// CHECK64: ClassDecl=B:[[@LINE+2]]:7 (Definition) [type=Test3::B] [typekind=Record] [sizeof=16] [alignof=8]
+// CHECK32: ClassDecl=B:[[@LINE+1]]:7 (Definition) [type=Test3::B] [typekind=Record] [sizeof=8] [alignof=4]
+class B {
+public:
+ virtual void b(){}
+// CHECK64: FieldDecl=b_field:[[@LINE+2]]:8 (Definition) [type=long] [typekind=Long] [sizeof=8] [alignof=8] [offsetof=64]
+// CHECK32: FieldDecl=b_field:[[@LINE+1]]:8 (Definition) [type=long] [typekind=Long] [sizeof=4] [alignof=4] [offsetof=32]
+ long b_field;
+protected:
+private:
+};
+
+// CHECK32: ClassDecl=A:[[@LINE+1]]:7 (Definition) [type=Test3::A] [typekind=Record] [sizeof=16] [alignof=4]
+class A : public B {
+public:
+// CHECK64: FieldDecl=a_field:[[@LINE+2]]:7 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=128]
+// CHECK32: FieldDecl=a_field:[[@LINE+1]]:7 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=64]
+ int a_field;
+ virtual void a(){}
+// CHECK64: FieldDecl=one:[[@LINE+2]]:8 (Definition) [type=char] [typekind=Char_S] [sizeof=1] [alignof=1] [offsetof=160]
+// CHECK32: FieldDecl=one:[[@LINE+1]]:8 (Definition) [type=char] [typekind=Char_S] [sizeof=1] [alignof=1] [offsetof=96]
+ char one;
+protected:
+private:
+};
+
+// CHECK64: ClassDecl=D:[[@LINE+2]]:7 (Definition) [type=Test3::D] [typekind=Record] [sizeof=16] [alignof=8]
+// CHECK32: ClassDecl=D:[[@LINE+1]]:7 (Definition) [type=Test3::D] [typekind=Record] [sizeof=12] [alignof=4]
+class D {
+public:
+ virtual void b(){}
+// CHECK64: FieldDecl=a:[[@LINE+2]]:10 (Definition) [type=double] [typekind=Double] [sizeof=8] [alignof=8] [offsetof=64]
+// CHECK32: FieldDecl=a:[[@LINE+1]]:10 (Definition) [type=double] [typekind=Double] [sizeof=8] [alignof=4] [offsetof=32]
+ double a;
+};
+
+// CHECK64: ClassDecl=C:[[@LINE+2]]:7 (Definition) [type=Test3::C] [typekind=Record] [sizeof=88] [alignof=8]
+// CHECK32: ClassDecl=C:[[@LINE+1]]:7 (Definition) [type=Test3::C] [typekind=Record] [sizeof=60] [alignof=4]
+class C : public virtual A,
+ public D, public B {
+public:
+ double c1_field;
+ int c2_field;
+ double c3_field;
+ int c4_field;
+ virtual void foo(){}
+ virtual void bar(){}
+protected:
+private:
+};
+
+struct BaseStruct
+{
+ BaseStruct(){}
+ double v0;
+ float v1;
+// CHECK64: FieldDecl=fg:[[@LINE+2]]:7 (Definition) [type=Test3::C] [typekind=Record] [sizeof=88] [alignof=8] [offsetof=128]
+// CHECK32: FieldDecl=fg:[[@LINE+1]]:7 (Definition) [type=Test3::C] [typekind=Record] [sizeof=60] [alignof=4] [offsetof=96]
+ C fg;
+// CHECK64: FieldDecl=rg:[[@LINE+2]]:8 (Definition) [type=Test3::C &] [typekind=LValueReference] [sizeof=88] [alignof=8] [offsetof=832]
+// CHECK32: FieldDecl=rg:[[@LINE+1]]:8 (Definition) [type=Test3::C &] [typekind=LValueReference] [sizeof=60] [alignof=4] [offsetof=576]
+ C &rg;
+ int x;
+};
+
+}
+
+namespace NotConstantSize {
+
+void f(int i) {
+// CHECK32: VarDecl=v2:[[@LINE+1]]:8 (Definition) [type=int [i]] [typekind=Unexposed] [sizeof=-4] [alignof=4]
+ int v2[i];
+ {
+ struct CS1 {
+// FIXME: should libclang return [offsetof=0] ?
+//CHECK32: FieldDecl=f1:[[@LINE+1]]:9 (Definition) [type=int [i]] [typekind=Unexposed] [sizeof=-4] [alignof=4] [offsetof=0]
+ int f1[i];
+//CHECK32: FieldDecl=f2:[[@LINE+1]]:11 (Definition) [type=float] [typekind=Float] [sizeof=4] [alignof=4] [offsetof=0]
+ float f2;
+ };
+ }
+}
+
+}
+
+namespace CrashTest {
+// test crash scenarios on dependent types.
+template<typename T>
+struct Foo {
+//CHECK32: FieldDecl=t:[[@LINE+1]]:5 (Definition) [type=T] [typekind=Unexposed] [sizeof=-3] [alignof=-3] [offsetof=-1]
+ T t;
+//CHECK32: FieldDecl=a:[[@LINE+1]]:7 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=-1]
+ int a;
+};
+
+Foo<Sizes::A> t1;
+Foo<Sizes::I> t2;
+
+void c;
+
+plopplop;
+
+// CHECK64: StructDecl=lastValid:[[@LINE+2]]:8 (Definition) [type=CrashTest::lastValid] [typekind=Record] [sizeof=1] [alignof=1]
+// CHECK32: StructDecl=lastValid:[[@LINE+1]]:8 (Definition) [type=CrashTest::lastValid] [typekind=Record] [sizeof=1] [alignof=1]
+struct lastValid {
+};
+
+}
diff --git a/test/Index/print-type.c b/test/Index/print-type.c
index 9358772dbf..4805f59f3f 100644
--- a/test/Index/print-type.c
+++ b/test/Index/print-type.c
@@ -11,17 +11,17 @@ int __attribute__((vector_size(16))) x;
typedef int __attribute__((vector_size(16))) int4_t;
// RUN: c-index-test -test-print-type %s | FileCheck %s
-// CHECK: FunctionDecl=f:3:6 (Definition) [type=int *(int *, char *, FooType, int *, void (*)(int))] [typekind=FunctionProto] [canonicaltype=int *(int *, char *, int, int *, void (*)(int))] [canonicaltypekind=FunctionProto] [resulttype=int *] [resulttypekind=Pointer] [args= [int *] [Pointer] [char *] [Pointer] [FooType] [Typedef] [int *] [Pointer] [void (*)(int)] [Pointer]] [isPOD=0]
+// CHECK: FunctionDecl=f:3:6 (Definition) [type=int *(int *, char *, FooType, int *, void (*)(int))] [typekind=FunctionProto] [canonicaltype=int *(int *, char *, int, int *, void (*)(int))] [canonicaltypekind=FunctionProto] [resulttype=int *] [resulttypekind=Pointer] [args= [int *] [Pointer] [char *] [Pointer] [FooType] [Typedef] [int [5]] [ConstantArray] [void (*)(int)] [Pointer]] [isPOD=0]
// CHECK: ParmDecl=p:3:13 (Definition) [type=int *] [typekind=Pointer] [isPOD=1]
// CHECK: ParmDecl=x:3:22 (Definition) [type=char *] [typekind=Pointer] [isPOD=1]
// CHECK: ParmDecl=z:3:33 (Definition) [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
// CHECK: TypeRef=FooType:1:13 [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
-// CHECK: ParmDecl=arr:3:40 (Definition) [type=int *] [typekind=Pointer] [isPOD=1]
+// CHECK: ParmDecl=arr:3:40 (Definition) [type=int [5]] [typekind=ConstantArray] [isPOD=1]
// CHECK: IntegerLiteral= [type=int] [typekind=Int] [isPOD=1]
// CHECK: ParmDecl=fn:3:55 (Definition) [type=void (*)(int)] [typekind=Pointer] [canonicaltype=void (*)(int)] [canonicaltypekind=Pointer] [isPOD=1]
// CHECK: ParmDecl=:3:62 (Definition) [type=int] [typekind=Int] [isPOD=1]
// CHECK: CompoundStmt= [type=] [typekind=Invalid] [isPOD=0]
-// CHECK: CallExpr=fn:3:55 [type=void] [typekind=Void] [isPOD=0]
+// CHECK: CallExpr=fn:3:55 [type=void] [typekind=Void] [args= [int] [Int]] [isPOD=0]
// CHECK: DeclRefExpr=fn:3:55 [type=void (*)(int)] [typekind=Pointer] [canonicaltype=void (*)(int)] [canonicaltypekind=Pointer] [isPOD=1]
// CHECK: UnaryOperator= [type=int] [typekind=Int] [isPOD=1]
// CHECK: DeclRefExpr=p:3:13 [type=int *] [typekind=Pointer] [isPOD=1]
diff --git a/test/Index/print-type.cpp b/test/Index/print-type.cpp
index 876bda9dd2..49a05fbbdb 100644
--- a/test/Index/print-type.cpp
+++ b/test/Index/print-type.cpp
@@ -23,6 +23,12 @@ struct Bar {
}
}
+template <typename T>
+T tbar(int);
+
+template <typename T>
+T tbar(int[5]);
+
// RUN: c-index-test -test-print-type %s | FileCheck %s
// CHECK: Namespace=outer:1:11 (Definition) [type=] [typekind=Invalid] [isPOD=0]
// CHECK: ClassTemplate=Foo:4:8 (Definition) [type=] [typekind=Invalid] [isPOD=0]
@@ -54,3 +60,7 @@ struct Bar {
// CHECK: DeclRefExpr=z:15:35 [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
// CHECK: TypedefDecl=OtherType:19:18 (Definition) [type=OtherType] [typekind=Typedef] [canonicaltype=double] [canonicaltypekind=Double] [isPOD=1]
// CHECK: TypedefDecl=ArrayType:20:15 (Definition) [type=ArrayType] [typekind=Typedef] [canonicaltype=int [5]] [canonicaltypekind=ConstantArray] [isPOD=1]
+// CHECK: FunctionTemplate=tbar:27:3 [type=T (int)] [typekind=FunctionProto] [canonicaltype=type-parameter-0-0 (int)] [canonicaltypekind=FunctionProto] [resulttype=T] [resulttypekind=Unexposed] [isPOD=0]
+// CHECK: TemplateTypeParameter=T:26:20 (Definition) [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0]
+// CHECK: FunctionTemplate=tbar:30:3 [type=T (int *)] [typekind=FunctionProto] [canonicaltype=type-parameter-0-0 (int *)] [canonicaltypekind=FunctionProto] [resulttype=T] [resulttypekind=Unexposed] [isPOD=0]
+// CHECK: ParmDecl=:30:11 (Definition) [type=int [5]] [typekind=ConstantArray] [isPOD=1]
diff --git a/test/Index/print-type.m b/test/Index/print-type.m
index 9325c3fbdd..6f146f8020 100644
--- a/test/Index/print-type.m
+++ b/test/Index/print-type.m
@@ -2,9 +2,14 @@
@property (readonly) id x;
-(int) mymethod;
-(const id) mymethod2:(id)x blah:(Class)y boo:(SEL)z;
+-(bycopy)methodIn:(in int)i andOut:(out short *)j , ...;
@end
// RUN: c-index-test -test-print-type %s | FileCheck %s
-// CHECK: ObjCPropertyDecl=x:2:25 [type=id] [typekind=ObjCId] [canonicaltype=id] [canonicaltypekind=ObjCObjectPointer] [isPOD=1]
+// CHECK: ObjCPropertyDecl=x:2:25 [readonly,] [type=id] [typekind=ObjCId] [canonicaltype=id] [canonicaltypekind=ObjCObjectPointer] [isPOD=1]
// CHECK: ObjCInstanceMethodDecl=mymethod:3:8 [type=] [typekind=Invalid] [resulttype=int] [resulttypekind=Int] [isPOD=0]
// CHECK: ObjCInstanceMethodDecl=mymethod2:blah:boo::4:13 [type=] [typekind=Invalid] [resulttype=const id] [resulttypekind=ObjCId] [args= [id] [ObjCId] [Class] [ObjCClass] [SEL] [ObjCSel]] [isPOD=0]
+// CHECK: ParmDecl=z:4:52 (Definition) [type=SEL] [typekind=ObjCSel] [canonicaltype=SEL *] [canonicaltypekind=Pointer] [isPOD=1]
+// CHECK: ObjCInstanceMethodDecl=methodIn:andOut::5:10 (variadic) [Bycopy,] [type=] [typekind=Invalid] [resulttype=id] [resulttypekind=ObjCId] [args= [int] [Int] [short *] [Pointer]] [isPOD=0]
+// CHECK: ParmDecl=i:5:27 (Definition) [In,] [type=int] [typekind=Int] [isPOD=1]
+// CHECK: ParmDecl=j:5:49 (Definition) [Out,] [type=short *] [typekind=Pointer] [isPOD=1]
diff --git a/test/Index/properties-class-extensions.m b/test/Index/properties-class-extensions.m
index aa992075c6..0fa0ecba6b 100644
--- a/test/Index/properties-class-extensions.m
+++ b/test/Index/properties-class-extensions.m
@@ -60,12 +60,12 @@
// CHECK: properties-class-extensions.m:9:15: ParmDecl=b:9:15 (Definition) Extent=[9:15 - 9:16]
// CHECK: properties-class-extensions.m:10:10: ObjCInstanceMethodDecl=bar:10:10 Extent=[10:1 - 10:14]
// CHECK: properties-class-extensions.m:15:12: ObjCInterfaceDecl=Bar:15:12 Extent=[15:1 - 17:5]
-// CHECK: properties-class-extensions.m:16:25: ObjCPropertyDecl=bar:16:25 Extent=[16:1 - 16:28]
+// CHECK: properties-class-extensions.m:16:25: ObjCPropertyDecl=bar:16:25 [readonly,] Extent=[16:1 - 16:28]
// CHECK: properties-class-extensions.m:16:22: TypeRef=id:0:0 Extent=[16:22 - 16:24]
// CHECK: properties-class-extensions.m:16:25: ObjCInstanceMethodDecl=bar:16:25 Extent=[16:25 - 16:28]
// CHECK: properties-class-extensions.m:18:12: ObjCCategoryDecl=:18:12 Extent=[18:1 - 20:5]
// CHECK: properties-class-extensions.m:18:12: ObjCClassRef=Bar:15:12 Extent=[18:12 - 18:15]
-// CHECK: properties-class-extensions.m:19:26: ObjCPropertyDecl=bar:19:26 Extent=[19:1 - 19:29]
+// CHECK: properties-class-extensions.m:19:26: ObjCPropertyDecl=bar:19:26 [readwrite,] Extent=[19:1 - 19:29]
// CHECK: properties-class-extensions.m:19:23: TypeRef=id:0:0 Extent=[19:23 - 19:25]
// CHECK-NOT: properties-class-extensions.m:16:25: ObjCInstanceMethodDecl=bar:16:25 Extent=[16:25 - 16:28]
// CHECK: properties-class-extensions.m:19:26: ObjCInstanceMethodDecl=setBar::19:26 Extent=[19:26 - 19:29]
@@ -73,7 +73,7 @@
// CHECK: properties-class-extensions.m:24:8: ObjCInterfaceDecl=Rdar8467189_Bar:24:8 Extent=[24:1 - 24:23]
// CHECK: properties-class-extensions.m:24:8: ObjCClassRef=Rdar8467189_Bar:24:8 Extent=[24:8 - 24:23]
// CHECK: properties-class-extensions.m:25:11: ObjCProtocolDecl=Rdar8467189_FooProtocol:25:11 (Definition) Extent=[25:1 - 27:5]
-// CHECK: properties-class-extensions.m:26:39: ObjCPropertyDecl=Rdar8467189_Bar:26:39 Extent=[26:1 - 26:54]
+// CHECK: properties-class-extensions.m:26:39: ObjCPropertyDecl=Rdar8467189_Bar:26:39 [readonly,] Extent=[26:1 - 26:54]
// CHECK: properties-class-extensions.m:26:22: ObjCClassRef=Rdar8467189_Bar:24:8 Extent=[26:22 - 26:37]
// CHECK: properties-class-extensions.m:26:39: ObjCInstanceMethodDecl=Rdar8467189_Bar:26:39 Extent=[26:39 - 26:54]
// CHECK: properties-class-extensions.m:28:12: ObjCInterfaceDecl=Rdar8467189_Foo:28:12 Extent=[28:1 - 29:5]
@@ -82,7 +82,7 @@
// CHECK-NOT: properties-class-extensions.m:31:23: ObjCClassRef=Rdar8467189_Bar:24:8 Extent=[31:23 - 31:38]
// CHECK: properties-class-extensions.m:30:12: ObjCCategoryDecl=:30:12 Extent=[30:1 - 32:5]
// CHECK: properties-class-extensions.m:30:12: ObjCClassRef=Rdar8467189_Foo:28:12 Extent=[30:12 - 30:27]
-// CHECK: properties-class-extensions.m:31:40: ObjCPropertyDecl=Rdar8467189_Bar:31:40 Extent=[31:1 - 31:55]
+// CHECK: properties-class-extensions.m:31:40: ObjCPropertyDecl=Rdar8467189_Bar:31:40 [readwrite,] Extent=[31:1 - 31:55]
// CHECK: properties-class-extensions.m:31:23: ObjCClassRef=Rdar8467189_Bar:24:8 Extent=[31:23 - 31:38]
// CHECK: properties-class-extensions.m:31:40: ObjCInstanceMethodDecl=Rdar8467189_Bar:31:40 [Overrides @26:39] Extent=[31:40 - 31:55]
// CHECK: properties-class-extensions.m:31:40: ObjCInstanceMethodDecl=setRdar8467189_Bar::31:40 Extent=[31:40 - 31:55]
@@ -90,7 +90,7 @@
// CHECK: properties-class-extensions.m:35:12: ObjCInterfaceDecl=Qux:35:12 Extent=[35:1 - 36:5]
// CHECK: properties-class-extensions.m:37:12: ObjCCategoryDecl=:37:12 Extent=[37:1 - 39:5]
// CHECK: properties-class-extensions.m:37:12: ObjCClassRef=Qux:35:12 Extent=[37:12 - 37:15]
-// CHECK: properties-class-extensions.m:38:34: ObjCPropertyDecl=qux:38:34 Extent=[38:1 - 38:37]
+// CHECK: properties-class-extensions.m:38:34: ObjCPropertyDecl=qux:38:34 [assign,readwrite,] Extent=[38:1 - 38:37]
// CHECK: properties-class-extensions.m:38:31: TypeRef=id:0:0 Extent=[38:31 - 38:33]
// CHECK: properties-class-extensions.m:38:34: ObjCInstanceMethodDecl=qux:38:34 Extent=[38:34 - 38:37]
// CHECK: properties-class-extensions.m:38:34: ObjCInstanceMethodDecl=setQux::38:34 Extent=[38:34 - 38:37]
diff --git a/test/Index/subclass-comment.mm b/test/Index/subclass-comment.mm
new file mode 100644
index 0000000000..9682a9f71d
--- /dev/null
+++ b/test/Index/subclass-comment.mm
@@ -0,0 +1,107 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: c-index-test -test-load-source all -comments-xml-schema=%S/../../bindings/xml/comment-xml-schema.rng %s > %t/out
+// RUN: FileCheck %s < %t/out
+// rdar://13647476
+
+//! NSObject is root of all.
+@interface NSObject
+@end
+// CHECK: CommentAST=[
+// CHECK-NEXT: (CXComment_FullComment
+// CHECK-NEXT: (CXComment_Paragraph
+// CHECK-NEXT: (CXComment_Text Text=[ NSObject is root of all.])))]
+
+//! An umbrella class for super classes.
+@interface SuperClass
+@end
+// CHECK: CommentAST=[
+// CHECK-NEXT: (CXComment_FullComment
+// CHECK-NEXT: (CXComment_Paragraph
+// CHECK-NEXT: (CXComment_Text Text=[ An umbrella class for super classes.])))]
+
+@interface SubClass : SuperClass
+@end
+// CHECK: CommentAST=[
+// CHECK-NEXT: (CXComment_FullComment
+// CHECK-NEXT: (CXComment_Paragraph
+// CHECK-NEXT: (CXComment_Text Text=[ An umbrella class for super classes.])))]
+
+@interface SubSubClass : SubClass
+@end
+// CHECK: CommentAST=[
+// CHECK-NEXT: (CXComment_FullComment
+// CHECK-NEXT: (CXComment_Paragraph
+// CHECK-NEXT: (CXComment_Text Text=[ An umbrella class for super classes.])))]
+
+@interface SubSubClass (Private)
+@end
+// CHECK: CommentAST=[
+// CHECK-NEXT: (CXComment_FullComment
+// CHECK-NEXT: (CXComment_Paragraph
+// CHECK-NEXT: (CXComment_Text Text=[ An umbrella class for super classes.])))]
+
+//! Something valuable to the organization.
+class Asset {
+};
+// CHECK: CommentAST=[
+// CHECK-NEXT: (CXComment_FullComment
+// CHECK-NEXT: (CXComment_Paragraph
+// CHECK-NEXT: (CXComment_Text Text=[ Something valuable to the organization.])))]
+
+//! An individual human or human individual.
+class Person : public Asset {
+};
+// CHECK: CommentAST=[
+// CHECK-NEXT: (CXComment_FullComment
+// CHECK-NEXT: (CXComment_Paragraph
+// CHECK-NEXT: (CXComment_Text Text=[ An individual human or human individual.])))]
+
+class Student : public Person {
+};
+// CHECK: CommentAST=[
+// CHECK-NEXT: (CXComment_FullComment
+// CHECK-NEXT: (CXComment_Paragraph
+// CHECK-NEXT: (CXComment_Text Text=[ An individual human or human individual.])))]
+
+//! Every thing is a part
+class Parts {
+};
+// CHECK: CommentAST=[
+// CHECK-NEXT: (CXComment_FullComment
+// CHECK-NEXT: (CXComment_Paragraph
+// CHECK-NEXT: (CXComment_Text Text=[ Every thing is a part])))]
+
+class Window : public virtual Parts {
+};
+// CHECK: CommentAST=[
+// CHECK-NEXT: (CXComment_FullComment
+// CHECK-NEXT: (CXComment_Paragraph
+// CHECK-NEXT: (CXComment_Text Text=[ Every thing is a part])))]
+
+class Door : public virtual Parts {
+};
+// CHECK: CommentAST=[
+// CHECK-NEXT: (CXComment_FullComment
+// CHECK-NEXT: (CXComment_Paragraph
+// CHECK-NEXT: (CXComment_Text Text=[ Every thing is a part])))]
+
+class House : public Window, Door {
+};
+// CHECK: CommentAST=[
+// CHECK-NEXT: (CXComment_FullComment
+// CHECK-NEXT: (CXComment_Paragraph
+// CHECK-NEXT: (CXComment_Text Text=[ Every thing is a part])))]
+
+//! Any Material
+class Material : virtual Parts {
+};
+
+class Building : Window, public Material {
+};
+// CHECK: CommentAST=[
+// CHECK-NEXT: (CXComment_FullComment
+// CHECK-NEXT: (CXComment_Paragraph
+// CHECK-NEXT: (CXComment_Text Text=[ Any Material])))]
+
+
diff --git a/test/Index/targeted-annotation.c b/test/Index/targeted-annotation.c
index cfa1046cc8..022a139d36 100644
--- a/test/Index/targeted-annotation.c
+++ b/test/Index/targeted-annotation.c
@@ -82,10 +82,10 @@ int LocalVar2;
// TOP: Identifier: "TARGETED_TOP_H" [2:9 - 2:23] preprocessing directive=
// TOP: Punctuation: "#" [3:1 - 3:2] preprocessing directive=
// TOP: Identifier: "define" [3:2 - 3:8] preprocessing directive=
-// TOP: Identifier: "TARGETED_TOP_H" [3:9 - 3:23] preprocessing directive=
-// TOP: Punctuation: "#" [5:1 - 5:2] preprocessing directive=
-// TOP: Identifier: "include" [5:2 - 5:9] preprocessing directive=
-// TOP: Literal: ""targeted-nested1.h"" [5:10 - 5:30] preprocessing directive=
+// TOP: Identifier: "TARGETED_TOP_H" [3:9 - 3:23] macro definition=TARGETED_TOP_H
+// TOP: Punctuation: "#" [5:1 - 5:2] inclusion directive=targeted-nested1.h
+// TOP: Identifier: "include" [5:2 - 5:9] inclusion directive=targeted-nested1.h
+// TOP: Literal: ""targeted-nested1.h"" [5:10 - 5:30] inclusion directive=targeted-nested1.h
// TOP: Keyword: "enum" [7:1 - 7:5] EnumDecl=:7:1 (Definition)
// TOP: Punctuation: "{" [7:6 - 7:7] EnumDecl=:7:1 (Definition)
// TOP: Identifier: "VALUE" [8:3 - 8:8] EnumConstantDecl=VALUE:8:3 (Definition)
diff --git a/test/Index/usrs.m b/test/Index/usrs.m
index be0e323c93..dccfb75872 100644
--- a/test/Index/usrs.m
+++ b/test/Index/usrs.m
@@ -86,6 +86,7 @@ int test_multi_declaration(void) {
id var_ext;
}
@property (assign) id pro_ext;
+-(int)methodWithFn:(void (*)(int *p))fn;
@end
// RUN: c-index-test -test-load-source-usrs all -target x86_64-apple-macosx10.7 %s | FileCheck %s
@@ -146,7 +147,7 @@ int test_multi_declaration(void) {
// CHECK: usrs.m c:objc(pl)P1 Extent=[79:1 - 81:5]
// CHECK: usrs.m c:objc(pl)P1(im)method Extent=[80:1 - 80:16]
// CHECK: usrs.m c:objc(cs)CWithExt2 Extent=[83:1 - 84:5]
-// CHECK: usrs.m c:objc(ext)CWithExt2@usrs.m@1111 Extent=[85:1 - 89:5]
+// CHECK: usrs.m c:objc(ext)CWithExt2@usrs.m@1111 Extent=[85:1 - 90:5]
// CHECK: usrs.m c:objc(cs)CWithExt2@var_ext Extent=[86:3 - 86:13]
// CHECK: usrs.m c:objc(cs)CWithExt2(py)pro_ext Extent=[88:1 - 88:30]
// CHECK: usrs.m c:objc(cs)CWithExt2(im)pro_ext Extent=[88:23 - 88:30]
@@ -279,4 +280,6 @@ int test_multi_declaration(void) {
// CHECK-source: usrs.m:76:10: IntegerLiteral= Extent=[76:10 - 76:11]
// CHECK-source: usrs.m:79:11: ObjCProtocolDecl=P1:79:11 (Definition) Extent=[79:1 - 81:5]
// CHECK-source: usrs.m:80:9: ObjCInstanceMethodDecl=method:80:9 Extent=[80:1 - 80:16]
-
+// CHECK-source: usrs.m:89:7: ObjCInstanceMethodDecl=methodWithFn::89:7 Extent=[89:1 - 89:41]
+// CHECK-source: usrs.m:89:38: ParmDecl=fn:89:38 (Definition) Extent=[89:21 - 89:40]
+// CHECK-source: usrs.m:89:35: ParmDecl=p:89:35 (Definition) Extent=[89:30 - 89:36]
diff --git a/test/Lexer/cxx1y_binary_literal.cpp b/test/Lexer/cxx1y_binary_literal.cpp
new file mode 100644
index 0000000000..96dce3dd44
--- /dev/null
+++ b/test/Lexer/cxx1y_binary_literal.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -std=c++1y %s -verify
+
+static_assert(0b1001 == 9, "");
+
+using I = int;
+using I = decltype(0b101001);
+using ULL = unsigned long long;
+using ULL = decltype(0b10101001ULL);
+
+constexpr unsigned long long operator""_foo(unsigned long long n) {
+ return n * 2;
+}
+static_assert(0b10001111_foo == 286, "");
+
+int k1 = 0b1234; // expected-error {{invalid digit '2' in binary constant}}
+// FIXME: If we ever need to support a standard suffix starting with [a-f],
+// we'll need to rework our binary literal parsing rules.
+int k2 = 0b10010f; // expected-error {{invalid digit 'f' in binary constant}}
+int k3 = 0b10010g; // expected-error {{invalid suffix 'g' on integer constant}}
diff --git a/test/Lexer/has_extension_cxx.cpp b/test/Lexer/has_extension_cxx.cpp
index 6ffeebda1f..68b542fb29 100644
--- a/test/Lexer/has_extension_cxx.cpp
+++ b/test/Lexer/has_extension_cxx.cpp
@@ -47,3 +47,9 @@ int no_local_type_template_args();
#endif
// CHECK: has_local_type_template_args
+
+#if __has_extension(cxx_binary_literals)
+int has_binary_literals();
+#endif
+
+// CHECK: has_binary_literals
diff --git a/test/Lexer/has_feature_c1x.c b/test/Lexer/has_feature_c1x.c
index c9a5f56ddf..e26e309c03 100644
--- a/test/Lexer/has_feature_c1x.c
+++ b/test/Lexer/has_feature_c1x.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -E -std=c1x %s -o - | FileCheck --check-prefix=CHECK-1X %s
+// RUN: %clang_cc1 -E -triple x86_64-linux-gnu -std=c1x %s -o - | FileCheck --check-prefix=CHECK-1X %s
// RUN: %clang_cc1 -E %s -o - | FileCheck --check-prefix=CHECK-NO-1X %s
#if __has_feature(c_atomic)
@@ -37,6 +37,15 @@ int no_alignas();
// CHECK-1X: has_alignas
// CHECK-NO-1X: no_alignas
+#if __has_feature(c_thread_local)
+int has_thread_local();
+#else
+int no_thread_local();
+#endif
+
+// CHECK-1X: has_thread_local
+// CHECK-NO-1X: no_thread_local
+
#if __STDC_VERSION__ > 199901L
int is_c1x();
#else
diff --git a/test/Lexer/has_feature_cxx0x.cpp b/test/Lexer/has_feature_cxx0x.cpp
index 8e0222dcec..62a965caac 100644
--- a/test/Lexer/has_feature_cxx0x.cpp
+++ b/test/Lexer/has_feature_cxx0x.cpp
@@ -1,5 +1,7 @@
-// RUN: %clang_cc1 -E -std=c++11 %s -o - | FileCheck --check-prefix=CHECK-0X %s
-// RUN: %clang_cc1 -E %s -o - | FileCheck --check-prefix=CHECK-NO-0X %s
+// RUN: %clang_cc1 -E -triple x86_64-linux-gnu -std=c++11 %s -o - | FileCheck --check-prefix=CHECK-11 %s
+// RUN: %clang_cc1 -E -triple armv7-apple-darwin -std=c++11 %s -o - | FileCheck --check-prefix=CHECK-NO-TLS %s
+// RUN: %clang_cc1 -E -triple x86_64-linux-gnu %s -o - | FileCheck --check-prefix=CHECK-NO-11 %s
+// RUN: %clang_cc1 -E -triple x86_64-linux-gnu -std=c++1y %s -o - | FileCheck --check-prefix=CHECK-1Y %s
#if __has_feature(cxx_atomic)
int has_atomic();
@@ -7,8 +9,9 @@ int has_atomic();
int no_atomic();
#endif
-// CHECK-0X: has_atomic
-// CHECK-NO-0X: no_atomic
+// CHECK-1Y: has_atomic
+// CHECK-11: has_atomic
+// CHECK-NO-11: no_atomic
#if __has_feature(cxx_lambdas)
int has_lambdas();
@@ -16,8 +19,9 @@ int has_lambdas();
int no_lambdas();
#endif
-// CHECK-0X: has_lambdas
-// CHECK-NO-0X: no_lambdas
+// CHECK-1Y: has_lambdas
+// CHECK-11: has_lambdas
+// CHECK-NO-11: no_lambdas
#if __has_feature(cxx_nullptr)
@@ -26,8 +30,9 @@ int has_nullptr();
int no_nullptr();
#endif
-// CHECK-0X: has_nullptr
-// CHECK-NO-0X: no_nullptr
+// CHECK-1Y: has_nullptr
+// CHECK-11: has_nullptr
+// CHECK-NO-11: no_nullptr
#if __has_feature(cxx_decltype)
@@ -36,8 +41,9 @@ int has_decltype();
int no_decltype();
#endif
-// CHECK-0X: has_decltype
-// CHECK-NO-0X: no_decltype
+// CHECK-1Y: has_decltype
+// CHECK-11: has_decltype
+// CHECK-NO-11: no_decltype
#if __has_feature(cxx_decltype_incomplete_return_types)
@@ -46,8 +52,9 @@ int has_decltype_incomplete_return_types();
int no_decltype_incomplete_return_types();
#endif
-// CHECK-0X: has_decltype_incomplete_return_types
-// CHECK-NO-0X: no_decltype_incomplete_return_types
+// CHECK-1Y: has_decltype_incomplete_return_types
+// CHECK-11: has_decltype_incomplete_return_types
+// CHECK-NO-11: no_decltype_incomplete_return_types
#if __has_feature(cxx_auto_type)
@@ -56,8 +63,9 @@ int has_auto_type();
int no_auto_type();
#endif
-// CHECK-0X: has_auto_type
-// CHECK-NO-0X: no_auto_type
+// CHECK-1Y: has_auto_type
+// CHECK-11: has_auto_type
+// CHECK-NO-11: no_auto_type
#if __has_feature(cxx_trailing_return)
@@ -66,8 +74,9 @@ int has_trailing_return();
int no_trailing_return();
#endif
-// CHECK-0X: has_trailing_return
-// CHECK-NO-0X: no_trailing_return
+// CHECK-1Y: has_trailing_return
+// CHECK-11: has_trailing_return
+// CHECK-NO-11: no_trailing_return
#if __has_feature(cxx_attributes)
@@ -76,8 +85,9 @@ int has_attributes();
int no_attributes();
#endif
-// CHECK-0X: has_attributes
-// CHECK-NO-0X: no_attributes
+// CHECK-1Y: has_attributes
+// CHECK-11: has_attributes
+// CHECK-NO-11: no_attributes
#if __has_feature(cxx_static_assert)
@@ -86,8 +96,9 @@ int has_static_assert();
int no_static_assert();
#endif
-// CHECK-0X: has_static_assert
-// CHECK-NO-0X: no_static_assert
+// CHECK-1Y: has_static_assert
+// CHECK-11: has_static_assert
+// CHECK-NO-11: no_static_assert
#if __has_feature(cxx_deleted_functions)
int has_deleted_functions();
@@ -95,8 +106,9 @@ int has_deleted_functions();
int no_deleted_functions();
#endif
-// CHECK-0X: has_deleted_functions
-// CHECK-NO-0X: no_deleted_functions
+// CHECK-1Y: has_deleted_functions
+// CHECK-11: has_deleted_functions
+// CHECK-NO-11: no_deleted_functions
#if __has_feature(cxx_defaulted_functions)
int has_defaulted_functions();
@@ -104,8 +116,9 @@ int has_defaulted_functions();
int no_defaulted_functions();
#endif
-// CHECK-0X: has_defaulted_functions
-// CHECK-NO-0X: no_defaulted_functions
+// CHECK-1Y: has_defaulted_functions
+// CHECK-11: has_defaulted_functions
+// CHECK-NO-11: no_defaulted_functions
#if __has_feature(cxx_rvalue_references)
int has_rvalue_references();
@@ -113,8 +126,9 @@ int has_rvalue_references();
int no_rvalue_references();
#endif
-// CHECK-0X: has_rvalue_references
-// CHECK-NO-0X: no_rvalue_references
+// CHECK-1Y: has_rvalue_references
+// CHECK-11: has_rvalue_references
+// CHECK-NO-11: no_rvalue_references
#if __has_feature(cxx_variadic_templates)
@@ -123,8 +137,9 @@ int has_variadic_templates();
int no_variadic_templates();
#endif
-// CHECK-0X: has_variadic_templates
-// CHECK-NO-0X: no_variadic_templates
+// CHECK-1Y: has_variadic_templates
+// CHECK-11: has_variadic_templates
+// CHECK-NO-11: no_variadic_templates
#if __has_feature(cxx_inline_namespaces)
@@ -133,8 +148,9 @@ int has_inline_namespaces();
int no_inline_namespaces();
#endif
-// CHECK-0X: has_inline_namespaces
-// CHECK-NO-0X: no_inline_namespaces
+// CHECK-1Y: has_inline_namespaces
+// CHECK-11: has_inline_namespaces
+// CHECK-NO-11: no_inline_namespaces
#if __has_feature(cxx_range_for)
@@ -143,8 +159,9 @@ int has_range_for();
int no_range_for();
#endif
-// CHECK-0X: has_range_for
-// CHECK-NO-0X: no_range_for
+// CHECK-1Y: has_range_for
+// CHECK-11: has_range_for
+// CHECK-NO-11: no_range_for
#if __has_feature(cxx_reference_qualified_functions)
@@ -153,8 +170,9 @@ int has_reference_qualified_functions();
int no_reference_qualified_functions();
#endif
-// CHECK-0X: has_reference_qualified_functions
-// CHECK-NO-0X: no_reference_qualified_functions
+// CHECK-1Y: has_reference_qualified_functions
+// CHECK-11: has_reference_qualified_functions
+// CHECK-NO-11: no_reference_qualified_functions
#if __has_feature(cxx_default_function_template_args)
int has_default_function_template_args();
@@ -162,8 +180,9 @@ int has_default_function_template_args();
int no_default_function_template_args();
#endif
-// CHECK-0X: has_default_function_template_args
-// CHECK-NO-0X: no_default_function_template_args
+// CHECK-1Y: has_default_function_template_args
+// CHECK-11: has_default_function_template_args
+// CHECK-NO-11: no_default_function_template_args
#if __has_feature(cxx_noexcept)
int has_noexcept();
@@ -171,8 +190,9 @@ int has_noexcept();
int no_noexcept();
#endif
-// CHECK-0X: has_noexcept
-// CHECK-NO-0X: no_noexcept
+// CHECK-1Y: has_noexcept
+// CHECK-11: has_noexcept
+// CHECK-NO-11: no_noexcept
#if __has_feature(cxx_override_control)
int has_override_control();
@@ -180,8 +200,9 @@ int has_override_control();
int no_override_control();
#endif
-// CHECK-0X: has_override_control
-// CHECK-NO-0X: no_override_control
+// CHECK-1Y: has_override_control
+// CHECK-11: has_override_control
+// CHECK-NO-11: no_override_control
#if __has_feature(cxx_alias_templates)
int has_alias_templates();
@@ -189,8 +210,9 @@ int has_alias_templates();
int no_alias_templates();
#endif
-// CHECK-0X: has_alias_templates
-// CHECK-NO-0X: no_alias_templates
+// CHECK-1Y: has_alias_templates
+// CHECK-11: has_alias_templates
+// CHECK-NO-11: no_alias_templates
#if __has_feature(cxx_implicit_moves)
int has_implicit_moves();
@@ -198,8 +220,9 @@ int has_implicit_moves();
int no_implicit_moves();
#endif
-// CHECK-0X: has_implicit_moves
-// CHECK-NO-0X: no_implicit_moves
+// CHECK-1Y: has_implicit_moves
+// CHECK-11: has_implicit_moves
+// CHECK-NO-11: no_implicit_moves
#if __has_feature(cxx_alignas)
int has_alignas();
@@ -207,8 +230,9 @@ int has_alignas();
int no_alignas();
#endif
-// CHECK-0X: has_alignas
-// CHECK-NO-0X: no_alignas
+// CHECK-1Y: has_alignas
+// CHECK-11: has_alignas
+// CHECK-NO-11: no_alignas
#if __has_feature(cxx_raw_string_literals)
int has_raw_string_literals();
@@ -216,8 +240,9 @@ int has_raw_string_literals();
int no_raw_string_literals();
#endif
-// CHECK-0X: has_raw_string_literals
-// CHECK-NO-0X: no_raw_string_literals
+// CHECK-1Y: has_raw_string_literals
+// CHECK-11: has_raw_string_literals
+// CHECK-NO-11: no_raw_string_literals
#if __has_feature(cxx_unicode_literals)
int has_unicode_literals();
@@ -225,8 +250,9 @@ int has_unicode_literals();
int no_unicode_literals();
#endif
-// CHECK-0X: has_unicode_literals
-// CHECK-NO-0X: no_unicode_literals
+// CHECK-1Y: has_unicode_literals
+// CHECK-11: has_unicode_literals
+// CHECK-NO-11: no_unicode_literals
#if __has_feature(cxx_constexpr)
int has_constexpr();
@@ -234,8 +260,9 @@ int has_constexpr();
int no_constexpr();
#endif
-// CHECK-0X: has_constexpr
-// CHECK-NO-0X: no_constexpr
+// CHECK-1Y: has_constexpr
+// CHECK-11: has_constexpr
+// CHECK-NO-11: no_constexpr
#if __has_feature(cxx_generalized_initializers)
int has_generalized_initializers();
@@ -243,8 +270,9 @@ int has_generalized_initializers();
int no_generalized_initializers();
#endif
-// CHECK-0X: has_generalized_initializers
-// CHECK-NO-0X: no_generalized_initializers
+// CHECK-1Y: has_generalized_initializers
+// CHECK-11: has_generalized_initializers
+// CHECK-NO-11: no_generalized_initializers
#if __has_feature(cxx_unrestricted_unions)
int has_unrestricted_unions();
@@ -252,8 +280,9 @@ int has_unrestricted_unions();
int no_unrestricted_unions();
#endif
-// CHECK-0X: has_unrestricted_unions
-// CHECK-NO-0X: no_unrestricted_unions
+// CHECK-1Y: has_unrestricted_unions
+// CHECK-11: has_unrestricted_unions
+// CHECK-NO-11: no_unrestricted_unions
#if __has_feature(cxx_user_literals)
int has_user_literals();
@@ -261,8 +290,9 @@ int has_user_literals();
int no_user_literals();
#endif
-// CHECK-0X: has_user_literals
-// CHECK-NO-0X: no_user_literals
+// CHECK-1Y: has_user_literals
+// CHECK-11: has_user_literals
+// CHECK-NO-11: no_user_literals
#if __has_feature(cxx_local_type_template_args)
int has_local_type_template_args();
@@ -270,5 +300,49 @@ int has_local_type_template_args();
int no_local_type_template_args();
#endif
-// CHECK-0X: has_local_type_template_args
-// CHECK-NO-0X: no_local_type_template_args
+// CHECK-1Y: has_local_type_template_args
+// CHECK-11: has_local_type_template_args
+// CHECK-NO-11: no_local_type_template_args
+
+#if __has_feature(cxx_inheriting_constructors)
+int has_inheriting_constructors();
+#else
+int no_inheriting_constructors();
+#endif
+
+// CHECK-1Y: has_inheriting_constructors
+// CHECK-11: has_inheriting_constructors
+// CHECK-NO-11: no_inheriting_constructors
+
+#if __has_feature(cxx_thread_local)
+int has_thread_local();
+#else
+int no_thread_local();
+#endif
+
+// CHECK-1Y: has_thread_local
+// CHECK-11: has_thread_local
+// CHECK-NO-11: no_thread_local
+// CHECK-NO-TLS: no_thread_local
+
+// === C++1y features ===
+
+#if __has_feature(cxx_binary_literals)
+int has_binary_literals();
+#else
+int no_binary_literals();
+#endif
+
+// CHECK-1Y: has_binary_literals
+// CHECK-11: no_binary_literals
+// CHECK-NO-11: no_binary_literals
+
+#if __has_feature(cxx_aggregate_nsdmi)
+int has_aggregate_nsdmi();
+#else
+int no_aggregate_nsdmi();
+#endif
+
+// CHECK-1Y: has_aggregate_nsdmi
+// CHECK-11: no_aggregate_nsdmi
+// CHECK-NO-11: no_aggregate_nsdmi
diff --git a/test/Lexer/pragma-message.c b/test/Lexer/pragma-message.c
index b67886fa33..d0bbe9ea3a 100644
--- a/test/Lexer/pragma-message.c
+++ b/test/Lexer/pragma-message.c
@@ -14,3 +14,19 @@
#pragma message ":O gcc accepts this! " STRING(__LINE__) // expected-warning {{:O gcc accepts this! 14}}
#pragma message(invalid) // expected-error {{expected string literal in pragma message}}
+
+// GCC supports a similar pragma, #pragma GCC warning (which generates a warning
+// message) and #pragma GCC error (which generates an error message).
+
+#pragma GCC warning(":O I'm a message! " STRING(__LINE__)) // expected-warning {{:O I'm a message! 21}}
+#pragma GCC warning ":O gcc accepts this! " STRING(__LINE__) // expected-warning {{:O gcc accepts this! 22}}
+
+#pragma GCC error(":O I'm a message! " STRING(__LINE__)) // expected-error {{:O I'm a message! 24}}
+#pragma GCC error ":O gcc accepts this! " STRING(__LINE__) // expected-error {{:O gcc accepts this! 25}}
+
+#define COMPILE_ERROR(x) _Pragma(STRING2(GCC error(x)))
+COMPILE_ERROR("Compile error at line " STRING(__LINE__) "!"); // expected-error {{Compile error at line 28!}}
+
+#pragma message // expected-error {{pragma message requires parenthesized string}}
+#pragma GCC warning("" // expected-error {{pragma warning requires parenthesized string}}
+#pragma GCC error(1) // expected-error {{expected string literal in pragma error}}
diff --git a/test/Lexer/pragma-message2.c b/test/Lexer/pragma-message2.c
new file mode 100644
index 0000000000..224ccfbbf8
--- /dev/null
+++ b/test/Lexer/pragma-message2.c
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -E -Werror -verify %s 2>&1 | FileCheck %s
+
+#pragma message "\\test" // expected-warning {{\test}}
+// CHECK: #pragma message("\134test")
+
+#pragma message("\\test") // expected-warning {{\test}}
+// CHECK: #pragma message("\134test")
+
+#pragma GCC warning "\"" "te" "st" "\"" // expected-warning {{"test"}}
+// CHECK: #pragma GCC warning "\042test\042"
+
+#pragma GCC warning("\"" "te" "st" "\"") // expected-warning {{"test"}}
+// CHECK: #pragma GCC warning "\042test\042"
+
+#pragma GCC error "" "[ ]" "" // expected-error {{[ ]}}
+// CHECK: #pragma GCC error "[\011]"
+
+#pragma GCC error("" "[ ]" "") // expected-error {{[ ]}}
+// CHECK: #pragma GCC error "[\011]"
diff --git a/test/Misc/ast-dump-decl.c b/test/Misc/ast-dump-decl.c
index c74da29f6d..94335b825c 100644
--- a/test/Misc/ast-dump-decl.c
+++ b/test/Misc/ast-dump-decl.c
@@ -139,7 +139,7 @@ extern int TestVarDeclSC;
// CHECK: VarDecl{{.*}} TestVarDeclSC 'int' extern
__thread int TestVarDeclThread;
-// CHECK: VarDecl{{.*}} TestVarDeclThread 'int' __thread
+// CHECK: VarDecl{{.*}} TestVarDeclThread 'int' tls{{$}}
__module_private__ int TestVarDeclPrivate;
// CHECK: VarDecl{{.*}} TestVarDeclPrivate 'int' __module_private__
diff --git a/test/Misc/ast-dump-decl.cpp b/test/Misc/ast-dump-decl.cpp
index c8f7d2fe6c..31715cd15e 100644
--- a/test/Misc/ast-dump-decl.cpp
+++ b/test/Misc/ast-dump-decl.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -fms-extensions -ast-dump -ast-dump-filter Test %s | FileCheck -check-prefix CHECK -strict-whitespace %s
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -fms-extensions -ast-dump -ast-dump-filter Test %s | FileCheck -check-prefix CHECK -strict-whitespace %s
class testEnumDecl {
enum class TestEnumDeclScoped;
@@ -92,6 +92,9 @@ class TestCXXRecordDeclPack : public T... {
// CHECK-NEXT: public 'T'...
// CHECK-NEXT: CXXRecordDecl{{.*}} class TestCXXRecordDeclPack
+thread_local int TestThreadLocalInt;
+// CHECK: TestThreadLocalInt {{.*}} tls_dynamic
+
__module_private__ class TestCXXRecordDeclPrivate;
// CHECK: CXXRecordDecl{{.*}} class TestCXXRecordDeclPrivate __module_private__
diff --git a/test/Misc/ast-dump-stmt.cpp b/test/Misc/ast-dump-stmt.cpp
new file mode 100644
index 0000000000..cf3e8bf289
--- /dev/null
+++ b/test/Misc/ast-dump-stmt.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -ast-dump -ast-dump-filter Test %s | FileCheck -strict-whitespace %s
+
+namespace n {
+void function() {}
+int Variable;
+}
+using n::function;
+using n::Variable;
+void TestFunction() {
+ void (*f)() = &function;
+// CHECK: DeclRefExpr{{.*}} (UsingShadow{{.*}}function
+ Variable = 4;
+// CHECK: DeclRefExpr{{.*}} (UsingShadow{{.*}}Variable
+}
diff --git a/test/Misc/diag-template-diffing-color.cpp b/test/Misc/diag-template-diffing-color.cpp
index 2c228414b3..c771857f39 100644
--- a/test/Misc/diag-template-diffing-color.cpp
+++ b/test/Misc/diag-template-diffing-color.cpp
@@ -70,3 +70,17 @@ void test19() {
// TREE: vector<
// TREE: [const != const [[CYAN]]volatile[[RESET]]] vector<
// TREE: [...]>>
+
+namespace default_args {
+ template <int x, int y = 1+1, int z = 2>
+ class A {};
+
+ void foo(A<0> &M) {
+ // CHECK: no viable conversion from 'A<[...], (default) [[CYAN]]1 + 1[[RESET]][[BOLD]] aka [[CYAN]]2[[RESET]][[BOLD]], (default) [[CYAN]]2[[RESET]][[BOLD]]>' to 'A<[...], [[CYAN]]0[[RESET]][[BOLD]], [[CYAN]]0[[RESET]][[BOLD]]>'
+ A<0, 0, 0> N = M;
+
+ // CHECK: no viable conversion from 'A<[2 * ...], (default) [[CYAN]]2[[RESET]][[BOLD]]>' to 'A<[2 * ...], [[CYAN]]0[[RESET]][[BOLD]]>'
+ A<0, 2, 0> N2 = M;
+ }
+
+}
diff --git a/test/Misc/diag-template-diffing-cxx98.cpp b/test/Misc/diag-template-diffing-cxx98.cpp
index cd40ccc374..a21e4cf060 100644
--- a/test/Misc/diag-template-diffing-cxx98.cpp
+++ b/test/Misc/diag-template-diffing-cxx98.cpp
@@ -4,4 +4,46 @@ namespace PR14342 {
template<typename T, char a> struct X {};
X<int, 1> x = X<long, 257>();
// CHECK: error: no viable conversion from 'X<long, [...]>' to 'X<int, [...]>'
-} \ No newline at end of file
+}
+
+namespace PR15513 {
+ template <int x, int y = x+1>
+ class A {};
+
+ void foo(A<0> &M) {
+ // CHECK: no viable conversion from 'A<[...], (default) x + 1 aka 1>' to 'A<[...], 0>'
+ A<0, 0> N = M;
+ // CHECK: no viable conversion from 'A<0, [...]>' to 'A<1, [...]>'
+ A<1, 1> O = M;
+ }
+}
+
+namespace default_args {
+ template <int x, int y = 1+1, int z = 2>
+ class A {};
+
+ void foo(A<0> &M) {
+ // CHECK: no viable conversion from 'A<[...], (default) 1 + 1 aka 2, (default) 2>' to 'A<[...], 0, 0>'
+ A<0, 0, 0> N = M;
+
+ // CHECK: no viable conversion from 'A<[2 * ...], (default) 2>' to 'A<[2 * ...], 0>'
+ A<0, 2, 0> N2 = M;
+ }
+
+}
+
+namespace qualifiers {
+ template <class T>
+ void foo(void (func(T*)), T*) {}
+
+ template <class T>
+ class vector{};
+
+ void bar(const vector<int>*) {}
+
+ void test(volatile vector<int>* V) {
+ foo(bar, V);
+ }
+
+ // CHECK: candidate template ignored: deduced conflicting types for parameter 'T' ('const vector<[...]>' vs. 'volatile vector<[...]>')
+}
diff --git a/test/Misc/diag-template-diffing.cpp b/test/Misc/diag-template-diffing.cpp
index 6be705511d..add96efd37 100644
--- a/test/Misc/diag-template-diffing.cpp
+++ b/test/Misc/diag-template-diffing.cpp
@@ -645,41 +645,41 @@ void Play1() {
}
// CHECK-ELIDE-NOTREE: no viable overloaded '='
-// CHECK-ELIDE-NOTREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'Foo1<1>' to 'Foo1<2>' for 1st argument
+// CHECK-ELIDE-NOTREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'Foo1<1>' to 'const Foo1<2>' for 1st argument
// CHECK-ELIDE-NOTREE: candidate function (the implicit move assignment operator) not viable: no known conversion from 'Foo1<1>' to 'Foo1<2>' for 1st argument
// CHECK-ELIDE-NOTREE: no viable overloaded '='
-// CHECK-ELIDE-NOTREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'Foo1<2>' to 'Foo1<1>' for 1st argument
+// CHECK-ELIDE-NOTREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'Foo1<2>' to 'const Foo1<1>' for 1st argument
// CHECK-ELIDE-NOTREE: candidate function (the implicit move assignment operator) not viable: no known conversion from 'Foo1<2>' to 'Foo1<1>' for 1st argument
// CHECK-NOELIDE-NOTREE: no viable overloaded '='
-// CHECK-NOELIDE-NOTREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'Foo1<1>' to 'Foo1<2>' for 1st argument
+// CHECK-NOELIDE-NOTREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'Foo1<1>' to 'const Foo1<2>' for 1st argument
// CHECK-NOELIDE-NOTREE: candidate function (the implicit move assignment operator) not viable: no known conversion from 'Foo1<1>' to 'Foo1<2>' for 1st argument
// CHECK-NOELIDE-NOTREE: no viable overloaded '='
-// CHECK-NOELIDE-NOTREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'Foo1<2>' to 'Foo1<1>' for 1st argument
+// CHECK-NOELIDE-NOTREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'Foo1<2>' to 'const Foo1<1>' for 1st argument
// CHECK-NOELIDE-NOTREE: candidate function (the implicit move assignment operator) not viable: no known conversion from 'Foo1<2>' to 'Foo1<1>' for 1st argument
// CHECK-ELIDE-TREE: no viable overloaded '='
// CHECK-ELIDE-TREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from argument type to parameter type for 1st argument
-// CHECK-ELIDE-TREE: Foo1<
+// CHECK-ELIDE-TREE: [(no qualifiers) != const] Foo1<
// CHECK-ELIDE-TREE: [1 != 2]>
// CHECK-ELIDE-TREE: candidate function (the implicit move assignment operator) not viable: no known conversion from argument type to parameter type for 1st argument
// CHECK-ELIDE-TREE: Foo1<
// CHECK-ELIDE-TREE: [1 != 2]>
// CHECK-ELIDE-TREE: no viable overloaded '='
// CHECK-ELIDE-TREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from argument type to parameter type for 1st argument
-// CHECK-ELIDE-TREE: Foo1<
+// CHECK-ELIDE-TREE: [(no qualifiers) != const] Foo1<
// CHECK-ELIDE-TREE: [2 != 1]>
// CHECK-ELIDE-TREE: candidate function (the implicit move assignment operator) not viable: no known conversion from argument type to parameter type for 1st argument
// CHECK-ELIDE-TREE: Foo1<
// CHECK-ELIDE-TREE: [2 != 1]>
// CHECK-NOELIDE-TREE: no viable overloaded '='
// CHECK-NOELIDE-TREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from argument type to parameter type for 1st argument
-// CHECK-NOELIDE-TREE: Foo1<
+// CHECK-NOELIDE-TREE: [(no qualifiers) != const] Foo1<
// CHECK-NOELIDE-TREE: [1 != 2]>
// CHECK-NOELIDE-TREE: candidate function (the implicit move assignment operator) not viable: no known conversion from argument type to parameter type for 1st argument
// CHECK-NOELIDE-TREE: Foo1<
// CHECK-NOELIDE-TREE: [1 != 2]>
// CHECK-NOELIDE-TREE: no viable overloaded '='
// CHECK-NOELIDE-TREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from argument type to parameter type for 1st argument
-// CHECK-NOELIDE-TREE: Foo1<
+// CHECK-NOELIDE-TREE: [(no qualifiers) != const] Foo1<
// CHECK-NOELIDE-TREE: [2 != 1]>
// CHECK-NOELIDE-TREE: candidate function (the implicit move assignment operator) not viable: no known conversion from argument type to parameter type for 1st argument
// CHECK-NOELIDE-TREE: Foo1<
@@ -694,41 +694,41 @@ void Play2() {
F3 = F2;
}
// CHECK-ELIDE-NOTREE: no viable overloaded '='
-// CHECK-ELIDE-NOTREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'Foo2<1>' to 'Foo2<2>' for 1st argument
+// CHECK-ELIDE-NOTREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'Foo2<1>' to 'const Foo2<2>' for 1st argument
// CHECK-ELIDE-NOTREE: candidate function (the implicit move assignment operator) not viable: no known conversion from 'Foo2<1>' to 'Foo2<2>' for 1st argument
// CHECK-ELIDE-NOTREE: no viable overloaded '='
-// CHECK-ELIDE-NOTREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'Foo2<(default) 2>' to 'Foo2<1>' for 1st argument
+// CHECK-ELIDE-NOTREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'Foo2<(default) 2>' to 'const Foo2<1>' for 1st argument
// CHECK-ELIDE-NOTREE: candidate function (the implicit move assignment operator) not viable: no known conversion from 'Foo2<(default) 2>' to 'Foo2<1>' for 1st argument
// CHECK-NOELIDE-NOTREE: no viable overloaded '='
-// CHECK-NOELIDE-NOTREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'Foo2<1>' to 'Foo2<2>' for 1st argument
+// CHECK-NOELIDE-NOTREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'Foo2<1>' to 'const Foo2<2>' for 1st argument
// CHECK-NOELIDE-NOTREE: candidate function (the implicit move assignment operator) not viable: no known conversion from 'Foo2<1>' to 'Foo2<2>' for 1st argument
// CHECK-NOELIDE-NOTREE: no viable overloaded '='
-// CHECK-NOELIDE-NOTREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'Foo2<(default) 2>' to 'Foo2<1>' for 1st argument
+// CHECK-NOELIDE-NOTREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'Foo2<(default) 2>' to 'const Foo2<1>' for 1st argument
// CHECK-NOELIDE-NOTREE: candidate function (the implicit move assignment operator) not viable: no known conversion from 'Foo2<(default) 2>' to 'Foo2<1>' for 1st argument
// CHECK-ELIDE-TREE: no viable overloaded '='
// CHECK-ELIDE-TREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from argument type to parameter type for 1st argument
-// CHECK-ELIDE-TREE: Foo2<
+// CHECK-ELIDE-TREE: [(no qualifiers) != const] Foo2<
// CHECK-ELIDE-TREE: [1 != 2]>
// CHECK-ELIDE-TREE: candidate function (the implicit move assignment operator) not viable: no known conversion from argument type to parameter type for 1st argument
// CHECK-ELIDE-TREE: Foo2<
// CHECK-ELIDE-TREE: [1 != 2]>
// CHECK-ELIDE-TREE: no viable overloaded '='
// CHECK-ELIDE-TREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from argument type to parameter type for 1st argument
-// CHECK-ELIDE-TREE: Foo2<
+// CHECK-ELIDE-TREE: [(no qualifiers) != const] Foo2<
// CHECK-ELIDE-TREE: [(default) 2 != 1]>
// CHECK-ELIDE-TREE: candidate function (the implicit move assignment operator) not viable: no known conversion from argument type to parameter type for 1st argument
// CHECK-ELIDE-TREE: Foo2<
// CHECK-ELIDE-TREE: [(default) 2 != 1]>
// CHECK-NOELIDE-TREE: no viable overloaded '='
// CHECK-NOELIDE-TREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from argument type to parameter type for 1st argument
-// CHECK-NOELIDE-TREE: Foo2<
+// CHECK-NOELIDE-TREE: [(no qualifiers) != const] Foo2<
// CHECK-NOELIDE-TREE: [1 != 2]>
// CHECK-NOELIDE-TREE: candidate function (the implicit move assignment operator) not viable: no known conversion from argument type to parameter type for 1st argument
// CHECK-NOELIDE-TREE: Foo2<
// CHECK-NOELIDE-TREE: [1 != 2]>
// CHECK-NOELIDE-TREE: no viable overloaded '='
// CHECK-NOELIDE-TREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from argument type to parameter type for 1st argument
-// CHECK-NOELIDE-TREE: Foo2<
+// CHECK-NOELIDE-TREE: [(no qualifiers) != const] Foo2<
// CHECK-NOELIDE-TREE: [(default) 2 != 1]>
// CHECK-NOELIDE-TREE: candidate function (the implicit move assignment operator) not viable: no known conversion from argument type to parameter type for 1st argument
// CHECK-NOELIDE-TREE: Foo2<
@@ -743,20 +743,20 @@ void Play3() {
F3 = F2;
}
// CHECK-ELIDE-NOTREE: no viable overloaded '='
-// CHECK-ELIDE-NOTREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'Foo3<1, (no argument)>' to 'Foo3<2, 1>' for 1st argument
+// CHECK-ELIDE-NOTREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'Foo3<1, (no argument)>' to 'const Foo3<2, 1>' for 1st argument
// CHECK-ELIDE-NOTREE: candidate function (the implicit move assignment operator) not viable: no known conversion from 'Foo3<1, (no argument)>' to 'Foo3<2, 1>' for 1st argument
// CHECK-ELIDE-NOTREE: no viable overloaded '='
-// CHECK-ELIDE-NOTREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'Foo3<2, 1>' to 'Foo3<1, (no argument)>' for 1st argument
+// CHECK-ELIDE-NOTREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'Foo3<2, 1>' to 'const Foo3<1, (no argument)>' for 1st argument
// CHECK-ELIDE-NOTREE: candidate function (the implicit move assignment operator) not viable: no known conversion from 'Foo3<2, 1>' to 'Foo3<1, (no argument)>' for 1st argument
// CHECK-NOELIDE-NOTREE: no viable overloaded '='
-// CHECK-NOELIDE-NOTREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'Foo3<1, (no argument)>' to 'Foo3<2, 1>' for 1st argument
+// CHECK-NOELIDE-NOTREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'Foo3<1, (no argument)>' to 'const Foo3<2, 1>' for 1st argument
// CHECK-NOELIDE-NOTREE: candidate function (the implicit move assignment operator) not viable: no known conversion from 'Foo3<1, (no argument)>' to 'Foo3<2, 1>' for 1st argument
// CHECK-NOELIDE-NOTREE: no viable overloaded '='
-// CHECK-NOELIDE-NOTREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'Foo3<2, 1>' to 'Foo3<1, (no argument)>' for 1st argument
+// CHECK-NOELIDE-NOTREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'Foo3<2, 1>' to 'const Foo3<1, (no argument)>' for 1st argument
// CHECK-NOELIDE-NOTREE: candidate function (the implicit move assignment operator) not viable: no known conversion from 'Foo3<2, 1>' to 'Foo3<1, (no argument)>' for 1st argument
// CHECK-ELIDE-TREE: no viable overloaded '='
// CHECK-ELIDE-TREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from argument type to parameter type for 1st argument
-// CHECK-ELIDE-TREE: Foo3<
+// CHECK-ELIDE-TREE: [(no qualifiers) != const] Foo3<
// CHECK-ELIDE-TREE: [1 != 2],
// CHECK-ELIDE-TREE: [(no argument) != 1]>
// CHECK-ELIDE-TREE: candidate function (the implicit move assignment operator) not viable: no known conversion from argument type to parameter type for 1st argument
@@ -765,7 +765,7 @@ void Play3() {
// CHECK-ELIDE-TREE: [(no argument) != 1]>
// CHECK-ELIDE-TREE: no viable overloaded '='
// CHECK-ELIDE-TREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from argument type to parameter type for 1st argument
-// CHECK-ELIDE-TREE: Foo3<
+// CHECK-ELIDE-TREE: [(no qualifiers) != const] Foo3<
// CHECK-ELIDE-TREE: [2 != 1],
// CHECK-ELIDE-TREE: [1 != (no argument)]>
// CHECK-ELIDE-TREE: candidate function (the implicit move assignment operator) not viable: no known conversion from argument type to parameter type for 1st argument
@@ -774,7 +774,7 @@ void Play3() {
// CHECK-ELIDE-TREE: [1 != (no argument)]>
// CHECK-NOELIDE-TREE: no viable overloaded '='
// CHECK-NOELIDE-TREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from argument type to parameter type for 1st argument
-// CHECK-NOELIDE-TREE: Foo3<
+// CHECK-NOELIDE-TREE: [(no qualifiers) != const] Foo3<
// CHECK-NOELIDE-TREE: [1 != 2],
// CHECK-NOELIDE-TREE: [(no argument) != 1]>
// CHECK-NOELIDE-TREE: candidate function (the implicit move assignment operator) not viable: no known conversion from argument type to parameter type for 1st argument
@@ -783,7 +783,7 @@ void Play3() {
// CHECK-NOELIDE-TREE: [(no argument) != 1]>
// CHECK-NOELIDE-TREE: no viable overloaded '='
// CHECK-NOELIDE-TREE: candidate function (the implicit copy assignment operator) not viable: no known conversion from argument type to parameter type for 1st argument
-// CHECK-NOELIDE-TREE: Foo3<
+// CHECK-NOELIDE-TREE: [(no qualifiers) != const] Foo3<
// CHECK-NOELIDE-TREE: [2 != 1],
// CHECK-NOELIDE-TREE: [1 != (no argument)]>
// CHECK-NOELIDE-TREE: candidate function (the implicit move assignment operator) not viable: no known conversion from argument type to parameter type for 1st argument
@@ -797,7 +797,7 @@ namespace PR14342 {
X<int, (signed char)-1> x = X<long, -1>();
X<int, 3UL> y = X<int, 2>();
// CHECK-ELIDE-NOTREE: error: no viable conversion from 'X<long, [...]>' to 'X<int, [...]>'
- // CHECK-ELIDE-NOTREE: error: no viable conversion from 'X<[...], 2>' to 'X<[...], 3UL>'
+ // CHECK-ELIDE-NOTREE: error: no viable conversion from 'X<[...], 2>' to 'X<[...], 3>'
}
namespace PR14489 {
@@ -903,6 +903,105 @@ namespace ValueDecl {
}
}
+namespace DependentDefault {
+ template <typename> struct Trait {
+ enum { V = 40 };
+ typedef int Ty;
+ static int I;
+ };
+ int other;
+
+ template <typename T, int = Trait<T>::V > struct A {};
+ template <typename T, typename = Trait<T>::Ty > struct B {};
+ template <typename T, int& = Trait<T>::I > struct C {};
+
+ void test() {
+
+ A<int> a1;
+ A<char> a2;
+ A<int, 10> a3;
+ a1 = a2;
+ // CHECK-ELIDE-NOTREE: no viable overloaded '='
+ // CHECK-ELIDE-NOTREE: no known conversion from 'A<char, [...]>' to 'A<int, [...]>'
+ a3 = a1;
+ // CHECK-ELIDE-NOTREE: no viable overloaded '='
+ // CHECK-ELIDE-NOTREE: no known conversion from 'A<[...], (default) 40>' to 'A<[...], 10>'
+ a2 = a3;
+ // CHECK-ELIDE-NOTREE: no viable overloaded '='
+ // CHECK-ELIDE-NOTREE: no known conversion from 'A<int, 10>' to 'A<char, 40>'
+
+ B<int> b1;
+ B<char> b2;
+ B<int, char> b3;
+ b1 = b2;
+ // CHECK-ELIDE-NOTREE: no viable overloaded '='
+ // CHECK-ELIDE-NOTREE: no known conversion from 'B<char, (default) Trait<T>::Ty>' to 'B<int, int>'
+ b3 = b1;
+ // CHECK-ELIDE-NOTREE: no viable overloaded '='
+ // CHECK-ELIDE-NOTREE: no known conversion from 'B<[...], (default) Trait<T>::Ty>' to 'B<[...], char>'
+ b2 = b3;
+ // CHECK-ELIDE-NOTREE: no viable overloaded '='
+ // CHECK-ELIDE-NOTREE: no known conversion from 'B<int, char>' to 'B<char, int>'
+
+ C<int> c1;
+ C<char> c2;
+ C<int, other> c3;
+ c1 = c2;
+ // CHECK-ELIDE-NOTREE: no viable overloaded '='
+ // CHECK-ELIDE-NOTREE: no known conversion from 'C<char, (default) I>' to 'C<int, I>'
+ c3 = c1;
+ // CHECK-ELIDE-NOTREE: no viable overloaded '='
+ // CHECK-ELIDE-NOTREE: no known conversion from 'C<[...], (default) I>' to 'C<[...], other>'
+ c2 = c3;
+ // CHECK-ELIDE-NOTREE: no viable overloaded '='
+ // CHECK-ELIDE-NOTREE: no known conversion from 'C<int, other>' to 'C<char, I>'
+ }
+}
+
+namespace VariadicDefault {
+ int i1, i2, i3;
+ template <int = 5, int...> struct A {};
+ template <int& = i1, int& ...> struct B {};
+ template <typename = void, typename...> struct C {};
+
+ void test() {
+ A<> a1;
+ A<5, 6, 7> a2;
+ A<1, 2> a3;
+ a2 = a1;
+ // CHECK-ELIDE-NOTREE: no viable overloaded '='
+ // CHECK-ELIDE-NOTREE: no known conversion from 'A<[...], (no argument), (no argument)>' to 'A<[...], 6, 7>'
+ a3 = a1;
+ // CHECK-ELIDE-NOTREE: no viable overloaded '='
+ // CHECK-ELIDE-NOTREE: no known conversion from 'A<(default) 5, (no argument)>' to 'A<1, 2>'
+
+ B<> b1;
+ B<i1, i2, i3> b2;
+ B<i2, i3> b3;
+ b2 = b1;
+ // CHECK-ELIDE-NOTREE: no viable overloaded '='
+ // CHECK-ELIDE-NOTREE: no known conversion from 'B<[...], (no argument), (no argument)>' to 'B<[...], i2, i3>'
+ b3 = b1;
+ // CHECK-ELIDE-NOTREE: no viable overloaded '='
+ // CHECK-ELIDE-NOTREE: no known conversion from 'B<(default) i1, (no argument)>' to 'B<i2, i3>'
+
+ B<i1, i2, i3> b4 = b1;
+ // CHECK-ELIDE-NOTREE: no viable conversion from 'B<[...], (no argument), (no argument)>' to 'B<[...], i2, i3>'
+ B<i2, i3> b5 = b1;
+ // CHECK-ELIDE-NOTREE: no viable conversion from 'B<(default) i1, (no argument)>' to 'B<i2, i3>'
+
+ C<> c1;
+ C<void, void> c2;
+ C<char, char> c3;
+ c2 = c1;
+ // CHECK-ELIDE-NOTREE: no viable overloaded '='
+ // CHECK-ELIDE-NOTREE: no known conversion from 'C<[...], (no argument)>' to 'C<[...], void>'
+ c3 = c1;
+ // CHECK-ELIDE-NOTREE: no viable overloaded '='
+ // CHECK-ELIDE-NOTREE: no known conversion from 'C<(default) void, (no argument)>' to 'C<char, char>'
+ }
+}
+
// CHECK-ELIDE-NOTREE: {{[0-9]*}} errors generated.
// CHECK-NOELIDE-NOTREE: {{[0-9]*}} errors generated.
// CHECK-ELIDE-TREE: {{[0-9]*}} errors generated.
diff --git a/test/Misc/diagnostic-crash.cpp b/test/Misc/diagnostic-crash.cpp
new file mode 100644
index 0000000000..cbb9ac60dd
--- /dev/null
+++ b/test/Misc/diagnostic-crash.cpp
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -verify -fsyntax-only %s
+// The diagnostics we produce for this code tickled a bug in raw_ostream.
+template <typename _Alloc> class allocator;
+template <class _CharT> struct char_traits;
+template <typename _CharT, typename _Traits = char_traits<_CharT>,
+ typename _Alloc = allocator<_CharT> >
+class basic_string;
+typedef basic_string<wchar_t> wstring;
+class Closure {
+};
+template <class A1> class Callback1 {
+};
+template <class A1, class A2> class Callback2 {
+};
+template <class R, class A2> class ResultCallback1 {
+};
+template <bool del, class R, class T, class P1, class P2, class A1>
+class AAAAAAAResultCallback_2_1 : public ResultCallback1<R, A1> {
+};
+template <bool del, class T, class P1, class P2, class A1>
+class AAAAAAAResultCallback_2_1< del, void, T, P1, P2, A1> :
+ public Callback1<A1> {
+ public:
+ typedef Callback1<A1> base;
+};
+template <class T1, class T2, class R, class P1, class P2, class A1>
+inline typename AAAAAAAResultCallback_2_1<true, R, T1, P1, P2, A1>::base*
+NewCallback(T1* obj, R(T2::* member)(P1, P2, A1), const P1& p1, const P2& p2) {}
+namespace util { class Status {}; }
+class xxxxxxxxxxxxxxxxx {
+ void Bar(wstring* s, util::Status* status,
+ Callback2<util::Status, wstring>* done);
+ void Foo();
+};
+void xxxxxxxxxxxxxxxxx::Foo() {
+ wstring* s = __null;
+ util::Status* status = __null;
+ Closure* cb = NewCallback(this, &xxxxxxxxxxxxxxxxx::Bar, s, status); // expected-error{{cannot initialize}}
+}
diff --git a/test/Misc/warn-in-system-header.c b/test/Misc/warn-in-system-header.c
index 6e0237d0dc..132f083af7 100644
--- a/test/Misc/warn-in-system-header.c
+++ b/test/Misc/warn-in-system-header.c
@@ -1,4 +1,4 @@
// RUN: %clang_cc1 -isystem %S %s -fsyntax-only -verify
#include <warn-in-system-header.h>
-// expected-warning {{the cake is a lie}}
+// expected-warning@warn-in-system-header.h:4 {{the cake is a lie}}
diff --git a/test/Misc/warning-flags.c b/test/Misc/warning-flags.c
index 931de8365b..a6dc8f1352 100644
--- a/test/Misc/warning-flags.c
+++ b/test/Misc/warning-flags.c
@@ -18,7 +18,7 @@ This test serves two purposes:
The list of warnings below should NEVER grow. It should gradually shrink to 0.
-CHECK: Warnings without flags (144):
+CHECK: Warnings without flags (143):
CHECK-NEXT: ext_delete_void_ptr_operand
CHECK-NEXT: ext_enum_friend
CHECK-NEXT: ext_expected_semi_decl_list
@@ -148,7 +148,6 @@ CHECK-NEXT: warn_related_result_type_compatibility_class
CHECK-NEXT: warn_related_result_type_compatibility_protocol
CHECK-NEXT: warn_second_parameter_of_va_start_not_last_named_argument
CHECK-NEXT: warn_second_parameter_to_va_arg_never_compatible
-CHECK-NEXT: warn_standalone_specifier
CHECK-NEXT: warn_static_inline_explicit_inst_ignored
CHECK-NEXT: warn_static_non_static
CHECK-NEXT: warn_template_export_unsupported
diff --git a/test/Modules/Inputs/Conflicts/conflict_a.h b/test/Modules/Inputs/Conflicts/conflict_a.h
new file mode 100644
index 0000000000..c16b5f5ef2
--- /dev/null
+++ b/test/Modules/Inputs/Conflicts/conflict_a.h
@@ -0,0 +1 @@
+int conflict_a;
diff --git a/test/Modules/Inputs/Conflicts/conflict_b.h b/test/Modules/Inputs/Conflicts/conflict_b.h
new file mode 100644
index 0000000000..4baf16f88e
--- /dev/null
+++ b/test/Modules/Inputs/Conflicts/conflict_b.h
@@ -0,0 +1 @@
+int conflict_b;
diff --git a/test/Modules/Inputs/Conflicts/module.map b/test/Modules/Inputs/Conflicts/module.map
new file mode 100644
index 0000000000..e6aafaccec
--- /dev/null
+++ b/test/Modules/Inputs/Conflicts/module.map
@@ -0,0 +1,10 @@
+module Conflicts {
+ explicit module A {
+ header "conflict_a.h"
+ conflict B, "we just don't like B"
+ }
+
+ module B {
+ header "conflict_b.h"
+ }
+}
diff --git a/test/Modules/Inputs/Modified/B.h b/test/Modules/Inputs/Modified/B.h
index d1c8bb5e8e..52526b7f3a 100644
--- a/test/Modules/Inputs/Modified/B.h
+++ b/test/Modules/Inputs/Modified/B.h
@@ -1,2 +1,3 @@
-#include "A.h"
+@import ModA;
+
int getB();
diff --git a/test/Modules/Inputs/Modified/module.map b/test/Modules/Inputs/Modified/module.map
index d9aed01430..27b0d7062c 100644
--- a/test/Modules/Inputs/Modified/module.map
+++ b/test/Modules/Inputs/Modified/module.map
@@ -1,2 +1,5 @@
-module A { header "A.h" }
-module B { header "B.h" }
+module ModA { header "A.h" }
+module ModB {
+ header "B.h"
+ export *
+}
diff --git a/test/Modules/Inputs/ModuleDiags/has_errors.h b/test/Modules/Inputs/ModuleDiags/has_errors.h
new file mode 100644
index 0000000000..2c0929a6f5
--- /dev/null
+++ b/test/Modules/Inputs/ModuleDiags/has_errors.h
@@ -0,0 +1,2 @@
+static void foo(void) { }
+static void foo(void) { }
diff --git a/test/Modules/Inputs/ModuleDiags/has_warnings.h b/test/Modules/Inputs/ModuleDiags/has_warnings.h
new file mode 100644
index 0000000000..87112be695
--- /dev/null
+++ b/test/Modules/Inputs/ModuleDiags/has_warnings.h
@@ -0,0 +1,3 @@
+
+int int_val;
+float *float_ptr = &int_val;
diff --git a/test/Modules/Inputs/ModuleDiags/module.map b/test/Modules/Inputs/ModuleDiags/module.map
new file mode 100644
index 0000000000..09b25088e6
--- /dev/null
+++ b/test/Modules/Inputs/ModuleDiags/module.map
@@ -0,0 +1,7 @@
+module HasWarnings {
+ header "has_warnings.h"
+}
+
+module HasErrors {
+ header "has_errors.h"
+}
diff --git a/test/Modules/Inputs/StdDef/module.map b/test/Modules/Inputs/StdDef/module.map
new file mode 100644
index 0000000000..69c69eac35
--- /dev/null
+++ b/test/Modules/Inputs/StdDef/module.map
@@ -0,0 +1,11 @@
+module StdDef {
+ module SizeT {
+ header "size_t.h"
+ export *
+ }
+
+ module Other {
+ header "other.h"
+ export *
+ }
+}
diff --git a/test/Modules/Inputs/StdDef/other.h b/test/Modules/Inputs/StdDef/other.h
new file mode 100644
index 0000000000..f29f6366cc
--- /dev/null
+++ b/test/Modules/Inputs/StdDef/other.h
@@ -0,0 +1,2 @@
+#include <stddef.h>
+
diff --git a/test/Modules/Inputs/StdDef/size_t.h b/test/Modules/Inputs/StdDef/size_t.h
new file mode 100644
index 0000000000..9ac61c5e0d
--- /dev/null
+++ b/test/Modules/Inputs/StdDef/size_t.h
@@ -0,0 +1,4 @@
+#ifndef _SIZE_T
+#define _SIZE_T
+typedef __SIZE_TYPE__ size_t;
+#endif
diff --git a/test/Modules/Inputs/System/usr/include/dbl_max.h b/test/Modules/Inputs/System/usr/include/dbl_max.h
new file mode 100644
index 0000000000..9a020d1bf5
--- /dev/null
+++ b/test/Modules/Inputs/System/usr/include/dbl_max.h
@@ -0,0 +1 @@
+#define DBL_MAX __DBL_MAX__
diff --git a/test/Modules/Inputs/System/usr/include/module.map b/test/Modules/Inputs/System/usr/include/module.map
index 884b59c80c..9b2f3af2ba 100644
--- a/test/Modules/Inputs/System/usr/include/module.map
+++ b/test/Modules/Inputs/System/usr/include/module.map
@@ -19,3 +19,14 @@ module cstd [system] {
header "stdint.h"
}
}
+
+module other_constants {
+ explicit module dbl_max {
+ header "dbl_max.h"
+ }
+}
+
+module uses_other_constants {
+ header "uses_other_constants.h"
+ export *
+}
diff --git a/test/Modules/Inputs/System/usr/include/uses_other_constants.h b/test/Modules/Inputs/System/usr/include/uses_other_constants.h
new file mode 100644
index 0000000000..f6d4cca9f8
--- /dev/null
+++ b/test/Modules/Inputs/System/usr/include/uses_other_constants.h
@@ -0,0 +1,3 @@
+@import other_constants;
+#include <float.h>
+
diff --git a/test/Modules/Inputs/builtin.h b/test/Modules/Inputs/builtin.h
new file mode 100644
index 0000000000..7be90177d1
--- /dev/null
+++ b/test/Modules/Inputs/builtin.h
@@ -0,0 +1,3 @@
+int i;
+int *p = &i;
+
diff --git a/test/Modules/Inputs/builtin_sub.h b/test/Modules/Inputs/builtin_sub.h
new file mode 100644
index 0000000000..79e3c03325
--- /dev/null
+++ b/test/Modules/Inputs/builtin_sub.h
@@ -0,0 +1,4 @@
+int getBos1(void) {
+ return __builtin_object_size(p, 0);
+}
+
diff --git a/test/Modules/Inputs/config.h b/test/Modules/Inputs/config.h
new file mode 100644
index 0000000000..f2dfda64c3
--- /dev/null
+++ b/test/Modules/Inputs/config.h
@@ -0,0 +1,7 @@
+#ifdef WANT_FOO
+int* foo();
+#endif
+
+#ifdef WANT_BAR
+char *bar();
+#endif
diff --git a/test/Modules/Inputs/diag_pragma.h b/test/Modules/Inputs/diag_pragma.h
new file mode 100644
index 0000000000..a8f958994c
--- /dev/null
+++ b/test/Modules/Inputs/diag_pragma.h
@@ -0,0 +1,3 @@
+#define DIAG_PRAGMA_MACRO 1
+
+#pragma clang diagnostic ignored "-Wparentheses"
diff --git a/test/Modules/Inputs/linkage-merge-bar.h b/test/Modules/Inputs/linkage-merge-bar.h
new file mode 100644
index 0000000000..cc528f7752
--- /dev/null
+++ b/test/Modules/Inputs/linkage-merge-bar.h
@@ -0,0 +1,3 @@
+#include <linkage-merge-foo.h>
+
+using ::g;
diff --git a/test/Modules/Inputs/linkage-merge-foo.h b/test/Modules/Inputs/linkage-merge-foo.h
new file mode 100644
index 0000000000..9cb62d2c0c
--- /dev/null
+++ b/test/Modules/Inputs/linkage-merge-foo.h
@@ -0,0 +1,2 @@
+int f();
+static int g(int);
diff --git a/test/Modules/Inputs/macros_left.h b/test/Modules/Inputs/macros_left.h
index a8aac75a2f..076b0464e6 100644
--- a/test/Modules/Inputs/macros_left.h
+++ b/test/Modules/Inputs/macros_left.h
@@ -12,3 +12,5 @@
#define LEFT_RIGHT_DIFFERENT3 float
#define LEFT_RIGHT_DIFFERENT float
+
+#define FN_ADD(a,b) (a+b)
diff --git a/test/Modules/Inputs/macros_right.h b/test/Modules/Inputs/macros_right.h
index 445f579cf6..dbbd2c3643 100644
--- a/test/Modules/Inputs/macros_right.h
+++ b/test/Modules/Inputs/macros_right.h
@@ -15,3 +15,5 @@
#undef TOP_RIGHT_REDEF
#define TOP_RIGHT_REDEF float
+
+#define FN_ADD(x, y) (x+y)
diff --git a/test/Modules/Inputs/macros_top.h b/test/Modules/Inputs/macros_top.h
index 9c3f3c071f..dd303ffee4 100644
--- a/test/Modules/Inputs/macros_top.h
+++ b/test/Modules/Inputs/macros_top.h
@@ -8,8 +8,8 @@
-
-
+#define TOP_RIGHT_REDEF float
+// The last definition will be exported from the sub-module.
#define TOP_RIGHT_REDEF int
#define TOP_RIGHT_UNDEF int
diff --git a/test/Modules/Inputs/module.map b/test/Modules/Inputs/module.map
index 53f2fd65d3..d20521f9c7 100644
--- a/test/Modules/Inputs/module.map
+++ b/test/Modules/Inputs/module.map
@@ -183,3 +183,29 @@ module cxx_inline_namespace {
module cxx_linkage_cache {
header "cxx-linkage-cache.h"
}
+
+module config {
+ header "config.h"
+ config_macros [exhaustive] WANT_FOO, WANT_BAR
+}
+
+module diag_pragma {
+ header "diag_pragma.h"
+}
+
+module builtin {
+ header "builtin.h"
+ explicit module sub {
+ header "builtin_sub.h"
+ }
+}
+
+module linkage_merge {
+ explicit module foo {
+ header "linkage-merge-foo.h"
+ }
+ explicit module bar {
+ header "linkage-merge-bar.h"
+ }
+
+}
diff --git a/test/Modules/Inputs/oldname/module.map b/test/Modules/Inputs/oldname/module.map
new file mode 100644
index 0000000000..5812f869b3
--- /dev/null
+++ b/test/Modules/Inputs/oldname/module.map
@@ -0,0 +1,4 @@
+module NewName {
+ header "new_name.h"
+ export *
+}
diff --git a/test/Modules/Inputs/oldname/new_name.h b/test/Modules/Inputs/oldname/new_name.h
new file mode 100644
index 0000000000..8bf2f1c8c3
--- /dev/null
+++ b/test/Modules/Inputs/oldname/new_name.h
@@ -0,0 +1 @@
+int same_api;
diff --git a/test/Modules/auto-module-import.m b/test/Modules/auto-module-import.m
index 4bd3c5279c..7351828182 100644
--- a/test/Modules/auto-module-import.m
+++ b/test/Modules/auto-module-import.m
@@ -1,10 +1,10 @@
-// other file: expected-note{{'no_umbrella_A_private' declared here}}
-
// RUN: rm -rf %t
// RUN: %clang_cc1 -Wauto-import -fmodules-cache-path=%t -fmodules -F %S/Inputs %s -verify
#include <DependsOnModule/DependsOnModule.h> // expected-warning{{treating #include as an import of module 'DependsOnModule'}}
+// expected-note@Inputs/NoUmbrella.framework/PrivateHeaders/A_Private.h:1{{'no_umbrella_A_private' declared here}}
+
#ifdef MODULE_H_MACRO
# error MODULE_H_MACRO should have been hidden
#endif
diff --git a/test/Modules/autolink.m b/test/Modules/autolink.m
index 7f75473cbb..4bf9d592a8 100644
--- a/test/Modules/autolink.m
+++ b/test/Modules/autolink.m
@@ -1,5 +1,6 @@
// RUN: rm -rf %t
-// RUN: %clang_cc1 -emit-llvm -o - -fmodules-cache-path=%t -fmodules -fmodules-autolink -F %S/Inputs -I %S/Inputs %s | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -o - -fmodules-cache-path=%t -fmodules -F %S/Inputs -I %S/Inputs %s | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -fno-autolink -o - -fmodules-cache-path=%t -fmodules -F %S/Inputs -I %S/Inputs %s | FileCheck --check-prefix=CHECK-AUTOLINK-DISABLED %s
@import autolink.sub2;
@@ -38,3 +39,6 @@ int use_no_umbrella() {
// CHECK: ![[DEPENDSONMODULE]] = metadata !{metadata !"-framework", metadata !"DependsOnModule"}
// CHECK: ![[MODULE]] = metadata !{metadata !"-framework", metadata !"Module"}
// CHECK: ![[NOUMBRELLA]] = metadata !{metadata !"-framework", metadata !"NoUmbrella"}
+
+// CHECK-AUTOLINK-DISABLED: !llvm.module.flags
+// CHECK-AUTOLINK-DISABLED-NOT: "Linker Options"
diff --git a/test/Modules/builtins.m b/test/Modules/builtins.m
new file mode 100644
index 0000000000..40b4f9c743
--- /dev/null
+++ b/test/Modules/builtins.m
@@ -0,0 +1,16 @@
+@import builtin;
+
+int foo() {
+ return __builtin_object_size(p, 0);
+}
+
+@import builtin.sub;
+
+int bar() {
+ return __builtin_object_size(p, 0);
+}
+
+
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -I %S/Inputs %s -verify
+// expected-no-diagnostics
diff --git a/test/Modules/compiler_builtins.m b/test/Modules/compiler_builtins.m
index 5ea7d795c7..4b8cb5bdc5 100644
--- a/test/Modules/compiler_builtins.m
+++ b/test/Modules/compiler_builtins.m
@@ -2,7 +2,6 @@
// RUN: %clang -fsyntax-only -fmodules -fmodules-cache-path=%t -D__need_wint_t %s -Xclang -verify
// RUN: %clang -fsyntax-only -std=c99 -fmodules -fmodules-cache-path=%t -D__need_wint_t %s -Xclang -verify
// expected-no-diagnostics
-// XFAIL: win32
#ifdef __SSE__
@import _Builtin_intrinsics.intel.sse;
diff --git a/test/Modules/config_macros.m b/test/Modules/config_macros.m
new file mode 100644
index 0000000000..200744d614
--- /dev/null
+++ b/test/Modules/config_macros.m
@@ -0,0 +1,28 @@
+@import config;
+
+int *test_foo() {
+ return foo();
+}
+
+char *test_bar() {
+ return bar(); // expected-warning{{implicit declaration of function 'bar' is invalid in C99}} \
+ // expected-warning{{incompatible integer to pointer conversion}}
+}
+
+#undef WANT_FOO // expected-note{{macro was #undef'd here}}
+@import config; // expected-warning{{#undef of configuration macro 'WANT_FOO' has no effect on the import of 'config'; pass '-UWANT_FOO' on the command line to configure the module}}
+
+#define WANT_FOO 2 // expected-note{{macro was defined here}}
+@import config; // expected-warning{{definition of configuration macro 'WANT_FOO' has no effect on the import of 'config'; pass '-DWANT_FOO=...' on the command line to configure the module}}
+
+#undef WANT_FOO
+#define WANT_FOO 1
+@import config; // okay
+
+#define WANT_BAR 1 // expected-note{{macro was defined here}}
+@import config; // expected-warning{{definition of configuration macro 'WANT_BAR' has no effect on the import of 'config'; pass '-DWANT_BAR=...' on the command line to configure the module}}
+
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t -DWANT_FOO=1 -emit-module -fmodule-name=config %S/Inputs/module.map
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -DWANT_FOO=1 %s -verify
+
diff --git a/test/Modules/conflicts.m b/test/Modules/conflicts.m
new file mode 100644
index 0000000000..2388e6f1d1
--- /dev/null
+++ b/test/Modules/conflicts.m
@@ -0,0 +1,7 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -Wauto-import -fmodules-cache-path=%t -fmodules -I %S/Inputs/Conflicts %s -verify
+
+@import Conflicts;
+
+@import Conflicts.A; // expected-warning{{module 'Conflicts.A' conflicts with already-imported module 'Conflicts.B': we just don't like B}}
+
diff --git a/test/Modules/cstd.m b/test/Modules/cstd.m
index 6d896a9155..3d1dcf38e3 100644
--- a/test/Modules/cstd.m
+++ b/test/Modules/cstd.m
@@ -1,6 +1,9 @@
// RUN: rm -rf %t
// RUN: %clang -fsyntax-only -isystem %S/Inputs/System/usr/include -fmodules -fmodules-cache-path=%t -D__need_wint_t -Werror=implicit-function-declaration %s
+@import uses_other_constants;
+const double other_value = DBL_MAX;
+
// Supplied by compiler, but referenced from the "/usr/include" module map.
@import cstd.float_constants;
@@ -16,7 +19,7 @@ void test_fprintf(FILE *file) {
// Supplied by compiler, which forwards to the "/usr/include" version.
@import cstd.stdint;
-my_awesome_nonstandard_integer_type value;
+my_awesome_nonstandard_integer_type value2;
// Supplied by the compiler; that version wins.
@import cstd.stdbool;
@@ -25,5 +28,3 @@ my_awesome_nonstandard_integer_type value;
# error "bool was not defined!"
#endif
-
-
diff --git a/test/Modules/cycles.c b/test/Modules/cycles.c
index 4326e76a75..5f83092c95 100644
--- a/test/Modules/cycles.c
+++ b/test/Modules/cycles.c
@@ -6,8 +6,8 @@
// CHECK: While building module 'MutuallyRecursive1' imported from
// CHECK: While building module 'MutuallyRecursive2' imported from
// CHECK: MutuallyRecursive2.h:3:9: fatal error: cyclic dependency in module 'MutuallyRecursive1': MutuallyRecursive1 -> MutuallyRecursive2 -> MutuallyRecursive1
-// CHECK: While building module 'MutuallyRecursive1' imported from
// CHECK: MutuallyRecursive1.h:2:9: fatal error: could not build module 'MutuallyRecursive2'
// CHECK: cycles.c:4:9: fatal error: could not build module 'MutuallyRecursive1'
-// CHECK-NOT: error:
+// CHECK: 3 errors generated
+
diff --git a/test/Modules/decldef.m b/test/Modules/decldef.m
index 7fb8a61386..7ed82b57e9 100644
--- a/test/Modules/decldef.m
+++ b/test/Modules/decldef.m
@@ -1,8 +1,7 @@
// RUN: rm -rf %t
// RUN: %clang_cc1 -fmodules -fobjc-arc -I %S/Inputs -fmodules-cache-path=%t %s -verify
-
-// In other file: expected-note {{previous definition is here}}
+// expected-note@Inputs/def.h:5 {{previous definition is here}}
@class Def;
Def *def;
diff --git a/test/Modules/decldef.mm b/test/Modules/decldef.mm
index 732c2a27e2..593f53b2c6 100644
--- a/test/Modules/decldef.mm
+++ b/test/Modules/decldef.mm
@@ -1,8 +1,7 @@
// RUN: rm -rf %t
// RUN: %clang_cc1 -fmodules -fobjc-arc -I %S/Inputs -fmodules-cache-path=%t %s -verify
-
-// In other file: expected-note {{previous definition is here}}
+// expected-note@Inputs/def.h:5 {{previous definition is here}}
@class Def;
Def *def;
diff --git a/test/Modules/diag-pragma.c b/test/Modules/diag-pragma.c
new file mode 100644
index 0000000000..7ec3400bba
--- /dev/null
+++ b/test/Modules/diag-pragma.c
@@ -0,0 +1,13 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diag_pragma %S/Inputs/module.map
+// RUN: %clang_cc1 -fmodules -x objective-c -verify -fmodules-cache-path=%t %s
+// FIXME: When we have a syntax for modules in C, use that.
+
+@import diag_pragma;
+
+int foo(int x) {
+ if (x = DIAG_PRAGMA_MACRO) // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+ // expected-note {{place parentheses}} expected-note {{use '=='}}
+ return 0;
+ return 1;
+}
diff --git a/test/Modules/diamond-pch.c b/test/Modules/diamond-pch.c
index 079f6afa9c..e7ad02dbe4 100644
--- a/test/Modules/diamond-pch.c
+++ b/test/Modules/diamond-pch.c
@@ -1,14 +1,20 @@
-
-
-
-// in diamond-bottom.h: expected-note{{passing argument to parameter 'x' here}}
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_top %S/Inputs/module.map
+// RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_left %S/Inputs/module.map
+// RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_right %S/Inputs/module.map
+// RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_bottom %S/Inputs/module.map
+// RUN: %clang_cc1 -fmodules -x objective-c -emit-pch -fmodules-cache-path=%t -o %t.pch %S/Inputs/diamond.h
+// RUN: %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t -include-pch %t.pch %s -verify
+// FIXME: When we have a syntax for modules in C, use that.
void test_diamond(int i, float f, double d, char c) {
top(&i);
left(&f);
right(&d);
bottom(&c);
- bottom(&d); // expected-warning{{incompatible pointer types passing 'double *' to parameter of type 'char *'}}
+ bottom(&d);
+ // expected-warning@-1{{incompatible pointer types passing 'double *' to parameter of type 'char *'}}
+ // expected-note@Inputs/diamond_bottom.h:4{{passing argument to parameter 'x' here}}
// Names in multiple places in the diamond.
top_left(&c);
@@ -17,12 +23,3 @@ void test_diamond(int i, float f, double d, char c) {
struct left_and_right lr;
lr.left = 17;
}
-
-// RUN: rm -rf %t
-// RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_top %S/Inputs/module.map
-// RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_left %S/Inputs/module.map
-// RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_right %S/Inputs/module.map
-// RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_bottom %S/Inputs/module.map
-// RUN: %clang_cc1 -fmodules -x objective-c -emit-pch -fmodules-cache-path=%t -o %t.pch %S/Inputs/diamond.h
-// RUN: %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t -include-pch %t.pch %s -verify
-// FIXME: When we have a syntax for modules in C, use that.
diff --git a/test/Modules/diamond.c b/test/Modules/diamond.c
index 0bac1b7596..89d5bc0dda 100644
--- a/test/Modules/diamond.c
+++ b/test/Modules/diamond.c
@@ -1,7 +1,10 @@
-
-
-
-// in diamond-bottom.h: expected-note{{passing argument to parameter 'x' here}}
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_top %S/Inputs/module.map
+// RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_left %S/Inputs/module.map
+// RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_right %S/Inputs/module.map
+// RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_bottom %S/Inputs/module.map
+// RUN: %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t %s -verify
+// FIXME: When we have a syntax for modules in C, use that.
@import diamond_bottom;
@@ -10,7 +13,9 @@ void test_diamond(int i, float f, double d, char c) {
left(&f);
right(&d);
bottom(&c);
- bottom(&d); // expected-warning{{incompatible pointer types passing 'double *' to parameter of type 'char *'}}
+ bottom(&d);
+ // expected-warning@-1{{incompatible pointer types passing 'double *' to parameter of type 'char *'}}
+ // expected-note@Inputs/diamond_bottom.h:4{{passing argument to parameter 'x' here}}
// Names in multiple places in the diamond.
top_left(&c);
@@ -20,10 +25,3 @@ void test_diamond(int i, float f, double d, char c) {
lr.left = 17;
}
-// RUN: rm -rf %t
-// RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_top %S/Inputs/module.map
-// RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_left %S/Inputs/module.map
-// RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_right %S/Inputs/module.map
-// RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_bottom %S/Inputs/module.map
-// RUN: %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t %s -verify
-// FIXME: When we have a syntax for modules in C, use that.
diff --git a/test/Modules/driver.c b/test/Modules/driver.c
index 0a787b996a..08fdaab441 100644
--- a/test/Modules/driver.c
+++ b/test/Modules/driver.c
@@ -1,6 +1,6 @@
// RUN: %clang -fmodules %s -### 2>&1 | FileCheck -check-prefix NO_MODULE_CACHE %s
// RUN: %clang -fmodules -fmodules-cache-path=blarg %s -### 2>&1 | FileCheck -check-prefix WITH_MODULE_CACHE %s
-// CHECK-NO_MODULE_CACHE: {{clang.*"-fmodules-cache-path=.*clang-module-cache"}}
+// CHECK-NO_MODULE_CACHE: {{clang.*"-fmodules-cache-path=.*ModuleCache"}}
// CHECK-WITH_MODULE_CACHE: {{clang.*"-fmodules-cache-path=blarg"}}
diff --git a/test/Modules/linkage-merge.cpp b/test/Modules/linkage-merge.cpp
new file mode 100644
index 0000000000..9cc9ae64bf
--- /dev/null
+++ b/test/Modules/linkage-merge.cpp
@@ -0,0 +1,12 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -verify -fmodules -fmodules-cache-path=%t -I %S/Inputs %s
+
+#include "linkage-merge-bar.h"
+
+static int f(int);
+int f(int);
+
+static void g(int);
+// expected-error@-1 {{declaration conflicts with target of using declaration already in scope}}
+// expected-note@Inputs/linkage-merge-foo.h:2 {{target of using declaration}}
+// expected-note@Inputs/linkage-merge-bar.h:3 {{using declaration}}
diff --git a/test/Modules/linkage-merge.m b/test/Modules/linkage-merge.m
index 16e2205078..e838ca1018 100644
--- a/test/Modules/linkage-merge.m
+++ b/test/Modules/linkage-merge.m
@@ -1,27 +1,26 @@
-// In module: expected-note{{previous declaration}}
-
-
-
-
-// In module: expected-note{{previous definition is here}}
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t -emit-module -fmodule-name=linkage_merge_left %S/Inputs/module.map
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -w %s -verify
// Test redeclarations of functions where the original declaration is
// still hidden.
@import linkage_merge_left; // excludes "sub"
-extern int f0(float); // expected-error{{conflicting types for 'f0'}}
+extern int f0(float);
+// expected-error@-1{{conflicting types for 'f0'}}
+// expected-note@Inputs/linkage-merge-sub.h:1{{previous declaration}}
+
static int f1(float); // okay: considered distinct
static int f2(float); // okay: considered distinct
extern int f3(float); // okay: considered distinct
-extern float v0; // expected-error{{redefinition of 'v0' with a different type: 'float' vs 'int'}}
+extern float v0;
+// expected-error@-1{{redefinition of 'v0' with a different type: 'float' vs 'int'}}
+// expected-note@Inputs/linkage-merge-sub.h:6{{previous definition is here}}
+
static float v1;
static float v2;
extern float v3;
typedef float T0;
-
-// RUN: rm -rf %t
-// RUN: %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t -emit-module -fmodule-name=linkage_merge_left %S/Inputs/module.map
-// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -w %s -verify
diff --git a/test/Modules/lookup.cpp b/test/Modules/lookup.cpp
index 002b6d1556..efd88f47e3 100644
--- a/test/Modules/lookup.cpp
+++ b/test/Modules/lookup.cpp
@@ -5,7 +5,7 @@ import lookup_left_cxx;
#define IMPORT(X) @import X
IMPORT(lookup_right_cxx);
-// in lookup_left.hpp: expected-warning@3 {{weak identifier 'weak_identifier' never declared}}
+// expected-warning@Inputs/lookup_left.hpp:3 {{weak identifier 'weak_identifier' never declared}}
void test(int i, float f) {
// unqualified lookup
diff --git a/test/Modules/lookup.m b/test/Modules/lookup.m
index abe95420d4..54c7491390 100644
--- a/test/Modules/lookup.m
+++ b/test/Modules/lookup.m
@@ -1,19 +1,19 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -emit-module -x objective-c -fmodule-name=lookup_left_objc %S/Inputs/module.map
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -emit-module -x objective-c -fmodule-name=lookup_right_objc %S/Inputs/module.map
+// RUN: %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t -verify %s
+// RUN: %clang_cc1 -fmodules -ast-print -x objective-c -fmodules-cache-path=%t %s | FileCheck -check-prefix=CHECK-PRINT %s
-// lookup_left.h: expected-note{{using}}
-// lookup_right.h: expected-note{{also found}}
@import lookup_left_objc;
@import lookup_right_objc;
void test(id x) {
- [x method]; // expected-warning{{multiple methods named 'method' found}}
+ [x method];
+// expected-warning@-1{{multiple methods named 'method' found}}
+// expected-note@Inputs/lookup_left.h:2{{using}}
+// expected-note@Inputs/lookup_right.h:3{{also found}}
}
-// RUN: rm -rf %t
-// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -emit-module -x objective-c -fmodule-name=lookup_left_objc %S/Inputs/module.map
-// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -emit-module -x objective-c -fmodule-name=lookup_right_objc %S/Inputs/module.map
-// RUN: %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t -verify %s
-// RUN: %clang_cc1 -fmodules -ast-print -x objective-c -fmodules-cache-path=%t %s | FileCheck -check-prefix=CHECK-PRINT %s
-
// CHECK-PRINT: - (int) method;
// CHECK-PRINT: - (double) method
// CHECK-PRINT: void test(id x)
diff --git a/test/Modules/macros.c b/test/Modules/macros.c
index 406e554a7a..433e03324b 100644
--- a/test/Modules/macros.c
+++ b/test/Modules/macros.c
@@ -1,4 +1,3 @@
-// XFAIL: *
// RUN: rm -rf %t
// RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=macros_top %S/Inputs/module.map
// RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=macros_left %S/Inputs/module.map
@@ -9,13 +8,13 @@
// FIXME: When we have a syntax for modules in C, use that.
// These notes come from headers in modules, and are bogus.
-// FIXME: expected-note{{previous definition is here}}
-// expected-note{{other definition of 'LEFT_RIGHT_DIFFERENT'}}
-// expected-note{{expanding this definition of 'TOP_RIGHT_REDEF'}}
-// FIXME: expected-note{{previous definition is here}} \
-// expected-note{{expanding this definition of 'LEFT_RIGHT_DIFFERENT'}}
-
-// expected-note{{other definition of 'TOP_RIGHT_REDEF'}}
+// FIXME: expected-note@Inputs/macros_left.h:11{{previous definition is here}}
+// FIXME: expected-note@Inputs/macros_right.h:12{{previous definition is here}}
+// expected-note@Inputs/macros_right.h:12{{expanding this definition of 'LEFT_RIGHT_DIFFERENT'}}
+// expected-note@Inputs/macros_top.h:13{{other definition of 'TOP_RIGHT_REDEF'}}
+// expected-note@Inputs/macros_right.h:13{{expanding this definition of 'LEFT_RIGHT_DIFFERENT2'}}
+// expected-note@Inputs/macros_left.h:14{{other definition of 'LEFT_RIGHT_DIFFERENT'}}
+// expected-note@Inputs/macros_right.h:17{{expanding this definition of 'TOP_RIGHT_REDEF'}}
@import macros;
@@ -80,8 +79,8 @@ void f() {
# error TOP should be visible
#endif
-#ifdef TOP_LEFT_UNDEF
-# error TOP_LEFT_UNDEF should not be visible
+#ifndef TOP_LEFT_UNDEF
+# error TOP_LEFT_UNDEF should still be defined
#endif
void test1() {
@@ -89,7 +88,8 @@ void test1() {
TOP_RIGHT_REDEF *ip = &i;
}
-#define LEFT_RIGHT_DIFFERENT2 double // FIXME: expected-warning{{'LEFT_RIGHT_DIFFERENT2' macro redefined}}
+#define LEFT_RIGHT_DIFFERENT2 double // FIXME: expected-warning{{'LEFT_RIGHT_DIFFERENT2' macro redefined}} \
+ // expected-note{{other definition of 'LEFT_RIGHT_DIFFERENT2'}}
// Import right module (which also imports top)
@import macros_right;
@@ -112,11 +112,11 @@ void test2() {
int i;
float f;
double d;
- TOP_RIGHT_REDEF *ip = &i; // expected-warning{{ambiguous expansion of macro 'TOP_RIGHT_REDEF'}}
+ TOP_RIGHT_REDEF *fp = &f; // expected-warning{{ambiguous expansion of macro 'TOP_RIGHT_REDEF'}}
- LEFT_RIGHT_IDENTICAL *ip2 = &i;
- LEFT_RIGHT_DIFFERENT *fp = &f; // expected-warning{{ambiguous expansion of macro 'LEFT_RIGHT_DIFFERENT'}}
- LEFT_RIGHT_DIFFERENT2 *dp = &d;
+ LEFT_RIGHT_IDENTICAL *ip = &i;
+ LEFT_RIGHT_DIFFERENT *ip2 = &i; // expected-warning{{ambiguous expansion of macro 'LEFT_RIGHT_DIFFERENT'}}
+ LEFT_RIGHT_DIFFERENT2 *ip3 = &i; // expected-warning{{ambiguous expansion of macro 'LEFT_RIGHT_DIFFERENT2}}
int LEFT_RIGHT_DIFFERENT3;
}
@@ -125,6 +125,7 @@ void test2() {
void test3() {
double d;
LEFT_RIGHT_DIFFERENT *dp = &d; // okay
+ int x = FN_ADD(1,2);
}
#ifndef TOP_RIGHT_UNDEF
@@ -133,6 +134,6 @@ void test3() {
@import macros_right.undef;
-#ifdef TOP_RIGHT_UNDEF
-# error TOP_RIGHT_UNDEF should not be defined
+#ifndef TOP_RIGHT_UNDEF
+# error TOP_RIGHT_UNDEF should still be defined
#endif
diff --git a/test/Modules/method_pool.m b/test/Modules/method_pool.m
index 9a8897b383..6fd74b0885 100644
--- a/test/Modules/method_pool.m
+++ b/test/Modules/method_pool.m
@@ -8,8 +8,8 @@
- (void)method5:(D*)obj;
@end
-// in other file: // expected-note@7{{using}}
-// in other file: expected-note@12{{also found}}
+// expected-note@Inputs/MethodPoolA.h:7{{using}}
+// expected-note@Inputs/MethodPoolB.h:12{{also found}}
void testMethod1(id object) {
[object method1];
@@ -51,8 +51,8 @@ void testMethod3Again(id object) {
void testMethod3AgainAgain(id object) {
[object method3]; // expected-warning{{multiple methods named 'method3' found}}
- // expected-note@2{{using}}
- // expected-note@2{{also found}}
+ // expected-note@Inputs/MethodPoolBSub.h:2{{using}}
+ // expected-note@Inputs/MethodPoolASub.h:2{{also found}}
}
void testMethod4Again(id object) {
diff --git a/test/Modules/modify-module.m b/test/Modules/modify-module.m
index 7433e6f7a2..953c917cdd 100644
--- a/test/Modules/modify-module.m
+++ b/test/Modules/modify-module.m
@@ -6,17 +6,22 @@
// RUN: cp %S/Inputs/Modified/A.h %t/include
// RUN: cp %S/Inputs/Modified/B.h %t/include
// RUN: cp %S/Inputs/Modified/module.map %t/include
-// RUN: %clang_cc1 -fmodules-cache-path=%t/cache -fmodules -I %t/include %s -verify
-// expected-no-diagnostics
+// RUN: %clang_cc1 -fdisable-module-hash -fmodules-cache-path=%t/cache -fmodules -I %t/include %s -verify
// RUN: echo '' >> %t/include/B.h
-// RUN: %clang_cc1 -fmodules-cache-path=%t/cache -fmodules -I %t/include %s -verify
+// RUN: %clang_cc1 -fdisable-module-hash -fmodules-cache-path=%t/cache -fmodules -I %t/include %s -verify
// RUN: echo 'int getA(); int getA2();' > %t/include/A.h
-// RUN: %clang_cc1 -fmodules-cache-path=%t/cache -fmodules -I %t/include %s -verify
+// RUN: %clang_cc1 -fdisable-module-hash -fmodules-cache-path=%t/cache -fmodules -I %t/include %s -verify
+// RUN: rm %t/cache/ModA.pcm
+// RUN: %clang_cc1 -fdisable-module-hash -fmodules-cache-path=%t/cache -fmodules -I %t/include %s -verify
+// RUN: touch %t/cache/ModA.pcm
+// RUN: %clang_cc1 -fdisable-module-hash -fmodules-cache-path=%t/cache -fmodules -I %t/include %s -verify
+
+// expected-no-diagnostics
// FIXME: It is intended to suppress this on win32.
// REQUIRES: ansi-escape-sequences
-@import B;
+@import ModB;
int getValue() { return getA() + getB(); }
diff --git a/test/Modules/module-private.cpp b/test/Modules/module-private.cpp
index d4e73b5396..438dcab984 100644
--- a/test/Modules/module-private.cpp
+++ b/test/Modules/module-private.cpp
@@ -15,7 +15,7 @@ int test_broken() {
HiddenStruct hidden; // \
// expected-error{{must use 'struct' tag to refer to type 'HiddenStruct' in this scope}} \
// expected-error{{definition of 'struct HiddenStruct' must be imported}}
- // expected-note@3 {{previous definition is here}}
+ // expected-note@Inputs/module_private_left.h:3 {{previous definition is here}}
Integer i; // expected-error{{unknown type name 'Integer'}}
diff --git a/test/Modules/module_file_info.m b/test/Modules/module_file_info.m
new file mode 100644
index 0000000000..09319d60fe
--- /dev/null
+++ b/test/Modules/module_file_info.m
@@ -0,0 +1,34 @@
+
+@import DependsOnModule;
+
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -w -fmodules -fdisable-module-hash -fmodules-cache-path=%t -F %S/Inputs -DBLARG -DWIBBLE=WOBBLE %s
+// RUN: %clang_cc1 -module-file-info %t/DependsOnModule.pcm | FileCheck %s
+
+// CHECK: Generated by this Clang:
+
+// CHECK: Language options:
+// CHECK: C99: Yes
+// CHECK: Objective-C 1: Yes
+// CHECK: modules extension to C: Yes
+
+// CHECK: Target options:
+// CHECK: Triple:
+// CHECK: CPU:
+// CHECK: ABI:
+// CHECK: C++ ABI:
+// CHECK: Linker version:
+
+// CHECK: Header search options:
+// CHECK: System root [-isysroot=]: '/'
+// CHECK: Use builtin include directories [-nobuiltininc]: Yes
+// CHECK: Use standard system include directories [-nostdinc]: Yes
+// CHECK: Use standard C++ include directories [-nostdinc++]: Yes
+// CHECK: Use libc++ (rather than libstdc++) [-stdlib=]:
+
+// CHECK: Preprocessor options:
+// CHECK: Uses compiler/target-specific predefines [-undef]: Yes
+// CHECK: Uses detailed preprocessing record (for indexing): No
+// CHECK: Predefined macros:
+// CHECK: -DBLARG
+// CHECK: -DWIBBLE=WOBBLE
diff --git a/test/Modules/namespaces.cpp b/test/Modules/namespaces.cpp
index 0e9dbffcbb..426e0025f9 100644
--- a/test/Modules/namespaces.cpp
+++ b/test/Modules/namespaces.cpp
@@ -73,5 +73,5 @@ void testAnonymousNotMerged() {
N12::consumeFoo(N12::getFoo()); // expected-error{{cannot initialize a parameter of type 'N12::<anonymous>::Foo *' with an rvalue of type 'N12::<anonymous>::Foo *'}}
}
-// namespaces-right.h: expected-note@60 {{passing argument to parameter here}}
-// namespaces-right.h: expected-note@67 {{passing argument to parameter here}}
+// expected-note@Inputs/namespaces-right.h:60 {{passing argument to parameter here}}
+// expected-note@Inputs/namespaces-right.h:67 {{passing argument to parameter here}}
diff --git a/test/Modules/normal-module-map.cpp b/test/Modules/normal-module-map.cpp
index 423e808bca..8155318fb3 100644
--- a/test/Modules/normal-module-map.cpp
+++ b/test/Modules/normal-module-map.cpp
@@ -1,5 +1,3 @@
-// Note: inside the module. expected-note{{'nested_umbrella_a' declared here}}
-
// RUN: rm -rf %t
// RUN: %clang_cc1 -x objective-c -fmodules-cache-path=%t -fmodules -I %S/Inputs/normal-module-map %s -verify
#include "Umbrella/umbrella_sub.h"
@@ -25,7 +23,9 @@ int testNestedUmbrellaA() {
}
int testNestedUmbrellaBFail() {
- return nested_umbrella_b; // expected-error{{use of undeclared identifier 'nested_umbrella_b'; did you mean 'nested_umbrella_a'?}}
+ return nested_umbrella_b;
+ // expected-error@-1{{use of undeclared identifier 'nested_umbrella_b'; did you mean 'nested_umbrella_a'?}}
+ // expected-note@Inputs/normal-module-map/nested_umbrella/a.h:1{{'nested_umbrella_a' declared here}}
}
@import nested_umbrella.b;
diff --git a/test/Modules/objc-categories.m b/test/Modules/objc-categories.m
index d3ebcb7527..81fb28bafb 100644
--- a/test/Modules/objc-categories.m
+++ b/test/Modules/objc-categories.m
@@ -8,11 +8,8 @@
@import category_bottom;
-
-
-
-// in category_left.h: expected-note {{previous definition}}
-// in category_right.h: expected-warning@11 {{duplicate definition of category}}
+// expected-note@Inputs/category_left.h:14 {{previous definition}}
+// expected-warning@Inputs/category_right.h:11 {{duplicate definition of category}}
@interface Foo(Source)
-(void)source;
@@ -75,7 +72,7 @@ void test_hidden_right_errors(Foo *foo) {
[p4 p4_method]; // expected-warning{{instance method '-p4_method' not found (return type defaults to 'id')}}
id p4p = p4.p4_prop; // expected-error{{property 'p4_prop' not found on object of type 'id<P4>'}}
p4p = foo.p4_prop; // expected-error{{property 'p4_prop' not found on object of type 'Foo *'; did you mean 'p3_prop'?}}
- // expected-note@7{{'p3_prop' declared here}}
+ // expected-note@Inputs/category_left_sub.h:7{{'p3_prop' declared here}}
}
@import category_right.sub;
diff --git a/test/Modules/on-demand-build.m b/test/Modules/on-demand-build.m
index 31742f7e03..e958759420 100644
--- a/test/Modules/on-demand-build.m
+++ b/test/Modules/on-demand-build.m
@@ -7,7 +7,7 @@
@interface OtherClass
@end
-// in module: expected-note@17{{class method 'alloc' is assumed to return an instance of its receiver type ('Module *')}}
+// expected-note@Inputs/Module.framework/Headers/Module.h:17{{class method 'alloc' is assumed to return an instance of its receiver type ('Module *')}}
void test_getModuleVersion() {
const char *version = getModuleVersion();
const char *version2 = [Module version];
diff --git a/test/Modules/prune.m b/test/Modules/prune.m
new file mode 100644
index 0000000000..8af7e6c395
--- /dev/null
+++ b/test/Modules/prune.m
@@ -0,0 +1,46 @@
+// Test the automatic pruning of module cache entries.
+#ifdef IMPORT_DEPENDS_ON_MODULE
+@import DependsOnModule;
+#else
+@import Module;
+#endif
+
+// We need 'touch' and 'find' for this test to work.
+// REQUIRES: shell
+
+// Clear out the module cache
+// RUN: rm -rf %t
+// Run Clang twice so we end up creating the timestamp file (the second time).
+// RUN: %clang_cc1 -DIMPORT_DEPENDS_ON_MODULE -fmodules-ignore-macro=DIMPORT_DEPENDS_ON_MODULE -fmodules -F %S/Inputs -fmodules-cache-path=%t %s -verify
+// RUN: %clang_cc1 -DIMPORT_DEPENDS_ON_MODULE -fmodules-ignore-macro=DIMPORT_DEPENDS_ON_MODULE -fmodules -F %S/Inputs -fmodules-cache-path=%t %s -verify
+// RUN: ls %t | grep modules.timestamp
+// RUN: ls -R %t | grep ^Module.pcm
+// RUN: ls -R %t | grep DependsOnModule.pcm
+
+// Set the timestamp back more than two days. We should try to prune,
+// but nothing gets pruned because the module files are new enough.
+// RUN: touch -m -a -t 201101010000 %t/modules.timestamp
+// RUN: %clang_cc1 -fmodules -F %S/Inputs -fmodules-cache-path=%t -fmodules -fmodules-prune-interval=172800 -fmodules-prune-after=345600 %s -verify
+// RUN: ls %t | grep modules.timestamp
+// RUN: ls -R %t | grep ^Module.pcm
+// RUN: ls -R %t | grep DependsOnModule.pcm
+
+// Set the DependsOnModule access time back more than four days.
+// This shouldn't prune anything, because the timestamp has been updated, so
+// the pruning mechanism won't fire.
+// RUN: find %t -name DependsOnModule.pcm | xargs touch -a -t 201101010000
+// RUN: %clang_cc1 -fmodules -F %S/Inputs -fmodules-cache-path=%t -fmodules -fmodules-prune-interval=172800 -fmodules-prune-after=345600 %s -verify
+// RUN: ls %t | grep modules.timestamp
+// RUN: ls -R %t | grep ^Module.pcm
+// RUN: ls -R %t | grep DependsOnModule.pcm
+
+// Set both timestamp and DependsOnModule.pcm back beyond the cutoff.
+// This should trigger pruning, which will remove DependsOnModule but not Module.
+// RUN: touch -m -a -t 201101010000 %t/modules.timestamp
+// RUN: find %t -name DependsOnModule.pcm | xargs touch -a -t 201101010000
+// RUN: %clang_cc1 -fmodules -F %S/Inputs -fmodules-cache-path=%t -fmodules -fmodules-prune-interval=172800 -fmodules-prune-after=345600 %s -verify
+// RUN: ls %t | grep modules.timestamp
+// RUN: ls -R %t | grep ^Module.pcm
+// RUN: ls -R %t | not grep DependsOnModule.pcm
+
+// expected-no-diagnostics
diff --git a/test/Modules/redecl-merge.m b/test/Modules/redecl-merge.m
index e37366748d..37e5967f4e 100644
--- a/test/Modules/redecl-merge.m
+++ b/test/Modules/redecl-merge.m
@@ -27,8 +27,8 @@ int *call_eventually_noreturn_again(void) {
int *call_eventually_noreturn2_again(void) {
// noreturn and non-noreturn functions have different types
eventually_noreturn2(); // expected-error{{call to 'eventually_noreturn2' is ambiguous}}
- // expected-note@93{{candidate function}}
- // expected-note@90{{candidate function}}
+ // expected-note@Inputs/redecl-merge-left.h:93{{candidate function}}
+ // expected-note@Inputs/redecl-merge-right.h:90{{candidate function}}
}
@implementation A
@@ -79,24 +79,26 @@ void testTypedefMerge(int i, double d) {
T1 *ip = &i;
// FIXME: Typedefs aren't actually merged in the sense of other merges, because
// we should only merge them when the types are identical.
- // in other file: expected-note@60{{candidate found by name lookup is 'T2'}}
- // in other file: expected-note@63{{candidate found by name lookup is 'T2'}}
+ // expected-note@Inputs/redecl-merge-left.h:60{{candidate found by name lookup is 'T2'}}
+ // expected-note@Inputs/redecl-merge-right.h:63{{candidate found by name lookup is 'T2'}}
T2 *dp = &d; // expected-error{{reference to 'T2' is ambiguous}}
}
void testFuncMerge(int i) {
func0(i);
func1(i);
- // in other file: expected-note@64{{candidate function}}
- // in other file: expected-note@70{{candidate function}}
+ // expected-note@Inputs/redecl-merge-left.h:64{{candidate function}}
+ // expected-note@Inputs/redecl-merge-right.h:70{{candidate function}}
func2(i); // expected-error{{call to 'func2' is ambiguous}}
}
void testVarMerge(int i) {
var1 = i;
- // in other files: expected-note@77 2{{candidate found by name lookup is 'var2'}}
+ // expected-note@Inputs/redecl-merge-left.h:77{{candidate found by name lookup is 'var2'}}
+ // expected-note@Inputs/redecl-merge-right.h:77{{candidate found by name lookup is 'var2'}}
var2 = i; // expected-error{{reference to 'var2' is ambiguous}}
- // in other files: expected-note@79 2{{candidate found by name lookup is 'var3'}}
+ // expected-note@Inputs/redecl-merge-left.h:79{{candidate found by name lookup is 'var3'}}
+ // expected-note@Inputs/redecl-merge-right.h:79{{candidate found by name lookup is 'var3'}}
var3 = i; // expected-error{{reference to 'var3' is ambiguous}}
}
diff --git a/test/Modules/redecls/a.h b/test/Modules/redecls/a.h
new file mode 100644
index 0000000000..1647f86606
--- /dev/null
+++ b/test/Modules/redecls/a.h
@@ -0,0 +1,3 @@
+@interface AA
+@end
+@class AA;
diff --git a/test/Modules/redecls/b.h b/test/Modules/redecls/b.h
new file mode 100644
index 0000000000..d41573ddc7
--- /dev/null
+++ b/test/Modules/redecls/b.h
@@ -0,0 +1 @@
+@class AA;
diff --git a/test/Modules/redecls/main.m b/test/Modules/redecls/main.m
new file mode 100644
index 0000000000..9ec02b03f2
--- /dev/null
+++ b/test/Modules/redecls/main.m
@@ -0,0 +1,27 @@
+// RUN: rm -rf %t.mcp
+// RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodule-name=a %S/module.map -fmodules-cache-path=%t.mcp
+// RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodule-name=b %S/module.map -fmodules-cache-path=%t.mcp
+// RUN: %clang_cc1 -fmodules %s -emit-pch -o %t1.pch -fmodules-cache-path=%t.mcp
+// RUN: %clang_cc1 -fmodules %s -emit-pch -o %t2.pch -include-pch %t1.pch -fmodules-cache-path=%t.mcp
+// RUN: %clang_cc1 -fmodules %s -fsyntax-only -include-pch %t2.pch -fmodules-cache-path=%t.mcp -verify
+
+#ifndef HEADER1
+#define HEADER1
+
+@import a;
+
+#elif !defined(HEADER2)
+#define HEADER2
+
+@class AA;
+@import b;
+
+#else
+
+// rdar://13712705
+@interface SS : AA
+@end
+
+#warning parsed this
+#endif
+// expected-warning@-2{{parsed this}}
diff --git a/test/Modules/redecls/module.map b/test/Modules/redecls/module.map
new file mode 100644
index 0000000000..a36568207b
--- /dev/null
+++ b/test/Modules/redecls/module.map
@@ -0,0 +1,2 @@
+module a { header "a.h" }
+module b { header "b.h" }
diff --git a/test/Modules/renamed.m b/test/Modules/renamed.m
new file mode 100644
index 0000000000..4e8f5329bb
--- /dev/null
+++ b/test/Modules/renamed.m
@@ -0,0 +1,8 @@
+@import NewName;
+
+int f() { return same_api; }
+
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -I %S/Inputs -fmodules-cache-path=%t %s -verify
+
+// expected-no-diagnostics
diff --git a/test/Modules/serialized-diags.m b/test/Modules/serialized-diags.m
new file mode 100644
index 0000000000..18bce06047
--- /dev/null
+++ b/test/Modules/serialized-diags.m
@@ -0,0 +1,32 @@
+@import HasWarnings;
+
+#ifdef WITH_ERRORS
+@import HasErrors;
+#endif
+
+float float_val;
+double *double_ptr = &float_val;
+
+// RUN: rm -rf %t %t.diag %t.out
+// RUN: %clang -fmodules -fmodules-cache-path=%t/ModuleCache -I %S/Inputs/ModuleDiags -fsyntax-only %s --serialize-diagnostics %t.diag > /dev/null 2>&1
+// RUN: c-index-test -read-diagnostics %t.diag > %t.out 2>&1
+// RUN: FileCheck --input-file=%t.out %s
+
+// CHECK: has_warnings.h:3:8: warning: incompatible pointer types initializing 'float *'
+// CHECK: serialized-diags.m:1:9: note: while building module 'HasWarnings' imported from
+// CHECK: serialized-diags.m:8:9: warning: incompatible pointer types initializing 'double *'
+// CHECK: Number of diagnostics: 2
+
+// RUN: rm -rf %t %t.diag_errors %t.out_errors
+// RUN: not %clang -fmodules -fmodules-cache-path=%t/ModuleCache -I %S/Inputs/ModuleDiags -fsyntax-only -DWITH_ERRORS %s --serialize-diagnostics %t.diag_errors > /dev/null 2>&1
+// RUN: c-index-test -read-diagnostics %t.diag_errors > %t.out_errors 2>&1
+// RUN: FileCheck -check-prefix=CHECK-WITH-ERRORS --input-file=%t.out_errors %s
+
+// CHECK-WITH-ERRORS: has_warnings.h:3:8: warning: incompatible pointer types initializing 'float *'
+// CHECK-WITH-ERRORS: serialized-diags.m:1:9: note: while building module 'HasWarnings'
+// CHECK-WITH-ERRORS: has_errors.h:2:13: error: redefinition of 'foo'
+// CHECK-WITH-ERRORS: serialized-diags.m:4:9: note: while building module 'HasErrors'
+// CHECK-WITH-ERRORS: has_errors.h:1:13: note: previous definition is here
+// CHECK-WITH-ERRORS: serialized-diags.m:4:9: fatal: could not build module 'HasErrors'
+// CHECK-WITH-ERRORS: Number of diagnostics: 3
+
diff --git a/test/Modules/stddef.m b/test/Modules/stddef.m
new file mode 100644
index 0000000000..83f73f9d33
--- /dev/null
+++ b/test/Modules/stddef.m
@@ -0,0 +1,7 @@
+@import StdDef.Other;
+
+size_t getSize();
+
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs/StdDef %s -verify
+// expected-no-diagnostics
diff --git a/test/Modules/subframeworks.m b/test/Modules/subframeworks.m
index 22dfcca365..ad70cc2b22 100644
--- a/test/Modules/subframeworks.m
+++ b/test/Modules/subframeworks.m
@@ -23,7 +23,7 @@ CXXOnly cxxonly;
@import HasSubModules;
-// expected-warning@1{{treating #include as an import of module 'HasSubModules.Sub.Types'}}
+// expected-warning@Inputs/HasSubModules.framework/Frameworks/Sub.framework/PrivateHeaders/SubPriv.h:1{{treating #include as an import of module 'HasSubModules.Sub.Types'}}
#import <HasSubModules/HasSubModulesPriv.h>
struct FrameworkSubStruct ss;
diff --git a/test/Modules/system_version.m b/test/Modules/system_version.m
new file mode 100644
index 0000000000..85b3263f72
--- /dev/null
+++ b/test/Modules/system_version.m
@@ -0,0 +1,32 @@
+// Test checking that we're hashing a system version file in the
+// module hash.
+// REQUIRES: shell
+
+// First, build a system root.
+// RUN: rm -rf %t
+// RUN: mkdir -p %t/usr/include
+// RUN: cp %S/Inputs/Modified/A.h %t/usr/include
+// RUN: cp %S/Inputs/Modified/B.h %t/usr/include
+// RUN: cp %S/Inputs/Modified/module.map %t/usr/include
+
+// Run once with no system version file. We should end up with one module.
+// RUN: %clang_cc1 -fmodules-cache-path=%t/cache -fmodules -isysroot %t -I %t/usr/include %s -verify
+// RUN: ls -R %t | grep -c ModA.pcm| grep 1
+
+// Add a system version file and run again. We should now have two
+// module variants.
+// RUN: mkdir -p %t/System/Library/CoreServices
+// RUN: echo "hello" > %t/System/Library/CoreServices/SystemVersion.plist
+// RUN: %clang_cc1 -fmodules-cache-path=%t/cache -fmodules -isysroot %t -I %t/usr/include %s -verify
+// RUN: ls -R %t | grep -c ModA.pcm| grep 2
+
+// Change the system version file and run again. We should now have three
+// module variants.
+// RUN: mkdir -p %t/System/Library/CoreServices
+// RUN: echo "modules" > %t/System/Library/CoreServices/SystemVersion.plist
+// RUN: %clang_cc1 -fmodules-cache-path=%t/cache -fmodules -isysroot %t -I %t/usr/include %s -verify
+// RUN: ls -R %t | grep -c ModA.pcm| grep 3
+
+// expected-no-diagnostics
+@import ModA;
+
diff --git a/test/OpenMP/no_option.c b/test/OpenMP/no_option.c
new file mode 100644
index 0000000000..4acc8d0656
--- /dev/null
+++ b/test/OpenMP/no_option.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -verify -o - %s
+// expected-no-diagnostics
+
+int a;
+#pragma omp threadprivate(a,b)
+#pragma omp parallel
diff --git a/test/OpenMP/no_option_no_warn.c b/test/OpenMP/no_option_no_warn.c
new file mode 100644
index 0000000000..c989991371
--- /dev/null
+++ b/test/OpenMP/no_option_no_warn.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -verify -Wno-source-uses-openmp -o - %s
+// expected-no-diagnostics
+
+int a;
+#pragma omp threadprivate(a,b)
+#pragma omp parallel
diff --git a/test/OpenMP/openmp_common.c b/test/OpenMP/openmp_common.c
new file mode 100644
index 0000000000..ca5d89a662
--- /dev/null
+++ b/test/OpenMP/openmp_common.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - %s
+
+#pragma omp // expected-error {{expected an OpenMP directive}}
+#pragma omp unknown_directive // expected-error {{expected an OpenMP directive}}
+
+void foo() {
+#pragma omp // expected-error {{expected an OpenMP directive}}
+#pragma omp unknown_directive // expected-error {{expected an OpenMP directive}}
+}
diff --git a/test/OpenMP/option_warn.c b/test/OpenMP/option_warn.c
new file mode 100644
index 0000000000..ddec8e113e
--- /dev/null
+++ b/test/OpenMP/option_warn.c
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -verify -Wsource-uses-openmp -o - %s
+
+int a;
+#pragma omp threadprivate(a,b) // expected-warning {{unexpected '#pragma omp ...' in program}}
+#pragma omp parallel
diff --git a/test/OpenMP/predefined_macro.c b/test/OpenMP/predefined_macro.c
index e18c3d26d4..cf6c0cc611 100644
--- a/test/OpenMP/predefined_macro.c
+++ b/test/OpenMP/predefined_macro.c
@@ -15,3 +15,20 @@
#endif // _OPENMP
#endif // FOPENMP
+// RUN: %clang_cc1 -fopenmp -verify -DFOPENMP -o - %s
+// RUN: %clang_cc1 -verify -o - %s
+// expected-no-diagnostics
+#ifdef FOPENMP
+// -fopenmp option is specified
+#ifndef _OPENMP
+#error "No _OPENMP macro is defined with -fopenmp option"
+#elsif _OPENMP != 201107
+#error "_OPENMP has incorrect value"
+#endif // _OPENMP
+#else
+// No -fopenmp option is specified
+#ifdef _OPENMP
+#error "_OPENMP macro is defined without -fopenmp option"
+#endif // _OPENMP
+#endif // FOPENMP
+
diff --git a/test/OpenMP/threadprivate_ast_print.cpp b/test/OpenMP/threadprivate_ast_print.cpp
new file mode 100644
index 0000000000..deb829e926
--- /dev/null
+++ b/test/OpenMP/threadprivate_ast_print.cpp
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
+// expected-no-diagnostics
+
+struct St{
+ int a;
+};
+
+struct St1{
+ int a;
+ static int b;
+// CHECK: static int b;
+#pragma omp threadprivate(b)
+// CHECK-NEXT: #pragma omp threadprivate(b)
+} d;
+
+int a, b;
+// CHECK: int a;
+// CHECK: int b;
+#pragma omp threadprivate(a)
+// CHECK-NEXT: #pragma omp threadprivate(a)
+#pragma omp threadprivate(d, b)
+// CHECK-NEXT: #pragma omp threadprivate(d,b)
+
+template <class T> T foo() {
+ static T v;
+ #pragma omp threadprivate(v)
+ return v;
+}
+//CHECK: template <class T = int> int foo() {
+//CHECK-NEXT: static int v;
+//CHECK-NEXT: #pragma omp threadprivate(v)
+//CHECK: template <class T> T foo() {
+//CHECK-NEXT: static T v;
+//CHECK-NEXT: #pragma omp threadprivate(v)
+
+int main () {
+ static int a;
+// CHECK: static int a;
+#pragma omp threadprivate(a)
+// CHECK-NEXT: #pragma omp threadprivate(a)
+ a=2;
+ return (foo<int>());
+}
diff --git a/test/OpenMP/threadprivate_messages.cpp b/test/OpenMP/threadprivate_messages.cpp
new file mode 100644
index 0000000000..0c448b2ef2
--- /dev/null
+++ b/test/OpenMP/threadprivate_messages.cpp
@@ -0,0 +1,119 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 %s
+
+#pragma omp threadprivate // expected-error {{expected '(' after 'threadprivate'}}
+#pragma omp threadprivate( // expected-error {{expected unqualified-id}}
+#pragma omp threadprivate() // expected-error {{expected unqualified-id}}
+#pragma omp threadprivate(1) // expected-error {{expected unqualified-id}}
+struct CompleteSt{
+ int a;
+};
+
+struct CompleteSt1{
+#pragma omp threadprivate(1) // expected-error {{expected unqualified-id}}
+ int a;
+} d; // expected-note {{forward declaration of 'd'}}
+
+int a; // expected-note {{forward declaration of 'a'}}
+
+#pragma omp threadprivate(a)
+#pragma omp threadprivate(u) // expected-error {{use of undeclared identifier 'u'}}
+#pragma omp threadprivate(d, a) // expected-error {{'#pragma omp threadprivate' must precede all references to variable 'a'}}
+int foo() { // expected-note {{declared here}}
+ static int l;
+#pragma omp threadprivate(l)) // expected-warning {{extra tokens at end of '#pragma omp threadprivate' are ignored}}
+ return (a);
+}
+
+#pragma omp threadprivate a // expected-error {{expected '(' after 'threadprivate'}}
+#pragma omp threadprivate(d // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{'#pragma omp threadprivate' must precede all references to variable 'd'}}
+#pragma omp threadprivate(d))
+int x, y;
+#pragma omp threadprivate(x)) // expected-warning {{extra tokens at end of '#pragma omp threadprivate' are ignored}}
+#pragma omp threadprivate(y)), // expected-warning {{extra tokens at end of '#pragma omp threadprivate' are ignored}}
+#pragma omp threadprivate(a,d) // expected-error {{'#pragma omp threadprivate' must precede all references to variable 'a'}} expected-error {{'#pragma omp threadprivate' must precede all references to variable 'd'}}
+#pragma omp threadprivate(d.a) // expected-error {{expected unqualified-id}}
+#pragma omp threadprivate((float)a) // expected-error {{expected unqualified-id}}
+int foa;
+#pragma omp threadprivate(faa) // expected-error {{use of undeclared identifier 'faa'; did you mean 'foa'?}}
+#pragma omp threadprivate(foo) // expected-error {{'foo' is not a global variable, static local variable or static data member}}
+#pragma omp threadprivate (int a=2) // expected-error {{expected unqualified-id}}
+
+struct IncompleteSt; // expected-note {{forward declaration of 'IncompleteSt'}}
+
+extern IncompleteSt e;
+#pragma omp threadprivate (e) // expected-error {{a threadprivate variable must not have incomplete type 'IncompleteSt'}}
+
+int &f = a; // expected-note {{forward declaration of 'f'}}
+#pragma omp threadprivate (f) // expected-error {{arguments of '#pragma omp threadprivate' cannot be of reference type 'int &'}}
+
+class Class {
+ private:
+ int a; // expected-note {{declared here}}
+ static int b;
+ Class() : a(0){}
+ public:
+ Class (int aaa) : a(aaa) {}
+#pragma omp threadprivate (b, a) // expected-error {{'a' is not a global variable, static local variable or static data member}}
+} g(10);
+#pragma omp threadprivate (b) // expected-error {{use of undeclared identifier 'b'}}
+#pragma omp threadprivate (Class::b) // expected-error {{expected unqualified-id}}
+#pragma omp threadprivate (g)
+
+namespace ns {
+ int m;
+#pragma omp threadprivate (m)
+}
+#pragma omp threadprivate (m) // expected-error {{use of undeclared identifier 'm'}}
+#pragma omp threadprivate (ns::m) // expected-error {{expected unqualified-id}}
+#pragma omp threadprivate (ns:m) // expected-error {{expected unqualified-id}}
+
+const int h = 12;
+const volatile int i = 10;
+#pragma omp threadprivate (h, i)
+
+
+template <class T>
+class TempClass {
+ private:
+ T a;
+ TempClass() : a(){}
+ public:
+ TempClass (T aaa) : a(aaa) {}
+ static T s;
+#pragma omp threadprivate (s)
+};
+#pragma omp threadprivate (s) // expected-error {{use of undeclared identifier 's'}}
+
+static __thread int t; // expected-note {{forward declaration of 't'}}
+#pragma omp threadprivate (t) // expected-error {{variable 't' cannot be threadprivate because it is thread-local}}
+
+int o; // expected-note {{candidate found by name lookup is 'o'}}
+namespace {
+int o; // expected-note {{candidate found by name lookup is '<anonymous namespace>::o'}}
+}
+#pragma omp threadprivate (o) // expected-error {{reference to 'o' is ambiguous}}
+
+int main(int argc, char **argv) { // expected-note {{forward declaration of 'argc'}}
+
+ int x, y = argc; // expected-note {{forward declaration of 'y'}}
+ static double d1;
+ static double d2;
+ static double d3; // expected-note {{forward declaration of 'd3'}}
+
+ d.a = a;
+ d2++;
+ ;
+#pragma omp threadprivate(argc+y) // expected-error {{expected unqualified-id}}
+#pragma omp threadprivate(argc,y) // expected-error 2 {{arguments of '#pragma omp threadprivate' must have static storage duration}}
+#pragma omp threadprivate(d2) // expected-error {{'#pragma omp threadprivate' must precede all references to variable 'd2'}}
+#pragma omp threadprivate(d1)
+ {
+ ++a;d2=0;
+#pragma omp threadprivate(d3) // expected-error {{'#pragma omp threadprivate' must appear in the scope of the 'd3' variable declaration}}
+ }
+#pragma omp threadprivate(d3)
+
+#pragma omp threadprivate(a) // expected-error {{'#pragma omp threadprivate' must appear in the scope of the 'a' variable declaration}}
+ return (y);
+#pragma omp threadprivate(d) // expected-error {{'#pragma omp threadprivate' must appear in the scope of the 'd' variable declaration}}
+}
diff --git a/test/PCH/captured-stmt.cpp b/test/PCH/captured-stmt.cpp
new file mode 100644
index 0000000000..6f5ca3836e
--- /dev/null
+++ b/test/PCH/captured-stmt.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -x c++-header -emit-pch %s -o %t
+// RUN: %clang_cc1 -include-pch %t -fsyntax-only -verify %s
+
+// expected-no-diagnostics
+
+#ifndef HEADER_INCLUDED
+#define HEADER_INCLUDED
+
+static inline void foo(int &x, int y) {
+ // Capturing x and y
+ #pragma clang __debug captured
+ {
+ x += y;
+ }
+}
+
+struct C {
+ int val;
+
+ explicit C(int v) : val(v) { }
+
+ void bar(int &x) {
+ // Capturing x and this
+ #pragma clang __debug captured
+ {
+ x += val;
+ }
+ }
+};
+
+#else
+
+void test_foo(int &x) {
+ foo(x, 10);
+}
+
+void test_bar(int &x) {
+ C Obj(10);
+ Obj.bar(x);
+}
+
+#endif
diff --git a/test/PCH/chain-late-anonymous-namespace.cpp b/test/PCH/chain-late-anonymous-namespace.cpp
index 87205c631b..edae285c90 100644
--- a/test/PCH/chain-late-anonymous-namespace.cpp
+++ b/test/PCH/chain-late-anonymous-namespace.cpp
@@ -2,6 +2,8 @@
// RUN: %clang_cc1 -include %s -include %s -fsyntax-only %s
// with PCH
// RUN: %clang_cc1 -chain-include %s -chain-include %s -fsyntax-only %s
+// with PCH, with modules enabled
+// RUN: %clang_cc1 -chain-include %s -chain-include %s -fsyntax-only -fmodules %s
#if !defined(PASS1)
#define PASS1
diff --git a/test/PCH/cxx-constexpr.cpp b/test/PCH/cxx-constexpr.cpp
index 8fe48f7377..13f04a7947 100644
--- a/test/PCH/cxx-constexpr.cpp
+++ b/test/PCH/cxx-constexpr.cpp
@@ -4,6 +4,9 @@
// RUN: %clang_cc1 -pedantic-errors -std=c++11 -emit-pch %s -o %t-cxx11
// RUN: %clang_cc1 -pedantic-errors -std=c++11 -include-pch %t-cxx11 -verify %s
+// RUN: %clang_cc1 -pedantic-errors -std=c++98 -emit-pch %s -o %t -fmodules
+// RUN: %clang_cc1 -pedantic-errors -std=c++98 -include-pch %t -verify %s -fmodules
+
#ifndef HEADER_INCLUDED
#define HEADER_INCLUDED
diff --git a/test/PCH/cxx-templates.cpp b/test/PCH/cxx-templates.cpp
index ddebae4df2..58c4c177fd 100644
--- a/test/PCH/cxx-templates.cpp
+++ b/test/PCH/cxx-templates.cpp
@@ -5,7 +5,7 @@
// Test with pch.
// RUN: %clang_cc1 -std=c++11 -fcxx-exceptions -fexceptions -x c++-header -emit-pch -o %t %S/cxx-templates.h
// RUN: %clang_cc1 -std=c++11 -fcxx-exceptions -fexceptions -include-pch %t -verify %s -ast-dump -o -
-// RUN: %clang_cc1 -std=c++11 -fcxx-exceptions -fexceptions -include-pch %t %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -fcxx-exceptions -fexceptions -include-pch %t %s -emit-llvm -o - -error-on-deserialized-decl doNotDeserialize | FileCheck %s
// expected-no-diagnostics
diff --git a/test/PCH/cxx-templates.h b/test/PCH/cxx-templates.h
index 3dda059026..e672b0b387 100644
--- a/test/PCH/cxx-templates.h
+++ b/test/PCH/cxx-templates.h
@@ -246,3 +246,26 @@ struct __mt_alloc {
}
};
}
+
+namespace PR13020 {
+template<typename T>
+void f() {
+ enum E {
+ enumerator
+ };
+
+ T t = enumerator;
+}
+
+template void f<int>();
+}
+
+template<typename T> void doNotDeserialize() {}
+template<typename T> struct ContainsDoNotDeserialize {
+ static int doNotDeserialize;
+};
+template<typename T> struct ContainsDoNotDeserialize2 {
+ static void doNotDeserialize();
+};
+template<typename T> int ContainsDoNotDeserialize<T>::doNotDeserialize = 0;
+template<typename T> void ContainsDoNotDeserialize2<T>::doNotDeserialize() {}
diff --git a/test/PCH/cxx-typeid.cpp b/test/PCH/cxx-typeid.cpp
index d1e0f9ded7..534863af21 100644
--- a/test/PCH/cxx-typeid.cpp
+++ b/test/PCH/cxx-typeid.cpp
@@ -1,8 +1,8 @@
// Test this without pch.
-// RUN: %clang -include %S/cxx-typeid.h -fsyntax-only -Xclang -verify %s
+// RUN: %clang_cc1 -include %S/cxx-typeid.h -fsyntax-only -verify %s
-// RUN: %clang -ccc-pch-is-pch -x c++-header -o %t.gch %S/cxx-typeid.h
-// RUN: %clang -ccc-pch-is-pch -include %t -fsyntax-only -Xclang -verify %s
+// RUN: %clang_cc1 -x c++-header -emit-pch -o %t.pch %S/cxx-typeid.h
+// RUN: %clang_cc1 -include-pch %t.pch -fsyntax-only -verify %s
// expected-no-diagnostics
diff --git a/test/PCH/cxx-typeid.h b/test/PCH/cxx-typeid.h
index aa3b16aa0b..f10f4de87c 100644
--- a/test/PCH/cxx-typeid.h
+++ b/test/PCH/cxx-typeid.h
@@ -1,3 +1,44 @@
// Header for PCH test cxx-typeid.cpp
-#include <typeinfo>
+#ifndef CXX_TYPEID_H
+#define CXX_TYPEID_H
+
+namespace std {
+
+class type_info
+{
+public:
+ virtual ~type_info();
+
+ bool operator==(const type_info& rhs) const;
+ bool operator!=(const type_info& rhs) const;
+
+ bool before(const type_info& rhs) const;
+ unsigned long hash_code() const;
+ const char* name() const;
+
+ type_info(const type_info& rhs);
+ type_info& operator=(const type_info& rhs);
+};
+
+class bad_cast
+{
+public:
+ bad_cast();
+ bad_cast(const bad_cast&);
+ bad_cast& operator=(const bad_cast&);
+ virtual const char* what() const;
+};
+
+class bad_typeid
+{
+public:
+ bad_typeid();
+ bad_typeid(const bad_typeid&);
+ bad_typeid& operator=(const bad_typeid&);
+ virtual const char* what() const;
+};
+
+} // std
+
+#endif
diff --git a/test/PCH/cxx-using.cpp b/test/PCH/cxx-using.cpp
index 2ca7dad0dd..2cab1f031a 100644
--- a/test/PCH/cxx-using.cpp
+++ b/test/PCH/cxx-using.cpp
@@ -6,10 +6,9 @@
// RUN: %clang_cc1 -include-pch %t -fsyntax-only -verify %s
void m() {
- D s; // expected-note {{candidate function}}
+ D s;
s.f(); // expected-error {{no matching member}}
}
-
-
-// expected-note {{candidate function}}
+// expected-note@cxx-using.h:9 {{candidate function}}
+// expected-note@cxx-using.h:15 {{candidate function}}
diff --git a/test/PCH/cxx11-statement-attributes.cpp b/test/PCH/cxx11-statement-attributes.cpp
index 3bb7b40aa9..722ca6e9ff 100644
--- a/test/PCH/cxx11-statement-attributes.cpp
+++ b/test/PCH/cxx11-statement-attributes.cpp
@@ -4,8 +4,7 @@
// RUN: %clang_cc1 -x c++-header -emit-pch -std=c++11 -o %t %S/Inputs/cxx11-statement-attributes.h
// RUN: %clang_cc1 -include-pch %t -std=c++11 -Wimplicit-fallthrough -fsyntax-only %s -o - -verify
-// Warning from Inputs/cxx11-statement-attributes.h:
-// expected-warning@10 {{fallthrough annotation does not directly precede switch label}}
+// expected-warning@Inputs/cxx11-statement-attributes.h:10 {{fallthrough annotation does not directly precede switch label}}
void g(int n) {
f<1>(n); // expected-note {{in instantiation of function template specialization 'f<1>' requested here}}
diff --git a/test/PCH/cxx1y-decltype-auto.cpp b/test/PCH/cxx1y-decltype-auto.cpp
new file mode 100644
index 0000000000..a1c9339cb6
--- /dev/null
+++ b/test/PCH/cxx1y-decltype-auto.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -pedantic -std=c++1y -emit-pch %s -o %t
+// RUN: %clang_cc1 -pedantic -std=c++1y -include-pch %t -verify %s
+
+#ifndef HEADER_INCLUDED
+
+#define HEADER_INCLUDED
+
+template<typename T> void f(T t) {
+ auto a = t.x;
+ decltype(auto) b = t.x;
+ auto c = (t.x);
+ decltype(auto) d = (t.x);
+}
+
+#else
+
+struct Z {
+ int x : 5; // expected-note {{bit-field}}
+};
+
+// expected-error@12 {{non-const reference cannot bind to bit-field 'x'}}
+template void f(Z); // expected-note {{in instantiation of}}
+
+#endif
diff --git a/test/PCH/cxx1y-default-initializer.cpp b/test/PCH/cxx1y-default-initializer.cpp
new file mode 100644
index 0000000000..5a68f27045
--- /dev/null
+++ b/test/PCH/cxx1y-default-initializer.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -pedantic -std=c++1y -emit-pch %s -o %t
+// RUN: %clang_cc1 -pedantic -std=c++1y -include-pch %t -verify %s
+
+#ifndef HEADER_INCLUDED
+
+#define HEADER_INCLUDED
+
+struct A {
+ int x;
+ int y = 3;
+ int z = x + y;
+};
+template<typename T> constexpr A make() { return A {}; }
+template<typename T> constexpr A make(T t) { return A { t }; }
+
+struct B {
+ int z1, z2 = z1;
+ constexpr B(int k) : z1(k) {}
+};
+
+#else
+
+static_assert(A{}.z == 3, "");
+static_assert(A{1}.z == 4, "");
+static_assert(A{.y = 5}.z == 5, ""); // expected-warning {{C99}}
+static_assert(A{3, .y = 1}.z == 4, ""); // expected-warning {{C99}}
+static_assert(make<int>().z == 3, "");
+static_assert(make<int>(12).z == 15, "");
+
+#endif
diff --git a/test/PCH/functions.c b/test/PCH/functions.c
index 35e3921058..fa2ba8d29c 100644
--- a/test/PCH/functions.c
+++ b/test/PCH/functions.c
@@ -4,18 +4,20 @@
// Test with pch.
// RUN: %clang_cc1 -emit-pch -o %t %S/functions.h
// RUN: %clang_cc1 -include-pch %t -fsyntax-only -verify %s
-// expected-note{{'f1' declared here}}
+
int f0(int x0, int y0, ...) { return x0 + y0; }
-// expected-note{{passing argument to parameter here}}
+
float *test_f1(int val, double x, double y) {
if (val > 5)
return f1(x, y);
else
return f1(x); // expected-error{{too few arguments to function call}}
+ // expected-note@functions.h:7{{'f1' declared here}}
}
void test_g0(int *x, float * y) {
g0(y); // expected-warning{{incompatible pointer types passing 'float *' to parameter of type 'int *'}}
+ // expected-note@functions.h:9{{passing argument to parameter here}}
g0(x);
}
diff --git a/test/PCH/headersearch.cpp b/test/PCH/headersearch.cpp
index 8ca0c361c4..4b24ac6b40 100644
--- a/test/PCH/headersearch.cpp
+++ b/test/PCH/headersearch.cpp
@@ -20,15 +20,15 @@
// RUN: cp -pR %t_orig %t_moved
// Check diagnostic with location in original source:
-// RUN: %clang_cc1 -include-pch all.h.pch -I%t_moved -I%t_moved/sub2 -Wpadded -emit-obj -o %t.o %s 2> %t.stderr
+// RUN: %clang_cc1 -include-pch all.h.pch -I%t_moved -I%t_moved/sub2 -Wpadded -emit-llvm-only %s 2> %t.stderr
// RUN: grep 'struct orig_sub' %t.stderr
// Check diagnostic with 2nd location in original source:
-// RUN: not %clang_cc1 -DREDECL -include-pch all.h.pch -I%t_moved -I%t_moved/sub2 -emit-obj -o %t.o %s 2> %t.stderr
+// RUN: not %clang_cc1 -DREDECL -include-pch all.h.pch -I%t_moved -I%t_moved/sub2 -emit-llvm-only %s 2> %t.stderr
// RUN: grep 'void foo' %t.stderr
// Check diagnostic with instantiation location in original source:
-// RUN: not %clang_cc1 -DINSTANTIATION -include-pch all.h.pch -I%t_moved -I%t_moved/sub2 -emit-obj -o %t.o %s 2> %t.stderr
+// RUN: not %clang_cc1 -DINSTANTIATION -include-pch all.h.pch -I%t_moved -I%t_moved/sub2 -emit-llvm-only %s 2> %t.stderr
// RUN: grep 'orig_sub2_1' %t.stderr
void qq(orig_sub*) {all();}
diff --git a/test/PCH/method_pool.m b/test/PCH/method_pool.m
index 20010fbd1c..139f8ba4a6 100644
--- a/test/PCH/method_pool.m
+++ b/test/PCH/method_pool.m
@@ -9,13 +9,5 @@ int message_id(id x) {
return [x instMethod:17]; // expected-warning{{multiple methods}}
}
-
-
-
-
-/* Whitespace below is significant */
-/* expected-note{{using}} */
-
-
-
-/* expected-note{{also}} */
+/* expected-note@method_pool.h:17{{using}} */
+/* expected-note@method_pool.h:21{{also}} */
diff --git a/test/PCH/nonvisible-external-defs.c b/test/PCH/nonvisible-external-defs.c
index 49392ca2fe..092e2c9d9b 100644
--- a/test/PCH/nonvisible-external-defs.c
+++ b/test/PCH/nonvisible-external-defs.c
@@ -7,4 +7,4 @@
int g(int, float); // expected-error{{conflicting types}}
-// expected-note{{previous declaration}}
+// expected-note@nonvisible-external-defs.h:10{{previous declaration}}
diff --git a/test/PCH/reloc.c b/test/PCH/reloc.c
index 4c426e4f77..8dabb8b03d 100644
--- a/test/PCH/reloc.c
+++ b/test/PCH/reloc.c
@@ -10,5 +10,5 @@ int x = 2; // expected-error{{redefinition}}
int y = 5; // expected-error{{redefinition}}
-// expected-note{{previous definition}}
-// expected-note{{previous definition}}
+// expected-note@libroot/usr/include/reloc.h:13{{previous definition}}
+// expected-note@libroot/usr/include/reloc2.h:14{{previous definition}}
diff --git a/test/PCH/tentative-defs.c b/test/PCH/tentative-defs.c
index 0072818a1a..42882307dc 100644
--- a/test/PCH/tentative-defs.c
+++ b/test/PCH/tentative-defs.c
@@ -5,5 +5,4 @@
// RUN: grep "@variable = common global i32 0" %t | count 1
// RUN: grep "@incomplete_array = common global .*1 x i32" %t | count 1
-
-// FIXME: tentative-defs.h expected-warning{{tentative}}
+// FIXME: expected-warning@tentative-defs.h:9{{tentative}}
diff --git a/test/PCH/thread-local.cpp b/test/PCH/thread-local.cpp
new file mode 100644
index 0000000000..f65c12af09
--- /dev/null
+++ b/test/PCH/thread-local.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -pedantic-errors -std=c++11 -triple x86_64-linux-gnu -emit-pch %s -o %t
+// RUN: %clang_cc1 -pedantic-errors -std=c++11 -triple x86_64-linux-gnu -include-pch %t -verify %s
+
+#ifndef HEADER_INCLUDED
+
+#define HEADER_INCLUDED
+extern thread_local int a;
+extern _Thread_local int b;
+extern int c;
+
+#else
+
+_Thread_local int a; // expected-error {{thread-local declaration of 'a' with static initialization follows declaration with dynamic initialization}}
+// expected-note@7 {{previous declaration is here}}
+thread_local int b; // expected-error {{thread-local declaration of 'b' with dynamic initialization follows declaration with static initialization}}
+// expected-note@8 {{previous declaration is here}}
+thread_local int c; // expected-error {{thread-local declaration of 'c' follows non-thread-local declaration}}
+// expected-note@9 {{previous declaration is here}}
+
+#endif
diff --git a/test/PCH/typo.cpp b/test/PCH/typo.cpp
index f8161d17df..6ab66c2cab 100644
--- a/test/PCH/typo.cpp
+++ b/test/PCH/typo.cpp
@@ -1,17 +1,14 @@
-
-// In header: expected-note{{'boost::function' declared here}}
-
-
-// In header: expected-note{{'boost::graph::adjacency_list' declared here}}
-
-
-
-adjacent_list<int, int> g; // expected-error{{no template named 'adjacent_list'; did you mean 'boost::graph::adjacency_list'?}}
-Function<int(int)> f; // expected-error{{no template named 'Function'; did you mean 'boost::function'?}}
-
// Without PCH
// RUN: %clang_cc1 -include %S/Inputs/typo.hpp -verify %s
// With PCH
// RUN: %clang_cc1 -x c++-header -emit-pch -o %t %S/Inputs/typo.hpp
// RUN: %clang_cc1 -include-pch %t -verify %s
+
+adjacent_list<int, int> g;
+// expected-error@-1{{no template named 'adjacent_list'; did you mean 'boost::graph::adjacency_list'?}}
+// expected-note@Inputs/typo.hpp:5{{'boost::graph::adjacency_list' declared here}}
+
+Function<int(int)> f;
+// expected-error@-1{{no template named 'Function'; did you mean 'boost::function'?}}
+// expected-note@Inputs/typo.hpp:2{{'boost::function' declared here}}
diff --git a/test/PCH/typo.m b/test/PCH/typo.m
index c6f0275bc2..876b9438d1 100644
--- a/test/PCH/typo.m
+++ b/test/PCH/typo.m
@@ -1,6 +1,7 @@
// RUN: %clang_cc1 -x objective-c-header -emit-pch -o %t %S/Inputs/typo.h
// RUN: %clang_cc1 -include-pch %t -verify %s
-// In header: expected-note{{declared here}}
+
void f() {
[NSstring alloc]; // expected-error{{unknown receiver 'NSstring'; did you mean 'NSString'?}}
+ // expected-note@Inputs/typo.h:3{{declared here}}
}
diff --git a/test/Parser/MicrosoftExtensions.c b/test/Parser/MicrosoftExtensions.c
index 4c6f4f891d..35c63d4b55 100644
--- a/test/Parser/MicrosoftExtensions.c
+++ b/test/Parser/MicrosoftExtensions.c
@@ -6,7 +6,7 @@ void (*__fastcall fastpfunc)();
struct __declspec(uuid("00000000-0000-0000-C000-000000000046")) __declspec(novtable) IUnknown {}; /* expected-warning{{__declspec attribute 'novtable' is not supported}} */
extern __declspec(dllimport) void __stdcall VarR4FromDec();
__declspec(deprecated) __declspec(deprecated) char * __cdecl ltoa( long _Val, char * _DstBuf, int _Radix);
-__declspec(noalias) __declspec(restrict) void * __cdecl xxx( void * _Memory ); /* expected-warning{{__declspec attribute 'noalias' is not supported}} expected-warning{{__declspec attribute 'restrict' is not supported}} */
+__declspec(safebuffers) __declspec(noalias) __declspec(restrict) void * __cdecl xxx( void * _Memory ); /* expected-warning{{__declspec attribute 'safebuffers' is not supported}} expected-warning{{__declspec attribute 'noalias' is not supported}} expected-warning{{__declspec attribute 'restrict' is not supported}} */
typedef __w64 unsigned long ULONG_PTR, *PULONG_PTR;
void * __ptr64 PtrToPtr64(const void *p)
diff --git a/test/Parser/MicrosoftExtensions.cpp b/test/Parser/MicrosoftExtensions.cpp
index fd38dca194..d8a597a8cc 100644
--- a/test/Parser/MicrosoftExtensions.cpp
+++ b/test/Parser/MicrosoftExtensions.cpp
@@ -331,3 +331,32 @@ namespace Inheritance {
class __multiple_inheritance B;
class __virtual_inheritance C;
}
+
+struct StructWithProperty {
+ __declspec(property) int V0; // expected-error {{expected '(' after 'property'}}
+ __declspec(property()) int V1; // expected-error {{property does not specify a getter or a putter}}
+ __declspec(property(set)) int V2; // expected-error {{putter for property must be specified as 'put', not 'set'}} expected-error {{expected '=' after 'set'}}
+ __declspec(property(ptu)) int V3; // expected-error {{missing 'get=' or 'put='}}
+ __declspec(property(ptu=PutV)) int V4; // expected-error {{expected 'get' or 'put' in property declaration}}
+ __declspec(property(get)) int V5; // expected-error {{expected '=' after 'get'}}
+ __declspec(property(get&)) int V6; // expected-error {{expected '=' after 'get'}}
+ __declspec(property(get=)) int V7; // expected-error {{expected name of accessor method}}
+ __declspec(property(get=GetV)) int V8; // no-warning
+ __declspec(property(get=GetV=)) int V9; // expected-error {{expected ',' or ')' at end of property accessor list}}
+ __declspec(property(get=GetV,)) int V10; // expected-error {{expected 'get' or 'put' in property declaration}}
+ __declspec(property(get=GetV,put=SetV)) int V11; // no-warning
+ __declspec(property(get=GetV,put=SetV,get=GetV)) int V12; // expected-error {{property declaration specifies 'get' accessor twice}}
+
+ int GetV() { return 123; }
+ void SetV(int v) {}
+};
+void TestProperty() {
+ StructWithProperty sp;
+ sp.V8;
+ sp.V8 = 0; // expected-error {{no setter defined for property 'V8'}}
+ int i = sp.V11;
+ sp.V11 = i++;
+ sp.V11 += 8;
+ sp.V11++;
+ ++sp.V11;
+}
diff --git a/test/Parser/asm.c b/test/Parser/asm.c
index 23052c389e..b95e08bcca 100644
--- a/test/Parser/asm.c
+++ b/test/Parser/asm.c
@@ -8,6 +8,12 @@ void f1() {
void f2() {
asm("foo" : "=r" (a)); // expected-error {{use of undeclared identifier 'a'}}
asm("foo" : : "r" (b)); // expected-error {{use of undeclared identifier 'b'}}
+
+ asm const (""); // expected-warning {{ignored const qualifier on asm}}
+ asm volatile ("");
+ asm restrict (""); // expected-warning {{ignored restrict qualifier on asm}}
+ // FIXME: Once GCC supports _Atomic, check whether it allows this.
+ asm _Atomic (""); // expected-warning {{ignored _Atomic qualifier on asm}}
}
diff --git a/test/Parser/atomic.c b/test/Parser/atomic.c
new file mode 100644
index 0000000000..432deeb59c
--- /dev/null
+++ b/test/Parser/atomic.c
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -std=c11 %s -fsyntax-only -verify -pedantic
+
+typedef _Atomic(int) atomic_int;
+typedef _Atomic int atomic_int;
+typedef _Atomic _Atomic _Atomic(int) atomic_int; // expected-warning {{duplicate '_Atomic' declaration specifier}}
+
+typedef const int const_int;
+
+typedef const atomic_int const_atomic_int;
+typedef _Atomic const int const_atomic_int;
+typedef const _Atomic int const_atomic_int;
+typedef const _Atomic(int) const_atomic_int;
+typedef const _Atomic(_Atomic int) const_atomic_int; // expected-error {{_Atomic cannot be applied to atomic type '_Atomic(int)'}}
+typedef _Atomic const_int const_atomic_int;
+typedef _Atomic(const_int) const_atomic_int; // expected-error {{_Atomic cannot be applied to qualified type 'const_int' (aka 'const int')}}
+
+typedef int *_Atomic atomic_int_ptr;
+typedef _Atomic(int *) atomic_int_ptr;
+typedef int (*_Atomic atomic_int_ptr);
+
+typedef int _Atomic *int_atomic_ptr;
+typedef _Atomic(int) *int_atomic_ptr;
+
+typedef int int_fn();
+typedef _Atomic int_fn atomic_int_fn; // expected-error {{_Atomic cannot be applied to function type 'int_fn' (aka 'int ()')}}
+typedef _Atomic int atomic_int_array[3];
+typedef _Atomic atomic_int_array atomic_int_atomic_array; // expected-error {{_Atomic cannot be applied to array type 'atomic_int_array' (aka '_Atomic(int) [3]')}}
+
+_Atomic struct S { int n; }; // expected-warning {{'_Atomic' ignored on this declaration}}
+
+typedef _Atomic int __attribute__((address_space(1))) atomic_addr_space_int;
+typedef _Atomic(int) __attribute__((address_space(1))) atomic_addr_space_int;
+
+typedef _Atomic int __attribute__((vector_size(16))) atomic_vector_int;
+typedef _Atomic(int __attribute__((vector_size(16)))) atomic_vector_int;
diff --git a/test/Parser/attributes.mm b/test/Parser/attributes.mm
new file mode 100644
index 0000000000..d92e3d35cf
--- /dev/null
+++ b/test/Parser/attributes.mm
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -verify -fsyntax-only -Wno-objc-root-class %s
+
+__attribute__((deprecated)) @class B; // expected-error {{prefix attribute must be followed by an interface or protocol}}
+
+__attribute__((deprecated)) @interface A @end
+__attribute__((deprecated)) @protocol P0;
+__attribute__((deprecated)) @protocol P1
+@end
+
+#define EXP __attribute__((visibility("default")))
+class EXP C {};
+EXP class C2 {}; // expected-warning {{attribute 'visibility' is ignored, place it after "class" to apply attribute to type declaration}}
+
+@interface EXP I @end // expected-error {{postfix attributes are not allowed on Objective-C directives, place them in front of '@interface'}}
+EXP @interface I2 @end
+
+@implementation EXP I @end // expected-error-re {{postfix attributes are not allowed on Objective-C directives$}}
+// FIXME: Prefix attribute recovery skips until ';'
+EXP @implementation I2 @end; // expected-error {{prefix attribute must be followed by an interface or protocol}}
+
+@class EXP OC; // expected-error-re {{postfix attributes are not allowed on Objective-C directives$}}
+EXP @class OC2; // expected-error {{prefix attribute must be followed by an interface or protocol}}
+
+@protocol EXP P @end // expected-error {{postfix attributes are not allowed on Objective-C directives, place them in front of '@protocol'}}
+EXP @protocol P2 @end
diff --git a/test/Parser/c11-noreturn.c b/test/Parser/c11-noreturn.c
index 7a2fe50f88..e61901dfb7 100644
--- a/test/Parser/c11-noreturn.c
+++ b/test/Parser/c11-noreturn.c
@@ -4,11 +4,15 @@
_Noreturn int f();
int _Noreturn f(); // expected-note {{previous}}
int f _Noreturn(); // expected-error {{expected ';'}} expected-error 2{{}}
-int f() _Noreturn; // expected-error {{expected ';'}} expected-warning {{does not declare anything}}
+int f() _Noreturn; // expected-error {{expected ';'}} expected-warning {{does not declare anything}} expected-error {{'_Noreturn' can only appear on functions}}
_Noreturn char c1; // expected-error {{'_Noreturn' can only appear on functions}}
char _Noreturn c2; // expected-error {{'_Noreturn' can only appear on functions}}
typedef _Noreturn int g(); // expected-error {{'_Noreturn' can only appear on functions}}
+_Noreturn int; // expected-error {{'_Noreturn' can only appear on functions}} expected-warning {{does not declare anything}}
+_Noreturn struct S; // expected-error {{'_Noreturn' can only appear on functions}}
+_Noreturn enum E { e }; // expected-error {{'_Noreturn' can only appear on functions}}
+
// CHECK-EXT: _Noreturn functions are a C11-specific feature
diff --git a/test/Parser/captured-statements.c b/test/Parser/captured-statements.c
new file mode 100644
index 0000000000..30dddb549c
--- /dev/null
+++ b/test/Parser/captured-statements.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -verify %s
+
+void test1()
+{
+ #pragma clang __debug captured x // expected-warning {{extra tokens at end of #pragma clang __debug captured directive}}
+ {
+ }
+}
+
+void test2()
+{
+ #pragma clang __debug captured
+ int x; // expected-error {{expected '{'}}
+}
diff --git a/test/Parser/crash-report.c b/test/Parser/crash-report.c
new file mode 100644
index 0000000000..42481aa7d0
--- /dev/null
+++ b/test/Parser/crash-report.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 %s 2>&1 | FileCheck %s
+// REQUIRES: crash-recovery
+
+#prag\
+ma clang __debug crash
+
+// CHECK: prag\
+// CHECK-NEXT: ma
+
diff --git a/test/Parser/cxx-class.cpp b/test/Parser/cxx-class.cpp
index 8ed5882a28..5fac797285 100644
--- a/test/Parser/cxx-class.cpp
+++ b/test/Parser/cxx-class.cpp
@@ -88,6 +88,17 @@ namespace ctor_error {
// expected-error{{unknown type name 'UnknownType'}}
}
+namespace nns_decl {
+ struct A {
+ struct B;
+ };
+ namespace N {
+ union C;
+ }
+ struct A::B; // expected-error {{forward declaration of struct cannot have a nested name specifier}}
+ union N::C; // expected-error {{forward declaration of union cannot have a nested name specifier}}
+}
+
// PR13775: Don't assert here.
namespace PR13775 {
class bar
diff --git a/test/Parser/cxx0x-ambig.cpp b/test/Parser/cxx0x-ambig.cpp
index dac3c099fc..4c22ed3a9b 100644
--- a/test/Parser/cxx0x-ambig.cpp
+++ b/test/Parser/cxx0x-ambig.cpp
@@ -38,8 +38,8 @@ namespace bitfield {
constexpr T() {}
constexpr T(int) {}
constexpr T(T, T, T, T) {}
- constexpr T operator=(T) { return *this; }
- constexpr operator int() { return 4; }
+ constexpr T operator=(T) const { return *this; }
+ constexpr operator int() const { return 4; }
};
constexpr T a, b, c, d;
@@ -68,7 +68,7 @@ namespace bitfield {
};
struct U {
- constexpr operator T() { return T(); } // expected-note 2{{candidate}}
+ constexpr operator T() const { return T(); } // expected-note 2{{candidate}}
};
// This could be a bit-field.
struct S7 {
@@ -133,3 +133,19 @@ namespace ellipsis {
void l(int(S<int>::*...)(T)); // expected-warning {{ISO C++11 requires a parenthesized pack declaration to have a name}}
};
}
+
+namespace braced_init_list {
+ struct X {
+ void foo() {}
+ };
+
+ void (*pf1)() {};
+ void (X::*pmf1)() {&X::foo};
+ void (X::*pmf2)() = {&X::foo};
+
+ void test() {
+ void (*pf2)() {};
+ void (X::*pmf3)() {&X::foo};
+ void (X::*pmf4)() = {&X::foo};
+ }
+}
diff --git a/test/Parser/cxx0x-decl.cpp b/test/Parser/cxx0x-decl.cpp
index b9441fd681..e6cba726ab 100644
--- a/test/Parser/cxx0x-decl.cpp
+++ b/test/Parser/cxx0x-decl.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -verify -fsyntax-only -std=c++11 -pedantic-errors %s
+// RUN: %clang_cc1 -verify -fsyntax-only -std=c++11 -pedantic-errors -triple x86_64-linux-gnu %s
// Make sure we know these are legitimate commas and not typos for ';'.
namespace Commas {
@@ -46,16 +46,15 @@ using PR14855 = int S::; // expected-error {{expected ';' after alias declaratio
// a constexpr function.
struct ConstexprTrailingReturn {
int n;
- constexpr auto f() -> decltype((n));
+ constexpr auto f() const -> decltype((n));
};
constexpr const int &ConstexprTrailingReturn::f() const { return n; }
namespace TestIsValidAfterTypeSpecifier {
struct s {} v;
-// FIXME: We should accept this once we support thread_local.
struct s
-thread_local tl; // expected-error {{expected unqualified-id}}
+thread_local tl;
struct s
&r0 = v;
diff --git a/test/Parser/missing-closing-rbrace.m b/test/Parser/missing-closing-rbrace.m
new file mode 100644
index 0000000000..d811421e48
--- /dev/null
+++ b/test/Parser/missing-closing-rbrace.m
@@ -0,0 +1,3 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// rdar: //6854840
+@interface A {@end // expected-error {{'@end' appears where closing brace '}' is expected}}
diff --git a/test/Parser/objc-boxing.m b/test/Parser/objc-boxing.m
index a16a137b8f..a6bb0243cf 100644
--- a/test/Parser/objc-boxing.m
+++ b/test/Parser/objc-boxing.m
@@ -24,3 +24,11 @@ id missing_parentheses() {
return @(5; // expected-error {{expected ')'}} \
// expected-note {{to match this '('}}
}
+
+// rdar://10679157
+void bar(id p);
+void foo(id p) {
+ bar(@{p, p}); // expected-error {{expected ':'}}
+ bar(0);
+ bar(0);
+}
diff --git a/test/Parser/objc-error-qualified-implementation.m b/test/Parser/objc-error-qualified-implementation.m
new file mode 100644
index 0000000000..444fb5dab4
--- /dev/null
+++ b/test/Parser/objc-error-qualified-implementation.m
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -Wno-objc-root-class -verify %s
+// rdar://12233858
+
+@protocol P
+@end
+
+@interface I @end
+
+@implementation I<P> @end // expected-error {{@implementation declaration can not be protocol qualified}}
+
+@interface J < P,P >
+@end
+
+
+@implementation J < P,P > // expected-error {{@implementation declaration can not be protocol qualified}}
+@end
+
+@interface K @end
+
+@implementation K <P // expected-error {{@implementation declaration can not be protocol qualified}}
+@end // expected-error {{expected '>'}}
diff --git a/test/Parser/objcxx11-initialized-temps.mm b/test/Parser/objcxx11-initialized-temps.mm
new file mode 100644
index 0000000000..96f19fe6a5
--- /dev/null
+++ b/test/Parser/objcxx11-initialized-temps.mm
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// expected-no-diagnostics
+// rdar://12788429
+
+struct CGPoint {
+ double x;
+ double y;
+};
+typedef struct CGPoint CGPoint;
+
+struct CGSize {
+ double width;
+ double height;
+};
+typedef struct CGSize CGSize;
+
+struct CGRect {
+ CGPoint origin;
+ CGSize size;
+};
+typedef struct CGRect CGRect;
+
+typedef CGRect NSRect;
+
+void HappySetFrame(NSRect frame) {}
+
+__attribute__((objc_root_class))
+@interface NSObject @end
+
+@implementation NSObject
+- (void) sadSetFrame: (NSRect)frame {}
+
+- (void) nothing
+{
+ HappySetFrame({{0,0}, {13,14}});
+ [self sadSetFrame: {{0,0}, {13,14}}];
+}
+@end
diff --git a/test/Parser/pragma-options.c b/test/Parser/pragma-options.c
index 7844e71080..d168a2751a 100644
--- a/test/Parser/pragma-options.c
+++ b/test/Parser/pragma-options.c
@@ -20,3 +20,15 @@
#pragma align=reset
#pragma align=mac68k
#pragma align=power
+
+// PR13580
+struct S
+{
+ char a[3];
+#pragma align=packed
+ struct T
+ {
+ char b;
+ int c;
+ } d;
+};
diff --git a/test/Parser/pragma-pack.c b/test/Parser/pragma-pack.c
index 84778cd501..172a332510 100644
--- a/test/Parser/pragma-pack.c
+++ b/test/Parser/pragma-pack.c
@@ -30,3 +30,17 @@
_Pragma("pack(push)")
/* expected-warning {{expected integer or identifier in '#pragma pack'}}*/ _Pragma("pack(push,)")
+
+// PR13580
+struct S
+{
+ char a[3];
+#pragma pack(1)
+ struct T
+ {
+ char b;
+ int c;
+ } d;
+#pragma pack()
+ int e;
+};
diff --git a/test/Parser/prefix-attributes.m b/test/Parser/prefix-attributes.m
deleted file mode 100644
index 399421fd72..0000000000
--- a/test/Parser/prefix-attributes.m
+++ /dev/null
@@ -1,8 +0,0 @@
-// RUN: %clang_cc1 -verify -fsyntax-only %s
-
-__attribute__((deprecated)) @class B; // expected-error {{prefix attribute must be followed by an interface or protocol}}
-
-__attribute__((deprecated)) @interface A @end
-__attribute__((deprecated)) @protocol P0;
-__attribute__((deprecated)) @protocol P1
-@end
diff --git a/test/Preprocessor/aarch64-target-features.c b/test/Preprocessor/aarch64-target-features.c
index 65104e3311..8bb8427c0d 100644
--- a/test/Preprocessor/aarch64-target-features.c
+++ b/test/Preprocessor/aarch64-target-features.c
@@ -1,30 +1,32 @@
// RUN: %clang -target aarch64-none-linux-gnu -x c -E -dM %s -o - | FileCheck %s
-// CHECK: __AARCH 8
// CHECK: __AARCH64EL__
-// CHECK: __AARCH_ACLE 101
// CHECK-NOT: __AARCH_ADVSIMD_FP
// CHECK-NOT: __AARCH_FEATURE_ADVSIMD
-// CHECK-NOT: __AARCH_FEATURE_BIG_ENDIAN
-// CHECK: __AARCH_FEATURE_CLZ 1
-// CHECK: __AARCH_FEATURE_FMA 1
-// CHECK: __AARCH_FEATURE_LDREX 0xf
-// CHECK: __AARCH_FEATURE_UNALIGNED 1
-// CHECK: __AARCH_FP 0xe
-// CHECK-NOT: __AARCH_FP_FAST
-// CHECK: __AARCH_FP16_FORMAT_IEEE 1
-// CHECK: __AARCH_FP_FENV_ROUNDING 1
-// CHECK: __AARCH_PROFILE 'A'
-// CHECK: __AARCH_SIZEOF_MINIMAL_ENUM 4
-// CHECK: __AARCH_SIZEOF_WCHAR_T 4
+// CHECK: __ARM_ACLE 101
+// CHECK: __ARM_ARCH 8
+// CHECK: __ARM_ARCH_PROFILE 'A'
+// CHECK-NOT: __ARM_FEATURE_BIG_ENDIAN
+// CHECK: __ARM_FEATURE_CLZ 1
+// CHECK: __ARM_FEATURE_FMA 1
+// CHECK: __ARM_FEATURE_LDREX 0xf
+// CHECK: __ARM_FEATURE_UNALIGNED 1
+// CHECK: __ARM_FP 0xe
+// CHECK-NOT: __ARM_FP_FAST
+// CHECK: __ARM_FP16_FORMAT_IEEE 1
+// CHECK: __ARM_FP_FENV_ROUNDING 1
+// CHECK-NOT: __ARM_NEON_FP
+// CHECK-NOT: __ARM_NEON
+// CHECK: __ARM_SIZEOF_MINIMAL_ENUM 4
+// CHECK: __ARM_SIZEOF_WCHAR_T 4
// CHECK: __aarch64__
// RUN: %clang -target aarch64-none-linux-gnu -ffast-math -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-FASTMATH %s
-// CHECK-FASTMATH: __AARCH_FP_FAST
+// CHECK-FASTMATH: __ARM_FP_FAST
// RUN: %clang -target aarch64-none-linux-gnu -fshort-wchar -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SHORTWCHAR %s
-// CHECK-SHORTWCHAR: __AARCH_SIZEOF_WCHAR_T 2
+// CHECK-SHORTWCHAR: __ARM_SIZEOF_WCHAR_T 2
// RUN: %clang -target aarch64-none-linux-gnu -fshort-enums -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SHORTENUMS %s
-// CHECK-SHORTENUMS: __AARCH_SIZEOF_MINIMAL_ENUM 1
+// CHECK-SHORTENUMS: __ARM_SIZEOF_MINIMAL_ENUM 1
diff --git a/test/Preprocessor/cxx_oper_spelling.cpp b/test/Preprocessor/cxx_oper_spelling.cpp
index 0ae9afd7ee..5152977ba2 100644
--- a/test/Preprocessor/cxx_oper_spelling.cpp
+++ b/test/Preprocessor/cxx_oper_spelling.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -E %s | grep 'a: "and"'
+// RUN: %clang_cc1 -E %s | FileCheck %s
#define X(A) #A
@@ -8,4 +8,5 @@
//
// This should be spelled as 'and', not '&&'
a: X(and)
+// CHECK: a: "and"
diff --git a/test/Preprocessor/dependencies-and-pp.c b/test/Preprocessor/dependencies-and-pp.c
index 7877df3f78..fb49638040 100644
--- a/test/Preprocessor/dependencies-and-pp.c
+++ b/test/Preprocessor/dependencies-and-pp.c
@@ -3,29 +3,34 @@
// RUN: %clang -E -o %t.1 %s
// RUN: %clang -E -MD -MF %t.d -MT foo -o %t.2 %s
// RUN: diff %t.1 %t.2
-// RUN: grep "foo:" %t.d
-// RUN: grep "dependencies-and-pp.c" %t.d
+// RUN: FileCheck -check-prefix=TEST1 %s < %t.d
+// TEST1: foo:
+// TEST1: dependencies-and-pp.c
// Test -MQ flag without quoting
// RUN: %clang -E -MD -MF %t.d -MQ foo -o %t %s
-// RUN: grep "foo:" %t.d
+// RUN: FileCheck -check-prefix=TEST2 %s < %t.d
+// TEST2: foo:
// Test -MQ flag with quoting
// RUN: %clang -E -MD -MF %t.d -MQ '$fo\ooo ooo\ ooo\\ ooo#oo' -o %t %s
-// RUN: fgrep '$$fo\ooo\ ooo\\\ ooo\\\\\ ooo\#oo:' %t.d
+// RUN: FileCheck -check-prefix=TEST3 %s < %t.d
+// TEST3: $$fo\ooo\ ooo\\\ ooo\\\\\ ooo\#oo:
// Test consecutive -MT flags
// RUN: %clang -E -MD -MF %t.d -MT foo -MT bar -MT baz -o %t %s
// RUN: diff %t.1 %t
-// RUN: fgrep "foo bar baz:" %t.d
+// RUN: FileCheck -check-prefix=TEST4 %s < %t.d
+// TEST4: foo bar baz:
// Test consecutive -MT and -MQ flags
// RUN: %clang -E -MD -MF %t.d -MT foo -MQ '$(bar)' -MT 'b az' -MQ 'qu ux' -MQ ' space' -o %t %s
-// RUN: fgrep 'foo $$(bar) b az qu\ ux \ space:' %t.d
+// RUN: FileCheck -check-prefix=TEST5 %s < %t.d
+// TEST5: foo $$(bar) b az qu\ ux \ space:
// TODO: Test default target without quoting
// TODO: Test default target with quoting
diff --git a/test/Preprocessor/has_include.c b/test/Preprocessor/has_include.c
index 7cc67fac03..131e51919f 100644
--- a/test/Preprocessor/has_include.c
+++ b/test/Preprocessor/has_include.c
@@ -176,3 +176,12 @@ __has_include
#else
#error "__has_include failed (9)."
#endif
+
+#if FOO
+#elif __has_include(<foo>)
+#endif
+
+// PR15539
+#ifdef FOO
+#elif __has_include(<foo>)
+#endif
diff --git a/test/Preprocessor/init.c b/test/Preprocessor/init.c
index 73a3a7353e..9671f7e232 100644
--- a/test/Preprocessor/init.c
+++ b/test/Preprocessor/init.c
@@ -8,7 +8,17 @@
// BLOCKS:#define __BLOCKS__ 1
// BLOCKS:#define __block __attribute__((__blocks__(byref)))
//
-//
+//
+// RUN: %clang_cc1 -x c++ -std=c++1y -E -dM < /dev/null | FileCheck -check-prefix CXX1Y %s
+//
+// CXX1Y:#define __GNUG__
+// CXX1Y:#define __GXX_EXPERIMENTAL_CXX0X__ 1
+// CXX1Y:#define __GXX_RTTI 1
+// CXX1Y:#define __GXX_WEAK__ 1
+// CXX1Y:#define __cplusplus 201305L
+// CXX1Y:#define __private_extern__ extern
+//
+//
// RUN: %clang_cc1 -x c++ -std=c++11 -E -dM < /dev/null | FileCheck -check-prefix CXX11 %s
//
// CXX11:#define __GNUG__
@@ -67,6 +77,14 @@
// FREESTANDING:#define __STDC_HOSTED__ 0
//
//
+// RUN: %clang_cc1 -x c++ -std=gnu++1y -E -dM < /dev/null | FileCheck -check-prefix GXX1Y %s
+//
+// GXX1Y:#define __GNUG__
+// GXX1Y:#define __GXX_WEAK__ 1
+// GXX1Y:#define __cplusplus 201305L
+// GXX1Y:#define __private_extern__ extern
+//
+//
// RUN: %clang_cc1 -x c++ -std=gnu++11 -E -dM < /dev/null | FileCheck -check-prefix GXX11 %s
//
// GXX11:#define __GNUG__
@@ -88,10 +106,24 @@
// C94:#define __STDC_VERSION__ 199409L
//
//
-// RUN: %clang_cc1 -fms-extensions -triple i686-pc-win32 -fobjc-runtime=gcc -E -dM < /dev/null | FileCheck -check-prefix MSEXT %s
+// RUN: %clang_cc1 -fms-extensions -triple i686-pc-win32 -E -dM < /dev/null | FileCheck -check-prefix MSEXT %s
//
// MSEXT-NOT:#define __STDC__
// MSEXT:#define _INTEGRAL_MAX_BITS 64
+// MSEXT-NOT:#define _NATIVE_WCHAR_T_DEFINED 1
+// MSEXT-NOT:#define _WCHAR_T_DEFINED 1
+//
+//
+// RUN: %clang_cc1 -x c++ -fms-extensions -triple i686-pc-win32 -E -dM < /dev/null | FileCheck -check-prefix MSEXT-CXX %s
+//
+// MSEXT-CXX:#define _NATIVE_WCHAR_T_DEFINED 1
+// MSEXT-CXX:#define _WCHAR_T_DEFINED 1
+//
+//
+// RUN: %clang_cc1 -x c++ -fno-wchar -fms-extensions -triple i686-pc-win32 -E -dM < /dev/null | FileCheck -check-prefix MSEXT-CXX-NOWCHAR %s
+//
+// MSEXT-CXX-NOWCHAR-NOT:#define _NATIVE_WCHAR_T_DEFINED 1
+// MSEXT-CXX-NOWCHAR-NOT:#define _WCHAR_T_DEFINED 1
//
//
// RUN: %clang_cc1 -x objective-c -E -dM < /dev/null | FileCheck -check-prefix OBJC %s
@@ -248,6 +280,7 @@
// ARM:#define __SIZEOF_SIZE_T__ 4
// ARM:#define __SIZEOF_WCHAR_T__ 4
// ARM:#define __SIZEOF_WINT_T__ 4
+// ARM:#define __SIZE_MAX__ 4294967295U
// ARM:#define __SIZE_TYPE__ unsigned int
// ARM:#define __SIZE_WIDTH__ 32
// ARM:#define __THUMB_INTERWORK__ 1
@@ -351,6 +384,7 @@
// ARMEABISOFTFP:#define __SIZEOF_SIZE_T__ 4
// ARMEABISOFTFP:#define __SIZEOF_WCHAR_T__ 4
// ARMEABISOFTFP:#define __SIZEOF_WINT_T__ 4
+// ARMEABISOFTFP:#define __SIZE_MAX__ 4294967295U
// ARMEABISOFTFP:#define __SIZE_TYPE__ unsigned int
// ARMEABISOFTFP:#define __SIZE_WIDTH__ 32
// ARMEABISOFTFP:#define __SOFTFP__ 1
@@ -455,6 +489,7 @@
// ARMEABIHARDFP:#define __SIZEOF_SIZE_T__ 4
// ARMEABIHARDFP:#define __SIZEOF_WCHAR_T__ 4
// ARMEABIHARDFP:#define __SIZEOF_WINT_T__ 4
+// ARMEABIHARDFP:#define __SIZE_MAX__ 4294967295U
// ARMEABIHARDFP:#define __SIZE_TYPE__ unsigned int
// ARMEABIHARDFP:#define __SIZE_WIDTH__ 32
// ARMEABIHARDFP-NOT:#define __SOFTFP__ 1
@@ -554,6 +589,7 @@
// I386:#define __SIZEOF_SIZE_T__ 4
// I386:#define __SIZEOF_WCHAR_T__ 4
// I386:#define __SIZEOF_WINT_T__ 4
+// I386:#define __SIZE_MAX__ 4294967295U
// I386:#define __SIZE_TYPE__ unsigned int
// I386:#define __SIZE_WIDTH__ 32
// I386:#define __UINTMAX_TYPE__ long long unsigned int
@@ -651,6 +687,7 @@
// I386-LINUX:#define __SIZEOF_SIZE_T__ 4
// I386-LINUX:#define __SIZEOF_WCHAR_T__ 4
// I386-LINUX:#define __SIZEOF_WINT_T__ 4
+// I386-LINUX:#define __SIZE_MAX__ 4294967295U
// I386-LINUX:#define __SIZE_TYPE__ unsigned int
// I386-LINUX:#define __SIZE_WIDTH__ 32
// I386-LINUX:#define __UINTMAX_TYPE__ long long unsigned int
@@ -759,6 +796,7 @@
// MIPS32BE:#define __SIZEOF_SIZE_T__ 4
// MIPS32BE:#define __SIZEOF_WCHAR_T__ 4
// MIPS32BE:#define __SIZEOF_WINT_T__ 4
+// MIPS32BE:#define __SIZE_MAX__ 4294967295U
// MIPS32BE:#define __SIZE_TYPE__ unsigned int
// MIPS32BE:#define __SIZE_WIDTH__ 32
// MIPS32BE:#define __STDC_HOSTED__ 0
@@ -875,6 +913,7 @@
// MIPS32EL:#define __SIZEOF_SIZE_T__ 4
// MIPS32EL:#define __SIZEOF_WCHAR_T__ 4
// MIPS32EL:#define __SIZEOF_WINT_T__ 4
+// MIPS32EL:#define __SIZE_MAX__ 4294967295U
// MIPS32EL:#define __SIZE_TYPE__ unsigned int
// MIPS32EL:#define __SIZE_WIDTH__ 32
// MIPS32EL:#define __UINTMAX_TYPE__ long long unsigned int
@@ -988,6 +1027,7 @@
// MIPS64BE:#define __SIZEOF_SIZE_T__ 8
// MIPS64BE:#define __SIZEOF_WCHAR_T__ 4
// MIPS64BE:#define __SIZEOF_WINT_T__ 4
+// MIPS64BE:#define __SIZE_MAX__ 18446744073709551615UL
// MIPS64BE:#define __SIZE_TYPE__ long unsigned int
// MIPS64BE:#define __SIZE_WIDTH__ 64
// MIPS64BE:#define __UINTMAX_TYPE__ long long unsigned int
@@ -1103,6 +1143,7 @@
// MIPS64EL:#define __SIZEOF_SIZE_T__ 8
// MIPS64EL:#define __SIZEOF_WCHAR_T__ 4
// MIPS64EL:#define __SIZEOF_WINT_T__ 4
+// MIPS64EL:#define __SIZE_MAX__ 18446744073709551615UL
// MIPS64EL:#define __SIZE_TYPE__ long unsigned int
// MIPS64EL:#define __SIZE_WIDTH__ 64
// MIPS64EL:#define __UINTMAX_TYPE__ long long unsigned int
@@ -1141,6 +1182,12 @@
// MIPS-FABI-SINGLE:#define __mips_hard_float 1
// MIPS-FABI-SINGLE:#define __mips_single_float 1
//
+// RUN: %clang_cc1 -target-feature +soft-float -target-feature +single-float \
+// RUN: -E -dM -ffreestanding -triple=mips-none-none < /dev/null \
+// RUN: | FileCheck -check-prefix MIPS-FABI-SINGLE-SOFT %s
+// MIPS-FABI-SINGLE-SOFT:#define __mips_single_float 1
+// MIPS-FABI-SINGLE-SOFT:#define __mips_soft_float 1
+//
// Check MIPS features macros
//
// RUN: %clang_cc1 -target-feature +mips16 \
@@ -1153,6 +1200,16 @@
// RUN: | FileCheck -check-prefix NOMIPS16 %s
// NOMIPS16-NOT:#define __mips16 1
//
+// RUN: %clang_cc1 -target-feature +micromips \
+// RUN: -E -dM -triple=mips-none-none < /dev/null \
+// RUN: | FileCheck -check-prefix MICROMIPS %s
+// MICROMIPS:#define __mips_micromips 1
+//
+// RUN: %clang_cc1 -target-feature -micromips \
+// RUN: -E -dM -triple=mips-none-none < /dev/null \
+// RUN: | FileCheck -check-prefix NOMICROMIPS %s
+// NOMICROMIPS-NOT:#define __mips_micromips 1
+//
// RUN: %clang_cc1 -target-feature +dsp \
// RUN: -E -dM -triple=mips-none-none < /dev/null \
// RUN: | FileCheck -check-prefix MIPS-DSP %s
@@ -1249,6 +1306,7 @@
// MSP430:#define __SIZEOF_SIZE_T__ 2
// MSP430:#define __SIZEOF_WCHAR_T__ 2
// MSP430:#define __SIZEOF_WINT_T__ 2
+// MSP430:#define __SIZE_MAX__ 65535U
// MSP430:#define __SIZE_TYPE__ unsigned int
// MSP430:#define __SIZE_WIDTH__ 16
// MSP430:#define __UINTMAX_TYPE__ long unsigned int
@@ -1346,6 +1404,7 @@
// NVPTX32:#define __SIZEOF_SIZE_T__ 4
// NVPTX32:#define __SIZEOF_WCHAR_T__ 4
// NVPTX32:#define __SIZEOF_WINT_T__ 4
+// NVPTX32:#define __SIZE_MAX__ 4294967295U
// NVPTX32:#define __SIZE_TYPE__ unsigned int
// NVPTX32:#define __SIZE_WIDTH__ 32
// NVPTX32:#define __UINTMAX_TYPE__ long long unsigned int
@@ -1442,6 +1501,7 @@
// NVPTX64:#define __SIZEOF_SIZE_T__ 8
// NVPTX64:#define __SIZEOF_WCHAR_T__ 4
// NVPTX64:#define __SIZEOF_WINT_T__ 4
+// NVPTX64:#define __SIZE_MAX__ 18446744073709551615UL
// NVPTX64:#define __SIZE_TYPE__ long long unsigned int
// NVPTX64:#define __SIZE_WIDTH__ 64
// NVPTX64:#define __UINTMAX_TYPE__ long long unsigned int
@@ -1543,6 +1603,7 @@
// PPC603E:#define __SIZEOF_SIZE_T__ 4
// PPC603E:#define __SIZEOF_WCHAR_T__ 4
// PPC603E:#define __SIZEOF_WINT_T__ 4
+// PPC603E:#define __SIZE_MAX__ 4294967295U
// PPC603E:#define __SIZE_TYPE__ long unsigned int
// PPC603E:#define __SIZE_WIDTH__ 32
// PPC603E:#define __UINTMAX_TYPE__ long long unsigned int
@@ -1651,6 +1712,7 @@
// PPC64:#define __SIZEOF_SIZE_T__ 8
// PPC64:#define __SIZEOF_WCHAR_T__ 4
// PPC64:#define __SIZEOF_WINT_T__ 4
+// PPC64:#define __SIZE_MAX__ 18446744073709551615UL
// PPC64:#define __SIZE_TYPE__ long unsigned int
// PPC64:#define __SIZE_WIDTH__ 64
// PPC64:#define __UINTMAX_TYPE__ long unsigned int
@@ -1913,6 +1975,7 @@
// PPC64-LINUX:#define __SIZEOF_SIZE_T__ 8
// PPC64-LINUX:#define __SIZEOF_WCHAR_T__ 4
// PPC64-LINUX:#define __SIZEOF_WINT_T__ 4
+// PPC64-LINUX:#define __SIZE_MAX__ 18446744073709551615UL
// PPC64-LINUX:#define __SIZE_TYPE__ long unsigned int
// PPC64-LINUX:#define __SIZE_WIDTH__ 64
// PPC64-LINUX:#define __UINTMAX_TYPE__ long unsigned int
@@ -2017,6 +2080,7 @@
// PPC:#define __SIZEOF_SIZE_T__ 4
// PPC:#define __SIZEOF_WCHAR_T__ 4
// PPC:#define __SIZEOF_WINT_T__ 4
+// PPC:#define __SIZE_MAX__ 4294967295U
// PPC:#define __SIZE_TYPE__ long unsigned int
// PPC:#define __SIZE_WIDTH__ 32
// PPC:#define __UINTMAX_TYPE__ long long unsigned int
@@ -2117,6 +2181,7 @@
// PPC-LINUX:#define __SIZEOF_SIZE_T__ 4
// PPC-LINUX:#define __SIZEOF_WCHAR_T__ 4
// PPC-LINUX:#define __SIZEOF_WINT_T__ 4
+// PPC-LINUX:#define __SIZE_MAX__ 4294967295U
// PPC-LINUX:#define __SIZE_TYPE__ unsigned int
// PPC-LINUX:#define __SIZE_WIDTH__ 32
// PPC-LINUX:#define __UINTMAX_TYPE__ long long unsigned int
@@ -2130,6 +2195,98 @@
// PPC-LINUX:#define __powerpc__ 1
// PPC-LINUX:#define __ppc__ 1
//
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=s390x-none-none -fno-signed-char < /dev/null | FileCheck -check-prefix S390X %s
+//
+// S390X:#define __CHAR16_TYPE__ unsigned short
+// S390X:#define __CHAR32_TYPE__ unsigned int
+// S390X:#define __CHAR_BIT__ 8
+// S390X:#define __CHAR_UNSIGNED__ 1
+// S390X:#define __DBL_DENORM_MIN__ 4.9406564584124654e-324
+// S390X:#define __DBL_DIG__ 15
+// S390X:#define __DBL_EPSILON__ 2.2204460492503131e-16
+// S390X:#define __DBL_HAS_DENORM__ 1
+// S390X:#define __DBL_HAS_INFINITY__ 1
+// S390X:#define __DBL_HAS_QUIET_NAN__ 1
+// S390X:#define __DBL_MANT_DIG__ 53
+// S390X:#define __DBL_MAX_10_EXP__ 308
+// S390X:#define __DBL_MAX_EXP__ 1024
+// S390X:#define __DBL_MAX__ 1.7976931348623157e+308
+// S390X:#define __DBL_MIN_10_EXP__ (-307)
+// S390X:#define __DBL_MIN_EXP__ (-1021)
+// S390X:#define __DBL_MIN__ 2.2250738585072014e-308
+// S390X:#define __DECIMAL_DIG__ 36
+// S390X:#define __FLT_DENORM_MIN__ 1.40129846e-45F
+// S390X:#define __FLT_DIG__ 6
+// S390X:#define __FLT_EPSILON__ 1.19209290e-7F
+// S390X:#define __FLT_EVAL_METHOD__ 0
+// S390X:#define __FLT_HAS_DENORM__ 1
+// S390X:#define __FLT_HAS_INFINITY__ 1
+// S390X:#define __FLT_HAS_QUIET_NAN__ 1
+// S390X:#define __FLT_MANT_DIG__ 24
+// S390X:#define __FLT_MAX_10_EXP__ 38
+// S390X:#define __FLT_MAX_EXP__ 128
+// S390X:#define __FLT_MAX__ 3.40282347e+38F
+// S390X:#define __FLT_MIN_10_EXP__ (-37)
+// S390X:#define __FLT_MIN_EXP__ (-125)
+// S390X:#define __FLT_MIN__ 1.17549435e-38F
+// S390X:#define __FLT_RADIX__ 2
+// S390X:#define __INT16_TYPE__ short
+// S390X:#define __INT32_TYPE__ int
+// S390X:#define __INT64_C_SUFFIX__ L
+// S390X:#define __INT64_TYPE__ long long int
+// S390X:#define __INT8_TYPE__ char
+// S390X:#define __INTMAX_MAX__ 9223372036854775807LL
+// S390X:#define __INTMAX_TYPE__ long long int
+// S390X:#define __INTMAX_WIDTH__ 64
+// S390X:#define __INTPTR_TYPE__ long int
+// S390X:#define __INTPTR_WIDTH__ 64
+// S390X:#define __INT_MAX__ 2147483647
+// S390X:#define __LDBL_DENORM_MIN__ 6.47517511943802511092443895822764655e-4966L
+// S390X:#define __LDBL_DIG__ 33
+// S390X:#define __LDBL_EPSILON__ 1.92592994438723585305597794258492732e-34L
+// S390X:#define __LDBL_HAS_DENORM__ 1
+// S390X:#define __LDBL_HAS_INFINITY__ 1
+// S390X:#define __LDBL_HAS_QUIET_NAN__ 1
+// S390X:#define __LDBL_MANT_DIG__ 113
+// S390X:#define __LDBL_MAX_10_EXP__ 4932
+// S390X:#define __LDBL_MAX_EXP__ 16384
+// S390X:#define __LDBL_MAX__ 1.18973149535723176508575932662800702e+4932L
+// S390X:#define __LDBL_MIN_10_EXP__ (-4931)
+// S390X:#define __LDBL_MIN_EXP__ (-16381)
+// S390X:#define __LDBL_MIN__ 3.36210314311209350626267781732175260e-4932L
+// S390X:#define __LONG_LONG_MAX__ 9223372036854775807LL
+// S390X:#define __LONG_MAX__ 9223372036854775807L
+// S390X:#define __NO_INLINE__ 1
+// S390X:#define __POINTER_WIDTH__ 64
+// S390X:#define __PTRDIFF_TYPE__ long int
+// S390X:#define __PTRDIFF_WIDTH__ 64
+// S390X:#define __SCHAR_MAX__ 127
+// S390X:#define __SHRT_MAX__ 32767
+// S390X:#define __SIG_ATOMIC_WIDTH__ 32
+// S390X:#define __SIZEOF_DOUBLE__ 8
+// S390X:#define __SIZEOF_FLOAT__ 4
+// S390X:#define __SIZEOF_INT__ 4
+// S390X:#define __SIZEOF_LONG_DOUBLE__ 16
+// S390X:#define __SIZEOF_LONG_LONG__ 8
+// S390X:#define __SIZEOF_LONG__ 8
+// S390X:#define __SIZEOF_POINTER__ 8
+// S390X:#define __SIZEOF_PTRDIFF_T__ 8
+// S390X:#define __SIZEOF_SHORT__ 2
+// S390X:#define __SIZEOF_SIZE_T__ 8
+// S390X:#define __SIZEOF_WCHAR_T__ 4
+// S390X:#define __SIZEOF_WINT_T__ 4
+// S390X:#define __SIZE_TYPE__ long unsigned int
+// S390X:#define __SIZE_WIDTH__ 64
+// S390X:#define __UINTMAX_TYPE__ long long unsigned int
+// S390X:#define __USER_LABEL_PREFIX__ _
+// S390X:#define __WCHAR_MAX__ 2147483647
+// S390X:#define __WCHAR_TYPE__ int
+// S390X:#define __WCHAR_WIDTH__ 32
+// S390X:#define __WINT_TYPE__ int
+// S390X:#define __WINT_WIDTH__ 32
+// S390X:#define __s390__ 1
+// S390X:#define __s390x__ 1
+//
// RUN: %clang_cc1 -E -dM -ffreestanding -triple=sparc-none-none < /dev/null | FileCheck -check-prefix SPARC %s
//
// SPARC-NOT:#define _LP64
@@ -2212,6 +2369,7 @@
// SPARC:#define __SIZEOF_SIZE_T__ 4
// SPARC:#define __SIZEOF_WCHAR_T__ 4
// SPARC:#define __SIZEOF_WINT_T__ 4
+// SPARC:#define __SIZE_MAX__ 4294967295U
// SPARC:#define __SIZE_TYPE__ long unsigned int
// SPARC:#define __SIZE_WIDTH__ 32
// SPARC:#define __UINTMAX_TYPE__ long long unsigned int
@@ -2306,6 +2464,7 @@
// TCE:#define __SIZEOF_SIZE_T__ 4
// TCE:#define __SIZEOF_WCHAR_T__ 4
// TCE:#define __SIZEOF_WINT_T__ 4
+// TCE:#define __SIZE_MAX__ 4294967295U
// TCE:#define __SIZE_TYPE__ unsigned int
// TCE:#define __SIZE_WIDTH__ 32
// TCE:#define __TCE_V1__ 1
@@ -2406,6 +2565,7 @@
// X86_64:#define __SIZEOF_SIZE_T__ 8
// X86_64:#define __SIZEOF_WCHAR_T__ 4
// X86_64:#define __SIZEOF_WINT_T__ 4
+// X86_64:#define __SIZE_MAX__ 18446744073709551615UL
// X86_64:#define __SIZE_TYPE__ long unsigned int
// X86_64:#define __SIZE_WIDTH__ 64
// X86_64:#define __SSE2_MATH__ 1
@@ -2509,6 +2669,7 @@
// X86_64-LINUX:#define __SIZEOF_SIZE_T__ 8
// X86_64-LINUX:#define __SIZEOF_WCHAR_T__ 4
// X86_64-LINUX:#define __SIZEOF_WINT_T__ 4
+// X86_64-LINUX:#define __SIZE_MAX__ 18446744073709551615UL
// X86_64-LINUX:#define __SIZE_TYPE__ long unsigned int
// X86_64-LINUX:#define __SIZE_WIDTH__ 64
// X86_64-LINUX:#define __SSE2_MATH__ 1
diff --git a/test/Preprocessor/line-directive.c b/test/Preprocessor/line-directive.c
index ffa7c5a419..ea0a36fca3 100644
--- a/test/Preprocessor/line-directive.c
+++ b/test/Preprocessor/line-directive.c
@@ -29,7 +29,7 @@
# 42 "foo" 3 1 // expected-error {{invalid flag line marker directive}}
# 42 "foo" 42 // expected-error {{invalid flag line marker directive}}
# 42 "foo" 1 2 // expected-error {{invalid flag line marker directive}}
-
+# 42a33 // expected-error {{GNU line marker directive requires a simple digit sequence}}
// These are checked by the RUN line.
#line 92 "blonk.c"
@@ -85,12 +85,20 @@ typedef int q; // original definition in system header, should not diagnose.
#line 010 // expected-warning {{#line directive interprets number as decimal, not octal}}
extern int array[__LINE__ == 10 ? 1:-1];
+# 020 // expected-warning {{GNU line marker directive interprets number as decimal, not octal}}
+extern int array_gnuline[__LINE__ == 20 ? 1:-1];
+
/* PR3917 */
#line 41
extern char array2[\
_\
_LINE__ == 42 ? 1: -1]; /* line marker is location of first _ */
+# 51
+extern char array2_gnuline[\
+_\
+_LINE__ == 52 ? 1: -1]; /* line marker is location of first _ */
+
// rdar://11550996
#line 0 "line-directive.c" // expected-warning {{#line directive with zero argument is a GNU extension}}
undefined t; // expected-error {{unknown type name 'undefined'}}
diff --git a/test/Preprocessor/macro_misc.c b/test/Preprocessor/macro_misc.c
index 53d99821cc..3feaa210f7 100644
--- a/test/Preprocessor/macro_misc.c
+++ b/test/Preprocessor/macro_misc.c
@@ -21,3 +21,17 @@
#define FUNC_LIKE3(a) ( a) // expected-note {{previous definition is here}}
#define FUNC_LIKE3(a) (a) // expected-warning {{'FUNC_LIKE3' macro redefined}}
+// RUN: %clang_cc1 -fms-extensions -DMS_EXT %s -Eonly -verify
+#ifndef MS_EXT
+// This should under C99.
+#define FUNC_LIKE4(a,b) (a+b) // expected-note {{previous definition is here}}
+#define FUNC_LIKE4(x,y) (x+y) // expected-warning {{'FUNC_LIKE4' macro redefined}}
+#else
+// This shouldn't under MS extensions.
+#define FUNC_LIKE4(a,b) (a+b)
+#define FUNC_LIKE4(x,y) (x+y)
+
+// This should.
+#define FUNC_LIKE5(a,b) (a+b) // expected-note {{previous definition is here}}
+#define FUNC_LIKE5(x,y) (y+x) // expected-warning {{'FUNC_LIKE5' macro redefined}}
+#endif
diff --git a/test/Preprocessor/pp-modules.c b/test/Preprocessor/pp-modules.c
new file mode 100644
index 0000000000..213a5fd23c
--- /dev/null
+++ b/test/Preprocessor/pp-modules.c
@@ -0,0 +1,15 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -x objective-c %s -F %S/../Modules/Inputs -E -o - | FileCheck %s
+
+// CHECK: int bar();
+int bar();
+// CHECK: @import Module; /* clang -E: implicit import for "{{.*Headers[/\\]Module.h}}" */
+#include <Module/Module.h>
+// CHECK: int foo();
+int foo();
+// CHECK: @import Module; /* clang -E: implicit import for "{{.*Headers[/\\]Module.h}}" */
+#include <Module/Module.h>
+
+#include "pp-modules.h" // CHECK: # 1 "{{.*}}pp-modules.h" 1
+// CHECK: @import Module; /* clang -E: implicit import for "{{.*}}Module.h" */{{$}}
+// CHECK: # 14 "{{.*}}pp-modules.c" 2
diff --git a/test/Preprocessor/pp-modules.h b/test/Preprocessor/pp-modules.h
new file mode 100644
index 0000000000..e4ccacf143
--- /dev/null
+++ b/test/Preprocessor/pp-modules.h
@@ -0,0 +1 @@
+#include <Module/Module.h>
diff --git a/test/Preprocessor/pragma-captured.c b/test/Preprocessor/pragma-captured.c
new file mode 100644
index 0000000000..be2a62b5e4
--- /dev/null
+++ b/test/Preprocessor/pragma-captured.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -E %s | FileCheck %s
+
+// Test pragma clang __debug captured, for Captured Statements
+
+void test1()
+{
+ #pragma clang __debug captured
+ {
+ }
+// CHECK: void test1()
+// CHECK: {
+// CHECK: #pragma clang __debug captured
+}
diff --git a/test/Preprocessor/pragma_sysheader.c b/test/Preprocessor/pragma_sysheader.c
index 075c9803a5..3c94363152 100644
--- a/test/Preprocessor/pragma_sysheader.c
+++ b/test/Preprocessor/pragma_sysheader.c
@@ -7,7 +7,7 @@
// PR9861: Verify that line markers are not messed up in -E mode.
// CHECK: # 1 "{{.*}}pragma_sysheader.h" 1
-// CHECK-NEXT: # 1 "{{.*}}pragma_sysheader.h" 3
+// CHECK-NEXT: # 2 "{{.*}}pragma_sysheader.h" 3
// CHECK-NEXT: typedef int x;
// CHECK-NEXT: typedef int x;
// CHECK-NEXT: # 6 "{{.*}}pragma_sysheader.c" 2
diff --git a/test/Preprocessor/predefined-arch-macros.c b/test/Preprocessor/predefined-arch-macros.c
index 680f39af71..d0125cd0ed 100644
--- a/test/Preprocessor/predefined-arch-macros.c
+++ b/test/Preprocessor/predefined-arch-macros.c
@@ -1094,6 +1094,52 @@
// CHECK_BTVER1_M64: #define __tune_btver1__ 1
// CHECK_BTVER1_M64: #define __x86_64 1
// CHECK_BTVER1_M64: #define __x86_64__ 1
+// RUN: %clang -march=btver2 -m32 -E -dM %s -o - 2>&1 \
+// RUN: -target i386-unknown-linux \
+// RUN: | FileCheck %s -check-prefix=CHECK_BTVER2_M32
+// CHECK_BTVER2_M32-NOT: #define __3dNOW_A__ 1
+// CHECK_BTVER2_M32-NOT: #define __3dNOW__ 1
+// CHECK_BTVER2_M32: #define __AES__ 1
+// CHECK_BTVER2_M32: #define __AVX__ 1
+// CHECK_BTVER2_M32: #define __LZCNT__ 1
+// CHECK_BTVER2_M32: #define __MMX__ 1
+// CHECK_BTVER2_M32: #define __POPCNT__ 1
+// CHECK_BTVER2_M32: #define __SSE2_MATH__ 1
+// CHECK_BTVER2_M32: #define __SSE2__ 1
+// CHECK_BTVER2_M32: #define __SSE3__ 1
+// CHECK_BTVER2_M32: #define __SSE4A__ 1
+// CHECK_BTVER2_M32: #define __SSE_MATH__ 1
+// CHECK_BTVER2_M32: #define __SSE__ 1
+// CHECK_BTVER2_M32: #define __SSSE3__ 1
+// CHECK_BTVER2_M32: #define __btver2 1
+// CHECK_BTVER2_M32: #define __btver2__ 1
+// CHECK_BTVER2_M32: #define __i386 1
+// CHECK_BTVER2_M32: #define __i386__ 1
+// CHECK_BTVER2_M32: #define __tune_btver2__ 1
+// RUN: %clang -march=btver2 -m64 -E -dM %s -o - 2>&1 \
+// RUN: -target i386-unknown-linux \
+// RUN: | FileCheck %s -check-prefix=CHECK_BTVER2_M64
+// CHECK_BTVER2_M64-NOT: #define __3dNOW_A__ 1
+// CHECK_BTVER2_M64-NOT: #define __3dNOW__ 1
+// CHECK_BTVER2_M64: #define __AES__ 1
+// CHECK_BTVER2_M64: #define __AVX__ 1
+// CHECK_BTVER2_M64: #define __LZCNT__ 1
+// CHECK_BTVER2_M64: #define __MMX__ 1
+// CHECK_BTVER2_M64: #define __POPCNT__ 1
+// CHECK_BTVER2_M64: #define __SSE2_MATH__ 1
+// CHECK_BTVER2_M64: #define __SSE2__ 1
+// CHECK_BTVER2_M64: #define __SSE3__ 1
+// CHECK_BTVER2_M64: #define __SSE4A__ 1
+// CHECK_BTVER2_M64: #define __SSE_MATH__ 1
+// CHECK_BTVER2_M64: #define __SSE__ 1
+// CHECK_BTVER2_M64: #define __SSSE3__ 1
+// CHECK_BTVER2_M64: #define __amd64 1
+// CHECK_BTVER2_M64: #define __amd64__ 1
+// CHECK_BTVER2_M64: #define __btver2 1
+// CHECK_BTVER2_M64: #define __btver2__ 1
+// CHECK_BTVER2_M64: #define __tune_btver2__ 1
+// CHECK_BTVER2_M64: #define __x86_64 1
+// CHECK_BTVER2_M64: #define __x86_64__ 1
// RUN: %clang -march=bdver1 -m32 -E -dM %s -o - 2>&1 \
// RUN: -target i386-unknown-linux \
// RUN: | FileCheck %s -check-prefix=CHECK_BDVER1_M32
diff --git a/test/Preprocessor/predefined-macros.c b/test/Preprocessor/predefined-macros.c
index 2c193018b5..94671f3335 100644
--- a/test/Preprocessor/predefined-macros.c
+++ b/test/Preprocessor/predefined-macros.c
@@ -26,3 +26,21 @@
// RUN: %clang_cc1 %s -E -dM -o - \
// RUN: | FileCheck %s --check-prefix=CHECK-FINITE-MATH-FLAG-UNDEFINED
// CHECK-FINITE-MATH-FLAG-UNDEFINED: #define __FINITE_MATH_ONLY__ 0
+//
+// RUN: %clang_cc1 %s -E -dM -o - -triple i686 -target-cpu i386 \
+// RUN: | FileCheck %s --check-prefix=CHECK-SYNC_CAS_I386
+// CHECK-SYNC_CAS_I386-NOT: __GCC_HAVE_SYNC_COMPARE_AND_SWAP
+//
+// RUN: %clang_cc1 %s -E -dM -o - -triple i686 -target-cpu i486 \
+// RUN: | FileCheck %s --check-prefix=CHECK-SYNC_CAS_I486
+// CHECK-SYNC_CAS_I486: __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1
+// CHECK-SYNC_CAS_I486: __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2
+// CHECK-SYNC_CAS_I486: __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
+// CHECK-SYNC_CAS_I486-NOT: __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8
+//
+// RUN: %clang_cc1 %s -E -dM -o - -triple i686 -target-cpu i586 \
+// RUN: | FileCheck %s --check-prefix=CHECK-SYNC_CAS_I586
+// CHECK-SYNC_CAS_I586: __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1
+// CHECK-SYNC_CAS_I586: __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2
+// CHECK-SYNC_CAS_I586: __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
+// CHECK-SYNC_CAS_I586: __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8
diff --git a/test/Preprocessor/stdint.c b/test/Preprocessor/stdint.c
index 70c106bf79..c3be05d97c 100644
--- a/test/Preprocessor/stdint.c
+++ b/test/Preprocessor/stdint.c
@@ -528,6 +528,113 @@
// PPC:INTMAX_C_(0) 0LL
// PPC:UINTMAX_C_(0) 0ULL
//
+// RUN: %clang_cc1 -E -ffreestanding -triple=s390x-none-none %s | FileCheck -check-prefix S390X %s
+//
+// S390X:typedef signed long long int int64_t;
+// S390X:typedef unsigned long long int uint64_t;
+// S390X:typedef int64_t int_least64_t;
+// S390X:typedef uint64_t uint_least64_t;
+// S390X:typedef int64_t int_fast64_t;
+// S390X:typedef uint64_t uint_fast64_t;
+//
+// S390X:typedef signed int int32_t;
+// S390X:typedef unsigned int uint32_t;
+// S390X:typedef int32_t int_least32_t;
+// S390X:typedef uint32_t uint_least32_t;
+// S390X:typedef int32_t int_fast32_t;
+// S390X:typedef uint32_t uint_fast32_t;
+//
+// S390X:typedef signed short int16_t;
+// S390X:typedef unsigned short uint16_t;
+// S390X:typedef int16_t int_least16_t;
+// S390X:typedef uint16_t uint_least16_t;
+// S390X:typedef int16_t int_fast16_t;
+// S390X:typedef uint16_t uint_fast16_t;
+//
+// S390X:typedef signed char int8_t;
+// S390X:typedef unsigned char uint8_t;
+// S390X:typedef int8_t int_least8_t;
+// S390X:typedef uint8_t uint_least8_t;
+// S390X:typedef int8_t int_fast8_t;
+// S390X:typedef uint8_t uint_fast8_t;
+//
+// S390X:typedef int64_t intptr_t;
+// S390X:typedef uint64_t uintptr_t;
+//
+// S390X:typedef long long int intmax_t;
+// S390X:typedef long long unsigned int uintmax_t;
+//
+// S390X:INT8_MAX_ 127
+// S390X:INT8_MIN_ (-127 -1)
+// S390X:UINT8_MAX_ 255
+// S390X:INT_LEAST8_MIN_ (-127 -1)
+// S390X:INT_LEAST8_MAX_ 127
+// S390X:UINT_LEAST8_MAX_ 255
+// S390X:INT_FAST8_MIN_ (-127 -1)
+// S390X:INT_FAST8_MAX_ 127
+// S390X:UINT_FAST8_MAX_ 255
+//
+// S390X:INT16_MAX_ 32767
+// S390X:INT16_MIN_ (-32767 -1)
+// S390X:UINT16_MAX_ 65535
+// S390X:INT_LEAST16_MIN_ (-32767 -1)
+// S390X:INT_LEAST16_MAX_ 32767
+// S390X:UINT_LEAST16_MAX_ 65535
+// S390X:INT_FAST16_MIN_ (-32767 -1)
+// S390X:INT_FAST16_MAX_ 32767
+// S390X:UINT_FAST16_MAX_ 65535
+//
+// S390X:INT32_MAX_ 2147483647
+// S390X:INT32_MIN_ (-2147483647 -1)
+// S390X:UINT32_MAX_ 4294967295U
+// S390X:INT_LEAST32_MIN_ (-2147483647 -1)
+// S390X:INT_LEAST32_MAX_ 2147483647
+// S390X:UINT_LEAST32_MAX_ 4294967295U
+// S390X:INT_FAST32_MIN_ (-2147483647 -1)
+// S390X:INT_FAST32_MAX_ 2147483647
+// S390X:UINT_FAST32_MAX_ 4294967295U
+//
+// S390X:INT64_MAX_ 9223372036854775807L
+// S390X:INT64_MIN_ (-9223372036854775807LL -1)
+// S390X:UINT64_MAX_ 18446744073709551615UL
+// S390X:INT_LEAST64_MIN_ (-9223372036854775807LL -1)
+// S390X:INT_LEAST64_MAX_ 9223372036854775807L
+// S390X:UINT_LEAST64_MAX_ 18446744073709551615UL
+// S390X:INT_FAST64_MIN_ (-9223372036854775807LL -1)
+// S390X:INT_FAST64_MAX_ 9223372036854775807L
+// S390X:UINT_FAST64_MAX_ 18446744073709551615UL
+//
+// S390X:INTPTR_MIN_ (-9223372036854775807LL -1)
+// S390X:INTPTR_MAX_ 9223372036854775807L
+// S390X:UINTPTR_MAX_ 18446744073709551615UL
+// S390X:PTRDIFF_MIN_ (-9223372036854775807LL -1)
+// S390X:PTRDIFF_MAX_ 9223372036854775807L
+// S390X:SIZE_MAX_ 18446744073709551615UL
+//
+// S390X:INTMAX_MIN_ (-9223372036854775807LL -1)
+// S390X:INTMAX_MAX_ 9223372036854775807L
+// S390X:UINTMAX_MAX_ 18446744073709551615UL
+//
+// S390X:SIG_ATOMIC_MIN_ (-2147483647 -1)
+// S390X:SIG_ATOMIC_MAX_ 2147483647
+// S390X:WINT_MIN_ (-2147483647 -1)
+// S390X:WINT_MAX_ 2147483647
+//
+// S390X:WCHAR_MAX_ 2147483647
+// S390X:WCHAR_MIN_ (-2147483647 -1)
+//
+// S390X:INT8_C_(0) 0
+// S390X:UINT8_C_(0) 0U
+// S390X:INT16_C_(0) 0
+// S390X:UINT16_C_(0) 0U
+// S390X:INT32_C_(0) 0
+// S390X:UINT32_C_(0) 0U
+// S390X:INT64_C_(0) 0L
+// S390X:UINT64_C_(0) 0UL
+//
+// S390X:INTMAX_C_(0) 0L
+// S390X:UINTMAX_C_(0) 0UL
+//
// RUN: %clang_cc1 -E -ffreestanding -triple=sparc-none-none %s | FileCheck -check-prefix SPARC %s
//
// SPARC:typedef signed long long int int64_t;
diff --git a/test/Rewriter/rewrite-byref-in-nested-blocks.mm b/test/Rewriter/rewrite-byref-in-nested-blocks.mm
index 022bb5f4e3..f416b6622f 100644
--- a/test/Rewriter/rewrite-byref-in-nested-blocks.mm
+++ b/test/Rewriter/rewrite-byref-in-nested-blocks.mm
@@ -19,7 +19,7 @@ void f(void (^block)(void));
- (void)foo {
__block int kerfluffle;
// radar 7692183
- __block x;
+ __block int x;
f(^{
f(^{
y = 42;
diff --git a/test/Rewriter/rewrite-line-directive.m b/test/Rewriter/rewrite-line-directive.m
new file mode 100644
index 0000000000..5c4e9574c1
--- /dev/null
+++ b/test/Rewriter/rewrite-line-directive.m
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -E %s -o %t.mm
+// RUN: %clang -fms-extensions -rewrite-objc %t.mm -o %t-rw.cpp
+// RUN: FileCheck -check-prefix LP --input-file=%t-rw.cpp %s
+// RUN: %clang -g -fms-extensions -rewrite-objc %t.mm -o %t-rw.cpp
+// RUN: FileCheck -check-prefix LPG --input-file=%t-rw.cpp %s
+// rdar://13138170
+
+int z();
+
+int x() {
+ id foo;
+ for (id y in foo) {
+ z();
+ }
+ return 0;
+}
+// CHECK-LP-NOT: #line
+// CHECK-LPG: #line
diff --git a/test/Rewriter/rewrite-modern-qualified-type.mm b/test/Rewriter/rewrite-modern-qualified-type.mm
new file mode 100644
index 0000000000..53e0d23ef2
--- /dev/null
+++ b/test/Rewriter/rewrite-modern-qualified-type.mm
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fms-extensions -rewrite-objc %s -o %t-modern-rw.cpp
+// RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -D_Bool=bool -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-modern-rw.cpp
+// rdar://13562505
+
+@protocol OS_dispatch_object @end
+
+@interface NSObject @end
+
+@protocol OS_dispatch_queue <OS_dispatch_object> @end typedef NSObject<OS_dispatch_queue> *dispatch_queue_t;
+
+typedef id<OS_dispatch_queue> dispatch_queue_i;
diff --git a/test/Sema/MicrosoftCompatibility.cpp b/test/Sema/MicrosoftCompatibility.cpp
new file mode 100644
index 0000000000..15c25586c4
--- /dev/null
+++ b/test/Sema/MicrosoftCompatibility.cpp
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 %s -fsyntax-only -Wno-unused-value -Wmicrosoft -verify -fms-compatibility
+
+// PR15845
+int foo(xxx); // expected-error{{unknown type name}}
diff --git a/test/Sema/anonymous-struct-union.c b/test/Sema/anonymous-struct-union.c
index e0822901b0..35d3175416 100644
--- a/test/Sema/anonymous-struct-union.c
+++ b/test/Sema/anonymous-struct-union.c
@@ -78,7 +78,7 @@ void g() {
struct s0 { union { int f0; }; };
// <rdar://problem/6481130>
-typedef struct { }; // expected-warning{{declaration does not declare anything}}
+typedef struct { }; // expected-warning{{typedef requires a name}}
// PR3675
struct s1 {
diff --git a/test/Sema/arm-neon-types.c b/test/Sema/arm-neon-types.c
index 1a170dbb7e..a49de12d44 100644
--- a/test/Sema/arm-neon-types.c
+++ b/test/Sema/arm-neon-types.c
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -triple thumbv7-apple-darwin10 -target-cpu cortex-a8 -fsyntax-only -Wvector-conversion -ffreestanding -verify %s
+#ifndef INCLUDE
#include <arm_neon.h>
@@ -33,3 +34,14 @@ int16x8_t test5(int *p) {
void test6(float *p, int32x2_t v) {
return vst1_s32(p, v); // expected-warning {{incompatible pointer types}}
}
+
+#define INCLUDE
+#include "arm-neon-types.c"
+#else
+
+// Make sure we don't get a warning about using a static function in an
+// extern inline function from a header.
+extern inline uint8x8_t test7(uint8x8_t a, uint8x8_t b) {
+ return vadd_u8(a, b);
+}
+#endif
diff --git a/test/Sema/array-init.c b/test/Sema/array-init.c
index b3cae60495..f92852f341 100644
--- a/test/Sema/array-init.c
+++ b/test/Sema/array-init.c
@@ -187,7 +187,7 @@ char r6[sizeof r5 == 15 ? 1 : -1];
const char r7[] = "zxcv";
char r8[5] = "5char";
char r9[5] = "6chars"; //expected-warning{{initializer-string for char array is too long}}
-
+unsigned char r10[] = __extension__ (_Generic(0, int: (__extension__ "foo" )));
int r11[0] = {}; //expected-warning{{zero size arrays are an extension}} expected-warning{{use of GNU empty initializer extension}}
// Some struct tests
diff --git a/test/Sema/asm.c b/test/Sema/asm.c
index 155d736b99..c81f16a387 100644
--- a/test/Sema/asm.c
+++ b/test/Sema/asm.c
@@ -123,3 +123,26 @@ void test13(void) {
void *esp;
__asm__ volatile ("mov %%esp, %o" : "=r"(esp) : : ); // expected-error {{invalid % escape in inline assembly string}}
}
+
+// <rdar://problem/12700799>
+struct S; // expected-note 2 {{forward declaration of 'struct S'}}
+void test14(struct S *s) {
+ __asm("": : "a"(*s)); // expected-error {{dereference of pointer to incomplete type 'struct S'}}
+ __asm("": "=a" (*s) :); // expected-error {{dereference of pointer to incomplete type 'struct S'}}
+}
+
+// PR15759.
+double test15() {
+ double ret = 0;
+ __asm("0.0":"="(ret)); // expected-error {{invalid output constraint '=' in asm}}
+ __asm("0.0":"=&"(ret)); // expected-error {{invalid output constraint '=&' in asm}}
+ __asm("0.0":"+?"(ret)); // expected-error {{invalid output constraint '+?' in asm}}
+ __asm("0.0":"+!"(ret)); // expected-error {{invalid output constraint '+!' in asm}}
+ __asm("0.0":"+#"(ret)); // expected-error {{invalid output constraint '+#' in asm}}
+ __asm("0.0":"+*"(ret)); // expected-error {{invalid output constraint '+*' in asm}}
+ __asm("0.0":"=%"(ret)); // expected-error {{invalid output constraint '=%' in asm}}
+ __asm("0.0":"=,="(ret)); // expected-error {{invalid output constraint '=,=' in asm}}
+ __asm("0.0":"=,g"(ret)); // no-error
+ __asm("0.0":"=g"(ret)); // no-error
+ return ret;
+}
diff --git a/test/Sema/atomic-expr.c b/test/Sema/atomic-expr.c
new file mode 100644
index 0000000000..ecc04c4c68
--- /dev/null
+++ b/test/Sema/atomic-expr.c
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+// expected-no-diagnostics
+
+_Atomic(unsigned int) data1;
+int _Atomic data2;
+
+// Shift operations
+
+int func_01 (int x) {
+ return data1 << x;
+}
+
+int func_02 (int x) {
+ return x << data1;
+}
+
+int func_03 (int x) {
+ return data2 << x;
+}
+
+int func_04 (int x) {
+ return x << data2;
+}
+
+int func_05 () {
+ return data2 << data1;
+}
+
+int func_06 () {
+ return data1 << data2;
+}
+
+void func_07 (int x) {
+ data1 <<= x;
+}
+
+void func_08 (int x) {
+ data2 <<= x;
+}
+
+void func_09 (int* xp) {
+ *xp <<= data1;
+}
+
+void func_10 (int* xp) {
+ *xp <<= data2;
+}
diff --git a/test/Sema/atomic-ops.c b/test/Sema/atomic-ops.c
index a33ff2b19c..b3daa0704d 100644
--- a/test/Sema/atomic-ops.c
+++ b/test/Sema/atomic-ops.c
@@ -173,3 +173,6 @@ void f(_Atomic(int) *i, _Atomic(int*) *p, _Atomic(float) *d,
__c11_atomic_store(&const_atomic, 0, memory_order_release); // expected-error {{first argument to atomic operation must be a pointer to non-const _Atomic type ('const _Atomic(int) *' invalid)}}
__c11_atomic_load(&const_atomic, memory_order_acquire); // expected-error {{first argument to atomic operation must be a pointer to non-const _Atomic type ('const _Atomic(int) *' invalid)}}
}
+
+_Atomic(int*) PR12527_a;
+void PR12527() { int *b = PR12527_a; }
diff --git a/test/Sema/bitfield.c b/test/Sema/bitfield.c
index a1ce894037..ab05a7773d 100644
--- a/test/Sema/bitfield.c
+++ b/test/Sema/bitfield.c
@@ -39,3 +39,18 @@ int y;
struct PR8025 {
double : 2; // expected-error{{anonymous bit-field has non-integral type 'double'}}
};
+
+struct Test4 {
+ unsigned bitX : 4;
+ unsigned bitY : 4;
+ unsigned var;
+};
+void test4(struct Test4 *t) {
+ (void) sizeof(t->bitX); // expected-error {{invalid application of 'sizeof' to bit-field}}
+ (void) sizeof((t->bitY)); // expected-error {{invalid application of 'sizeof' to bit-field}}
+ (void) sizeof(t->bitX = 4); // not a bitfield designator in C
+ (void) sizeof(t->bitX += 4); // not a bitfield designator in C
+ (void) sizeof((void) 0, t->bitX); // not a bitfield designator in C
+ (void) sizeof(t->var ? t->bitX : t->bitY); // not a bitfield designator in C
+ (void) sizeof(t->var ? t->bitX : t->bitX); // not a bitfield designator in C
+}
diff --git a/test/Sema/block-return.c b/test/Sema/block-return.c
index 2ea4d813ab..6b4d99830c 100644
--- a/test/Sema/block-return.c
+++ b/test/Sema/block-return.c
@@ -134,3 +134,14 @@ void foo7()
void (^blk)(void) = ^{
return (void)0; // expected-warning {{void block literal should not return void expression}}
};
+
+// rdar://13463504
+enum Test8 { T8_a, T8_b, T8_c };
+void test8(void) {
+ extern void test8_helper(int (^)(int));
+ test8_helper(^(int flag) { if (flag) return T8_a; return T8_b; });
+}
+void test8b(void) {
+ extern void test8_helper2(char (^)(int)); // expected-note {{here}}
+ test8_helper2(^(int flag) { if (flag) return T8_a; return T8_b; }); // expected-error {{passing 'enum Test8 (^)(int)' to parameter of type 'char (^)(int)'}}
+}
diff --git a/test/Sema/builtins-aarch64.c b/test/Sema/builtins-aarch64.c
new file mode 100644
index 0000000000..03e03343eb
--- /dev/null
+++ b/test/Sema/builtins-aarch64.c
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -fsyntax-only -verify %s
+
+void test_clear_cache_chars(char *start, char *end) {
+ __clear_cache(start, end);
+}
+
+void test_clear_cache_voids(void *start, void *end) {
+ __clear_cache(start, end);
+}
+
+void test_clear_cache_no_args() {
+ // AArch32 version of this is variadic (at least syntactically).
+ // However, on AArch64 GCC does not permit this call and the
+ // implementation I've seen would go disastrously wrong.
+ __clear_cache(); // expected-error {{too few arguments to function call}}
+}
diff --git a/test/Sema/captured-statements.c b/test/Sema/captured-statements.c
new file mode 100644
index 0000000000..9285a7802d
--- /dev/null
+++ b/test/Sema/captured-statements.c
@@ -0,0 +1,78 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -fblocks
+
+void test_gotos() {
+ goto L1; // expected-error {{use of undeclared label 'L1'}}
+ goto L3; // OK
+ #pragma clang __debug captured
+ {
+L1:
+ goto L2; // OK
+L2:
+ goto L3; // expected-error {{use of undeclared label 'L3'}}
+ }
+L3: ;
+}
+
+void test_break_continue() {
+ while (1) {
+ #pragma clang __debug captured
+ {
+ break; // expected-error {{'break' statement not in loop or switch statement}}
+ continue; // expected-error {{'continue' statement not in loop statement}}
+ }
+ }
+}
+
+void test_return() {
+ while (1) {
+ #pragma clang __debug captured
+ {
+ return; // expected-error {{cannot return from default captured statement}}
+ }
+ }
+}
+
+void test_nest() {
+ int x;
+ #pragma clang __debug captured
+ {
+ int y;
+ #pragma clang __debug captured
+ {
+ int z;
+ #pragma clang __debug captured
+ {
+ x = z = y; // OK
+ }
+ }
+ }
+}
+
+void test_nest_block() {
+ __block int x;
+ int y;
+ ^{
+ int z;
+ #pragma clang __debug captured
+ {
+ x = y; // OK
+ y = z; // expected-error{{variable is not assignable (missing __block type specifier)}}
+ z = y; // OK
+ }
+ }();
+
+ __block int a;
+ int b;
+ #pragma clang __debug captured
+ {
+ __block int c;
+ int d;
+ ^{
+ a = b; // OK
+ a = c; // OK
+ b = d; // OK - Consistent with block inside a lambda
+ c = a; // OK
+ d = b; // expected-error{{variable is not assignable (missing __block type specifier)}}
+ }();
+ }
+}
diff --git a/test/Sema/compare.c b/test/Sema/compare.c
index b5d4ef5d12..887bce0630 100644
--- a/test/Sema/compare.c
+++ b/test/Sema/compare.c
@@ -93,8 +93,8 @@ int ints(long a, unsigned long b) {
// (C,b)
(C == (unsigned long) b) +
(C == (unsigned int) b) +
- (C == (unsigned short) b) + // expected-warning {{comparison of constant 65536 with expression of type 'unsigned short' is always false}}
- (C == (unsigned char) b) + // expected-warning {{comparison of constant 65536 with expression of type 'unsigned char' is always false}}
+ (C == (unsigned short) b) + // expected-warning {{comparison of constant 'C' (65536) with expression of type 'unsigned short' is always false}}
+ (C == (unsigned char) b) + // expected-warning {{comparison of constant 'C' (65536) with expression of type 'unsigned char' is always false}}
((long) C == b) +
((int) C == b) +
((short) C == b) +
@@ -105,8 +105,8 @@ int ints(long a, unsigned long b) {
((signed char) C == (unsigned char) b) +
(C < (unsigned long) b) +
(C < (unsigned int) b) +
- (C < (unsigned short) b) + // expected-warning {{comparison of constant 65536 with expression of type 'unsigned short' is always false}}
- (C < (unsigned char) b) + // expected-warning {{comparison of constant 65536 with expression of type 'unsigned char' is always false}}
+ (C < (unsigned short) b) + // expected-warning {{comparison of constant 'C' (65536) with expression of type 'unsigned short' is always false}}
+ (C < (unsigned char) b) + // expected-warning {{comparison of constant 'C' (65536) with expression of type 'unsigned char' is always false}}
((long) C < b) +
((int) C < b) +
((short) C < b) +
@@ -123,8 +123,8 @@ int ints(long a, unsigned long b) {
(a == (unsigned char) C) +
((long) a == C) +
((int) a == C) +
- ((short) a == C) + // expected-warning {{comparison of constant 65536 with expression of type 'short' is always false}}
- ((signed char) a == C) + // expected-warning {{comparison of constant 65536 with expression of type 'signed char' is always false}}
+ ((short) a == C) + // expected-warning {{comparison of constant 'C' (65536) with expression of type 'short' is always false}}
+ ((signed char) a == C) + // expected-warning {{comparison of constant 'C' (65536) with expression of type 'signed char' is always false}}
((long) a == (unsigned long) C) +
((int) a == (unsigned int) C) +
((short) a == (unsigned short) C) +
@@ -135,8 +135,8 @@ int ints(long a, unsigned long b) {
(a < (unsigned char) C) +
((long) a < C) +
((int) a < C) +
- ((short) a < C) + // expected-warning {{comparison of constant 65536 with expression of type 'short' is always true}}
- ((signed char) a < C) + // expected-warning {{comparison of constant 65536 with expression of type 'signed char' is always true}}
+ ((short) a < C) + // expected-warning {{comparison of constant 'C' (65536) with expression of type 'short' is always true}}
+ ((signed char) a < C) + // expected-warning {{comparison of constant 'C' (65536) with expression of type 'signed char' is always true}}
((long) a < (unsigned long) C) + // expected-warning {{comparison of integers of different signs}}
((int) a < (unsigned int) C) + // expected-warning {{comparison of integers of different signs}}
((short) a < (unsigned short) C) +
diff --git a/test/Sema/crash-invalid-array.c b/test/Sema/crash-invalid-array.c
index a3bc03b70b..eeac39148c 100644
--- a/test/Sema/crash-invalid-array.c
+++ b/test/Sema/crash-invalid-array.c
@@ -15,3 +15,10 @@ int main()
p[i][i] = i;
}
}
+
+// rdar://13705391
+void foo(int a[*][2]) {(void)a[0][1]; } // expected-error {{variable length array must be bound in function definition}}
+void foo1(int a[2][*]) {(void)a[0][1]; } // expected-error {{variable length array must be bound in function definition}}
+void foo2(int a[*][*]) {(void)a[0][1]; } // expected-error {{variable length array must be bound in function definition}}
+void foo3(int a[2][*][2]) {(void)a[0][1][1]; } // expected-error {{variable length array must be bound in function definition}}
+void foo4(int a[2][*][*]) {(void)a[0][1][1]; } // expected-error {{variable length array must be bound in function definition}}
diff --git a/test/Sema/decl-invalid.c b/test/Sema/decl-invalid.c
index f6fed3c92d..0544304c20 100644
--- a/test/Sema/decl-invalid.c
+++ b/test/Sema/decl-invalid.c
@@ -1,7 +1,7 @@
// RUN: %clang_cc1 %s -fsyntax-only -verify
// See Sema::ParsedFreeStandingDeclSpec about the double diagnostic
-typedef union <anonymous> __mbstate_t; // expected-error {{declaration of anonymous union must be a definition}} expected-warning {{declaration does not declare anything}}
+typedef union <anonymous> __mbstate_t; // expected-error {{declaration of anonymous union must be a definition}} expected-warning {{typedef requires a name}}
// PR2017
@@ -14,7 +14,7 @@ int a() {
}
int; // expected-warning {{declaration does not declare anything}}
-typedef int; // expected-warning {{declaration does not declare anything}}
+typedef int; // expected-warning {{typedef requires a name}}
const int; // expected-warning {{declaration does not declare anything}}
struct; // expected-error {{declaration of anonymous struct must be a definition}} // expected-warning {{declaration does not declare anything}}
typedef int I;
diff --git a/test/Sema/declspec.c b/test/Sema/declspec.c
index 7354028cba..30c009201c 100644
--- a/test/Sema/declspec.c
+++ b/test/Sema/declspec.c
@@ -10,7 +10,7 @@ int typedef validTypeDecl() { } // expected-error {{function definition declared
struct _zend_module_entry { } // expected-error {{expected ';' after struct}}
int gv1;
typedef struct _zend_function_entry { } // expected-error {{expected ';' after struct}} \
- // expected-warning {{declaration does not declare anything}}
+ // expected-warning {{typedef requires a name}}
int gv2;
static void buggy(int *x) { }
diff --git a/test/Sema/expr-comma-c99.c b/test/Sema/expr-comma-c99.c
index 6e97a4fc49..02886bff05 100644
--- a/test/Sema/expr-comma-c99.c
+++ b/test/Sema/expr-comma-c99.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -fsyntax-only -verify -std=c99
+// RUN: %clang_cc1 %s -fsyntax-only -verify -std=c99 -Wno-sizeof-array-decay
// expected-no-diagnostics
// rdar://6095180
diff --git a/test/Sema/expr-comma.c b/test/Sema/expr-comma.c
index 7902715915..e2beafe236 100644
--- a/test/Sema/expr-comma.c
+++ b/test/Sema/expr-comma.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -fsyntax-only -verify -std=c89
+// RUN: %clang_cc1 %s -fsyntax-only -verify -std=c89 -Wno-sizeof-array-decay
// expected-no-diagnostics
// rdar://6095180
diff --git a/test/Sema/exprs.c b/test/Sema/exprs.c
index df3e25857c..2fb17e4880 100644
--- a/test/Sema/exprs.c
+++ b/test/Sema/exprs.c
@@ -94,7 +94,7 @@ int test8(void) {
struct f { int x : 4; float y[]; };
int test9(struct f *P) {
int R;
- R = __alignof(P->x); // expected-error {{invalid application of '__alignof' to bit-field}}
+ R = __alignof(P->x); // expected-error {{invalid application of 'alignof' to bit-field}}
R = __alignof(P->y); // ok.
R = sizeof(P->x); // expected-error {{invalid application of 'sizeof' to bit-field}}
return R;
diff --git a/test/Sema/extern-redecl.c b/test/Sema/extern-redecl.c
index ae4386eaae..e9a4c571bd 100644
--- a/test/Sema/extern-redecl.c
+++ b/test/Sema/extern-redecl.c
@@ -22,3 +22,43 @@ int PR10013(void) {
static int test1_a[]; // expected-warning {{tentative array definition assumed to have one element}}
extern int test1_a[];
+
+// rdar://13535367
+void test2declarer() { extern int test2_array[100]; }
+extern int test2_array[];
+int test2v = sizeof(test2_array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int []'}}
+
+void test3declarer() {
+ { extern int test3_array[100]; }
+ extern int test3_array[];
+ int x = sizeof(test3_array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int []'}}
+}
+
+void test4() {
+ extern int test4_array[];
+ {
+ extern int test4_array[100];
+ int x = sizeof(test4_array); // fine
+ }
+ int x = sizeof(test4_array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int []'}}
+}
+
+// Test that invalid local extern declarations of library
+// builtins behave reasonably.
+extern void abort(void); // expected-note 2 {{previous declaration is here}}
+extern float *calloc(); // expected-warning {{incompatible redeclaration of library function}} expected-note {{is a builtin}} expected-note 2 {{previous declaration is here}}
+void test5a() {
+ int abort(); // expected-error {{conflicting types}}
+ float *malloc(); // expected-warning {{incompatible redeclaration of library function}} expected-note 2 {{is a builtin}}
+ int *calloc(); // expected-error {{conflicting types}}
+}
+void test5b() {
+ int abort(); // expected-error {{conflicting types}}
+ float *malloc(); // expected-warning {{incompatible redeclaration of library function}}
+ int *calloc(); // expected-error {{conflicting types}}
+}
+void test5c() {
+ void (*_abort)(void) = &abort;
+ void *(*_malloc)() = &malloc;
+ float *(*_calloc)() = &calloc;
+}
diff --git a/test/Sema/function-redecl.c b/test/Sema/function-redecl.c
index 3ee8763a56..561f7fae6b 100644
--- a/test/Sema/function-redecl.c
+++ b/test/Sema/function-redecl.c
@@ -62,7 +62,7 @@ void test2() {
// <rdar://problem/6127293>
int outer1(int); // expected-note{{previous declaration is here}}
struct outer3 { };
-int outer4(int);
+int outer4(int); // expected-note{{previous declaration is here}}
int outer5; // expected-note{{previous definition is here}}
int *outer7(int);
@@ -70,7 +70,7 @@ void outer_test() {
int outer1(float); // expected-error{{conflicting types for 'outer1'}}
int outer2(int); // expected-note{{previous declaration is here}}
int outer3(int); // expected-note{{previous declaration is here}}
- int outer4(int); // expected-note{{previous declaration is here}}
+ int outer4(int);
int outer5(int); // expected-error{{redefinition of 'outer5' as different kind of symbol}}
int* outer6(int); // expected-note{{previous declaration is here}}
int *outer7(int);
diff --git a/test/Sema/function.c b/test/Sema/function.c
index 1b0dc2adeb..bbf81a56cb 100644
--- a/test/Sema/function.c
+++ b/test/Sema/function.c
@@ -92,3 +92,14 @@ void t20(int i...) { } // expected-error {{requires a comma}}
int n;
void t21(int n, int (*array)[n]);
+
+int func_e(int x) {
+ int func_n(int y) { // expected-error {{function definition is not allowed here}}
+ if (y > 22) {
+ return y+2;
+ } else {
+ return y-2;
+ }
+ }
+ return x + 3;
+}
diff --git a/test/Sema/inline.c b/test/Sema/inline.c
index c27c00efaa..496e282eca 100644
--- a/test/Sema/inline.c
+++ b/test/Sema/inline.c
@@ -73,6 +73,16 @@ inline int useStaticAgain () { // expected-note 2 {{use 'static' to give inline
#pragma clang diagnostic pop
+inline void defineStaticVar() { // expected-note {{use 'static' to give inline function 'defineStaticVar' internal linkage}}
+ static const int x = 0; // ok
+ static int y = 0; // expected-warning {{non-constant static local variable in inline function may be different in different files}}
+}
+
+extern inline void defineStaticVarInExtern() {
+ static const int x = 0; // ok
+ static int y = 0; // ok
+}
+
#endif
diff --git a/test/Sema/no-documentation-warn-tagdecl-specifier.c b/test/Sema/no-documentation-warn-tagdecl-specifier.c
new file mode 100644
index 0000000000..a0702ad7df
--- /dev/null
+++ b/test/Sema/no-documentation-warn-tagdecl-specifier.c
@@ -0,0 +1,85 @@
+// RUN: %clang_cc1 -fsyntax-only -Wdocumentation -verify %s
+// rdar://12390371
+
+/** @return s Test*/
+struct s* f(void);
+struct s;
+
+struct s1;
+/** @return s1 Test 1*/
+struct s1* f1(void);
+
+struct s2;
+/** @return s2 Test 2*/
+struct s2* f2(void);
+struct s2;
+
+// expected-warning@+1 {{'@return' command used in a comment that is not attached to a function or method declaration}}
+/** @return s3 Test 3 - expected warning here */
+struct s3;
+struct s3* f3(void);
+
+/** @return s4 Test 4 */
+struct s4* f4(void);
+struct s4 { int is; };
+
+// expected-warning@+1 {{'@return' command used in a comment that is not attached to a function or method declaration}}
+/** @return s5 Test 5 - expected warning here */
+struct s5 { int is; };
+struct s5* f5(void);
+
+// expected-warning@+1 {{'@return' command used in a comment that is not attached to a function or method declaration}}
+/** @return s6 Test 6 - expected warning here */
+struct s6 *ps6;
+struct s6* f6(void);
+
+// expected-warning@+1 {{'@return' command used in a comment that is not attached to a function or method declaration}}
+/** @return s7 Test 7 - expected warning here */
+struct s7;
+struct s7* f7(void);
+
+struct s8 { int is8; };
+/** @return s8 Test 8 */
+struct s4 *f8(struct s8 *p);
+
+
+/** @return e Test*/
+enum e* g(void);
+enum e;
+
+enum e1;
+/** @return e1 Test 1*/
+enum e1* g1(void);
+
+enum e2;
+/** @return e2 Test 2*/
+enum e2* g2(void);
+enum e2;
+
+// expected-warning@+1 {{'@return' command used in a comment that is not attached to a function or method declaration}}
+/** @return e3 Test 3 - expected warning here */
+enum e3;
+enum e3* g3(void);
+
+/** @return e4 Test 4 */
+enum e4* g4(void);
+enum e4 { one };
+
+// expected-warning@+1 {{'@return' command used in a comment that is not attached to a function or method declaration}}
+/** @return e5 Test 5 - expected warning here */
+enum e5 { two };
+enum e5* g5(void);
+
+// expected-warning@+1 {{'@return' command used in a comment that is not attached to a function or method declaration}}
+/** @return e6 Test 6 - expected warning here */
+enum e6 *pe6;
+enum e6* g6(void);
+
+// expected-warning@+1 {{'@return' command used in a comment that is not attached to a function or method declaration}}
+/** @return e7 Test 7 - expected warning here */
+enum e7;
+enum e7* g7(void);
+
+enum e8 { three };
+/** @return e8 Test 8 */
+enum e4 *g8(enum e8 *p);
diff --git a/test/Sema/parentheses.c b/test/Sema/parentheses.c
index c3b3aa77c5..300e585588 100644
--- a/test/Sema/parentheses.c
+++ b/test/Sema/parentheses.c
@@ -1,25 +1,44 @@
// RUN: %clang_cc1 -Wparentheses -fsyntax-only -verify %s
-// RUN: %clang_cc1 -Wparentheses -fixit %s -o - | %clang_cc1 -Wparentheses -Werror -
+// RUN: %clang_cc1 -Wparentheses -fsyntax-only -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
// Test the various warnings under -Wparentheses
void if_assign(void) {
int i;
if (i = 4) {} // expected-warning {{assignment as a condition}} \
- // expected-note{{use '==' to turn this assignment into an equality comparison}} \
- // expected-note{{place parentheses around the assignment to silence this warning}}
+ // expected-note{{place parentheses around the assignment to silence this warning}} \
+ // expected-note{{use '==' to turn this assignment into an equality comparison}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:7-[[@LINE-3]]:7}:"("
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:12-[[@LINE-4]]:12}:")"
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:9-[[@LINE-5]]:10}:"=="
+
if ((i = 4)) {}
}
void bitwise_rel(unsigned i) {
(void)(i & 0x2 == 0); // expected-warning {{& has lower precedence than ==}} \
- // expected-note{{place parentheses around the & expression to evaluate it first}} \
- // expected-note{{place parentheses around the '==' expression to silence this warning}}
+ // expected-note{{place parentheses around the '==' expression to silence this warning}} \
+ // expected-note{{place parentheses around the & expression to evaluate it first}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:14-[[@LINE-3]]:14}:"("
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:22-[[@LINE-4]]:22}:")"
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:10-[[@LINE-5]]:10}:"("
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:17-[[@LINE-6]]:17}:")"
+
(void)(0 == i & 0x2); // expected-warning {{& has lower precedence than ==}} \
- // expected-note{{place parentheses around the & expression to evaluate it first}} \
- // expected-note{{place parentheses around the '==' expression to silence this warning}}
+ // expected-note{{place parentheses around the '==' expression to silence this warning}} \
+ // expected-note{{place parentheses around the & expression to evaluate it first}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:10}:"("
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:16-[[@LINE-4]]:16}:")"
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:15-[[@LINE-5]]:15}:"("
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:22-[[@LINE-6]]:22}:")"
+
(void)(i & 0xff < 30); // expected-warning {{& has lower precedence than <}} \
- // expected-note{{place parentheses around the & expression to evaluate it first}} \
- // expected-note{{place parentheses around the '<' expression to silence this warning}}
+ // expected-note{{place parentheses around the '<' expression to silence this warning}} \
+ // expected-note{{place parentheses around the & expression to evaluate it first}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:14-[[@LINE-3]]:14}:"("
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:23-[[@LINE-4]]:23}:")"
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:10-[[@LINE-5]]:10}:"("
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:18-[[@LINE-6]]:18}:")"
+
(void)((i & 0x2) == 0);
(void)(i & (0x2 == 0));
// Eager logical op
@@ -28,19 +47,33 @@ void bitwise_rel(unsigned i) {
(void)(i & i | i); // expected-warning {{'&' within '|'}} \
// expected-note {{place parentheses around the '&' expression to silence this warning}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:10-[[@LINE-2]]:10}:"("
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:15-[[@LINE-3]]:15}:")"
(void)(i | i & i); // expected-warning {{'&' within '|'}} \
// expected-note {{place parentheses around the '&' expression to silence this warning}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:14-[[@LINE-2]]:14}:"("
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:19-[[@LINE-3]]:19}:")"
(void)(i ||
i && i); // expected-warning {{'&&' within '||'}} \
- // expected-note {{place parentheses around the '&&' expression to silence this warning}}
+ // expected-note {{place parentheses around the '&&' expression to silence this warning}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:14-[[@LINE-2]]:14}:"("
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:20-[[@LINE-3]]:20}:")"
+
(void)(i || i && "w00t"); // no warning.
(void)("w00t" && i || i); // no warning.
+
(void)(i || i && "w00t" || i); // expected-warning {{'&&' within '||'}} \
// expected-note {{place parentheses around the '&&' expression to silence this warning}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:15-[[@LINE-2]]:15}:"("
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:26-[[@LINE-3]]:26}:")"
+
(void)(i || "w00t" && i || i); // expected-warning {{'&&' within '||'}} \
// expected-note {{place parentheses around the '&&' expression to silence this warning}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:15-[[@LINE-2]]:15}:"("
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:26-[[@LINE-3]]:26}:")"
+
(void)(i && i || 0); // no warning.
(void)(0 || i && i); // no warning.
}
@@ -49,25 +82,41 @@ _Bool someConditionFunc();
void conditional_op(int x, int y, _Bool b) {
(void)(x + someConditionFunc() ? 1 : 2); // expected-warning {{operator '?:' has lower precedence than '+'}} \
- // expected-note {{place parentheses around the '?:' expression to evaluate it first}} \
- // expected-note {{place parentheses around the '+' expression to silence this warning}}
+ // expected-note {{place parentheses around the '+' expression to silence this warning}} \
+ // expected-note {{place parentheses around the '?:' expression to evaluate it first}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:10}:"("
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:33-[[@LINE-4]]:33}:")"
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:14-[[@LINE-5]]:14}:"("
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:41-[[@LINE-6]]:41}:")"
(void)((x + someConditionFunc()) ? 1 : 2); // no warning
(void)(x - b ? 1 : 2); // expected-warning {{operator '?:' has lower precedence than '-'}} \
- // expected-note {{place parentheses around the '?:' expression to evaluate it first}} \
- // expected-note {{place parentheses around the '-' expression to silence this warning}}
+ // expected-note {{place parentheses around the '-' expression to silence this warning}} \
+ // expected-note {{place parentheses around the '?:' expression to evaluate it first}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:10}:"("
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:15-[[@LINE-4]]:15}:")"
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:14-[[@LINE-5]]:14}:"("
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:23-[[@LINE-6]]:23}:")"
(void)(x * (x == y) ? 1 : 2); // expected-warning {{operator '?:' has lower precedence than '*'}} \
- // expected-note {{place parentheses around the '?:' expression to evaluate it first}} \
- // expected-note {{place parentheses around the '*' expression to silence this warning}}
+ // expected-note {{place parentheses around the '*' expression to silence this warning}} \
+ // expected-note {{place parentheses around the '?:' expression to evaluate it first}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:10}:"("
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:22-[[@LINE-4]]:22}:")"
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:14-[[@LINE-5]]:14}:"("
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:30-[[@LINE-6]]:30}:")"
(void)(x / !x ? 1 : 2); // expected-warning {{operator '?:' has lower precedence than '/'}} \
- // expected-note {{place parentheses around the '?:' expression to evaluate it first}} \
- // expected-note {{place parentheses around the '/' expression to silence this warning}}
+ // expected-note {{place parentheses around the '/' expression to silence this warning}} \
+ // expected-note {{place parentheses around the '?:' expression to evaluate it first}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:10}:"("
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:16-[[@LINE-4]]:16}:")"
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:14-[[@LINE-5]]:14}:"("
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:24-[[@LINE-6]]:24}:")"
(void)(x % 2 ? 1 : 2); // no warning
}
-// RUN: %clang_cc1 -fsyntax-only -Wparentheses -Werror -fdiagnostics-show-option %s 2>&1 | FileCheck %s
-// CHECK: error: using the result of an assignment as a condition without parentheses [-Werror,-Wparentheses]
+// RUN: %clang_cc1 -fsyntax-only -Wparentheses -Werror -fdiagnostics-show-option %s 2>&1 | FileCheck %s -check-prefix=CHECK-FLAG
+// CHECK-FLAG: error: using the result of an assignment as a condition without parentheses [-Werror,-Wparentheses]
diff --git a/test/Sema/parentheses.cpp b/test/Sema/parentheses.cpp
index 8f5f24652d..ac2694f72e 100644
--- a/test/Sema/parentheses.cpp
+++ b/test/Sema/parentheses.cpp
@@ -1,20 +1,32 @@
// RUN: %clang_cc1 -Wparentheses -fsyntax-only -verify %s
-// RUN: %clang_cc1 -Wparentheses -fixit %s -o - | %clang_cc1 -Wparentheses -Werror -
+// RUN: %clang_cc1 -Wparentheses -fsyntax-only -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
bool someConditionFunc();
void conditional_op(int x, int y, bool b) {
(void)(x + someConditionFunc() ? 1 : 2); // expected-warning {{operator '?:' has lower precedence than '+'}} \
- // expected-note {{place parentheses around the '?:' expression to evaluate it first}} \
- // expected-note {{place parentheses around the '+' expression to silence this warning}}
+ // expected-note {{place parentheses around the '+' expression to silence this warning}} \
+ // expected-note {{place parentheses around the '?:' expression to evaluate it first}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:10}:"("
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:33-[[@LINE-4]]:33}:")"
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:14-[[@LINE-5]]:14}:"("
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:41-[[@LINE-6]]:41}:")"
(void)(x - b ? 1 : 2); // expected-warning {{operator '?:' has lower precedence than '-'}} \
- // expected-note {{place parentheses around the '?:' expression to evaluate it first}} \
- // expected-note {{place parentheses around the '-' expression to silence this warning}}
+ // expected-note {{place parentheses around the '-' expression to silence this warning}} \
+ // expected-note {{place parentheses around the '?:' expression to evaluate it first}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:10}:"("
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:15-[[@LINE-4]]:15}:")"
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:14-[[@LINE-5]]:14}:"("
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:23-[[@LINE-6]]:23}:")"
(void)(x * (x == y) ? 1 : 2); // expected-warning {{operator '?:' has lower precedence than '*'}} \
- // expected-note {{place parentheses around the '?:' expression to evaluate it first}} \
- // expected-note {{place parentheses around the '*' expression to silence this warning}}
+ // expected-note {{place parentheses around the '*' expression to silence this warning}} \
+ // expected-note {{place parentheses around the '?:' expression to evaluate it first}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:10}:"("
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:22-[[@LINE-4]]:22}:")"
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:14-[[@LINE-5]]:14}:"("
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:30-[[@LINE-6]]:30}:")"
}
class Stream {
@@ -28,8 +40,28 @@ public:
void f(Stream& s, bool b) {
(void)(s << b ? "foo" : "bar"); // expected-warning {{operator '?:' has lower precedence than '<<'}} \
- // expected-note {{place parentheses around the '?:' expression to evaluate it first}} \
- // expected-note {{place parentheses around the '<<' expression to silence this warning}}
+ // expected-note {{place parentheses around the '<<' expression to silence this warning}} \
+ // expected-note {{place parentheses around the '?:' expression to evaluate it first}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:10}:"("
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:16-[[@LINE-4]]:16}:")"
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:15-[[@LINE-5]]:15}:"("
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:32-[[@LINE-6]]:32}:")"
+
+ (void)(s << 5 == 1); // expected-warning {{overloaded operator << has lower precedence than comparison operator}} \
+ // expected-note {{place parentheses around the '<<' expression to silence this warning}} \
+ // expected-note {{place parentheses around comparison expression to evaluate it first}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:10}:"("
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:16-[[@LINE-4]]:16}:")"
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:15-[[@LINE-5]]:15}:"("
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:21-[[@LINE-6]]:21}:")"
+
+ (void)(s >> 5 == 1); // expected-warning {{overloaded operator >> has lower precedence than comparison operator}} \
+ // expected-note {{place parentheses around the '>>' expression to silence this warning}} \
+ // expected-note {{place parentheses around comparison expression to evaluate it first}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:10}:"("
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:16-[[@LINE-4]]:16}:")"
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:15-[[@LINE-5]]:15}:"("
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:21-[[@LINE-6]]:21}:")"
}
struct S {
@@ -39,8 +71,12 @@ struct S {
void test(S *s, bool (S::*m_ptr)()) {
(void)(*s + true ? "foo" : "bar"); // expected-warning {{operator '?:' has lower precedence than '+'}} \
- // expected-note {{place parentheses around the '?:' expression to evaluate it first}} \
- // expected-note {{place parentheses around the '+' expression to silence this warning}}
+ // expected-note {{place parentheses around the '+' expression to silence this warning}} \
+ // expected-note {{place parentheses around the '?:' expression to evaluate it first}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:10}:"("
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:19-[[@LINE-4]]:19}:")"
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:15-[[@LINE-5]]:15}:"("
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:35-[[@LINE-6]]:35}:")"
(void)((*s + true) ? "foo" : "bar"); // No warning.
@@ -51,9 +87,29 @@ void test(S *s, bool (S::*m_ptr)()) {
void test(int a, int b, int c) {
(void)(a >> b + c); // expected-warning {{operator '>>' has lower precedence than '+'; '+' will be evaluated first}} \
expected-note {{place parentheses around the '+' expression to silence this warning}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:15-[[@LINE-2]]:15}:"("
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:20-[[@LINE-3]]:20}:")"
+
(void)(a - b << c); // expected-warning {{operator '<<' has lower precedence than '-'; '-' will be evaluated first}} \
expected-note {{place parentheses around the '-' expression to silence this warning}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:10-[[@LINE-2]]:10}:"("
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:15-[[@LINE-3]]:15}:")"
+
Stream() << b + c;
Stream() >> b + c; // expected-warning {{operator '>>' has lower precedence than '+'; '+' will be evaluated first}} \
expected-note {{place parentheses around the '+' expression to silence this warning}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:15-[[@LINE-2]]:15}:"("
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:20-[[@LINE-3]]:20}:")"
+}
+
+namespace PR15628 {
+ struct BlockInputIter {
+ void* operator++(int);
+ void* operator--(int);
+ };
+
+ void test(BlockInputIter i) {
+ (void)(i++ ? true : false); // no-warning
+ (void)(i-- ? true : false); // no-warning
+ }
}
diff --git a/test/Sema/pragma-arc-cf-code-audited.c b/test/Sema/pragma-arc-cf-code-audited.c
index b646e8966c..c1aa804557 100644
--- a/test/Sema/pragma-arc-cf-code-audited.c
+++ b/test/Sema/pragma-arc-cf-code-audited.c
@@ -13,6 +13,6 @@
#include "Inputs/pragma-arc-cf-code-audited.h" // expected-error {{cannot #include files inside '#pragma clang arc_cf_code_audited'}}
// This is actually on the #pragma line in the header.
-// expected-error {{'#pragma clang arc_cf_code_audited' was not ended within this file}}
+// expected-error@Inputs/pragma-arc-cf-code-audited.h:16 {{'#pragma clang arc_cf_code_audited' was not ended within this file}}
#pragma clang arc_cf_code_audited begin // expected-error {{'#pragma clang arc_cf_code_audited' was not ended within this file}}
diff --git a/test/Sema/private-extern.c b/test/Sema/private-extern.c
index e480f3f224..e9b67d5070 100644
--- a/test/Sema/private-extern.c
+++ b/test/Sema/private-extern.c
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -verify -fsyntax-only -Wno-private-extern %s
+// RUN: %clang_cc1 -verify -fsyntax-only -Wno-private-extern -fmodules %s
static int g0; // expected-note{{previous definition}}
int g0; // expected-error{{non-static declaration of 'g0' follows static declaration}}
diff --git a/test/Sema/return.c b/test/Sema/return.c
index 77bd3f688e..7e7c8b7b84 100644
--- a/test/Sema/return.c
+++ b/test/Sema/return.c
@@ -197,8 +197,14 @@ int test29() {
exit(1);
}
-#include <setjmp.h>
+// Include these declarations here explicitly so we don't depend on system headers.
+typedef struct __jmp_buf_tag{} jmp_buf[1];
+
+extern void longjmp (struct __jmp_buf_tag __env[1], int __val) __attribute__ ((noreturn));
+extern void _longjmp (struct __jmp_buf_tag __env[1], int __val) __attribute__ ((noreturn));
+
jmp_buf test30_j;
+
int test30() {
if (j)
longjmp(test30_j, 1);
@@ -244,6 +250,11 @@ const int ignored_c_quals(); // expected-warning{{'const' type qualifier on retu
const volatile int ignored_cv_quals(); // expected-warning{{'const volatile' type qualifiers on return type have no effect}}
char* const volatile restrict ignored_cvr_quals(); // expected-warning{{'const volatile restrict' type qualifiers on return type have no effect}}
+typedef const int CI;
+CI ignored_quals_typedef();
+
+const CI ignored_quals_typedef_2(); // expected-warning{{'const' type qualifier}}
+
// Test that for switch(enum) that if the switch statement covers all the cases
// that we don't consider that for -Wreturn-type.
enum Cases { C1, C2, C3, C4 };
diff --git a/test/Sema/static-assert.c b/test/Sema/static-assert.c
index 9309987431..87fa0504b2 100644
--- a/test/Sema/static-assert.c
+++ b/test/Sema/static-assert.c
@@ -1,6 +1,10 @@
-// RUN: %clang_cc1 -std=c1x -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c11 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -xc++ -std=c++11 -fsyntax-only -verify %s
-_Static_assert("foo", "string is nonzero"); // expected-error {{static_assert expression is not an integral constant expression}}
+_Static_assert("foo", "string is nonzero");
+#ifndef __cplusplus
+// expected-error@-2 {{static_assert expression is not an integral constant expression}}
+#endif
_Static_assert(1, "1 is nonzero");
_Static_assert(0, "0 is nonzero"); // expected-error {{static_assert failed "0 is nonzero"}}
@@ -11,3 +15,28 @@ void foo(void) {
}
_Static_assert(1, invalid); // expected-error {{expected string literal for diagnostic message in static_assert}}
+
+struct A {
+ int a;
+ _Static_assert(1, "1 is nonzero");
+ _Static_assert(0, "0 is nonzero"); // expected-error {{static_assert failed "0 is nonzero"}}
+};
+
+#ifdef __cplusplus
+#define ASSERT_IS_TYPE(T) __is_same(T, T)
+#else
+#define ASSERT_IS_TYPE(T) __builtin_types_compatible_p(T, T)
+#endif
+
+#define UNION(T1, T2) union { \
+ __typeof__(T1) one; \
+ __typeof__(T2) two; \
+ _Static_assert(ASSERT_IS_TYPE(T1), "T1 is not a type"); \
+ _Static_assert(ASSERT_IS_TYPE(T2), "T2 is not a type"); \
+ _Static_assert(sizeof(T1) == sizeof(T2), "type size mismatch"); \
+ }
+
+typedef UNION(unsigned, struct A) U1;
+UNION(char[2], short) u2 = { .one = { 'a', 'b' } };
+typedef UNION(char, short) U3; // expected-error {{static_assert failed "type size mismatch"}}
+typedef UNION(float, 0.5f) U4; // expected-error {{expected a type}}
diff --git a/test/Sema/struct-decl.c b/test/Sema/struct-decl.c
index 6070e875f5..819e856ac8 100644
--- a/test/Sema/struct-decl.c
+++ b/test/Sema/struct-decl.c
@@ -54,6 +54,6 @@ static struct test1 { // expected-warning {{'static' ignored on this declaration
const struct test2 { // expected-warning {{'const' ignored on this declaration}}
int x;
};
-inline struct test3 { // expected-warning {{'inline' ignored on this declaration}}
+inline struct test3 { // expected-error {{'inline' can only appear on functions}}
int x;
};
diff --git a/test/Sema/switch-1.c b/test/Sema/switch-1.c
index 82ce6747a3..ce1e7dc943 100644
--- a/test/Sema/switch-1.c
+++ b/test/Sema/switch-1.c
@@ -1,6 +1,7 @@
// RUN: %clang_cc1 -fsyntax-only -verify -triple x86_64-apple-darwin10 %s
// RUN: %clang_cc1 -x c++ -fsyntax-only -verify -triple x86_64-apple-darwin10 %s
// rdar://11577384
+// rdar://13423975
int f(int i) {
switch (i) {
@@ -10,6 +11,9 @@ int f(int i) {
return 2;
case (123456 *789012) + 1: // expected-warning {{overflow in expression; result is -1375982336 with type 'int'}}
return 3;
+ case (2147483647*4)/4: // expected-warning {{overflow in expression; result is -4 with type 'int'}}
+ case (2147483647*4)%4: // expected-warning {{overflow in expression; result is -4 with type 'int'}}
+ return 4;
case 2147483647:
return 0;
}
diff --git a/test/Sema/thread-specifier.c b/test/Sema/thread-specifier.c
index 8c40fcd0a6..9d516e8f14 100644
--- a/test/Sema/thread-specifier.c
+++ b/test/Sema/thread-specifier.c
@@ -1,30 +1,110 @@
-// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -Wno-private-extern -verify -pedantic %s
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -Wno-private-extern -verify -pedantic %s -DGNU
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -Wno-private-extern -verify -pedantic -x c++ %s -DGNU
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -Wno-private-extern -verify -pedantic %s -DC11 -D__thread=_Thread_local
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -Wno-private-extern -verify -pedantic -x c++ %s -DC11 -D__thread=_Thread_local
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -Wno-private-extern -verify -pedantic -x c++ %s -DCXX11 -D__thread=thread_local -std=c++11
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -Wno-private-extern -verify -pedantic -x c++ %s -DC11 -D__thread=_Thread_local -std=c++11
+
+#ifdef __cplusplus
+// In C++, we define __private_extern__ to extern.
+#undef __private_extern__
+#endif
__thread int t1;
-__thread extern int t2; // expected-warning {{'__thread' before 'extern'}}
-__thread static int t3; // expected-warning {{'__thread' before 'static'}}
+__thread extern int t2;
+__thread static int t3;
+#ifdef GNU
+// expected-warning@-3 {{'__thread' before 'extern'}}
+// expected-warning@-3 {{'__thread' before 'static'}}
+#endif
+
__thread __private_extern__ int t4;
-struct t5 { __thread int x; }; // expected-error {{type name does not allow storage class to be specified}}
-__thread int t6(); // expected-error {{'__thread' is only allowed on variable declarations}}
+struct t5 { __thread int x; };
+#ifdef __cplusplus
+// expected-error-re@-2 {{'(__thread|_Thread_local|thread_local)' is only allowed on variable declarations}}
+#else
+// FIXME: The 'is only allowed on variable declarations' diagnostic is better here.
+// expected-error@-5 {{type name does not allow storage class to be specified}}
+#endif
-int f(__thread int t7) { // expected-error {{'__thread' is only allowed on variable declarations}}
- __thread int t8; // expected-error {{'__thread' variables must have global storage}}
+__thread int t6();
+#if defined(GNU)
+// expected-error@-2 {{'__thread' is only allowed on variable declarations}}
+#elif defined(C11)
+// expected-error@-4 {{'_Thread_local' is only allowed on variable declarations}}
+#else
+// expected-error@-6 {{'thread_local' is only allowed on variable declarations}}
+#endif
+
+int f(__thread int t7) { // expected-error {{' is only allowed on variable declarations}}
+ __thread int t8;
+#if defined(GNU)
+ // expected-error@-2 {{'__thread' variables must have global storage}}
+#elif defined(C11)
+ // expected-error@-4 {{'_Thread_local' variables must have global storage}}
+#endif
extern __thread int t9;
static __thread int t10;
__thread __private_extern__ int t11;
- __thread auto int t12; // expected-error {{'__thread' variables must have global storage}}
- __thread register int t13; // expected-error {{'__thread' variables must have global storage}}
+#if __cplusplus < 201103L
+ __thread auto int t12a; // expected-error-re {{cannot combine with previous '(__thread|_Thread_local)' declaration specifier}}
+ auto __thread int t12b; // expected-error {{cannot combine with previous 'auto' declaration specifier}}
+#elif !defined(CXX11)
+ __thread auto t12a = 0; // expected-error-re {{'_Thread_local' variables must have global storage}}
+ auto __thread t12b = 0; // expected-error-re {{'_Thread_local' variables must have global storage}}
+#endif
+ __thread register int t13a; // expected-error-re {{cannot combine with previous '(__thread|_Thread_local|thread_local)' declaration specifier}}
+ register __thread int t13b; // expected-error {{cannot combine with previous 'register' declaration specifier}}
}
-__thread typedef int t14; // expected-error {{'__thread' is only allowed on variable declarations}}
-__thread int t15; // expected-note {{previous definition is here}}
-int t15; // expected-error {{non-thread-local declaration of 't15' follows thread-local declaration}}
-int t16; // expected-note {{previous definition is here}}
+__thread typedef int t14; // expected-error-re {{cannot combine with previous '(__thread|_Thread_local|thread_local)' declaration specifier}}
+__thread int t15; // expected-note {{previous declaration is here}}
+extern int t15; // expected-error {{non-thread-local declaration of 't15' follows thread-local declaration}}
+extern int t16; // expected-note {{previous declaration is here}}
__thread int t16; // expected-error {{thread-local declaration of 't16' follows non-thread-local declaration}}
+#ifdef CXX11
+extern thread_local int t17; // expected-note {{previous declaration is here}}
+_Thread_local int t17; // expected-error {{thread-local declaration of 't17' with static initialization follows declaration with dynamic initialization}}
+extern _Thread_local int t18; // expected-note {{previous declaration is here}}
+thread_local int t18; // expected-error {{thread-local declaration of 't18' with dynamic initialization follows declaration with static initialization}}
+#endif
+
// PR13720
__thread int thread_int;
-int *thread_int_ptr = &thread_int; // expected-error{{initializer element is not a compile-time constant}}
+int *thread_int_ptr = &thread_int;
+#ifndef __cplusplus
+// expected-error@-2 {{initializer element is not a compile-time constant}}
+#endif
void g() {
int *p = &thread_int; // This is perfectly fine, though.
}
+#if __cplusplus >= 201103L
+constexpr int *thread_int_ptr_2 = &thread_int; // expected-error {{must be initialized by a constant expression}}
+#endif
+
+int non_const();
+__thread int non_const_init = non_const();
+#if !defined(__cplusplus)
+// expected-error@-2 {{initializer element is not a compile-time constant}}
+#elif !defined(CXX11)
+// expected-error@-4 {{initializer for thread-local variable must be a constant expression}}
+#if __cplusplus >= 201103L
+// expected-note@-6 {{use 'thread_local' to allow this}}
+#endif
+#endif
+
+#ifdef __cplusplus
+struct S {
+ ~S();
+};
+__thread S s;
+#if !defined(CXX11)
+// expected-error@-2 {{type of thread-local variable has non-trivial destruction}}
+#if __cplusplus >= 201103L
+// expected-note@-4 {{use 'thread_local' to allow this}}
+#endif
+#endif
+#endif
+
+__thread int aggregate[10] = {0};
diff --git a/test/Sema/var-redecl.c b/test/Sema/var-redecl.c
index f7576b6c02..363458b201 100644
--- a/test/Sema/var-redecl.c
+++ b/test/Sema/var-redecl.c
@@ -4,7 +4,7 @@ int outer1; // expected-note{{previous definition is here}}
extern int outer2; // expected-note{{previous definition is here}}
int outer4;
int outer4; // expected-note{{previous definition is here}}
-int outer5;
+int outer5; // expected-note{{previous definition is here}}
int outer6(float); // expected-note{{previous definition is here}}
int outer7(float);
@@ -13,7 +13,7 @@ void outer_test() {
extern float outer2; // expected-error{{redefinition of 'outer2' with a different type}}
extern float outer3; // expected-note{{previous definition is here}}
double outer4;
- extern int outer5; // expected-note{{previous definition is here}}
+ extern int outer5;
extern int outer6; // expected-error{{redefinition of 'outer6' as different kind of symbol}}
int outer7;
extern int outer8; // expected-note{{previous definition is here}}
diff --git a/test/Sema/warn-documentation.cpp b/test/Sema/warn-documentation.cpp
index 0132ef280c..b3ab0199dc 100644
--- a/test/Sema/warn-documentation.cpp
+++ b/test/Sema/warn-documentation.cpp
@@ -892,10 +892,10 @@ typedef const struct test_nocrash7 * test_nocrash8;
// We used to crash on this.
+// expected-warning@+1 {{unknown command tag name}}
/// aaa \unknown aaa \unknown aaa
int test_nocrash9;
-
// We used to crash on this. PR15068
// expected-warning@+2 {{empty paragraph passed to '@param' command}}
diff --git a/test/Sema/warn-documentation.m b/test/Sema/warn-documentation.m
index 98c4993561..0737a8dedd 100644
--- a/test/Sema/warn-documentation.m
+++ b/test/Sema/warn-documentation.m
@@ -123,6 +123,20 @@ typedef id OBJ;
}
@end
+// rdar://12379114
+// expected-warning@+4 {{'@methodgroup' command should be used in a comment attached to an Objective-C method declaration}}
+// expected-warning@+6 {{'@method' command should be used in a comment attached to an Objective-C method declaratio}}
+@interface rdar12379114
+/*!
+ @methodgroup Creating a request
+*/
+/*!
+ @method initWithTimeout is the 2nd method
+*/
+typedef unsigned int NSTimeInterval;
+- (id)initWithTimeout:(NSTimeInterval)timeout;
+@end
+
// expected-warning@+2 {{'@protocol' command should not be used in a comment attached to a non-protocol declaration}}
/*!
@protocol PROTO
@@ -135,6 +149,7 @@ struct S;
@class NSArray;
@interface NSArray @end
+// expected-warning@+3 {{unknown command tag name}}
/*!
@interface NSMutableArray
@super NSArray
diff --git a/test/Sema/warn-duplicate-enum.c b/test/Sema/warn-duplicate-enum.c
index 239f6f1995..f108b3aa6c 100644
--- a/test/Sema/warn-duplicate-enum.c
+++ b/test/Sema/warn-duplicate-enum.c
@@ -90,3 +90,12 @@ enum {
NMax = N2,
NCount = NMax + 1
};
+
+// PR15693
+enum enum1 {
+ VALUE // expected-note{{previous definition is here}}
+};
+
+enum enum2 {
+ VALUE // expected-error{{redefinition of enumerator 'VALUE'}}
+};
diff --git a/test/Sema/warn-sizeof-array-decay.c b/test/Sema/warn-sizeof-array-decay.c
new file mode 100644
index 0000000000..cc3ee1d0fc
--- /dev/null
+++ b/test/Sema/warn-sizeof-array-decay.c
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+void f(int x) {
+ char foo[10];
+ int bar[20];
+ char qux[30];
+
+ (void)sizeof(bar + 10); // expected-warning{{sizeof on pointer operation will return size of 'int *' instead of 'int [20]'}}
+ (void)sizeof(foo - 20); // expected-warning{{sizeof on pointer operation will return size of 'char *' instead of 'char [10]'}}
+ (void)sizeof(bar - x); // expected-warning{{sizeof on pointer operation will return size of 'int *' instead of 'int [20]'}}
+ (void)sizeof(foo + x); // expected-warning{{sizeof on pointer operation will return size of 'char *' instead of 'char [10]'}}
+
+ // This is ptrdiff_t.
+ (void)sizeof(foo - qux); // no-warning
+
+ (void)sizeof(foo, x); // no-warning
+ (void)sizeof(x, foo); // expected-warning{{sizeof on pointer operation will return size of 'char *' instead of 'char [10]'}}
+}
diff --git a/test/Sema/warn-unused-variables-werror.c b/test/Sema/warn-unused-variables-werror.c
new file mode 100644
index 0000000000..ceaff1ba69
--- /dev/null
+++ b/test/Sema/warn-unused-variables-werror.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fsyntax-only -Wunused-variable -Werror -verify %s
+
+void f() {
+ int i; // expected-error{{unused}}
+ int j; // expected-error{{unused}}
+}
diff --git a/test/SemaCXX/Inputs/warn-unused-variables.h b/test/SemaCXX/Inputs/warn-unused-variables.h
new file mode 100644
index 0000000000..5fac45922c
--- /dev/null
+++ b/test/SemaCXX/Inputs/warn-unused-variables.h
@@ -0,0 +1,11 @@
+// Verify that we don't warn about variables of internal-linkage type in
+// headers, as the use may be in another TU.
+namespace PR15558 {
+namespace {
+class A {};
+}
+
+class B {
+ static A a;
+};
+}
diff --git a/test/SemaCXX/MicrosoftExtensions.cpp b/test/SemaCXX/MicrosoftExtensions.cpp
index 449e24b03b..ab3ff69f27 100644
--- a/test/SemaCXX/MicrosoftExtensions.cpp
+++ b/test/SemaCXX/MicrosoftExtensions.cpp
@@ -208,3 +208,128 @@ void ::f(); // expected-warning{{extra qualification on member 'f'}}
class C {
C::C(); // expected-warning{{extra qualification on member 'C'}}
};
+
+struct StructWithProperty {
+ __declspec(property(get=GetV)) int V1;
+ __declspec(property(put=SetV)) int V2;
+ __declspec(property(get=GetV, put=SetV_NotExist)) int V3;
+ __declspec(property(get=GetV_NotExist, put=SetV)) int V4;
+ __declspec(property(get=GetV, put=SetV)) int V5;
+
+ int GetV() { return 123; }
+ void SetV(int i) {}
+};
+void TestProperty() {
+ StructWithProperty sp;
+ int i = sp.V2; // expected-error{{no getter defined for property 'V2'}}
+ sp.V1 = 12; // expected-error{{no setter defined for property 'V1'}}
+ int j = sp.V4; // expected-error{{no member named 'GetV_NotExist' in 'StructWithProperty'}} expected-error{{cannot find suitable getter for property 'V4'}}
+ sp.V3 = 14; // expected-error{{no member named 'SetV_NotExist' in 'StructWithProperty'}} expected-error{{cannot find suitable setter for property 'V3'}}
+ int k = sp.V5;
+ sp.V5 = k++;
+}
+
+/* 4 tests for PseudoObject, begin */
+struct SP1
+{
+ bool operator()() { return true; }
+};
+struct SP2
+{
+ __declspec(property(get=GetV)) SP1 V;
+ SP1 GetV() { return SP1(); }
+};
+void TestSP2() {
+ SP2 sp2;
+ bool b = sp2.V();
+}
+
+struct SP3 {
+ template <class T>
+ void f(T t) {}
+};
+template <class T>
+struct SP4
+{
+ __declspec(property(get=GetV)) int V;
+ int GetV() { return 123; }
+ void f() { SP3 s2; s2.f(V); }
+};
+void TestSP4() {
+ SP4<int> s;
+ s.f();
+}
+
+template <class T>
+struct SP5
+{
+ __declspec(property(get=GetV)) T V;
+ int GetV() { return 123; }
+ void f() { int *p = new int[V]; }
+};
+
+template <class T>
+struct SP6
+{
+public:
+ __declspec(property(get=GetV)) T V;
+ T GetV() { return 123; }
+ void f() { int t = V; }
+};
+void TestSP6() {
+ SP6<int> c;
+ c.f();
+}
+/* 4 tests for PseudoObject, end */
+
+// Property access: explicit, implicit, with Qualifier
+struct SP7 {
+ __declspec(property(get=GetV, put=SetV)) int V;
+ int GetV() { return 123; }
+ void SetV(int v) {}
+
+ void ImplicitAccess() { int i = V; V = i; }
+ void ExplicitAccess() { int i = this->V; this->V = i; }
+};
+struct SP8: public SP7 {
+ void AccessWithQualifier() { int i = SP7::V; SP7::V = i; }
+};
+
+// Property usage
+template <class T>
+struct SP9 {
+ __declspec(property(get=GetV, put=SetV)) T V;
+ T GetV() { return 0; }
+ void SetV(T v) {}
+ void f() { V = this->V; V < this->V; }
+ void g() { V++; }
+ void h() { V*=2; }
+};
+struct SP10 {
+ SP10(int v) {}
+ bool operator<(const SP10& v) { return true; }
+ SP10 operator*(int v) { return *this; }
+ SP10 operator+(int v) { return *this; }
+ SP10& operator=(const SP10& v) { return *this; }
+};
+void TestSP9() {
+ SP9<int> c;
+ int i = c.V; // Decl initializer
+ i = c.V; // Binary op operand
+ c.SetV(c.V); // CallExpr arg
+ int *p = new int[c.V + 1]; // Array size
+ p[c.V] = 1; // Array index
+
+ c.V = 123; // Setter
+
+ c.V++; // Unary op operand
+ c.V *= 2; // Unary op operand
+
+ SP9<int*> c2;
+ c2.V[0] = 123; // Array
+
+ SP9<SP10> c3;
+ c3.f(); // Overloaded binary op operand
+ c3.g(); // Overloaded incdec op operand
+ c3.h(); // Overloaded unary op operand
+}
diff --git a/test/SemaCXX/access.cpp b/test/SemaCXX/access.cpp
index 18ad301b5f..50f2eff87b 100644
--- a/test/SemaCXX/access.cpp
+++ b/test/SemaCXX/access.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
class C {
struct S; // expected-note {{previously declared 'private' here}}
@@ -32,3 +32,77 @@ namespace test1 {
class X {};
};
}
+
+// PR15209
+namespace PR15209 {
+ namespace alias_templates {
+ template<typename T1, typename T2> struct U { };
+ template<typename T1> using W = U<T1, float>;
+
+ class A {
+ typedef int I;
+ static constexpr I x = 0; // expected-note {{implicitly declared private here}}
+ static constexpr I y = 42; // expected-note {{implicitly declared private here}}
+ friend W<int>;
+ };
+
+ template<typename T1>
+ struct U<T1, float> {
+ int v_;
+ // the following will trigger for U<float, float> instantiation, via W<float>
+ U() : v_(A::x) { } // expected-error {{'x' is a private member of 'PR15209::alias_templates::A'}}
+ };
+
+ template<typename T1>
+ struct U<T1, int> {
+ int v_;
+ U() : v_(A::y) { } // expected-error {{'y' is a private member of 'PR15209::alias_templates::A'}}
+ };
+
+ template struct U<int, int>; // expected-note {{in instantiation of member function 'PR15209::alias_templates::U<int, int>::U' requested here}}
+
+ void f()
+ {
+ W<int>();
+ // we should issue diagnostics for the following
+ W<float>(); // expected-note {{in instantiation of member function 'PR15209::alias_templates::U<float, float>::U' requested here}}
+ }
+ }
+
+ namespace templates {
+ class A {
+ typedef int I; // expected-note {{implicitly declared private here}}
+ static constexpr I x = 0; // expected-note {{implicitly declared private here}}
+
+ template<int> friend struct B;
+ template<int> struct C;
+ template<template<int> class T> friend struct TT;
+ template<typename T> friend void funct(T);
+ };
+ template<A::I> struct B { };
+
+ template<A::I> struct A::C { };
+
+ template<template<A::I> class T> struct TT {
+ T<A::x> t;
+ };
+
+ template struct TT<B>;
+ template<A::I> struct D { }; // expected-error {{'I' is a private member of 'PR15209::templates::A'}}
+ template struct TT<D>;
+
+ // function template case
+ template<typename T>
+ void funct(T)
+ {
+ (void)A::x;
+ }
+
+ template void funct<int>(int);
+
+ void f()
+ {
+ (void)A::x; // expected-error {{'x' is a private member of 'PR15209::templates::A'}}
+ }
+ }
+}
diff --git a/test/SemaCXX/alignof.cpp b/test/SemaCXX/alignof.cpp
new file mode 100644
index 0000000000..a9de1ad07c
--- /dev/null
+++ b/test/SemaCXX/alignof.cpp
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+
+// rdar://13784901
+
+struct S0 {
+ int x;
+ static const int test0 = __alignof__(x); // expected-error {{invalid application of 'alignof' to a field of a class still being defined}}
+ static const int test1 = __alignof__(S0::x); // expected-error {{invalid application of 'alignof' to a field of a class still being defined}}
+ auto test2() -> char(&)[__alignof__(x)]; // expected-error {{invalid application of 'alignof' to a field of a class still being defined}}
+};
+
+struct S1; // expected-note 5 {{forward declaration}}
+extern S1 s1;
+const int test3 = __alignof__(s1); // expected-error {{invalid application of 'alignof' to an incomplete type 'S1'}}
+
+struct S2 {
+ S2();
+ S1 &s;
+ int x;
+
+ int test4 = __alignof__(x); // ok
+ int test5 = __alignof__(s); // expected-error {{invalid application of 'alignof' to an incomplete type 'S1'}}
+};
+
+const int test6 = __alignof__(S2::x);
+const int test7 = __alignof__(S2::s); // expected-error {{invalid application of 'alignof' to an incomplete type 'S1'}}
+
+// Arguably, these should fail like the S1 cases do: the alignment of
+// 's2.x' should depend on the alignment of both x-within-S2 and
+// s2-within-S3 and thus require 'S3' to be complete. If we start
+// doing the appropriate recursive walk to do that, we should make
+// sure that these cases don't explode.
+struct S3 {
+ S2 s2;
+
+ static const int test8 = __alignof__(s2.x);
+ static const int test9 = __alignof__(s2.s); // expected-error {{invalid application of 'alignof' to an incomplete type 'S1'}}
+ auto test10() -> char(&)[__alignof__(s2.x)];
+ static const int test11 = __alignof__(S3::s2.x);
+ static const int test12 = __alignof__(S3::s2.s); // expected-error {{invalid application of 'alignof' to an incomplete type 'S1'}}
+ auto test13() -> char(&)[__alignof__(s2.x)];
+};
+
+// Same reasoning as S3.
+struct S4 {
+ union {
+ int x;
+ };
+ static const int test0 = __alignof__(x);
+ static const int test1 = __alignof__(S0::x);
+ auto test2() -> char(&)[__alignof__(x)];
+};
diff --git a/test/SemaCXX/anonymous-union.cpp b/test/SemaCXX/anonymous-union.cpp
index 93b5b0abba..9c2cf24a83 100644
--- a/test/SemaCXX/anonymous-union.cpp
+++ b/test/SemaCXX/anonymous-union.cpp
@@ -110,7 +110,7 @@ struct BadMembers {
};
// <rdar://problem/6481130>
-typedef union { }; // expected-warning{{declaration does not declare anything}}
+typedef union { }; // expected-warning{{typedef requires a name}}
// <rdar://problem/7562438>
typedef struct objc_module *Foo ;
diff --git a/test/SemaCXX/ast-print.cpp b/test/SemaCXX/ast-print.cpp
index 5de8c4b51b..921f7d8baa 100644
--- a/test/SemaCXX/ast-print.cpp
+++ b/test/SemaCXX/ast-print.cpp
@@ -137,3 +137,14 @@ void test12() {
ConstrWithCleanupsClass cwcExplicitArg(VirualDestrClass(56));
}
+// CHECK: void test13() {
+// CHECK: _Atomic(int) i;
+// CHECK: __c11_atomic_init(&i, 0);
+// CHECK: __c11_atomic_load(&i, 0);
+// CHECK: }
+void test13() {
+ _Atomic(int) i;
+ __c11_atomic_init(&i, 0);
+ __c11_atomic_load(&i, 0);
+}
+
diff --git a/test/SemaCXX/atomic-type.cxx b/test/SemaCXX/atomic-type.cxx
index 18707eb8c5..947bb3c5f4 100644
--- a/test/SemaCXX/atomic-type.cxx
+++ b/test/SemaCXX/atomic-type.cxx
@@ -1,7 +1,9 @@
-// RUN: %clang_cc1 -verify %s
+// RUN: %clang_cc1 -verify -pedantic %s
template<typename T> struct atomic {
_Atomic(T) value;
+
+ void f() _Atomic; // expected-error {{expected ';' at end of declaration list}}
};
template<typename T> struct user {
@@ -15,9 +17,11 @@ user<int> u;
struct A { };
int &ovl1(_Atomic(int));
+int &ovl1(_Atomic int); // ok, redeclaration
long &ovl1(_Atomic(long));
float &ovl1(_Atomic(float));
double &ovl1(_Atomic(A const *const *));
+double &ovl1(A const *const *_Atomic);
short &ovl1(_Atomic(A **));
void test_overloading(int i, float f, _Atomic(int) ai, _Atomic(float) af,
@@ -33,3 +37,22 @@ void test_overloading(int i, float f, _Atomic(int) ai, _Atomic(float) af,
double &dr2 = ovl1(ac);
short &sr1 = ovl1(a);
}
+
+typedef int (A::*fp)() _Atomic; // expected-error {{expected ';' after top level declarator}} expected-warning {{does not declare anything}}
+
+typedef _Atomic(int(A::*)) atomic_mem_ptr_to_int;
+typedef int(A::*_Atomic atomic_mem_ptr_to_int);
+
+typedef _Atomic(int)(A::*mem_ptr_to_atomic_int);
+typedef _Atomic int(A::*mem_ptr_to_atomic_int);
+
+typedef _Atomic(int)&atomic_int_ref;
+typedef _Atomic int &atomic_int_ref;
+typedef _Atomic atomic_int_ref atomic_int_ref; // ok, qualifiers on references ignored in this case.
+
+typedef int &_Atomic atomic_reference_to_int; // expected-error {{'_Atomic' qualifier may not be applied to a reference}}
+typedef _Atomic(int &) atomic_reference_to_int; // expected-error {{_Atomic cannot be applied to reference type 'int &'}}
+
+struct S {
+ _Atomic union { int n; }; // expected-warning {{anonymous union cannot be '_Atomic'}}
+};
diff --git a/test/SemaCXX/attr-cxx0x.cpp b/test/SemaCXX/attr-cxx0x.cpp
index 002800e749..e9276cd2d9 100644
--- a/test/SemaCXX/attr-cxx0x.cpp
+++ b/test/SemaCXX/attr-cxx0x.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -fcxx-exceptions -verify -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -fcxx-exceptions -verify -pedantic -std=c++11 %s
int align_illegal alignas(3); //expected-error {{requested alignment is not a power of 2}}
char align_big alignas(int);
@@ -43,3 +43,5 @@ static_assert(alignof(align_class_template<16>) == 16, "template's alignment is
static_assert(alignof(align_class_temp_pack_type<short, int, long>) == alignof(long), "template's alignment is wrong");
static_assert(alignof(align_class_temp_pack_expr<8, 16, 32>) == 32, "template's alignment is wrong");
static_assert(alignof(outer<int,char>::inner<double,short>) == alignof(int) * alignof(double), "template's alignment is wrong");
+
+static_assert(alignof(int(int)) >= 1, "alignof(function) not positive"); // expected-warning{{invalid application of 'alignof' to a function type}}
diff --git a/test/SemaCXX/attr-noreturn.cpp b/test/SemaCXX/attr-noreturn.cpp
index f3d548b793..41214c4f4b 100644
--- a/test/SemaCXX/attr-noreturn.cpp
+++ b/test/SemaCXX/attr-noreturn.cpp
@@ -80,3 +80,86 @@ namespace PR12948 {
template<typename> void wibble() __attribute__((__noreturn__));
template<typename> voidfn wibble;
}
+
+// PR15291
+// Overload resolution per over.over should allow implicit noreturn adjustment.
+namespace PR15291 {
+ __attribute__((noreturn)) void foo(int) {}
+ __attribute__((noreturn)) void foo(double) {}
+
+ template <typename T>
+ __attribute__((noreturn)) void bar(T) {}
+
+ void baz(int) {}
+ void baz(double) {}
+
+ template <typename T>
+ void qux(T) {}
+
+ // expected-note@+5 {{candidate function [with T = void (*)(int) __attribute__((noreturn))] not viable: no overload of 'baz' matching 'void (*)(int) __attribute__((noreturn))' for 1st argument}}
+ // expected-note@+4 {{candidate function [with T = void (*)(int) __attribute__((noreturn))] not viable: no overload of 'qux' matching 'void (*)(int) __attribute__((noreturn))' for 1st argument}}
+ // expected-note@+3 {{candidate function [with T = void (*)(int) __attribute__((noreturn))] not viable: no overload of 'bar' matching 'void (*)(int) __attribute__((noreturn))' for 1st argument}}
+ // expected-note@+2 {{candidate function [with T = void (*)(int)] not viable: no overload of 'bar' matching 'void (*)(int)' for 1st argument}}
+ // expected-note@+1 {{candidate function [with T = void (int)] not viable: no overload of 'bar' matching 'void (*)(int)' for 1st argument}}
+ template <typename T> void accept_T(T) {}
+
+ // expected-note@+1 {{candidate function not viable: no overload of 'bar' matching 'void (*)(int)' for 1st argument}}
+ void accept_fptr(void (*f)(int)) {
+ f(42);
+ }
+
+ // expected-note@+2 {{candidate function not viable: no overload of 'baz' matching 'void (*)(int) __attribute__((noreturn))' for 1st argument}}
+ // expected-note@+1 {{candidate function not viable: no overload of 'qux' matching 'void (*)(int) __attribute__((noreturn))' for 1st argument}}
+ void accept_noreturn_fptr(void __attribute__((noreturn)) (*f)(int)) {
+ f(42);
+ }
+
+ typedef void (*fptr_t)(int);
+ typedef void __attribute__((noreturn)) (*fptr_noreturn_t)(int);
+
+ // expected-note@+1 {{candidate function not viable: no overload of 'bar' matching 'fptr_t' (aka 'void (*)(int)') for 1st argument}}
+ void accept_fptr_t(fptr_t f) {
+ f(42);
+ }
+
+ // expected-note@+2 {{candidate function not viable: no overload of 'baz' matching 'fptr_noreturn_t' (aka 'void (*)(int) __attribute__((noreturn))') for 1st argument}}
+ // expected-note@+1 {{candidate function not viable: no overload of 'qux' matching 'fptr_noreturn_t' (aka 'void (*)(int) __attribute__((noreturn))') for 1st argument}}
+ void accept_fptr_noreturn_t(fptr_noreturn_t f) {
+ f(42);
+ }
+
+ // Stripping noreturn should work if everything else is correct.
+ void strip_noreturn() {
+ accept_fptr(foo);
+ accept_fptr(bar<int>);
+ accept_fptr(bar<double>); // expected-error {{no matching function for call to 'accept_fptr'}}
+
+ accept_fptr_t(foo);
+ accept_fptr_t(bar<int>);
+ accept_fptr_t(bar<double>); // expected-error {{no matching function for call to 'accept_fptr_t'}}
+
+ accept_T<void __attribute__((noreturn)) (*)(int)>(foo);
+ accept_T<void __attribute__((noreturn)) (*)(int)>(bar<int>);
+ accept_T<void __attribute__((noreturn)) (*)(int)>(bar<double>); // expected-error {{no matching function for call to 'accept_T'}}
+
+ accept_T<void (*)(int)>(foo);
+ accept_T<void (*)(int)>(bar<int>);
+ accept_T<void (*)(int)>(bar<double>); // expected-error {{no matching function for call to 'accept_T'}}
+
+ accept_T<void (int)>(foo);
+ accept_T<void (int)>(bar<int>);
+ accept_T<void (int)>(bar<double>); // expected-error {{no matching function for call to 'accept_T'}}
+ }
+
+ // Introducing noreturn should not work.
+ void introduce_noreturn() {
+ accept_noreturn_fptr(baz); // expected-error {{no matching function for call to 'accept_noreturn_fptr'}}
+ accept_noreturn_fptr(qux<int>); // expected-error {{no matching function for call to 'accept_noreturn_fptr'}}
+
+ accept_fptr_noreturn_t(baz); // expected-error {{no matching function for call to 'accept_fptr_noreturn_t'}}
+ accept_fptr_noreturn_t(qux<int>); // expected-error {{no matching function for call to 'accept_fptr_noreturn_t'}}
+
+ accept_T<void __attribute__((noreturn)) (*)(int)>(baz); // expected-error {{no matching function for call to 'accept_T'}}
+ accept_T<void __attribute__((noreturn)) (*)(int)>(qux<int>); // expected-error {{no matching function for call to 'accept_T'}}
+ }
+}
diff --git a/test/SemaCXX/blocks.cpp b/test/SemaCXX/blocks.cpp
index a635e998d9..a2672d13b7 100644
--- a/test/SemaCXX/blocks.cpp
+++ b/test/SemaCXX/blocks.cpp
@@ -1,5 +1,4 @@
// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s -fblocks
-// expected-no-diagnostics
void tovoid(void*);
@@ -82,3 +81,22 @@ void move_block() {
__block MoveOnly mo;
}
+// Don't crash after failing to build a block due to a capture of an
+// invalid declaration.
+namespace test5 {
+ struct B { // expected-note 2 {{candidate constructor}}
+ void *p;
+ B(int); // expected-note {{candidate constructor}}
+ };
+
+ void use_block(void (^)());
+ void use_block_2(void (^)(), const B &a);
+
+ void test() {
+ B x; // expected-error {{no matching constructor for initialization}}
+ use_block(^{
+ int y;
+ use_block_2(^{ (void) y; }, x);
+ });
+ }
+}
diff --git a/test/SemaCXX/captured-statements.cpp b/test/SemaCXX/captured-statements.cpp
new file mode 100644
index 0000000000..dbb18a7b67
--- /dev/null
+++ b/test/SemaCXX/captured-statements.cpp
@@ -0,0 +1,166 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s -fblocks
+
+void test_nest_lambda() {
+ int x;
+ int y;
+ [&,y]() {
+ int z;
+ #pragma clang __debug captured
+ {
+ x = y; // OK
+ y = z; // expected-error{{cannot assign to a variable captured by copy in a non-mutable lambda}}
+ z = y; // OK
+ }
+ }();
+
+ int a;
+ #pragma clang __debug captured
+ {
+ int b;
+ int c;
+ [&,c]() {
+ a = b; // OK
+ b = c; // OK
+ c = a; // expected-error{{cannot assign to a variable captured by copy in a non-mutable lambda}}
+ }();
+ }
+}
+
+class test_obj_capture {
+ int a;
+ void b();
+ static void test() {
+ test_obj_capture c;
+ #pragma clang __debug captured
+ { (void)c.a; } // OK
+ #pragma clang __debug captured
+ { c.b(); } // OK
+ }
+};
+
+class test_this_capture {
+ int a;
+ void b();
+ void test() {
+ #pragma clang __debug captured
+ { (void)this; } // OK
+ #pragma clang __debug captured
+ { (void)a; } // OK
+ #pragma clang __debug captured
+ { b(); } // OK
+ }
+};
+
+template <typename T>
+void template_capture_var() {
+ T x; // expected-error{{declaration of reference variable 'x' requires an initializer}}
+ #pragma clang _debug captured
+ {
+ (void)x;
+ }
+}
+
+template <typename T>
+class Val {
+ T v;
+public:
+ void set(const T &v0) {
+ #pragma clang __debug captured
+ {
+ v = v0;
+ }
+ }
+};
+
+void test_capture_var() {
+ template_capture_var<int>(); // OK
+ template_capture_var<int&>(); // expected-note{{in instantiation of function template specialization 'template_capture_var<int &>' requested here}}
+
+ Val<float> Obj;
+ Obj.set(0.0f); // OK
+}
+
+template <typename S, typename T>
+S template_capture_var(S x, T y) {
+ #pragma clang _debug captured
+ {
+ x++;
+ y++; // expected-error{{read-only variable is not assignable}}
+ }
+
+ return x;
+}
+
+// Check if can recover from a template error.
+void test_capture_var_error() {
+ template_capture_var<int, int>(0, 1); // OK
+ template_capture_var<int, const int>(0, 1); // expected-note{{in instantiation of function template specialization 'template_capture_var<int, const int>' requested here}}
+ template_capture_var<int, int>(0, 1); // OK
+}
+
+template <typename T>
+void template_capture_in_lambda() {
+ T x, y;
+ [=, &y]() {
+ #pragma clang __debug captured
+ {
+ y += x;
+ }
+ }();
+}
+
+void test_lambda() {
+ template_capture_in_lambda<int>(); // OK
+}
+
+struct Foo {
+ void foo() { }
+ static void bar() { }
+};
+
+template <typename T>
+void template_capture_func(T &t) {
+ #pragma clang __debug captured
+ {
+ t.foo();
+ }
+
+ #pragma clang __debug captured
+ {
+ T::bar();
+ }
+}
+
+void test_template_capture_func() {
+ Foo Obj;
+ template_capture_func(Obj);
+}
+
+template <typename T>
+T captured_sum(const T &a, const T &b) {
+ T result;
+
+ #pragma clang __debug captured
+ {
+ result = a + b;
+ }
+
+ return result;
+}
+
+template <typename T, typename... Args>
+T captured_sum(const T &a, const Args&... args) {
+ T result;
+
+ #pragma clang __debug captured
+ {
+ result = a + captured_sum(args...);
+ }
+
+ return result;
+}
+
+void test_capture_variadic() {
+ (void)captured_sum(1, 2, 3); // OK
+ (void)captured_sum(1, 2, 3, 4, 5); // OK
+}
diff --git a/test/SemaCXX/class-base-member-init.cpp b/test/SemaCXX/class-base-member-init.cpp
index e84e57b747..2cdca829ff 100644
--- a/test/SemaCXX/class-base-member-init.cpp
+++ b/test/SemaCXX/class-base-member-init.cpp
@@ -90,3 +90,11 @@ namespace test5 {
}
};
}
+
+namespace rdar13185264 {
+ class X {
+ X() : a(), // expected-note{{previous initialization is here}}
+ a() { } // expected-error{{multiple initializations given for non-static member 'a'}}
+ union { void *a; };
+ };
+}
diff --git a/test/SemaCXX/compare.cpp b/test/SemaCXX/compare.cpp
index 5771912590..feb1ccb9a2 100644
--- a/test/SemaCXX/compare.cpp
+++ b/test/SemaCXX/compare.cpp
@@ -89,8 +89,8 @@ int test0(long a, unsigned long b) {
// (C,b)
(C == (unsigned long) b) +
(C == (unsigned int) b) +
- (C == (unsigned short) b) + // expected-warning {{comparison of constant 65536 with expression of type 'unsigned short' is always false}}
- (C == (unsigned char) b) + // expected-warning {{comparison of constant 65536 with expression of type 'unsigned char' is always false}}
+ (C == (unsigned short) b) + // expected-warning {{comparison of constant 'C' (65536) with expression of type 'unsigned short' is always false}}
+ (C == (unsigned char) b) + // expected-warning {{comparison of constant 'C' (65536) with expression of type 'unsigned char' is always false}}
((long) C == b) +
((int) C == b) +
((short) C == b) +
@@ -101,8 +101,8 @@ int test0(long a, unsigned long b) {
((signed char) C == (unsigned char) b) +
(C < (unsigned long) b) +
(C < (unsigned int) b) +
- (C < (unsigned short) b) + // expected-warning {{comparison of constant 65536 with expression of type 'unsigned short' is always false}}
- (C < (unsigned char) b) + // expected-warning {{comparison of constant 65536 with expression of type 'unsigned char' is always false}}
+ (C < (unsigned short) b) + // expected-warning {{comparison of constant 'C' (65536) with expression of type 'unsigned short' is always false}}
+ (C < (unsigned char) b) + // expected-warning {{comparison of constant 'C' (65536) with expression of type 'unsigned char' is always false}}
((long) C < b) +
((int) C < b) +
((short) C < b) +
@@ -119,8 +119,8 @@ int test0(long a, unsigned long b) {
(a == (unsigned char) C) +
((long) a == C) +
((int) a == C) +
- ((short) a == C) + // expected-warning {{comparison of constant 65536 with expression of type 'short' is always false}}
- ((signed char) a == C) + // expected-warning {{comparison of constant 65536 with expression of type 'signed char' is always false}}
+ ((short) a == C) + // expected-warning {{comparison of constant 'C' (65536) with expression of type 'short' is always false}}
+ ((signed char) a == C) + // expected-warning {{comparison of constant 'C' (65536) with expression of type 'signed char' is always false}}
((long) a == (unsigned long) C) +
((int) a == (unsigned int) C) +
((short) a == (unsigned short) C) +
@@ -131,8 +131,8 @@ int test0(long a, unsigned long b) {
(a < (unsigned char) C) +
((long) a < C) +
((int) a < C) +
- ((short) a < C) + // expected-warning {{comparison of constant 65536 with expression of type 'short' is always true}}
- ((signed char) a < C) + // expected-warning {{comparison of constant 65536 with expression of type 'signed char' is always true}}
+ ((short) a < C) + // expected-warning {{comparison of constant 'C' (65536) with expression of type 'short' is always true}}
+ ((signed char) a < C) + // expected-warning {{comparison of constant 'C' (65536) with expression of type 'signed char' is always true}}
((long) a < (unsigned long) C) + // expected-warning {{comparison of integers of different signs}}
((int) a < (unsigned int) C) + // expected-warning {{comparison of integers of different signs}}
((short) a < (unsigned short) C) +
diff --git a/test/SemaCXX/compound-literal.cpp b/test/SemaCXX/compound-literal.cpp
index fe0e45d3c6..595747e40c 100644
--- a/test/SemaCXX/compound-literal.cpp
+++ b/test/SemaCXX/compound-literal.cpp
@@ -1,4 +1,8 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++03 -verify -ast-dump %s > %t-03
+// RUN: FileCheck --input-file=%t-03 %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify -ast-dump %s > %t-11
+// RUN: FileCheck --input-file=%t-11 %s
+// RUN: FileCheck --input-file=%t-11 %s --check-prefix=CHECK-CXX11
// http://llvm.org/PR7905
namespace PR7905 {
@@ -12,3 +16,63 @@ void foo2() {
(void)(M<short> []) {{3}};
}
}
+
+// Check compound literals mixed with C++11 list-initialization.
+namespace brace_initializers {
+ struct POD {
+ int x, y;
+ };
+ struct HasCtor {
+ HasCtor(int x, int y);
+ };
+ struct HasDtor {
+ int x, y;
+ ~HasDtor();
+ };
+ struct HasCtorDtor {
+ HasCtorDtor(int x, int y);
+ ~HasCtorDtor();
+ };
+
+ void test() {
+ (void)(POD){1, 2};
+ // CHECK-NOT: CXXBindTemporaryExpr {{.*}} 'struct brace_initializers::POD'
+ // CHECK: CompoundLiteralExpr {{.*}} 'struct brace_initializers::POD'
+ // CHECK-NEXT: InitListExpr {{.*}} 'struct brace_initializers::POD'
+ // CHECK-NEXT: IntegerLiteral {{.*}} 1{{$}}
+ // CHECK-NEXT: IntegerLiteral {{.*}} 2{{$}}
+
+ (void)(HasDtor){1, 2};
+ // CHECK: CXXBindTemporaryExpr {{.*}} 'struct brace_initializers::HasDtor'
+ // CHECK-NEXT: CompoundLiteralExpr {{.*}} 'struct brace_initializers::HasDtor'
+ // CHECK-NEXT: InitListExpr {{.*}} 'struct brace_initializers::HasDtor'
+ // CHECK-NEXT: IntegerLiteral {{.*}} 1{{$}}
+ // CHECK-NEXT: IntegerLiteral {{.*}} 2{{$}}
+
+#if __cplusplus >= 201103L
+ (void)(HasCtor){1, 2};
+ // CHECK-CXX11-NOT: CXXBindTemporaryExpr {{.*}} 'struct brace_initializers::HasCtor'
+ // CHECK-CXX11: CompoundLiteralExpr {{.*}} 'struct brace_initializers::HasCtor'
+ // CHECK-CXX11-NEXT: CXXTemporaryObjectExpr {{.*}} 'struct brace_initializers::HasCtor'
+ // CHECK-CXX11-NEXT: IntegerLiteral {{.*}} 1{{$}}
+ // CHECK-CXX11-NEXT: IntegerLiteral {{.*}} 2{{$}}
+
+ (void)(HasCtorDtor){1, 2};
+ // CHECK-CXX11: CXXBindTemporaryExpr {{.*}} 'struct brace_initializers::HasCtorDtor'
+ // CHECK-CXX11-NEXT: CompoundLiteralExpr {{.*}} 'struct brace_initializers::HasCtorDtor'
+ // CHECK-CXX11-NEXT: CXXTemporaryObjectExpr {{.*}} 'struct brace_initializers::HasCtorDtor'
+ // CHECK-CXX11-NEXT: IntegerLiteral {{.*}} 1{{$}}
+ // CHECK-CXX11-NEXT: IntegerLiteral {{.*}} 2{{$}}
+#endif
+ }
+
+ struct PrivateDtor {
+ int x, y;
+ private:
+ ~PrivateDtor(); // expected-note {{declared private here}}
+ };
+
+ void testPrivateDtor() {
+ (void)(PrivateDtor){1, 2}; // expected-error {{temporary of type 'brace_initializers::PrivateDtor' has private destructor}}
+ }
+}
diff --git a/test/SemaCXX/condition.cpp b/test/SemaCXX/condition.cpp
index d805881194..73f3dceef6 100644
--- a/test/SemaCXX/condition.cpp
+++ b/test/SemaCXX/condition.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
void test() {
int x;
@@ -6,7 +6,7 @@ void test() {
if (int x=0) ++x;
typedef int arr[10];
- while (arr x=0) ; // expected-error {{an array type is not allowed here}} expected-error {{array initializer must be an initializer list}}
+ while (arr x={0}) ; // expected-error {{an array type is not allowed here}}
while (int f()=0) ; // expected-error {{a function type is not allowed here}}
struct S {} s;
@@ -19,9 +19,7 @@ void test() {
while (struct NewS *x=0) ;
while (struct S {} *x=0) ; // expected-error {{types may not be defined in conditions}}
while (struct {} *x=0) ; // expected-error {{types may not be defined in conditions}}
- switch (enum {E} x=0) ; // expected-error {{types may not be defined in conditions}} \
- // expected-warning{{enumeration value 'E' not handled in switch}} expected-warning {{switch statement has empty body}} \
- // expected-note{{put the semicolon on a separate line}}
+ switch (enum {E} x=0) ; // expected-error {{types may not be defined in conditions}}
if (int x=0) { // expected-note 2 {{previous definition is here}}
int x; // expected-error {{redefinition of 'x'}}
diff --git a/test/SemaCXX/constant-expression-cxx11.cpp b/test/SemaCXX/constant-expression-cxx11.cpp
index 30aa7d7b0b..09a9cb5dd8 100644
--- a/test/SemaCXX/constant-expression-cxx11.cpp
+++ b/test/SemaCXX/constant-expression-cxx11.cpp
@@ -21,7 +21,7 @@ template<typename T, size_t N> constexpr T *begin(T (&xs)[N]) { return xs; }
template<typename T, size_t N> constexpr T *end(T (&xs)[N]) { return xs + N; }
struct MemberZero {
- constexpr int zero() { return 0; }
+ constexpr int zero() const { return 0; }
};
namespace DerivedToVBaseCast {
@@ -304,16 +304,16 @@ struct Str {
expected-note {{reinterpret_cast is not allowed in a constant expression}}
int c : (S*)(long)(sptr) == (S*)(long)(sptr); // \
expected-warning {{not an integral constant expression}} \
- expected-note {{cast which performs the conversions of a reinterpret_cast is not allowed in a constant expression}}
+ expected-note {{cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression}}
int d : (S*)(42) == (S*)(42); // \
expected-warning {{not an integral constant expression}} \
- expected-note {{cast which performs the conversions of a reinterpret_cast is not allowed in a constant expression}}
+ expected-note {{cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression}}
int e : (Str*)(sptr) == (Str*)(sptr); // \
expected-warning {{not an integral constant expression}} \
- expected-note {{cast which performs the conversions of a reinterpret_cast is not allowed in a constant expression}}
+ expected-note {{cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression}}
int f : &(U&)(*sptr) == &(U&)(*sptr); // \
expected-warning {{not an integral constant expression}} \
- expected-note {{cast which performs the conversions of a reinterpret_cast is not allowed in a constant expression}}
+ expected-note {{cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression}}
int g : (S*)(void*)(sptr) == sptr; // \
expected-warning {{not an integral constant expression}} \
expected-note {{cast from 'void *' is not allowed in a constant expression}}
@@ -362,7 +362,7 @@ constexpr char c0 = "nought index"[0];
constexpr char c1 = "nice index"[10];
constexpr char c2 = "nasty index"[12]; // expected-error {{must be initialized by a constant expression}} expected-warning {{is past the end}} expected-note {{read of dereferenced one-past-the-end pointer}}
constexpr char c3 = "negative index"[-1]; // expected-error {{must be initialized by a constant expression}} expected-warning {{is before the beginning}} expected-note {{cannot refer to element -1 of array of 15 elements}}
-constexpr char c4 = ((char*)(int*)"no reinterpret_casts allowed")[14]; // expected-error {{must be initialized by a constant expression}} expected-note {{cast which performs the conversions of a reinterpret_cast}}
+constexpr char c4 = ((char*)(int*)"no reinterpret_casts allowed")[14]; // expected-error {{must be initialized by a constant expression}} expected-note {{cast that performs the conversions of a reinterpret_cast}}
constexpr const char *p = "test" + 2;
static_assert(*p == 's', "");
@@ -414,6 +414,19 @@ struct V {
};
static_assert(V().c[1] == "i"[0], "");
+namespace Parens {
+ constexpr unsigned char a[] = ("foo"), b[] = {"foo"}, c[] = {("foo")},
+ d[4] = ("foo"), e[5] = {"foo"}, f[6] = {("foo")};
+ static_assert(a[0] == 'f', "");
+ static_assert(b[1] == 'o', "");
+ static_assert(c[2] == 'o', "");
+ static_assert(d[0] == 'f', "");
+ static_assert(e[1] == 'o', "");
+ static_assert(f[2] == 'o', "");
+ static_assert(f[5] == 0, "");
+ static_assert(f[6] == 0, ""); // expected-error {{constant expression}} expected-note {{one-past-the-end}}
+}
+
}
namespace Array {
@@ -486,7 +499,7 @@ static_assert(CountZero(arr, arr + 40) == 36, "");
struct ArrayElem {
constexpr ArrayElem() : n(0) {}
int n;
- constexpr int f() { return n; }
+ constexpr int f() const { return n; }
};
struct ArrayRVal {
constexpr ArrayRVal() {}
@@ -731,14 +744,14 @@ namespace ConversionOperators {
struct T {
constexpr T(int n) : k(5*n - 3) {}
- constexpr operator int() { return k; }
+ constexpr operator int() const { return k; }
int k;
};
struct S {
constexpr S(int n) : k(2*n + 1) {}
- constexpr operator int() { return k; }
- constexpr operator T() { return T(k); }
+ constexpr operator int() const { return k; }
+ constexpr operator T() const { return T(k); }
int k;
};
@@ -750,7 +763,7 @@ static_assert(check(S(5), 11), "");
namespace PR14171 {
struct X {
- constexpr (operator int)() { return 0; }
+ constexpr (operator int)() const { return 0; }
};
static_assert(X() == 0, "");
@@ -764,13 +777,13 @@ namespace Temporaries {
struct S {
constexpr S() {}
- constexpr int f();
+ constexpr int f() const;
};
struct T : S {
constexpr T(int n) : S(), n(n) {}
int n;
};
-constexpr int S::f() {
+constexpr int S::f() const {
// 'this' must be the postfix-expression in a class member access expression,
// so we can't just use
// return static_cast<T*>(this)->n;
@@ -825,7 +838,7 @@ namespace MemberPointer {
struct A {
constexpr A(int n) : n(n) {}
int n;
- constexpr int f() { return n + 3; }
+ constexpr int f() const { return n + 3; }
};
constexpr A a(7);
static_assert(A(5).*&A::n == 5, "");
@@ -836,7 +849,7 @@ namespace MemberPointer {
struct B : A {
constexpr B(int n, int m) : A(n), m(m) {}
int m;
- constexpr int g() { return n + m + 1; }
+ constexpr int g() const { return n + m + 1; }
};
constexpr B b(9, 13);
static_assert(B(4, 11).*&A::n == 4, "");
@@ -857,7 +870,7 @@ namespace MemberPointer {
m(m), n(n), pf(pf), pn(pn) {}
constexpr S() : m(), n(), pf(&S::f), pn(&S::n) {}
- constexpr int f() { return this->*pn; }
+ constexpr int f() const { return this->*pn; }
virtual int g() const;
int m, n;
@@ -938,7 +951,7 @@ namespace ArrayBaseDerived {
};
struct Derived : Base {
constexpr Derived() {}
- constexpr const int *f() { return &n; }
+ constexpr const int *f() const { return &n; }
};
constexpr Derived a[10];
@@ -1038,7 +1051,7 @@ static_assert(makeComplexWrap(1,0) != complex(0, 1), "");
}
namespace PR11595 {
- struct A { constexpr bool operator==(int x) { return true; } };
+ struct A { constexpr bool operator==(int x) const { return true; } };
struct B { B(); A& x; };
static_assert(B().x == 3, ""); // expected-error {{constant expression}} expected-note {{non-literal type 'PR11595::B' cannot be used in a constant expression}}
@@ -1312,6 +1325,13 @@ namespace InvalidClasses {
}
}
+namespace NamespaceAlias {
+ constexpr int f() {
+ namespace NS = NamespaceAlias; // expected-warning {{use of this statement in a constexpr function is a C++1y extension}}
+ return &NS::f != nullptr;
+ }
+}
+
// Constructors can be implicitly constexpr, even for a non-literal type.
namespace ImplicitConstexpr {
struct Q { Q() = default; Q(const Q&) = default; Q(Q&&) = default; ~Q(); }; // expected-note 3{{here}}
@@ -1455,3 +1475,31 @@ namespace PR14203 {
// constructor here.
int n = sizeof(short{duration(duration())});
}
+
+namespace ArrayEltInit {
+ struct A {
+ constexpr A() : p(&p) {}
+ void *p;
+ };
+ constexpr A a[10];
+ static_assert(a[0].p == &a[0].p, "");
+ static_assert(a[9].p == &a[9].p, "");
+ static_assert(a[0].p != &a[9].p, "");
+ static_assert(a[9].p != &a[0].p, "");
+
+ constexpr A b[10] = {};
+ static_assert(b[0].p == &b[0].p, "");
+ static_assert(b[9].p == &b[9].p, "");
+ static_assert(b[0].p != &b[9].p, "");
+ static_assert(b[9].p != &b[0].p, "");
+}
+
+namespace PR15884 {
+ struct S {};
+ constexpr S f() { return {}; }
+ constexpr S *p = &f();
+ // expected-error@-1 {{taking the address of a temporary}}
+ // expected-error@-2 {{constexpr variable 'p' must be initialized by a constant expression}}
+ // expected-note@-3 {{pointer to temporary is not a constant expression}}
+ // expected-note@-4 {{temporary created here}}
+}
diff --git a/test/SemaCXX/constant-expression-cxx1y.cpp b/test/SemaCXX/constant-expression-cxx1y.cpp
new file mode 100644
index 0000000000..60ec82062d
--- /dev/null
+++ b/test/SemaCXX/constant-expression-cxx1y.cpp
@@ -0,0 +1,459 @@
+// RUN: %clang_cc1 -std=c++1y -verify %s -fcxx-exceptions -triple=x86_64-linux-gnu
+
+struct S {
+ // dummy ctor to make this a literal type
+ constexpr S(int);
+
+ S();
+
+ int arr[10];
+
+ constexpr int &get(int n) { return arr[n]; }
+ constexpr const int &get(int n) const { return arr[n]; }
+};
+
+S s = S();
+const S &sr = s;
+static_assert(&s.get(4) - &sr.get(2) == 2, "");
+
+// Compound-statements can be used in constexpr functions.
+constexpr int e() {{{{}} return 5; }}
+static_assert(e() == 5, "");
+
+// Types can be defined in constexpr functions.
+constexpr int f() {
+ enum E { e1, e2, e3 };
+
+ struct S {
+ constexpr S(E e) : e(e) {}
+ constexpr int get() { return e; }
+ E e;
+ };
+
+ return S(e2).get();
+}
+static_assert(f() == 1, "");
+
+// Variables can be declared in constexpr functions.
+constexpr int g(int k) {
+ const int n = 9;
+ int k2 = k * k;
+ int k3 = k2 * k;
+ return 3 * k3 + 5 * k2 + n * k - 20;
+}
+static_assert(g(2) == 42, "");
+constexpr int h(int n) {
+ static const int m = n; // expected-error {{static variable not permitted in a constexpr function}}
+ return m;
+}
+constexpr int i(int n) {
+ thread_local const int m = n; // expected-error {{thread_local variable not permitted in a constexpr function}}
+ return m;
+}
+
+// if-statements can be used in constexpr functions.
+constexpr int j(int k) {
+ if (k == 5)
+ return 1;
+ if (k == 1)
+ return 5;
+ else {
+ if (int n = 2 * k - 4) {
+ return n + 1;
+ return 2;
+ }
+ }
+} // expected-note 2{{control reached end of constexpr function}}
+static_assert(j(0) == -3, "");
+static_assert(j(1) == 5, "");
+static_assert(j(2), ""); // expected-error {{constant expression}} expected-note {{in call to 'j(2)'}}
+static_assert(j(3) == 3, "");
+static_assert(j(4) == 5, "");
+static_assert(j(5) == 1, "");
+
+// There can be 0 return-statements.
+constexpr void k() {
+}
+
+// If the return type is not 'void', no return statements => never a constant
+// expression, so still diagnose that case.
+[[noreturn]] constexpr int fn() { // expected-error {{no return statement in constexpr function}}
+ fn();
+}
+
+// We evaluate the body of a constexpr constructor, to check for side-effects.
+struct U {
+ constexpr U(int n) {
+ if (j(n)) {} // expected-note {{in call to 'j(2)'}}
+ }
+};
+constexpr U u1{1};
+constexpr U u2{2}; // expected-error {{constant expression}} expected-note {{in call to 'U(2)'}}
+
+// We allow expression-statements.
+constexpr int l(bool b) {
+ if (b)
+ throw "invalid value for b!"; // expected-note {{subexpression not valid}}
+ return 5;
+}
+static_assert(l(false) == 5, "");
+static_assert(l(true), ""); // expected-error {{constant expression}} expected-note {{in call to 'l(true)'}}
+
+// Potential constant expression checking is still applied where possible.
+constexpr int htonl(int x) { // expected-error {{never produces a constant expression}}
+ typedef unsigned char uchar;
+ uchar arr[4] = { uchar(x >> 24), uchar(x >> 16), uchar(x >> 8), uchar(x) };
+ return *reinterpret_cast<int*>(arr); // expected-note {{reinterpret_cast is not allowed in a constant expression}}
+}
+
+constexpr int maybe_htonl(bool isBigEndian, int x) {
+ if (isBigEndian)
+ return x;
+
+ typedef unsigned char uchar;
+ uchar arr[4] = { uchar(x >> 24), uchar(x >> 16), uchar(x >> 8), uchar(x) };
+ return *reinterpret_cast<int*>(arr); // expected-note {{reinterpret_cast is not allowed in a constant expression}}
+}
+
+constexpr int swapped = maybe_htonl(false, 123); // expected-error {{constant expression}} expected-note {{in call}}
+
+namespace NS {
+ constexpr int n = 0;
+}
+constexpr int namespace_alias() {
+ namespace N = NS;
+ return N::n;
+}
+
+namespace assign {
+ constexpr int a = 0;
+ const int b = 0;
+ int c = 0; // expected-note 2{{here}}
+
+ constexpr void set(const int &a, int b) {
+ const_cast<int&>(a) = b; // expected-note 2{{constant expression cannot modify an object that is visible outside that expression}}
+ }
+ constexpr int wrap(int a, int b) {
+ set(a, b);
+ return a;
+ }
+
+ static_assert((set(a, 1), a) == 1, ""); // expected-error {{constant expression}} expected-note {{in call to 'set(a, 1)'}}
+ static_assert((set(b, 1), b) == 1, ""); // expected-error {{constant expression}} expected-note {{in call to 'set(b, 1)'}}
+ static_assert((set(c, 1), c) == 1, ""); // expected-error {{constant expression}} expected-note {{read of non-const variable 'c'}}
+
+ static_assert(wrap(a, 1) == 1, "");
+ static_assert(wrap(b, 1) == 1, "");
+ static_assert(wrap(c, 1) == 1, ""); // expected-error {{constant expression}} expected-note {{read of non-const variable 'c'}}
+}
+
+namespace string_assign {
+ template<typename T>
+ constexpr void swap(T &a, T &b) {
+ T tmp = a;
+ a = b;
+ b = tmp;
+ }
+ template<typename Iterator>
+ constexpr void reverse(Iterator begin, Iterator end) {
+ while (begin != end && begin != --end)
+ swap(*begin++, *end);
+ }
+ template<typename Iterator1, typename Iterator2>
+ constexpr bool equal(Iterator1 a, Iterator1 ae, Iterator2 b, Iterator2 be) {
+ while (a != ae && b != be)
+ if (*a++ != *b++)
+ return false;
+ return a == ae && b == be;
+ }
+ constexpr bool test1(int n) {
+ char stuff[100] = "foobarfoo";
+ const char stuff2[100] = "oofraboof";
+ reverse(stuff, stuff + n); // expected-note {{cannot refer to element 101 of array of 100 elements}}
+ return equal(stuff, stuff + n, stuff2, stuff2 + n);
+ }
+ static_assert(!test1(1), "");
+ static_assert(test1(3), "");
+ static_assert(!test1(6), "");
+ static_assert(test1(9), "");
+ static_assert(!test1(100), "");
+ static_assert(!test1(101), ""); // expected-error {{constant expression}} expected-note {{in call to 'test1(101)'}}
+
+ // FIXME: We should be able to reject this before it's called
+ constexpr void f() {
+ char foo[10] = { "z" }; // expected-note {{here}}
+ foo[10] = 'x'; // expected-warning {{past the end}} expected-note {{assignment to dereferenced one-past-the-end pointer}}
+ }
+ constexpr int k = (f(), 0); // expected-error {{constant expression}} expected-note {{in call}}
+}
+
+namespace array_resize {
+ constexpr int do_stuff(int k1, int k2) {
+ int arr[1234] = { 1, 2, 3, 4 };
+ arr[k1] = 5; // expected-note {{past-the-end}} expected-note {{cannot refer to element 1235}} expected-note {{cannot refer to element -1}}
+ return arr[k2];
+ }
+ static_assert(do_stuff(1, 2) == 3, "");
+ static_assert(do_stuff(0, 0) == 5, "");
+ static_assert(do_stuff(1233, 1233) == 5, "");
+ static_assert(do_stuff(1233, 0) == 1, "");
+ static_assert(do_stuff(1234, 0) == 1, ""); // expected-error {{constant expression}} expected-note {{in call}}
+ static_assert(do_stuff(1235, 0) == 1, ""); // expected-error {{constant expression}} expected-note {{in call}}
+ static_assert(do_stuff(-1, 0) == 1, ""); // expected-error {{constant expression}} expected-note {{in call}}
+}
+
+namespace potential_const_expr {
+ constexpr void set(int &n) { n = 1; }
+ constexpr int div_zero_1() { int z = 0; set(z); return 100 / z; } // no error
+ constexpr int div_zero_2() { // expected-error {{never produces a constant expression}}
+ int z = 0;
+ return 100 / (set(z), 0); // expected-note {{division by zero}}
+ }
+ int n; // expected-note {{declared here}}
+ constexpr int ref() { // expected-error {{never produces a constant expression}}
+ int &r = n;
+ return r; // expected-note {{read of non-const variable 'n'}}
+ }
+}
+
+namespace subobject {
+ union A { constexpr A() : y(5) {} int x, y; };
+ struct B { A a; };
+ struct C : B {};
+ union D { constexpr D() : c() {} constexpr D(int n) : n(n) {} C c; int n; };
+ constexpr void f(D &d) {
+ d.c.a.y = 3;
+ // expected-note@-1 {{cannot modify an object that is visible outside}}
+ // expected-note@-2 {{assignment to member 'c' of union with active member 'n'}}
+ }
+ constexpr bool check(D &d) { return d.c.a.y == 3; }
+
+ constexpr bool g() { D d; f(d); return d.c.a.y == 3; }
+ static_assert(g(), "");
+
+ D d;
+ constexpr bool h() { f(d); return check(d); } // expected-note {{in call}}
+ static_assert(h(), ""); // expected-error {{constant expression}} expected-note {{in call}}
+
+ constexpr bool i() { D d(0); f(d); return check(d); } // expected-note {{in call}}
+ static_assert(i(), ""); // expected-error {{constant expression}} expected-note {{in call}}
+
+ constexpr bool j() { D d; d.c.a.x = 3; return check(d); } // expected-note {{assignment to member 'x' of union with active member 'y'}}
+ static_assert(j(), ""); // expected-error {{constant expression}} expected-note {{in call}}
+}
+
+namespace lifetime {
+ constexpr int &&id(int &&n) { return static_cast<int&&>(n); }
+ constexpr int &&dead() { return id(0); } // expected-note {{temporary created here}}
+ constexpr int bad() { int &&n = dead(); n = 1; return n; } // expected-note {{assignment to temporary whose lifetime has ended}}
+ static_assert(bad(), ""); // expected-error {{constant expression}} expected-note {{in call}}
+}
+
+namespace const_modify {
+ constexpr int modify(int &n) { return n = 1; } // expected-note {{modification of object of const-qualified type 'const int'}}
+ constexpr int test1() { int k = 0; return modify(k); }
+ constexpr int test2() { const int k = 0; return modify(const_cast<int&>(k)); } // expected-note {{in call}}
+ static_assert(test1() == 1, "");
+ static_assert(test2() == 1, ""); // expected-error {{constant expression}} expected-note {{in call}}
+}
+
+namespace null {
+ constexpr int test(int *p) {
+ return *p = 123; // expected-note {{assignment to dereferenced null pointer}}
+ }
+ static_assert(test(0), ""); // expected-error {{constant expression}} expected-note {{in call}}
+}
+
+namespace incdec {
+ template<typename T> constexpr T &ref(T &&r) { return r; }
+ template<typename T> constexpr T postinc(T &&r) { return (r++, r); }
+ template<typename T> constexpr T postdec(T &&r) { return (r--, r); }
+
+ static_assert(++ref(0) == 1, "");
+ static_assert(ref(0)++ == 0, "");
+ static_assert(postinc(0) == 1, "");
+ static_assert(--ref(0) == -1, "");
+ static_assert(ref(0)-- == 0, "");
+ static_assert(postdec(0) == -1, "");
+
+ constexpr int overflow_int_inc_1 = ref(0x7fffffff)++; // expected-error {{constant}} expected-note {{2147483648}}
+ constexpr int overflow_int_inc_1_ok = ref(0x7ffffffe)++;
+ constexpr int overflow_int_inc_2 = ++ref(0x7fffffff); // expected-error {{constant}} expected-note {{2147483648}}
+ constexpr int overflow_int_inc_2_ok = ++ref(0x7ffffffe);
+
+ // inc/dec on short can't overflow because we promote to int first
+ static_assert(++ref<short>(0x7fff) == (int)0xffff8000u, "");
+ static_assert(--ref<short>(0x8000) == 0x7fff, "");
+
+ // inc on bool sets to true
+ static_assert(++ref(false), ""); // expected-warning {{deprecated}}
+ static_assert(++ref(true), ""); // expected-warning {{deprecated}}
+
+ int arr[10];
+ static_assert(++ref(&arr[0]) == &arr[1], "");
+ static_assert(++ref(&arr[9]) == &arr[10], "");
+ static_assert(++ref(&arr[10]) == &arr[11], ""); // expected-error {{constant}} expected-note {{cannot refer to element 11}}
+ static_assert(ref(&arr[0])++ == &arr[0], "");
+ static_assert(ref(&arr[10])++ == &arr[10], ""); // expected-error {{constant}} expected-note {{cannot refer to element 11}}
+ static_assert(postinc(&arr[0]) == &arr[1], "");
+ static_assert(--ref(&arr[10]) == &arr[9], "");
+ static_assert(--ref(&arr[1]) == &arr[0], "");
+ static_assert(--ref(&arr[0]) != &arr[0], ""); // expected-error {{constant}} expected-note {{cannot refer to element -1}}
+ static_assert(ref(&arr[1])-- == &arr[1], "");
+ static_assert(ref(&arr[0])-- == &arr[0], ""); // expected-error {{constant}} expected-note {{cannot refer to element -1}}
+ static_assert(postdec(&arr[1]) == &arr[0], "");
+
+ int x;
+ static_assert(++ref(&x) == &x + 1, "");
+
+ static_assert(++ref(0.0) == 1.0, "");
+ static_assert(ref(0.0)++ == 0.0, "");
+ static_assert(postinc(0.0) == 1.0, "");
+ static_assert(--ref(0.0) == -1.0, "");
+ static_assert(ref(0.0)-- == 0.0, "");
+ static_assert(postdec(0.0) == -1.0, "");
+
+ static_assert(++ref(1e100) == 1e100, "");
+ static_assert(--ref(1e100) == 1e100, "");
+
+ union U {
+ int a, b;
+ };
+ constexpr int f(U u) {
+ return ++u.b; // expected-note {{increment of member 'b' of union with active member 'a'}}
+ }
+ constexpr int wrong_member = f({0}); // expected-error {{constant}} expected-note {{in call to 'f({.a = 0})'}}
+ constexpr int vol = --ref<volatile int>(0); // expected-error {{constant}} expected-note {{decrement of volatile-qualified}}
+
+ constexpr int incr(int k) {
+ int x = k;
+ if (x++ == 100)
+ return x;
+ return incr(x);
+ }
+ static_assert(incr(0) == 101, "");
+}
+
+namespace loops {
+ constexpr int fib_loop(int a) {
+ int f_k = 0, f_k_plus_one = 1;
+ for (int k = 1; k != a; ++k) {
+ int f_k_plus_two = f_k + f_k_plus_one;
+ f_k = f_k_plus_one;
+ f_k_plus_one = f_k_plus_two;
+ }
+ return f_k_plus_one;
+ }
+ static_assert(fib_loop(46) == 1836311903, "");
+
+ constexpr bool breaks_work() {
+ int a = 0;
+ for (int n = 0; n != 100; ++n) {
+ ++a;
+ if (a == 5) continue;
+ if ((a % 5) == 0) break;
+ }
+
+ int b = 0;
+ while (b != 17) {
+ ++b;
+ if (b == 6) continue;
+ if ((b % 6) == 0) break;
+ }
+
+ int c = 0;
+ do {
+ ++c;
+ if (c == 7) continue;
+ if ((c % 7) == 0) break;
+ } while (c != 21);
+
+ return a == 10 && b == 12 & c == 14;
+ }
+ static_assert(breaks_work(), "");
+
+ void not_constexpr();
+ constexpr bool no_cont_after_break() {
+ for (;;) {
+ break;
+ not_constexpr();
+ }
+ while (true) {
+ break;
+ not_constexpr();
+ }
+ do {
+ break;
+ not_constexpr();
+ } while (true);
+ return true;
+ }
+ static_assert(no_cont_after_break(), "");
+
+ constexpr bool cond() {
+ for (int a = 1; bool b = a != 3; ++a) {
+ if (!b)
+ return false;
+ }
+ while (bool b = true) {
+ b = false;
+ break;
+ }
+ return true;
+ }
+ static_assert(cond(), "");
+
+ constexpr int range_for() {
+ int arr[] = { 1, 2, 3, 4, 5 };
+ int sum = 0;
+ for (int x : arr)
+ sum = sum + x;
+ return sum;
+ }
+ static_assert(range_for() == 15, "");
+
+ template<int...N> struct ints {};
+ template<typename A, typename B> struct join_ints;
+ template<int...As, int...Bs> struct join_ints<ints<As...>, ints<Bs...>> {
+ using type = ints<As..., sizeof...(As) + Bs...>;
+ };
+ template<unsigned N> struct make_ints {
+ using type = typename join_ints<typename make_ints<N/2>::type, typename make_ints<(N+1)/2>::type>::type;
+ };
+ template<> struct make_ints<0> { using type = ints<>; };
+ template<> struct make_ints<1> { using type = ints<0>; };
+
+ struct ignore { template<typename ...Ts> constexpr ignore(Ts &&...) {} };
+
+ template<typename T, unsigned N> struct array {
+ constexpr array() : arr{} {}
+ template<typename ...X>
+ constexpr array(X ...x) : arr{} {
+ init(typename make_ints<sizeof...(X)>::type{}, x...);
+ }
+ template<int ...I, typename ...X> constexpr void init(ints<I...>, X ...x) {
+ ignore{arr[I] = x ...};
+ }
+ T arr[N];
+ struct iterator {
+ T *p;
+ constexpr explicit iterator(T *p) : p(p) {}
+ constexpr bool operator!=(iterator o) { return p != o.p; }
+ constexpr iterator &operator++() { ++p; return *this; }
+ constexpr T &operator*() { return *p; }
+ };
+ constexpr iterator begin() { return iterator(arr); }
+ constexpr iterator end() { return iterator(arr + N); }
+ };
+
+ constexpr int range_for_2() {
+ array<int, 5> arr { 1, 2, 3, 4, 5 };
+ int sum = 0;
+ for (int k : arr) {
+ sum = sum + k;
+ if (sum > 8) break;
+ }
+ return sum;
+ }
+ static_assert(range_for_2() == 10, "");
+}
diff --git a/test/SemaCXX/constexpr-printing.cpp b/test/SemaCXX/constexpr-printing.cpp
index 9170fa1ec2..e545f45d60 100644
--- a/test/SemaCXX/constexpr-printing.cpp
+++ b/test/SemaCXX/constexpr-printing.cpp
@@ -9,7 +9,7 @@ struct S {
int n, m;
};
-constexpr int extract(const S &s) { return s.n; } // expected-note {{read of uninitialized object is not allowed in a constant expression}}
+constexpr int extract(const S &s) { return s.n; } // expected-note {{read of object outside its lifetime is not allowed in a constant expression}}
constexpr S s1; // ok
void f() {
diff --git a/test/SemaCXX/constexpr-value-init.cpp b/test/SemaCXX/constexpr-value-init.cpp
index e459f097b9..d137bd88db 100644
--- a/test/SemaCXX/constexpr-value-init.cpp
+++ b/test/SemaCXX/constexpr-value-init.cpp
@@ -1,7 +1,7 @@
// RUN: %clang_cc1 %s -std=c++11 -fsyntax-only -verify
struct A {
- constexpr A() : a(b + 1), b(a + 1) {} // expected-note {{uninitialized}}
+ constexpr A() : a(b + 1), b(a + 1) {} // expected-note {{outside its lifetime}}
int a;
int b;
};
diff --git a/test/SemaCXX/constructor-initializer.cpp b/test/SemaCXX/constructor-initializer.cpp
index c54956db41..17576328c1 100644
--- a/test/SemaCXX/constructor-initializer.cpp
+++ b/test/SemaCXX/constructor-initializer.cpp
@@ -232,13 +232,15 @@ namespace PR7402 {
// <rdar://problem/8308215>: don't crash.
// Lots of questionable recovery here; errors can change.
namespace test3 {
- class A : public std::exception {}; // expected-error {{undeclared identifier}} expected-error {{expected class name}} expected-note 2 {{candidate}}
+ class A : public std::exception {}; // expected-error {{undeclared identifier}} expected-error {{expected class name}} expected-note 4 {{candidate}}
class B : public A {
public:
B(const String& s, int e=0) // expected-error {{unknown type name}}
: A(e), m_String(s) , m_ErrorStr(__null) {} // expected-error {{no matching constructor}} expected-error {{does not name}}
B(const B& e)
- : A(e), m_String(e.m_String), m_ErrorStr(__null) { // expected-error {{does not name}} expected-error {{no member named 'm_String' in 'test3::B'}}
+ : A(e), m_String(e.m_String), m_ErrorStr(__null) { // expected-error {{does not name}} \
+ // expected-error {{no member named 'm_String' in 'test3::B'}} \
+ // expected-error {{no matching}}
}
};
}
diff --git a/test/SemaCXX/cxx0x-defaulted-functions.cpp b/test/SemaCXX/cxx0x-defaulted-functions.cpp
index 3ba03c4eee..bc03bcd2a1 100644
--- a/test/SemaCXX/cxx0x-defaulted-functions.cpp
+++ b/test/SemaCXX/cxx0x-defaulted-functions.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -fcxx-exceptions %s
void fn() = default; // expected-error {{only special member}}
struct foo {
@@ -175,3 +175,16 @@ extern "C" {
template<typename _Tp> // expected-error {{templates must have C++ linkage}}
void PR13573(const _Tp&) = delete; // expected-error {{only functions can have deleted definitions}}
}
+
+namespace PR15597 {
+ template<typename T> struct A {
+ A() noexcept(true) = default;
+ ~A() noexcept(true) = default;
+ };
+ template<typename T> struct B {
+ B() noexcept(false) = default; // expected-error {{does not match the calculated one}}
+ ~B() noexcept(false) = default; // expected-error {{does not match the calculated one}}
+ };
+ A<int> a;
+ B<int> b; // expected-note {{here}}
+}
diff --git a/test/SemaCXX/cxx11-ast-print.cpp b/test/SemaCXX/cxx11-ast-print.cpp
index f95eeb50fe..f7bfc1123a 100644
--- a/test/SemaCXX/cxx11-ast-print.cpp
+++ b/test/SemaCXX/cxx11-ast-print.cpp
@@ -41,3 +41,5 @@ const char *p10 = 3.300e+15_fritz;
// CHECK: ;
;
// CHECK-NOT: ;
+
+
diff --git a/test/SemaCXX/cxx11-crashes.cpp b/test/SemaCXX/cxx11-crashes.cpp
index bd51af1da2..a4d4829f3f 100644
--- a/test/SemaCXX/cxx11-crashes.cpp
+++ b/test/SemaCXX/cxx11-crashes.cpp
@@ -70,7 +70,9 @@ namespace b6981007 {
for (auto x : s) {
// We used to attempt to evaluate the initializer of this variable,
// and crash because it has an undeduced type.
- const int &n(x);
+ // FIXME: We should set the loop variable to be invalid if we can't build
+ // the loop, to suppress this follow-on error.
+ const int &n(x); // expected-error {{could not bind to an lvalue of type 'auto'}}
}
}
}
diff --git a/test/SemaCXX/cxx11-inheriting-ctors.cpp b/test/SemaCXX/cxx11-inheriting-ctors.cpp
new file mode 100644
index 0000000000..67d55213a0
--- /dev/null
+++ b/test/SemaCXX/cxx11-inheriting-ctors.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -std=c++11 %s -verify
+
+// expected-no-diagnostics
+
+namespace PR15757 {
+ struct S {
+ };
+
+ template<typename X, typename Y> struct T {
+ template<typename A> T(X x, A &&a) {}
+
+ template<typename A> explicit T(A &&a)
+ noexcept(noexcept(T(X(), static_cast<A &&>(a))))
+ : T(X(), static_cast<A &&>(a)) {}
+ };
+
+ template<typename X, typename Y> struct U : T<X, Y> {
+ using T<X, Y>::T;
+ };
+
+ U<S, char> foo(char ch) { return U<S, char>(ch); }
+
+ int main() {
+ U<S, int> a(42);
+ U<S, char> b('4');
+ return 0;
+ }
+}
diff --git a/test/SemaCXX/cxx11-thread-local-print.cpp b/test/SemaCXX/cxx11-thread-local-print.cpp
new file mode 100644
index 0000000000..9d9a82b7e6
--- /dev/null
+++ b/test/SemaCXX/cxx11-thread-local-print.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -std=c++11 -triple=x86_64-linux-gnu -ast-print %s | FileCheck %s
+
+// CHECK: __thread int gnu_tl;
+// CHECK: _Thread_local int c11_tl;
+// CHECK: thread_local int cxx11_tl;
+__thread int gnu_tl;
+_Thread_local int c11_tl;
+thread_local int cxx11_tl;
+
diff --git a/test/SemaCXX/cxx11-thread-local.cpp b/test/SemaCXX/cxx11-thread-local.cpp
new file mode 100644
index 0000000000..f1dddc1c3b
--- /dev/null
+++ b/test/SemaCXX/cxx11-thread-local.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -std=c++11 -triple=x86_64-linux-gnu -verify %s
+
+struct S {
+ static thread_local int a;
+ static int b; // expected-note {{here}}
+ thread_local int c; // expected-error {{'thread_local' is only allowed on variable declarations}}
+ static thread_local int d; // expected-note {{here}}
+};
+
+thread_local int S::a;
+thread_local int S::b; // expected-error {{thread-local declaration of 'b' follows non-thread-local declaration}}
+thread_local int S::c; // expected-error {{non-static data member defined out-of-line}}
+int S::d; // expected-error {{non-thread-local declaration of 'd' follows thread-local declaration}}
+
+thread_local int x[3];
+thread_local int y[3];
+thread_local int z[3]; // expected-note {{previous}}
+
+void f() {
+ thread_local int x;
+ static thread_local int y;
+ extern thread_local int z; // expected-error {{redefinition of 'z' with a different type}}
+}
diff --git a/test/SemaCXX/cxx11-user-defined-literals-unused.cpp b/test/SemaCXX/cxx11-user-defined-literals-unused.cpp
new file mode 100644
index 0000000000..cd93ffbf21
--- /dev/null
+++ b/test/SemaCXX/cxx11-user-defined-literals-unused.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s -Wunused
+
+namespace {
+double operator"" _x(long double value) { return double(value); }
+int operator"" _ii(long double value) { return int(value); } // expected-warning {{not needed and will not be emitted}}
+}
+
+namespace rdar13589856 {
+ template<class T> double value() { return 3.2_x; }
+ template<class T> int valuei() { return 3.2_ii; }
+
+ double get_value() { return value<double>(); }
+}
diff --git a/test/SemaCXX/cxx1y-array-runtime-bound.cpp b/test/SemaCXX/cxx1y-array-runtime-bound.cpp
new file mode 100644
index 0000000000..1643adbe0b
--- /dev/null
+++ b/test/SemaCXX/cxx1y-array-runtime-bound.cpp
@@ -0,0 +1,68 @@
+// RUN: %clang_cc1 -std=c++1y %s -verify -triple=x86_64-linux-gnu -pedantic-errors
+
+// FIXME: many diagnostics here say 'variably modified type'.
+// catch this case and say 'array of runtime bound' instead.
+
+namespace std { struct type_info; }
+
+struct S {
+ int arr[__SIZE_MAX__ / 32];
+};
+S s[32]; // expected-error {{array is too large}}
+
+int n;
+int a[n]; // expected-error {{not allowed at file scope}}
+
+struct T {
+ int a[n]; // expected-error {{fields must have a constant size}}
+ static int b[n]; // expected-error {{not allowed at file scope}}
+};
+
+int g(int n, int a[n]);
+
+template<typename T> struct X {};
+template<int N, int[N]> struct Y {};
+template<int[n]> struct Z {}; // expected-error {{of variably modified type}}
+
+int f(int n) {
+ int arb[n]; // expected-note 3{{here}}
+ [arb] {} (); // expected-error {{cannot be captured}}
+
+ // FIXME: an array of runtime bound can be captured by reference.
+ [&arb] { // expected-error {{cannot be captured}}
+ // Capturing the array implicitly captures the bound, if we need it
+ // in a range-based for loop.
+ for (auto &n : arb) { } // expected-error {{cannot be captured}}
+ } ();
+
+ X<int[n]> x; // expected-error {{variably modified type}}
+
+ int arb_neg[-1]; // expected-error {{negative size}}
+ int arb_of_array[n][2];
+ int arr[3] = { 1, 2, 3, 4 }; // expected-error {{excess elements}}
+ char foo[4] = "fool"; // expected-error {{initializer-string for char array is too long}}
+
+ static int not_auto1[n]; // expected-error {{can not have 'static'}}
+ extern int not_auto2[n]; // expected-error {{can not have 'extern'}}
+ // FIXME: say 'thread_local' not 'static'.
+ thread_local int not_auto1[n]; // expected-error {{can not have 'static'}}
+
+ // FIXME: these should all be invalid.
+ auto &&ti1 = typeid(arb);
+ auto &&ti2 = typeid(int[n]);
+ auto &&so1 = sizeof(arb);
+ auto &&so2 = sizeof(int[n]);
+ auto *p = &arb;
+ decltype(arb) arb2;
+ int (*arbp)[n] = 0;
+ const int (&arbr)[n] = arbr; // expected-warning {{not yet bound}}
+ typedef int arbty[n];
+ int array_of_arb[2][n];
+
+ struct Dyn { Dyn() {} Dyn(int) {} ~Dyn() {} };
+
+ // FIXME: these should be valid.
+ int arb_dynamic[n] = { 1, 2, 3, 4 }; // expected-error {{may not be initialized}}
+ Dyn dyn[n]; // expected-error {{non-POD}}
+ Dyn dyn_init[n] = { 1, 2, 3, 4 }; // expected-error {{non-POD}}
+}
diff --git a/test/SemaCXX/cxx1y-constexpr-not-const.cpp b/test/SemaCXX/cxx1y-constexpr-not-const.cpp
new file mode 100644
index 0000000000..3f100b8b69
--- /dev/null
+++ b/test/SemaCXX/cxx1y-constexpr-not-const.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -std=c++11 %s -verify
+// RUN: %clang_cc1 -std=c++1y %s -verify -DCXX1Y
+
+struct X {
+ constexpr int f(); // @5
+ int f(); // @6
+};
+
+#ifdef CXX1Y
+// FIXME: Detect this situation and provide a better recovery.
+
+// expected-error@6 {{class member cannot be redeclared}}
+// expected-note@5 {{previous}}
+// expected-error@6 {{non-constexpr declaration of 'f' follows constexpr declaration}}
+// expected-note@5 {{previous}}
+#else
+// expected-warning@5 {{'constexpr' non-static member function will not be implicitly 'const' in C++1y; add 'const' to avoid a change in behavior}}
+#endif
diff --git a/test/SemaCXX/cxx1y-deduced-return-type.cpp b/test/SemaCXX/cxx1y-deduced-return-type.cpp
new file mode 100644
index 0000000000..f0146f88d6
--- /dev/null
+++ b/test/SemaCXX/cxx1y-deduced-return-type.cpp
@@ -0,0 +1,338 @@
+// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only %s
+
+auto f(); // expected-note {{previous}}
+int f(); // expected-error {{differ only in their return type}}
+
+auto &g();
+auto g() -> auto &;
+
+auto h() -> auto *;
+auto *h();
+
+struct Conv1 {
+ operator auto(); // expected-note {{declared here}}
+} conv1;
+int conv1a = conv1; // expected-error {{function 'operator auto' with deduced return type cannot be used before it is defined}}
+// expected-error@-1 {{no viable conversion}}
+Conv1::operator auto() { return 123; }
+int conv1b = conv1;
+int conv1c = conv1.operator auto();
+int conv1d = conv1.operator int(); // expected-error {{no member named 'operator int'}}
+
+struct Conv2 {
+ operator auto() { return 0; } // expected-note 2{{previous}}
+ operator auto() { return 0.; } // expected-error {{cannot be redeclared}} expected-error {{redefinition of 'operator auto'}}
+};
+
+struct Conv3 {
+ operator auto() { int *p = nullptr; return p; } // expected-note {{candidate}}
+ operator auto*() { int *p = nullptr; return p; } // expected-note {{candidate}}
+} conv3;
+int *conv3a = conv3; // expected-error {{ambiguous}}
+int *conv3b = conv3.operator auto();
+int *conv3c = conv3.operator auto*();
+
+template<typename T>
+struct Conv4 {
+ operator auto() { return T(); }
+};
+Conv4<int> conv4int;
+int conv4a = conv4int;
+int conv4b = conv4int.operator auto();
+
+auto a();
+auto a() { return 0; }
+using T = decltype(a());
+using T = int;
+auto a(); // expected-note {{previous}}
+using T = decltype(a());
+auto *a(); // expected-error {{differ only in their return type}}
+
+auto b(bool k) {
+ if (k)
+ return "hello";
+ return "goodbye";
+}
+
+auto *ptr_1() {
+ return 100; // expected-error {{cannot deduce return type 'auto *' from returned value of type 'int'}}
+}
+
+const auto &ref_1() {
+ return 0; // expected-warning {{returning reference to local temporary}}
+}
+
+auto init_list() {
+ return { 1, 2, 3 }; // expected-error {{cannot deduce return type from initializer list}}
+}
+
+auto fwd_decl(); // expected-note 2{{here}}
+
+int n = fwd_decl(); // expected-error {{function 'fwd_decl' with deduced return type cannot be used before it is defined}}
+int k = sizeof(fwd_decl()); // expected-error {{used before it is defined}}
+
+auto fac(int n) {
+ if (n <= 2)
+ return n;
+ return n * fac(n-1); // ok
+}
+
+auto fac_2(int n) { // expected-note {{declared here}}
+ if (n > 2)
+ return n * fac_2(n-1); // expected-error {{cannot be used before it is defined}}
+ return n;
+}
+
+auto void_ret() {}
+using Void = void;
+using Void = decltype(void_ret());
+
+auto &void_ret_2() {} // expected-error {{cannot deduce return type 'auto &' for function with no return statements}}
+const auto void_ret_3() {} // ok, return type 'const void' is adjusted to 'void'
+
+const auto void_ret_4() {
+ if (false)
+ return void();
+ if (false)
+ return;
+ return 0; // expected-error {{'auto' in return type deduced as 'int' here but deduced as 'void' in earlier return statement}}
+}
+
+namespace Templates {
+ template<typename T> auto f1() {
+ return T() + 1;
+ }
+ template<typename T> auto &f2(T &&v) { return v; }
+ int a = f1<int>();
+ const int &b = f2(0);
+ double d;
+ float &c = f2(0.0); // expected-error {{non-const lvalue reference to type 'float' cannot bind to a value of unrelated type 'double'}}
+
+ template<typename T> auto fwd_decl(); // expected-note {{declared here}}
+ int e = fwd_decl<int>(); // expected-error {{cannot be used before it is defined}}
+ template<typename T> auto fwd_decl() { return 0; }
+ int f = fwd_decl<int>();
+ template<typename T> auto fwd_decl();
+ int g = fwd_decl<char>();
+
+ auto (*p)() = f1; // expected-error {{incompatible initializer}}
+ auto (*q)() = f1<int>; // ok
+
+ typedef decltype(f2(1.2)) dbl; // expected-note {{previous}}
+ typedef float dbl; // expected-error {{typedef redefinition with different types ('float' vs 'decltype(f2(1.2))' (aka 'double &'))}}
+
+ extern template auto fwd_decl<double>();
+ int k1 = fwd_decl<double>();
+ extern template int fwd_decl<char>(); // expected-error {{does not refer to a function template}}
+ int k2 = fwd_decl<char>();
+
+ template<typename T> auto instantiate() { T::error; } // expected-error {{has no members}}
+ extern template auto instantiate<int>(); // ok
+ int k = instantiate<int>(); // expected-note {{in instantiation of}}
+ template<> auto instantiate<char>() {} // ok
+ template<> void instantiate<double>() {} // expected-error {{no function template matches}}
+
+ template<typename T> auto arg_single() { return 0; }
+ template<typename T> auto arg_multi() { return 0l; }
+ template<typename T> auto arg_multi(int) { return "bad"; }
+ template<typename T> struct Outer {
+ static auto arg_single() { return 0.f; }
+ static auto arg_multi() { return 0.; }
+ static auto arg_multi(int) { return "bad"; }
+ };
+ template<typename T> T &take_fn(T (*p)());
+
+ int &check1 = take_fn(arg_single); // expected-error {{no matching}} expected-note@-2 {{couldn't infer}}
+ int &check2 = take_fn(arg_single<int>);
+ int &check3 = take_fn<int>(arg_single); // expected-error {{no matching}} expected-note@-4{{no overload of 'arg_single'}}
+ int &check4 = take_fn<int>(arg_single<int>);
+ long &check5 = take_fn(arg_multi); // expected-error {{no matching}} expected-note@-6 {{couldn't infer}}
+ long &check6 = take_fn(arg_multi<int>);
+ long &check7 = take_fn<long>(arg_multi); // expected-error {{no matching}} expected-note@-8{{no overload of 'arg_multi'}}
+ long &check8 = take_fn<long>(arg_multi<int>);
+
+ float &mem_check1 = take_fn(Outer<int>::arg_single);
+ float &mem_check2 = take_fn<float>(Outer<char>::arg_single);
+ double &mem_check3 = take_fn(Outer<long>::arg_multi);
+ double &mem_check4 = take_fn<double>(Outer<double>::arg_multi);
+
+ namespace Deduce1 {
+ template<typename T> auto f() { return 0; } // expected-note {{candidate}}
+ template<typename T> void g(T(*)()); // expected-note 2{{candidate}}
+ void h() {
+ auto p = f<int>;
+ auto (*q)() = f<int>;
+ int (*r)() = f; // expected-error {{does not match}}
+ g(f<int>);
+ g<int>(f); // expected-error {{no matching function}}
+ g(f); // expected-error {{no matching function}}
+ }
+ }
+
+ namespace Deduce2 {
+ template<typename T> auto f(int) { return 0; } // expected-note {{candidate}}
+ template<typename T> void g(T(*)(int)); // expected-note 2{{candidate}}
+ void h() {
+ auto p = f<int>;
+ auto (*q)(int) = f<int>;
+ int (*r)(int) = f; // expected-error {{does not match}}
+ g(f<int>);
+ g<int>(f); // expected-error {{no matching function}}
+ g(f); // expected-error {{no matching function}}
+ }
+ }
+
+ namespace Deduce3 {
+ template<typename T> auto f(T) { return 0; }
+ template<typename T> void g(T(*)(int)); // expected-note {{couldn't infer}}
+ void h() {
+ auto p = f<int>;
+ auto (*q)(int) = f<int>;
+ int (*r)(int) = f; // ok
+ g(f<int>);
+ g<int>(f); // ok
+ g(f); // expected-error {{no matching function}}
+ }
+ }
+
+ namespace DeduceInDeducedReturnType {
+ template<typename T, typename U> auto f() -> auto (T::*)(U) {
+ int (T::*result)(U) = nullptr;
+ return result;
+ }
+ struct S {};
+ int (S::*(*p)())(double) = f;
+ int (S::*(*q)())(double) = f<S, double>;
+ }
+}
+
+auto fwd_decl_using();
+namespace N { using ::fwd_decl_using; }
+auto fwd_decl_using() { return 0; }
+namespace N { int k = N::fwd_decl_using(); }
+
+namespace OverloadResolutionNonTemplate {
+ auto f();
+ auto f(int); // expected-note {{here}}
+
+ int &g(int (*f)()); // expected-note {{not viable: no overload of 'f' matching 'int (*)()'}}
+ char &g(int (*f)(int)); // expected-note {{not viable: no overload of 'f' matching 'int (*)(int)'}}
+
+ int a = g(f); // expected-error {{no matching function}}
+
+ auto f() { return 0; }
+
+ // FIXME: It's not completely clear whether this should be ill-formed.
+ int &b = g(f); // expected-error {{used before it is defined}}
+
+ auto f(int) { return 0.0; }
+
+ int &c = g(f); // ok
+}
+
+namespace OverloadResolutionTemplate {
+ auto f();
+ template<typename T> auto f(T);
+
+ int &g(int (*f)()); // expected-note {{not viable: no overload of 'f' matching 'int (*)()'}} expected-note {{candidate}}
+ char &g(int (*f)(int)); // expected-note {{not viable: no overload of 'f' matching 'int (*)(int)'}} expected-note {{candidate}}
+
+ int a = g(f); // expected-error {{no matching function}}
+
+ auto f() { return 0; }
+
+ int &b = g(f); // ok (presumably), due to deduction failure forming type of 'f<int>'
+
+ template<typename T> auto f(T) { return 0; }
+
+ int &c = g(f); // expected-error {{ambiguous}}
+}
+
+namespace DefaultedMethods {
+ struct A {
+ auto operator=(const A&) = default; // expected-error {{must return 'DefaultedMethods::A &'}}
+ A &operator=(A&&); // expected-note {{previous}}
+ };
+ auto A::operator=(A&&) = default; // expected-error {{differs from the declaration in the return type}}
+}
+
+namespace Constexpr {
+ constexpr auto f1(int n) { return n; }
+ struct NonLiteral { ~NonLiteral(); } nl; // expected-note {{user-provided destructor}}
+ constexpr auto f2(int n) { return nl; } // expected-error {{return type 'Constexpr::NonLiteral' is not a literal type}}
+}
+
+// It's not really clear whether these are valid, but this matches g++.
+using size_t = decltype(sizeof(0));
+auto operator new(size_t n, const char*); // expected-error {{must return type 'void *'}}
+auto operator delete(void *, const char*); // expected-error {{must return type 'void'}}
+
+namespace Virtual {
+ struct S {
+ virtual auto f() { return 0; } // expected-error {{function with deduced return type cannot be virtual}} expected-note {{here}}
+ };
+ // Allow 'auto' anyway for error recovery.
+ struct T : S {
+ int f();
+ };
+ struct U : S {
+ auto f(); // expected-error {{different return}}
+ };
+
+ // And here's why...
+ struct V { virtual auto f(); }; // expected-error {{cannot be virtual}}
+ struct W : V { virtual auto f(); }; // expected-error {{cannot be virtual}}
+ auto V::f() { return 0; } // in tu1.cpp
+ auto W::f() { return 0.0; } // in tu2.cpp
+ W w;
+ int k1 = w.f();
+ int k2 = ((V&)w).f();
+}
+
+namespace std_examples {
+
+namespace NoReturn {
+ auto f() {}
+ void (*p)() = &f;
+
+ auto *g() {} // expected-error {{cannot deduce return type 'auto *' for function with no return statements}}
+}
+
+namespace UseBeforeComplete {
+ auto n = n; // expected-error {{variable 'n' declared with 'auto' type cannot appear in its own initializer}}
+ auto f(); // expected-note {{declared here}}
+ void g() { &f; } // expected-error {{function 'f' with deduced return type cannot be used before it is defined}}
+ auto sum(int i) {
+ if (i == 1)
+ return i;
+ else
+ return sum(i - 1) + i;
+ }
+}
+
+namespace Redecl {
+ auto f();
+ auto f() { return 42; }
+ auto f(); // expected-note 2{{previous}}
+ int f(); // expected-error {{functions that differ only in their return type cannot be overloaded}}
+ decltype(auto) f(); // expected-error {{cannot be overloaded}}
+
+ template<typename T> auto g(T t) { return t; } // expected-note {{candidate}}
+ template auto g(int);
+ template char g(char); // expected-error {{does not refer to a function}}
+ template<> auto g(double);
+
+ template<typename T> T g(T t) { return t; } // expected-note {{candidate}}
+ template char g(char);
+ template auto g(float);
+
+ void h() { return g(42); } // expected-error {{ambiguous}}
+}
+
+namespace ExplicitInstantiationDecl {
+ template<typename T> auto f(T t) { return t; }
+ extern template auto f(int);
+ int (*p)(int) = f;
+}
+
+}
diff --git a/test/SemaCXX/cxx1y-initializer-aggregates.cpp b/test/SemaCXX/cxx1y-initializer-aggregates.cpp
new file mode 100644
index 0000000000..9b542403de
--- /dev/null
+++ b/test/SemaCXX/cxx1y-initializer-aggregates.cpp
@@ -0,0 +1,63 @@
+// RUN: %clang_cc1 -std=c++1y %s -verify
+
+namespace in_class_init {
+ union U { char c; double d = 4.0; };
+ constexpr U u1 = U();
+ constexpr U u2 {};
+ constexpr U u3 { 'x' };
+ static_assert(u1.d == 4.0, "");
+ static_assert(u2.d == 4.0, "");
+ static_assert(u3.c == 'x', "");
+
+ struct A {
+ int n = 5;
+ int m = n * 3;
+ union {
+ char c;
+ double d = 4.0;
+ };
+ };
+ constexpr A a1 {};
+ constexpr A a2 { 8 };
+ constexpr A a3 { 1, 2, { 3 } };
+ constexpr A a4 { 1, 2, { .d = 3.0 } };
+ static_assert(a1.d == 4.0, "");
+ static_assert(a2.m == 24, "");
+ static_assert(a2.d == 4.0, "");
+ static_assert(a3.c == 3, "");
+ static_assert(a3.d == 4.0, ""); // expected-error {{constant expression}} expected-note {{active member 'c'}}
+ static_assert(a4.d == 3.0, "");
+
+ struct B {
+ int n;
+ constexpr int f() { return n * 5; }
+ int m = f();
+ };
+ B b1 {};
+ constexpr B b2 { 2 };
+ B b3 { 1, 2 };
+ static_assert(b2.m == 10, "");
+
+ struct C {
+ int k;
+ union {
+ int l = k; // expected-error {{invalid use of non-static}}
+ };
+ };
+}
+
+namespace nested_aggregate_init {
+ struct A {
+ int n = 5;
+ int b = n * 3;
+ };
+ struct B {
+ constexpr B(int k) : d(1.23), k(k) {}
+ // Within this aggregate, both this object's 'this' and the temporary's
+ // 'this' are used.
+ constexpr int f() const { return A{k}.b; }
+ double d;
+ int k;
+ };
+ static_assert(B(6).f() == 18, "");
+}
diff --git a/test/SemaCXX/cxx98-compat-pedantic.cpp b/test/SemaCXX/cxx98-compat-pedantic.cpp
index 18fd1520ec..208ea4ce92 100644
--- a/test/SemaCXX/cxx98-compat-pedantic.cpp
+++ b/test/SemaCXX/cxx98-compat-pedantic.cpp
@@ -1,3 +1,5 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++1y -DCXX1Y -Wc++98-compat-pedantic -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++1y -DCXX1Y -Wc++98-compat -Werror %s
// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wc++98-compat-pedantic -verify %s
// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wc++98-compat -Werror %s
// RUN: %clang_cc1 -fsyntax-only -std=c++98 -Werror %s
@@ -38,3 +40,12 @@ long long ll1 = // expected-warning {{'long long' is incompatible with C++98}}
unsigned long long ull1 = // expected-warning {{'long long' is incompatible with C++98}}
42ULL; // expected-warning {{'long long' is incompatible with C++98}}
+int k = 0b1001;
+#ifdef CXX1Y
+// expected-warning@-2 {{binary integer literals are incompatible with C++ standards before C++1y}}
+#endif
+
+void f(int n) { int a[n]; }
+#ifdef CXX1Y
+// expected-warning@-2 {{arrays of runtime bound are incompatible with C++ standards before C++1y}}
+#endif
diff --git a/test/SemaCXX/enum-scoped.cpp b/test/SemaCXX/enum-scoped.cpp
index a1f911d79d..d01000d22b 100644
--- a/test/SemaCXX/enum-scoped.cpp
+++ b/test/SemaCXX/enum-scoped.cpp
@@ -252,3 +252,17 @@ namespace pr13128 {
enum class E { C };
};
}
+
+namespace PR15633 {
+ template<typename T> struct A {
+ struct B {
+ enum class E : T;
+ enum class E2 : T;
+ };
+ };
+ template<typename T> enum class A<T>::B::E { e };
+ template class A<int>;
+
+ struct B { enum class E; };
+ template<typename T> enum class B::E { e }; // expected-error {{enumeration cannot be a template}}
+}
diff --git a/test/SemaCXX/enum-unscoped-nonexistent.cpp b/test/SemaCXX/enum-unscoped-nonexistent.cpp
index d49800caa6..e9da38f558 100644
--- a/test/SemaCXX/enum-unscoped-nonexistent.cpp
+++ b/test/SemaCXX/enum-unscoped-nonexistent.cpp
@@ -5,8 +5,8 @@ struct Base {
};
template<typename T> struct S : Base {
enum E : int;
- constexpr int f();
- constexpr int g(); // expected-note {{declared here}}
+ constexpr int f() const;
+ constexpr int g() const; // expected-note {{declared here}}
void h();
};
template<> enum S<char>::E : int {}; // expected-note {{enum 'S<char>::E' was explicitly specialized here}}
@@ -16,13 +16,13 @@ template<typename T> enum S<T>::E : int { b = 8 };
// The unqualified-id here names a member of the non-dependent base class Base
// and not the injected enumerator name 'a' from the specialization.
-template<typename T> constexpr int S<T>::f() { return a; }
+template<typename T> constexpr int S<T>::f() const { return a; }
static_assert(S<char>().f() == 1, "");
static_assert(S<int>().f() == 1, "");
// The unqualified-id here names a member of the current instantiation, which
// bizarrely might not exist in some instantiations.
-template<typename T> constexpr int S<T>::g() { return b; } // expected-error {{enumerator 'b' does not exist in instantiation of 'S<char>'}}
+template<typename T> constexpr int S<T>::g() const { return b; } // expected-error {{enumerator 'b' does not exist in instantiation of 'S<char>'}}
static_assert(S<char>().g() == 1, ""); // expected-note {{here}} expected-error {{not an integral constant expression}} expected-note {{undefined}}
static_assert(S<short>().g() == 2, "");
static_assert(S<long>().g() == 8, "");
diff --git a/test/SemaCXX/extern-c.cpp b/test/SemaCXX/extern-c.cpp
new file mode 100644
index 0000000000..c55b10d9d6
--- /dev/null
+++ b/test/SemaCXX/extern-c.cpp
@@ -0,0 +1,58 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace test1 {
+ extern "C" {
+ void f() {
+ void test1_g(int); // expected-note {{previous declaration is here}}
+ }
+ }
+}
+int test1_g(int); // expected-error {{functions that differ only in their return type cannot be overloaded}}
+
+namespace test2 {
+ extern "C" {
+ void f() {
+ extern int test2_x; // expected-note {{previous definition is here}}
+ }
+ }
+}
+float test2_x; // expected-error {{redefinition of 'test2_x' with a different type: 'float' vs 'int'}}
+
+namespace test3 {
+ extern "C" {
+ void f() {
+ extern int test3_b; // expected-note {{previous definition is here}}
+ }
+ }
+ extern "C" {
+ float test3_b; // expected-error {{redefinition of 'test3_b' with a different type: 'float' vs 'int'}}
+ }
+}
+
+extern "C" {
+ void test4_f() {
+ extern int test4_b; // expected-note {{previous definition is here}}
+ }
+}
+static float test4_b; // expected-error {{redefinition of 'test4_b' with a different type: 'float' vs 'int'}}
+
+extern "C" {
+ void test5_f() {
+ extern int test5_b; // expected-note {{previous definition is here}}
+ }
+}
+extern "C" {
+ static float test5_b; // expected-error {{redefinition of 'test5_b' with a different type: 'float' vs 'int'}}
+}
+
+extern "C" {
+ void f() {
+ extern int test6_b;
+ }
+}
+namespace foo {
+ extern "C" {
+ static float test6_b;
+ extern float test6_b;
+ }
+}
diff --git a/test/SemaCXX/for-range-unused.cpp b/test/SemaCXX/for-range-unused.cpp
index ce6b379cc1..ec11015552 100644
--- a/test/SemaCXX/for-range-unused.cpp
+++ b/test/SemaCXX/for-range-unused.cpp
@@ -7,7 +7,7 @@ template <typename T>
void doIt() {
int a; // expected-warning {{unused variable 'a'}}
- for (auto& e : elements)
+ for (auto& e : elements) // expected-warning {{unused variable 'e'}}
;
}
@@ -17,5 +17,5 @@ template <typename T>
int main(int, char**) {
Vector<int> vector;
- vector.doIt();
+ vector.doIt(); // expected-note {{here}}
}
diff --git a/test/SemaCXX/friend.cpp b/test/SemaCXX/friend.cpp
index c5b11eb5a3..b401a06a7e 100644
--- a/test/SemaCXX/friend.cpp
+++ b/test/SemaCXX/friend.cpp
@@ -138,3 +138,19 @@ namespace test7 {
};
}
}
+
+// PR15485
+namespace test8 {
+ namespace ns1 {
+ namespace ns2 {
+ template<class T> void f(T t); // expected-note {{target of using declaration}}
+ }
+ using ns2::f; // expected-note {{using declaration}}
+ }
+ struct A { void f(); }; // expected-note {{target of using declaration}}
+ struct B : public A { using A::f; }; // expected-note {{using declaration}}
+ struct X {
+ template<class T> friend void ns1::f(T t); // expected-error {{cannot befriend target of using declaration}}
+ friend void B::f(); // expected-error {{cannot befriend target of using declaration}}
+ };
+}
diff --git a/test/SemaCXX/function-extern-c.cpp b/test/SemaCXX/function-extern-c.cpp
index a4b8400abc..6ab9657350 100644
--- a/test/SemaCXX/function-extern-c.cpp
+++ b/test/SemaCXX/function-extern-c.cpp
@@ -49,7 +49,7 @@ namespace test2 {
struct A {
A(const A&);
};
- A f(void); // expected-warning {{'f' has C-linkage specified, but returns user-defined type 'test2::A' which is incompatible with C}}
+ A f(void); // no warning. warning is already issued on first declaration.
}
namespace test3 {
@@ -61,3 +61,38 @@ namespace test3 {
static A f(void);
}
}
+
+// rdar://13364028
+namespace rdar13364028 {
+class A {
+public:
+ virtual int x();
+};
+
+extern "C" {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wreturn-type-c-linkage"
+A xyzzy();
+#pragma clang diagnostic pop
+A bbb(); // expected-warning {{'bbb' has C-linkage specified, but returns user-defined type 'rdar13364028::A' which is incompatible with C}}
+A ccc() { // expected-warning {{'ccc' has C-linkage specified, but returns user-defined type 'rdar13364028::A' which is incompatible with C}}
+ return A();
+};
+}
+
+A xyzzy();
+
+A xyzzy()
+{
+ return A();
+}
+
+A bbb()
+{
+ return A();
+}
+
+A bbb();
+
+A ccc();
+}
diff --git a/test/SemaCXX/function-redecl.cpp b/test/SemaCXX/function-redecl.cpp
index 7bf44b1c36..b9d1f23af4 100644
--- a/test/SemaCXX/function-redecl.cpp
+++ b/test/SemaCXX/function-redecl.cpp
@@ -116,32 +116,3 @@ bool Foo::isGood() { // expected-error {{out-of-line definition of 'isGood' does
}
void Foo::beEvil() {} // expected-error {{out-of-line definition of 'beEvil' does not match any declaration in namespace 'redecl_typo::Foo'; did you mean 'BeEvil'?}}
}
-
-namespace test2 {
- extern "C" {
- void f() {
- void test2_g(int); // expected-note {{previous declaration is here}}
- }
- }
-}
-int test2_g(int); // expected-error {{functions that differ only in their return type cannot be overloaded}}
-
-namespace test3 {
- extern "C" {
- void f() {
- extern int test3_x; // expected-note {{previous definition is here}}
- }
- }
-}
-float test3_x; // expected-error {{redefinition of 'test3_x' with a different type: 'float' vs 'int'}}
-
-namespace test4 {
- extern "C" {
- void f() {
- extern int b; // expected-note {{previous definition is here}}
- }
- }
- extern "C" {
- float b; // expected-error {{redefinition of 'b' with a different type: 'float' vs 'int'}}
- }
-}
diff --git a/test/SemaCXX/i-c-e-cxx.cpp b/test/SemaCXX/i-c-e-cxx.cpp
index 5631577e0f..c80323ccd7 100644
--- a/test/SemaCXX/i-c-e-cxx.cpp
+++ b/test/SemaCXX/i-c-e-cxx.cpp
@@ -60,7 +60,7 @@ int* y = reinterpret_cast<const char&>(x); // expected-error {{cannot initialize
// This isn't an integral constant expression, but make sure it folds anyway.
struct PR8836 { char _; long long a; }; // expected-warning {{long long}}
-int PR8836test[(__typeof(sizeof(int)))&reinterpret_cast<const volatile char&>((((PR8836*)0)->a))]; // expected-warning {{folded to constant array as an extension}} expected-note {{cast which performs the conversions of a reinterpret_cast is not allowed in a constant expression}}
+int PR8836test[(__typeof(sizeof(int)))&reinterpret_cast<const volatile char&>((((PR8836*)0)->a))]; // expected-warning {{folded to constant array as an extension}} expected-note {{cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression}}
const int nonconst = 1.0; // expected-note {{declared here}}
int arr[nonconst]; // expected-warning {{folded to constant array as an extension}} expected-note {{initializer of 'nonconst' is not a constant expression}}
diff --git a/test/SemaCXX/linkage-spec.cpp b/test/SemaCXX/linkage-spec.cpp
index cb7e32c05d..504df0d35c 100644
--- a/test/SemaCXX/linkage-spec.cpp
+++ b/test/SemaCXX/linkage-spec.cpp
@@ -90,6 +90,10 @@ extern "C++" using N::value;
// PR7076
extern "C" const char *Version_string = "2.9";
+extern "C" {
+ extern const char *Version_string2 = "2.9";
+}
+
namespace PR9162 {
extern "C" {
typedef struct _ArtsSink ArtsSink;
@@ -102,3 +106,11 @@ namespace PR9162 {
return sizeof(ArtsSink);
}
}
+
+namespace pr14958 {
+ namespace js { extern int ObjectClass; }
+ extern "C" {
+ namespace js {}
+ }
+ int js::ObjectClass;
+}
diff --git a/test/SemaCXX/linkage.cpp b/test/SemaCXX/linkage.cpp
index 6b73d596e0..13d295a5d5 100644
--- a/test/SemaCXX/linkage.cpp
+++ b/test/SemaCXX/linkage.cpp
@@ -94,3 +94,12 @@ extern "C" {
// CHECK: define linkonce_odr i8* @_ZN5test21A1BILj0EE3fooEv(
// CHECK: define linkonce_odr i8* @_ZN5test11A3fooILj0EEEPvv(
+
+namespace test5 {
+ struct foo {
+ };
+ extern "C" {
+ const foo bar[] = {
+ };
+ }
+}
diff --git a/test/SemaCXX/linkage2.cpp b/test/SemaCXX/linkage2.cpp
index 2cee581b49..3cfa98138b 100644
--- a/test/SemaCXX/linkage2.cpp
+++ b/test/SemaCXX/linkage2.cpp
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -fmodules %s
namespace test1 {
int x; // expected-note {{previous definition is here}}
@@ -125,3 +126,41 @@ extern "C" {
void __attribute__((overloadable)) test11_g(double);
}
}
+
+namespace test12 {
+ const int n = 0;
+ extern const int n;
+ void f() {
+ extern const int n;
+ }
+}
+
+namespace test13 {
+ static void a(void);
+ extern void a();
+ static void a(void) {}
+}
+
+namespace test14 {
+ namespace {
+ void a(void); // expected-note {{previous declaration is here}}
+ static void a(void) {} // expected-error {{static declaration of 'a' follows non-static declaration}}
+ }
+}
+
+namespace test15 {
+ const int a = 5; // expected-note {{previous definition is here}}
+ static const int a; // expected-error {{redefinition of 'a'}}
+}
+
+namespace test16 {
+ extern "C" {
+ class Foo {
+ int x;
+ friend int bar(Foo *y);
+ };
+ int bar(Foo *y) {
+ return y->x;
+ }
+ }
+}
diff --git a/test/SemaCXX/member-pointer-ms.cpp b/test/SemaCXX/member-pointer-ms.cpp
index 3b2d0fceb9..7dca121905 100644
--- a/test/SemaCXX/member-pointer-ms.cpp
+++ b/test/SemaCXX/member-pointer-ms.cpp
@@ -1,14 +1,167 @@
-// RUN: %clang_cc1 -cxx-abi microsoft -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++11 -cxx-abi microsoft -fms-compatibility -fsyntax-only -triple=i386-pc-win32 -verify %s
+// RUN: %clang_cc1 -std=c++11 -cxx-abi microsoft -fms-compatibility -fsyntax-only -triple=x86_64-pc-win32 -verify %s
+//
+// This file should also give no diagnostics when run through cl.exe from MSVS
+// 2012, which supports C++11 and static_assert. It should pass for both 64-bit
+// and 32-bit x86.
+//
+// expected-no-diagnostics
-// Test that we reject pointers to members of incomplete classes (for now)
-struct A; //expected-note{{forward declaration of 'A'}}
-int A::*pai1; //expected-error{{incomplete type 'A'}}
+// Test the size of various member pointer combinations:
+// - complete and incomplete
+// - single, multiple, and virtual inheritance (and unspecified for incomplete)
+// - data and function pointers
+// - templated with declared specializations with annotations
+// - template that can be instantiated
-// Test that we don't allow reinterpret_casts from pointers of one size to
-// pointers of a different size.
-struct A {};
-struct B {};
-struct C: A, B {};
+// http://llvm.org/PR12070
+struct Foo {
+ typedef int Foo::*FooInt;
+ int f;
+};
-void (A::*paf)();
-void (C::*pcf)() = reinterpret_cast<void (C::*)()>(paf); //expected-error{{cannot reinterpret_cast from member pointer type}}
+enum {
+ kSingleDataSize = 1 * sizeof(int),
+ kSingleFunctionSize = 1 * sizeof(void *),
+ kMultipleDataSize = 1 * sizeof(int),
+ kMultipleFunctionSize = 2 * sizeof(void *),
+ kVirtualDataSize = 2 * sizeof(int),
+ kVirtualFunctionSize = 2 * sizeof(int) + 1 * sizeof(void *),
+ // Unspecified is weird, it's 1 more slot than virtual.
+ kUnspecifiedDataSize = kVirtualDataSize + 1 * sizeof(int),
+ kUnspecifiedFunctionSize = kVirtualFunctionSize + 1 * sizeof(void *),
+};
+
+// incomplete types
+class __single_inheritance IncSingle;
+class __multiple_inheritance IncMultiple;
+class __virtual_inheritance IncVirtual;
+static_assert(sizeof(int IncSingle::*) == kSingleDataSize, "");
+static_assert(sizeof(int IncMultiple::*) == kMultipleDataSize, "");
+static_assert(sizeof(int IncVirtual::*) == kVirtualDataSize, "");
+static_assert(sizeof(void (IncSingle::*)()) == kSingleFunctionSize, "");
+static_assert(sizeof(void (IncMultiple::*)()) == kMultipleFunctionSize, "");
+static_assert(sizeof(void (IncVirtual::*)()) == kVirtualFunctionSize, "");
+
+// An incomplete type with an unspecified inheritance model seems to take one
+// more slot than virtual. It's not clear what it's used for yet.
+class IncUnspecified;
+static_assert(sizeof(int IncUnspecified::*) == kUnspecifiedDataSize, "");
+static_assert(sizeof(void (IncUnspecified::*)()) == kUnspecifiedFunctionSize, "");
+
+// complete types
+struct B1 { };
+struct B2 { };
+struct Single { };
+struct Multiple : B1, B2 { };
+struct Virtual : virtual B1 { };
+static_assert(sizeof(int Single::*) == kSingleDataSize, "");
+static_assert(sizeof(int Multiple::*) == kMultipleDataSize, "");
+static_assert(sizeof(int Virtual::*) == kVirtualDataSize, "");
+static_assert(sizeof(void (Single::*)()) == kSingleFunctionSize, "");
+static_assert(sizeof(void (Multiple::*)()) == kMultipleFunctionSize, "");
+static_assert(sizeof(void (Virtual::*)()) == kVirtualFunctionSize, "");
+
+// Test both declared and defined templates.
+template <typename T> class X;
+template <> class __single_inheritance X<IncSingle>;
+template <> class __multiple_inheritance X<IncMultiple>;
+template <> class __virtual_inheritance X<IncVirtual>;
+// Don't declare X<IncUnspecified>.
+static_assert(sizeof(int X<IncSingle>::*) == kSingleDataSize, "");
+static_assert(sizeof(int X<IncMultiple>::*) == kMultipleDataSize, "");
+static_assert(sizeof(int X<IncVirtual>::*) == kVirtualDataSize, "");
+static_assert(sizeof(int X<IncUnspecified>::*) == kUnspecifiedDataSize, "");
+static_assert(sizeof(void (X<IncSingle>::*)()) == kSingleFunctionSize, "");
+static_assert(sizeof(void (X<IncMultiple>::*)()) == kMultipleFunctionSize, "");
+static_assert(sizeof(void (X<IncVirtual>::*)()) == kVirtualFunctionSize, "");
+static_assert(sizeof(void (X<IncUnspecified>::*)()) == kUnspecifiedFunctionSize, "");
+
+template <typename T>
+struct Y : T { };
+static_assert(sizeof(int Y<Single>::*) == kSingleDataSize, "");
+static_assert(sizeof(int Y<Multiple>::*) == kMultipleDataSize, "");
+static_assert(sizeof(int Y<Virtual>::*) == kVirtualDataSize, "");
+static_assert(sizeof(void (Y<Single>::*)()) == kSingleFunctionSize, "");
+static_assert(sizeof(void (Y<Multiple>::*)()) == kMultipleFunctionSize, "");
+static_assert(sizeof(void (Y<Virtual>::*)()) == kVirtualFunctionSize, "");
+
+struct A { int x; void bar(); };
+struct B : A { virtual void foo(); };
+static_assert(sizeof(int B::*) == kSingleDataSize, "");
+// A non-primary base class uses the multiple inheritance model for member
+// pointers.
+static_assert(sizeof(void (B::*)()) == kMultipleFunctionSize, "");
+
+struct AA { int x; virtual void foo(); };
+struct BB : AA { void bar(); };
+struct CC : BB { virtual void baz(); };
+static_assert(sizeof(void (CC::*)()) == kSingleFunctionSize, "");
+
+// We start out unspecified.
+struct ForwardDecl1;
+struct ForwardDecl2;
+
+// Re-declare to force us to iterate decls when adding attributes.
+struct ForwardDecl1;
+struct ForwardDecl2;
+
+typedef int ForwardDecl1::*MemPtr1;
+typedef int ForwardDecl2::*MemPtr2;
+MemPtr1 variable_forces_sizing;
+
+struct ForwardDecl1 : B {
+ virtual void foo();
+};
+struct ForwardDecl2 : B {
+ virtual void foo();
+};
+
+static_assert(sizeof(variable_forces_sizing) == kUnspecifiedDataSize, "");
+static_assert(sizeof(MemPtr1) == kUnspecifiedDataSize, "");
+// FIXME: Clang fails this assert because it locks in the inheritance model at
+// the point of the typedef instead of the first usage, while MSVC does not.
+//static_assert(sizeof(MemPtr2) == kSingleDataSize, "");
+
+struct MemPtrInBody {
+ typedef int MemPtrInBody::*MemPtr;
+ int a;
+ operator MemPtr() const {
+ return a ? &MemPtrInBody::a : 0;
+ }
+};
+
+static_assert(sizeof(MemPtrInBody::MemPtr) == kSingleDataSize, "");
+
+// Passing a member pointer through a template should get the right size.
+template<typename T>
+struct SingleTemplate;
+template<typename T>
+struct SingleTemplate<void (T::*)(void)> {
+ static_assert(sizeof(int T::*) == kSingleDataSize, "");
+ static_assert(sizeof(void (T::*)()) == kSingleFunctionSize, "");
+};
+
+template<typename T>
+struct UnspecTemplate;
+template<typename T>
+struct UnspecTemplate<void (T::*)(void)> {
+ static_assert(sizeof(int T::*) == kUnspecifiedDataSize, "");
+ static_assert(sizeof(void (T::*)()) == kUnspecifiedFunctionSize, "");
+};
+
+struct NewUnspecified;
+SingleTemplate<void (IncSingle::*)()> tmpl_single;
+UnspecTemplate<void (NewUnspecified::*)()> tmpl_unspec;
+
+struct NewUnspecified { };
+
+static_assert(sizeof(void (NewUnspecified::*)()) == kUnspecifiedFunctionSize, "");
+
+template <typename T>
+struct MemPtrInTemplate {
+ // We can't require that the template arg be complete until we're
+ // instantiated.
+ int T::*data_ptr;
+ void (T::*func_ptr)();
+};
diff --git a/test/SemaCXX/pascal-strings.cpp b/test/SemaCXX/pascal-strings.cpp
index 89194b54aa..f4c692db58 100644
--- a/test/SemaCXX/pascal-strings.cpp
+++ b/test/SemaCXX/pascal-strings.cpp
@@ -4,3 +4,5 @@ const wchar_t *pascalString = L"\pThis is a Pascal string";
unsigned char a[3] = "\pa";
unsigned char b[3] = "\pab";
unsigned char c[3] = "\pabc"; // expected-error {{initializer-string for char array is too long}}
+unsigned char d[3] = ("\pab");
+unsigned char e[3] = ("\pabc"); // expected-error {{initializer-string for char array is too long}}
diff --git a/test/SemaCXX/return.cpp b/test/SemaCXX/return.cpp
index 2f98a277f6..580f0a7233 100644
--- a/test/SemaCXX/return.cpp
+++ b/test/SemaCXX/return.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -fcxx-exceptions -fexceptions -fsyntax-only -Wignored-qualifiers -verify
+// RUN: %clang_cc1 %s -std=c++11 -fcxx-exceptions -fexceptions -fsyntax-only -Wignored-qualifiers -verify
int test1() {
throw;
@@ -45,6 +45,27 @@ const
j();
const volatile int scalar_cv(); // expected-warning{{'const volatile' type qualifiers on return type have no effect}}
+
+// FIXME: Maintain enough information that we can point the diagnostic at the 'volatile' keyword.
+const
+int S::*
+volatile
+mixed_ret(); // expected-warning {{'volatile' type qualifier on return type has no effect}}
+
+const int volatile // expected-warning {{'const volatile' type qualifiers on return type have no effect}}
+ (((parens())));
+
+_Atomic(int) atomic();
+
+_Atomic // expected-warning {{'_Atomic' type qualifier on return type has no effect}}
+ int
+ atomic();
+
+auto
+ trailing_return_type() -> // expected-warning {{'const' type qualifier on return type has no effect}}
+ const int;
+
+const int ret_array()[4]; // expected-error {{cannot return array}}
}
namespace PR9328 {
@@ -56,6 +77,7 @@ namespace PR9328 {
}
class foo {
+ operator const int ();
operator int * const ();
};
diff --git a/test/SemaCXX/storage-class.cpp b/test/SemaCXX/storage-class.cpp
index 01cfbfc51f..74121843e5 100644
--- a/test/SemaCXX/storage-class.cpp
+++ b/test/SemaCXX/storage-class.cpp
@@ -3,5 +3,5 @@ extern const int PR6495a = 42;
extern int PR6495b = 42; // expected-warning{{'extern' variable has an initializer}}
extern const int PR6495c[] = {42,43,44};
-extern struct Test1 {}; // expected-warning {{'extern' ignored on this declaration}}
+extern struct Test1 {}; // expected-warning {{'extern' is not permitted on a declaration of a type}}
extern "C" struct Test0 {}; // no warning
diff --git a/test/SemaCXX/switch-implicit-fallthrough.cpp b/test/SemaCXX/switch-implicit-fallthrough.cpp
index 0f7891dc53..d7959238c6 100644
--- a/test/SemaCXX/switch-implicit-fallthrough.cpp
+++ b/test/SemaCXX/switch-implicit-fallthrough.cpp
@@ -247,3 +247,21 @@ int fallthrough_targets(int n) {
}
return n;
}
+
+// Fallthrough annotations in local classes used to generate "fallthrough
+// annotation does not directly precede switch label" warning.
+void fallthrough_in_local_class() {
+ class C {
+ void f(int x) {
+ switch (x) {
+ case 0:
+ x++;
+ [[clang::fallthrough]]; // no diagnostics
+ case 1:
+ x++;
+ break;
+ }
+ }
+ };
+}
+
diff --git a/test/SemaCXX/trailing-return-0x.cpp b/test/SemaCXX/trailing-return-0x.cpp
index 462b4fa3da..bd601db2ac 100644
--- a/test/SemaCXX/trailing-return-0x.cpp
+++ b/test/SemaCXX/trailing-return-0x.cpp
@@ -85,3 +85,12 @@ namespace PR12053 {
f2(0); // expected-error{{no matching function for call to 'f2'}}
}
}
+
+namespace DR1608 {
+ struct S {
+ void operator+();
+ int operator[](int);
+ auto f() -> decltype(+*this); // expected-note {{here}}
+ auto f() -> decltype((*this)[0]); // expected-error {{cannot be overloaded}}
+ };
+}
diff --git a/test/SemaCXX/type-traits.cpp b/test/SemaCXX/type-traits.cpp
index 4b6c44d257..aa18ff4e67 100644
--- a/test/SemaCXX/type-traits.cpp
+++ b/test/SemaCXX/type-traits.cpp
@@ -39,9 +39,34 @@ struct DerivesEmpty : Empty {};
struct HasCons { HasCons(int); };
struct HasCopyAssign { HasCopyAssign operator =(const HasCopyAssign&); };
struct HasMoveAssign { HasMoveAssign operator =(const HasMoveAssign&&); };
+struct HasNoThrowMoveAssign {
+ HasNoThrowMoveAssign& operator=(
+ const HasNoThrowMoveAssign&&) throw(); };
+struct HasNoExceptNoThrowMoveAssign {
+ HasNoExceptNoThrowMoveAssign& operator=(
+ const HasNoExceptNoThrowMoveAssign&&) noexcept;
+};
+struct HasThrowMoveAssign {
+ HasThrowMoveAssign& operator=(
+ const HasThrowMoveAssign&&) throw(POD); };
+struct HasNoExceptFalseMoveAssign {
+ HasNoExceptFalseMoveAssign& operator=(
+ const HasNoExceptFalseMoveAssign&&) noexcept(false); };
+struct HasMoveCtor { HasMoveCtor(const HasMoveCtor&&); };
+struct HasMemberMoveCtor { HasMoveCtor member; };
+struct HasMemberMoveAssign { HasMoveAssign member; };
+struct HasStaticMemberMoveCtor { static HasMoveCtor member; };
+struct HasStaticMemberMoveAssign { static HasMoveAssign member; };
+struct HasMemberThrowMoveAssign { HasThrowMoveAssign member; };
+struct HasMemberNoExceptFalseMoveAssign {
+ HasNoExceptFalseMoveAssign member; };
+struct HasMemberNoThrowMoveAssign { HasNoThrowMoveAssign member; };
+struct HasMemberNoExceptNoThrowMoveAssign {
+ HasNoExceptNoThrowMoveAssign member; };
+
struct HasDefaultTrivialCopyAssign {
- HasDefaultTrivialCopyAssign &operator =(const HasDefaultTrivialCopyAssign&)
- = default;
+ HasDefaultTrivialCopyAssign &operator=(
+ const HasDefaultTrivialCopyAssign&) = default;
};
struct TrivialMoveButNotCopy {
TrivialMoveButNotCopy &operator=(TrivialMoveButNotCopy&&) = default;
@@ -69,6 +94,7 @@ struct DerivesHasPriv : HasPriv {};
struct DerivesHasProt : HasProt {};
struct DerivesHasRef : HasRef {};
struct DerivesHasVirt : HasVirt {};
+struct DerivesHasMoveCtor : HasMoveCtor {};
struct HasNoThrowCopyAssign {
void operator =(const HasNoThrowCopyAssign&) throw();
@@ -165,7 +191,7 @@ typedef Empty EmptyAr[10];
struct Bit0 { int : 0; };
struct Bit0Cons { int : 0; Bit0Cons(); };
struct BitOnly { int x : 3; };
-//struct DerivesVirt : virtual POD {};
+struct DerivesVirt : virtual POD {};
void is_empty()
{
@@ -941,6 +967,19 @@ struct AllDefaulted {
~AllDefaulted() = default;
};
+struct NoDefaultMoveAssignDueToUDCopyCtor {
+ NoDefaultMoveAssignDueToUDCopyCtor(const NoDefaultMoveAssignDueToUDCopyCtor&);
+};
+
+struct NoDefaultMoveAssignDueToUDCopyAssign {
+ NoDefaultMoveAssignDueToUDCopyAssign& operator=(
+ const NoDefaultMoveAssignDueToUDCopyAssign&);
+};
+
+struct NoDefaultMoveAssignDueToDtor {
+ ~NoDefaultMoveAssignDueToDtor();
+};
+
struct AllDeleted {
AllDeleted() = delete;
AllDeleted(const AllDeleted &) = delete;
@@ -1203,6 +1242,32 @@ void has_trivial_default_constructor() {
{ int arr[F(__has_trivial_constructor(ExtDefaulted))]; }
}
+void has_trivial_move_constructor() {
+ // n3376 12.8 [class.copy]/12
+ // A copy/move constructor for class X is trivial if it is not
+ // user-provided, its declared parameter type is the same as
+ // if it had been implicitly declared, and if
+ // — class X has no virtual functions (10.3) and no virtual
+ // base classes (10.1), and
+ // — the constructor selected to copy/move each direct base
+ // class subobject is trivial, and
+ // — for each non-static data member of X that is of class
+ // type (or array thereof), the constructor selected
+ // to copy/move that member is trivial;
+ // otherwise the copy/move constructor is non-trivial.
+ { int arr[T(__has_trivial_move_constructor(POD))]; }
+ { int arr[T(__has_trivial_move_constructor(Union))]; }
+ { int arr[T(__has_trivial_move_constructor(HasCons))]; }
+ { int arr[T(__has_trivial_move_constructor(HasStaticMemberMoveCtor))]; }
+ { int arr[T(__has_trivial_move_constructor(AllDeleted))]; }
+
+ { int arr[F(__has_trivial_move_constructor(HasVirt))]; }
+ { int arr[F(__has_trivial_move_constructor(DerivesVirt))]; }
+ { int arr[F(__has_trivial_move_constructor(HasMoveCtor))]; }
+ { int arr[F(__has_trivial_move_constructor(DerivesHasMoveCtor))]; }
+ { int arr[F(__has_trivial_move_constructor(HasMemberMoveCtor))]; }
+}
+
void has_trivial_copy_constructor() {
{ int arr[T(__has_trivial_copy(Int))]; }
{ int arr[T(__has_trivial_copy(IntAr))]; }
@@ -1355,6 +1420,54 @@ void has_nothrow_assign() {
{ int arr[F(__has_nothrow_assign(PR11110))]; }
}
+void has_nothrow_move_assign() {
+ { int arr[T(__has_nothrow_move_assign(Int))]; }
+ { int arr[T(__has_nothrow_move_assign(Enum))]; }
+ { int arr[T(__has_nothrow_move_assign(Int*))]; }
+ { int arr[T(__has_nothrow_move_assign(Enum POD::*))]; }
+ { int arr[T(__has_nothrow_move_assign(POD))]; }
+ { int arr[T(__has_nothrow_move_assign(HasPriv))]; }
+ { int arr[T(__has_nothrow_move_assign(HasNoThrowMoveAssign))]; }
+ { int arr[T(__has_nothrow_move_assign(HasNoExceptNoThrowMoveAssign))]; }
+ { int arr[T(__has_nothrow_move_assign(HasMemberNoThrowMoveAssign))]; }
+ { int arr[T(__has_nothrow_move_assign(HasMemberNoExceptNoThrowMoveAssign))]; }
+ { int arr[T(__has_nothrow_move_assign(AllDeleted))]; }
+
+
+ { int arr[F(__has_nothrow_move_assign(HasThrowMoveAssign))]; }
+ { int arr[F(__has_nothrow_move_assign(HasNoExceptFalseMoveAssign))]; }
+ { int arr[F(__has_nothrow_move_assign(HasMemberThrowMoveAssign))]; }
+ { int arr[F(__has_nothrow_move_assign(HasMemberNoExceptFalseMoveAssign))]; }
+ { int arr[F(__has_nothrow_move_assign(NoDefaultMoveAssignDueToUDCopyCtor))]; }
+ { int arr[F(__has_nothrow_move_assign(NoDefaultMoveAssignDueToUDCopyAssign))]; }
+ { int arr[F(__has_nothrow_move_assign(NoDefaultMoveAssignDueToDtor))]; }
+}
+
+void has_trivial_move_assign() {
+ // n3376 12.8 [class.copy]/25
+ // A copy/move assignment operator for class X is trivial if it
+ // is not user-provided, its declared parameter type is the same
+ // as if it had been implicitly declared, and if:
+ // — class X has no virtual functions (10.3) and no virtual base
+ // classes (10.1), and
+ // — the assignment operator selected to copy/move each direct
+ // base class subobject is trivial, and
+ // — for each non-static data member of X that is of class type
+ // (or array thereof), the assignment operator
+ // selected to copy/move that member is trivial;
+ { int arr[T(__has_trivial_move_assign(Int))]; }
+ { int arr[T(__has_trivial_move_assign(HasStaticMemberMoveAssign))]; }
+ { int arr[T(__has_trivial_move_assign(AllDeleted))]; }
+
+ { int arr[F(__has_trivial_move_assign(HasVirt))]; }
+ { int arr[F(__has_trivial_move_assign(DerivesVirt))]; }
+ { int arr[F(__has_trivial_move_assign(HasMoveAssign))]; }
+ { int arr[F(__has_trivial_move_assign(DerivesHasMoveAssign))]; }
+ { int arr[F(__has_trivial_move_assign(HasMemberMoveAssign))]; }
+ { int arr[F(__has_nothrow_move_assign(NoDefaultMoveAssignDueToUDCopyCtor))]; }
+ { int arr[F(__has_nothrow_move_assign(NoDefaultMoveAssignDueToUDCopyAssign))]; }
+}
+
void has_nothrow_copy() {
{ int arr[T(__has_nothrow_copy(Int))]; }
{ int arr[T(__has_nothrow_copy(IntAr))]; }
diff --git a/test/SemaCXX/typo-correction.cpp b/test/SemaCXX/typo-correction.cpp
index 4a3f0f6b29..caa6355fe9 100644
--- a/test/SemaCXX/typo-correction.cpp
+++ b/test/SemaCXX/typo-correction.cpp
@@ -250,3 +250,13 @@ void f(B &x) {
x.Createfoo(0,0); // expected-error {{no member named 'Createfoo' in 'PR13387::B'; did you mean 'CreateFoo'?}}
}
}
+
+struct DataStruct {void foo();};
+struct T {
+ DataStruct data_struct;
+ void f();
+};
+// should be void T::f();
+void f() {
+ data_struct->foo(); // expected-error-re{{use of undeclared identifier 'data_struct'$}}
+}
diff --git a/test/SemaCXX/undefined-internal.cpp b/test/SemaCXX/undefined-internal.cpp
index 839fdafb34..1b76a86dcb 100644
--- a/test/SemaCXX/undefined-internal.cpp
+++ b/test/SemaCXX/undefined-internal.cpp
@@ -323,3 +323,10 @@ namespace test13 {
}
}
+namespace test14 {
+ extern "C" const int foo;
+
+ int f() {
+ return foo;
+ }
+}
diff --git a/test/SemaCXX/uninitialized.cpp b/test/SemaCXX/uninitialized.cpp
index 3a41114e87..665cfe7e91 100644
--- a/test/SemaCXX/uninitialized.cpp
+++ b/test/SemaCXX/uninitialized.cpp
@@ -496,3 +496,30 @@ namespace references {
int &b;
};
}
+
+namespace operators {
+ struct A {
+ A(bool);
+ bool operator==(A);
+ };
+
+ A makeA();
+
+ A a1 = a1 = makeA(); // expected-warning{{variable 'a1' is uninitialized when used within its own initialization}}
+ A a2 = a2 == a1; // expected-warning{{variable 'a2' is uninitialized when used within its own initialization}}
+ A a3 = a2 == a3; // expected-warning{{variable 'a3' is uninitialized when used within its own initialization}}
+
+ int x = x = 5;
+}
+
+namespace lambdas {
+ struct A {
+ template<typename T> A(T) {}
+ int x;
+ };
+ A a0([] { return a0.x; }); // ok
+ void f() {
+ A a1([=] { return a1.x; }); // expected-warning{{variable 'a1' is uninitialized when used within its own initialization}}
+ A a2([&] { return a2.x; }); // ok
+ }
+}
diff --git a/test/SemaCXX/warn-c++11-extensions.cpp b/test/SemaCXX/warn-c++11-extensions.cpp
index 8f35171119..bf8612aa39 100644
--- a/test/SemaCXX/warn-c++11-extensions.cpp
+++ b/test/SemaCXX/warn-c++11-extensions.cpp
@@ -5,3 +5,5 @@ long long ll1 = // expected-warning {{'long long' is a C++11 extension}}
unsigned long long ull1 = // expected-warning {{'long long' is a C++11 extension}}
42ULL; // expected-warning {{'long long' is a C++11 extension}}
+enum struct E1 { A, B }; // expected-warning {{scoped enumerations are a C++11 extension}}
+enum class E2 { C, D }; // expected-warning {{scoped enumerations are a C++11 extension}}
diff --git a/test/SemaCXX/warn-enum-compare.cpp b/test/SemaCXX/warn-enum-compare.cpp
index c68275e1a7..0c287948cd 100644
--- a/test/SemaCXX/warn-enum-compare.cpp
+++ b/test/SemaCXX/warn-enum-compare.cpp
@@ -39,8 +39,8 @@ void test () {
while (b == c);
while (B1 == name1::B2);
while (B2 == name2::B1);
- while (x == AnonAA); // expected-warning {{comparison of constant 42 with expression of type 'Foo' is always false}}
- while (AnonBB == y); // expected-warning {{comparison of constant 45 with expression of type 'Bar' is always false}}
+ while (x == AnonAA); // expected-warning {{comparison of constant 'AnonAA' (42) with expression of type 'Foo' is always false}}
+ while (AnonBB == y); // expected-warning {{comparison of constant 'AnonBB' (45) with expression of type 'Bar' is always false}}
while (AnonAA == AnonAB);
while (AnonAB == AnonBA);
while (AnonBB == AnonAA);
diff --git a/test/SemaCXX/warn-overloaded-virtual.cpp b/test/SemaCXX/warn-overloaded-virtual.cpp
index 9b0f5aa9f3..629d59dee5 100644
--- a/test/SemaCXX/warn-overloaded-virtual.cpp
+++ b/test/SemaCXX/warn-overloaded-virtual.cpp
@@ -120,3 +120,21 @@ struct MostDerived: Derived3, Derived2 {
void func();
};
}
+
+namespace {
+ class A {
+ virtual int foo(bool) const;
+ // expected-note@-1{{type mismatch at 1st parameter ('bool' vs 'int')}}
+ virtual int foo(int, int) const;
+ // expected-note@-1{{different number of parameters (2 vs 1)}}
+ virtual int foo(int*) const;
+ // expected-note@-1{{type mismatch at 1st parameter ('int *' vs 'int')}}
+ virtual int foo(int) volatile;
+ // expected-note@-1{{different qualifiers (volatile vs const)}}
+ };
+
+ class B : public A {
+ virtual int foo(int) const;
+ // expected-warning@-1{{hides overloaded virtual functions}}
+ };
+}
diff --git a/test/SemaCXX/warn-reinterpret-base-class.cpp b/test/SemaCXX/warn-reinterpret-base-class.cpp
new file mode 100644
index 0000000000..67902f7a90
--- /dev/null
+++ b/test/SemaCXX/warn-reinterpret-base-class.cpp
@@ -0,0 +1,323 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -Wreinterpret-base-class -Wno-unused-volatile-lvalue %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -fdiagnostics-parseable-fixits -Wreinterpret-base-class -Wno-unused-volatile-lvalue %s 2>&1 | FileCheck %s
+
+// PR 13824
+class A {
+};
+class DA : public A {
+};
+class DDA : public DA {
+};
+class DAo : protected A {
+};
+class DAi : private A {
+};
+
+class DVA : public virtual A {
+};
+class DDVA : public virtual DA {
+};
+class DMA : public virtual A, public virtual DA {
+};
+
+class B;
+
+struct C {
+ // Do not fail on incompletely-defined classes.
+ decltype(reinterpret_cast<C *>(0)) foo;
+ decltype(reinterpret_cast<A *>((C *) 0)) bar;
+ decltype(reinterpret_cast<C *>((A *) 0)) baz;
+};
+
+void reinterpret_not_defined_class(B *b, C *c) {
+ // Should not fail if class has no definition.
+ (void)*reinterpret_cast<C *>(b);
+ (void)*reinterpret_cast<B *>(c);
+
+ (void)reinterpret_cast<C &>(*b);
+ (void)reinterpret_cast<B &>(*c);
+}
+
+// Do not fail on erroneous classes with fields of incompletely-defined types.
+// Base class is malformed.
+namespace BaseMalformed {
+ struct A; // expected-note {{forward declaration of 'BaseMalformed::A'}}
+ struct B {
+ A a; // expected-error {{field has incomplete type 'BaseMalformed::A'}}
+ };
+ struct C : public B {} c;
+ B *b = reinterpret_cast<B *>(&c);
+} // end anonymous namespace
+
+// Child class is malformed.
+namespace ChildMalformed {
+ struct A; // expected-note {{forward declaration of 'ChildMalformed::A'}}
+ struct B {};
+ struct C : public B {
+ A a; // expected-error {{field has incomplete type 'ChildMalformed::A'}}
+ } c;
+ B *b = reinterpret_cast<B *>(&c);
+} // end anonymous namespace
+
+// Base class outside upcast base-chain is malformed.
+namespace BaseBaseMalformed {
+ struct A; // expected-note {{forward declaration of 'BaseBaseMalformed::A'}}
+ struct Y {};
+ struct X { A a; }; // expected-error {{field has incomplete type 'BaseBaseMalformed::A'}}
+ struct B : Y, X {};
+ struct C : B {} c;
+ B *p = reinterpret_cast<B*>(&c);
+}
+
+namespace InheritanceMalformed {
+ struct A; // expected-note {{forward declaration of 'InheritanceMalformed::A'}}
+ struct B : A {}; // expected-error {{base class has incomplete type}}
+ struct C : B {} c;
+ B *p = reinterpret_cast<B*>(&c);
+}
+
+// Virtual base class outside upcast base-chain is malformed.
+namespace VBaseMalformed{
+ struct A; // expected-note {{forward declaration of 'VBaseMalformed::A'}}
+ struct X { A a; }; // expected-error {{field has incomplete type 'VBaseMalformed::A'}}
+ struct B : public virtual X {};
+ struct C : B {} c;
+ B *p = reinterpret_cast<B*>(&c);
+}
+
+void reinterpret_not_updowncast(A *pa, const A *pca, A &a, const A &ca) {
+ (void)*reinterpret_cast<C *>(pa);
+ (void)*reinterpret_cast<const C *>(pa);
+ (void)*reinterpret_cast<volatile C *>(pa);
+ (void)*reinterpret_cast<const volatile C *>(pa);
+
+ (void)*reinterpret_cast<const C *>(pca);
+ (void)*reinterpret_cast<const volatile C *>(pca);
+
+ (void)reinterpret_cast<C &>(a);
+ (void)reinterpret_cast<const C &>(a);
+ (void)reinterpret_cast<volatile C &>(a);
+ (void)reinterpret_cast<const volatile C &>(a);
+
+ (void)reinterpret_cast<const C &>(ca);
+ (void)reinterpret_cast<const volatile C &>(ca);
+}
+
+void reinterpret_pointer_downcast(A *a, const A *ca) {
+ (void)*reinterpret_cast<DA *>(a);
+ (void)*reinterpret_cast<const DA *>(a);
+ (void)*reinterpret_cast<volatile DA *>(a);
+ (void)*reinterpret_cast<const volatile DA *>(a);
+
+ (void)*reinterpret_cast<const DA *>(ca);
+ (void)*reinterpret_cast<const volatile DA *>(ca);
+
+ (void)*reinterpret_cast<DDA *>(a);
+ (void)*reinterpret_cast<DAo *>(a);
+ (void)*reinterpret_cast<DAi *>(a);
+ // expected-warning@+2 {{'reinterpret_cast' to class 'DVA *' from its virtual base 'A *' behaves differently from 'static_cast'}}
+ // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
+ (void)*reinterpret_cast<DVA *>(a);
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast"
+
+ // expected-warning@+2 {{'reinterpret_cast' to class 'DDVA *' from its virtual base 'A *' behaves differently from 'static_cast'}}
+ // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
+ (void)*reinterpret_cast<DDVA *>(a);
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast"
+
+ // expected-warning@+2 {{'reinterpret_cast' to class 'DMA *' from its virtual base 'A *' behaves differently from 'static_cast'}}
+ // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
+ (void)*reinterpret_cast<DMA *>(a);
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast"
+}
+
+void reinterpret_reference_downcast(A a, A &ra, const A &cra) {
+ (void)reinterpret_cast<DA &>(a);
+ (void)reinterpret_cast<const DA &>(a);
+ (void)reinterpret_cast<volatile DA &>(a);
+ (void)reinterpret_cast<const volatile DA &>(a);
+
+ (void)reinterpret_cast<DA &>(ra);
+ (void)reinterpret_cast<const DA &>(ra);
+ (void)reinterpret_cast<volatile DA &>(ra);
+ (void)reinterpret_cast<const volatile DA &>(ra);
+
+ (void)reinterpret_cast<const DA &>(cra);
+ (void)reinterpret_cast<const volatile DA &>(cra);
+
+ (void)reinterpret_cast<DDA &>(a);
+ (void)reinterpret_cast<DAo &>(a);
+ (void)reinterpret_cast<DAi &>(a);
+ // expected-warning@+2 {{'reinterpret_cast' to class 'DVA &' from its virtual base 'A' behaves differently from 'static_cast'}}
+ // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
+ (void)reinterpret_cast<DVA &>(a);
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
+
+ // expected-warning@+2 {{'reinterpret_cast' to class 'DDVA &' from its virtual base 'A' behaves differently from 'static_cast'}}
+ // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
+ (void)reinterpret_cast<DDVA &>(a);
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
+
+ // expected-warning@+2 {{'reinterpret_cast' to class 'DMA &' from its virtual base 'A' behaves differently from 'static_cast'}}
+ // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
+ (void)reinterpret_cast<DMA &>(a);
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
+}
+
+void reinterpret_pointer_upcast(DA *da, const DA *cda, DDA *dda, DAo *dao,
+ DAi *dai, DVA *dva, DDVA *ddva, DMA *dma) {
+ (void)*reinterpret_cast<A *>(da);
+ (void)*reinterpret_cast<const A *>(da);
+ (void)*reinterpret_cast<volatile A *>(da);
+ (void)*reinterpret_cast<const volatile A *>(da);
+
+ (void)*reinterpret_cast<const A *>(cda);
+ (void)*reinterpret_cast<const volatile A *>(cda);
+
+ (void)*reinterpret_cast<A *>(dda);
+ (void)*reinterpret_cast<DA *>(dda);
+ (void)*reinterpret_cast<A *>(dao);
+ (void)*reinterpret_cast<A *>(dai);
+ // expected-warning@+2 {{'reinterpret_cast' from class 'DVA *' to its virtual base 'A *' behaves differently from 'static_cast'}}
+ // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
+ (void)*reinterpret_cast<A *>(dva);
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast"
+
+ // expected-warning@+2 {{'reinterpret_cast' from class 'DDVA *' to its virtual base 'A *' behaves differently from 'static_cast'}}
+ // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
+ (void)*reinterpret_cast<A *>(ddva);
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast"
+
+ // expected-warning@+2 {{'reinterpret_cast' from class 'DDVA *' to its virtual base 'DA *' behaves differently from 'static_cast'}}
+ // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
+ (void)*reinterpret_cast<DA *>(ddva);
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast"
+
+ // expected-warning@+2 {{'reinterpret_cast' from class 'DMA *' to its virtual base 'A *' behaves differently from 'static_cast'}}
+ // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
+ (void)*reinterpret_cast<A *>(dma);
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast"
+
+ // expected-warning@+2 {{'reinterpret_cast' from class 'DMA *' to its virtual base 'DA *' behaves differently from 'static_cast'}}
+ // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
+ (void)*reinterpret_cast<DA *>(dma);
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast"
+}
+
+void reinterpret_reference_upcast(DA &da, const DA &cda, DDA &dda, DAo &dao,
+ DAi &dai, DVA &dva, DDVA &ddva, DMA &dma) {
+ (void)reinterpret_cast<A &>(da);
+ (void)reinterpret_cast<const A &>(da);
+ (void)reinterpret_cast<volatile A &>(da);
+ (void)reinterpret_cast<const volatile A &>(da);
+
+ (void)reinterpret_cast<const A &>(cda);
+ (void)reinterpret_cast<const volatile A &>(cda);
+
+ (void)reinterpret_cast<A &>(dda);
+ (void)reinterpret_cast<DA &>(dda);
+ (void)reinterpret_cast<A &>(dao);
+ (void)reinterpret_cast<A &>(dai);
+ // expected-warning@+2 {{'reinterpret_cast' from class 'DVA' to its virtual base 'A &' behaves differently from 'static_cast'}}
+ // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
+ (void)reinterpret_cast<A &>(dva);
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
+
+ // expected-warning@+2 {{'reinterpret_cast' from class 'DDVA' to its virtual base 'A &' behaves differently from 'static_cast'}}
+ // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
+ (void)reinterpret_cast<A &>(ddva);
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
+
+ // expected-warning@+2 {{'reinterpret_cast' from class 'DDVA' to its virtual base 'DA &' behaves differently from 'static_cast'}}
+ // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
+ (void)reinterpret_cast<DA &>(ddva);
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
+
+ // expected-warning@+2 {{'reinterpret_cast' from class 'DMA' to its virtual base 'A &' behaves differently from 'static_cast'}}
+ // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
+ (void)reinterpret_cast<A &>(dma);
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
+
+ // expected-warning@+2 {{'reinterpret_cast' from class 'DMA' to its virtual base 'DA &' behaves differently from 'static_cast'}}
+ // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
+ (void)reinterpret_cast<DA &>(dma);
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
+}
+
+struct E {
+ int x;
+};
+
+class F : public E {
+ virtual int foo() { return x; }
+};
+
+class G : public F {
+};
+
+class H : public E, public A {
+};
+
+class I : virtual public F {
+};
+
+typedef const F * K;
+typedef volatile K L;
+
+void different_subobject_downcast(E *e, F *f, A *a) {
+ // expected-warning@+2 {{'reinterpret_cast' to class 'F *' from its base at non-zero offset 'E *' behaves differently from 'static_cast'}}
+ // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
+ (void)reinterpret_cast<F *>(e);
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
+
+ // expected-warning@+2 {{'reinterpret_cast' to class 'G *' from its base at non-zero offset 'E *' behaves differently from 'static_cast'}}
+ // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
+ (void)reinterpret_cast<G *>(e);
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
+
+ (void)reinterpret_cast<H *>(e);
+ // expected-warning@+2 {{'reinterpret_cast' to class 'I *' from its virtual base 'E *' behaves differently from 'static_cast'}}
+ // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
+ (void)reinterpret_cast<I *>(e);
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
+
+
+ (void)reinterpret_cast<G *>(f);
+ // expected-warning@+2 {{'reinterpret_cast' to class 'I *' from its virtual base 'F *' behaves differently from 'static_cast'}}
+ // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
+ (void)reinterpret_cast<I *>(f);
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
+
+ (void)reinterpret_cast<H *>(a);
+
+ // expected-warning@+2 {{'reinterpret_cast' to class 'L' (aka 'const F *volatile') from its base at non-zero offset 'E *' behaves differently from 'static_cast'}}
+ // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
+ (void)reinterpret_cast<L>(e);
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
+}
+
+void different_subobject_upcast(F *f, G *g, H *h, I *i) {
+ // expected-warning@+2 {{'reinterpret_cast' from class 'F *' to its base at non-zero offset 'E *' behaves differently from 'static_cast'}}
+ // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
+ (void)reinterpret_cast<E *>(f);
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
+
+ (void)reinterpret_cast<F *>(g);
+ // expected-warning@+2 {{'reinterpret_cast' from class 'G *' to its base at non-zero offset 'E *' behaves differently from 'static_cast'}}
+ // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
+ (void)reinterpret_cast<E *>(g);
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
+
+ (void)reinterpret_cast<E *>(h);
+ (void)reinterpret_cast<A *>(h);
+
+ // expected-warning@+2 {{'reinterpret_cast' from class 'I *' to its virtual base 'F *' behaves differently from 'static_cast'}}
+ // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
+ (void)reinterpret_cast<F *>(i);
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
+
+ // expected-warning@+2 {{'reinterpret_cast' from class 'I *' to its virtual base 'E *' behaves differently from 'static_cast'}}
+ // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
+ (void)reinterpret_cast<E *>(i);
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
+}
diff --git a/test/SemaCXX/warn-thread-safety-analysis.cpp b/test/SemaCXX/warn-thread-safety-analysis.cpp
index 3f41124d47..bc4b40ead7 100644
--- a/test/SemaCXX/warn-thread-safety-analysis.cpp
+++ b/test/SemaCXX/warn-thread-safety-analysis.cpp
@@ -1475,8 +1475,8 @@ namespace substitution_test {
public:
Mutex mu;
- void lockData() __attribute__((exclusive_lock_function(mu))) { }
- void unlockData() __attribute__((unlock_function(mu))) { }
+ void lockData() __attribute__((exclusive_lock_function(mu)));
+ void unlockData() __attribute__((unlock_function(mu)));
void doSomething() __attribute__((exclusive_locks_required(mu))) { }
};
@@ -1484,8 +1484,8 @@ namespace substitution_test {
class DataLocker {
public:
- void lockData (MyData *d) __attribute__((exclusive_lock_function(d->mu))) { }
- void unlockData(MyData *d) __attribute__((unlock_function(d->mu))) { }
+ void lockData (MyData *d) __attribute__((exclusive_lock_function(d->mu)));
+ void unlockData(MyData *d) __attribute__((unlock_function(d->mu)));
};
@@ -2858,7 +2858,7 @@ void Foo::lock1() EXCLUSIVE_LOCK_FUNCTION(mu1_) {
}
void Foo::slock1() SHARED_LOCK_FUNCTION(mu1_) {
- mu1_.Lock();
+ mu1_.ReaderLock();
}
void Foo::lock3() EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_, mu3_) {
@@ -3640,8 +3640,8 @@ class Foo {
LOCKS_EXCLUDED(mu2_);
void lock() EXCLUSIVE_LOCK_FUNCTION(mu1_)
EXCLUSIVE_LOCK_FUNCTION(mu2_);
- void readerlock() EXCLUSIVE_LOCK_FUNCTION(mu1_)
- EXCLUSIVE_LOCK_FUNCTION(mu2_);
+ void readerlock() SHARED_LOCK_FUNCTION(mu1_)
+ SHARED_LOCK_FUNCTION(mu2_);
void unlock() UNLOCK_FUNCTION(mu1_)
UNLOCK_FUNCTION(mu2_);
bool trylock() EXCLUSIVE_TRYLOCK_FUNCTION(true, mu1_)
@@ -3663,9 +3663,9 @@ void Foo::foo2() {
}
void Foo::foo3() { }
-void Foo::lock() { }
-void Foo::readerlock() { }
-void Foo::unlock() { }
+void Foo::lock() { mu1_.Lock(); mu2_.Lock(); }
+void Foo::readerlock() { mu1_.ReaderLock(); mu2_.ReaderLock(); }
+void Foo::unlock() { mu1_.Unlock(); mu2_.Unlock(); }
bool Foo::trylock() { return true; }
bool Foo::readertrylock() { return true; }
@@ -3915,3 +3915,73 @@ void bar2() EXCLUSIVE_LOCKS_REQUIRED(getMutex1(), getMutex2());
} // end namespace UnevaluatedContextTest
+
+namespace LockUnlockFunctionTest {
+
+// Check built-in lock functions
+class LOCKABLE MyLockable {
+public:
+ void lock() EXCLUSIVE_LOCK_FUNCTION() { mu_.Lock(); }
+ void readerLock() SHARED_LOCK_FUNCTION() { mu_.ReaderLock(); }
+ void unlock() UNLOCK_FUNCTION() { mu_.Unlock(); }
+
+private:
+ Mutex mu_;
+};
+
+
+class Foo {
+public:
+ // Correct lock/unlock functions
+ void lock() EXCLUSIVE_LOCK_FUNCTION(mu_) {
+ mu_.Lock();
+ }
+
+ void readerLock() SHARED_LOCK_FUNCTION(mu_) {
+ mu_.ReaderLock();
+ }
+
+ void unlock() UNLOCK_FUNCTION(mu_) {
+ mu_.Unlock();
+ }
+
+ // Check failure to lock.
+ void lockBad() EXCLUSIVE_LOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}}
+ mu2_.Lock();
+ mu2_.Unlock();
+ } // expected-warning {{expecting mutex 'mu_' to be locked at the end of function}}
+
+ void readerLockBad() SHARED_LOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}}
+ mu2_.Lock();
+ mu2_.Unlock();
+ } // expected-warning {{expecting mutex 'mu_' to be locked at the end of function}}
+
+ void unlockBad() UNLOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}}
+ mu2_.Lock();
+ mu2_.Unlock();
+ } // expected-warning {{mutex 'mu_' is still locked at the end of function}}
+
+ // Check locking the wrong thing.
+ void lockBad2() EXCLUSIVE_LOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}}
+ mu2_.Lock(); // expected-note {{mutex acquired here}}
+ } // expected-warning {{expecting mutex 'mu_' to be locked at the end of function}} \
+ // expected-warning {{mutex 'mu2_' is still locked at the end of function}}
+
+
+ void readerLockBad2() SHARED_LOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}}
+ mu2_.ReaderLock(); // expected-note {{mutex acquired here}}
+ } // expected-warning {{expecting mutex 'mu_' to be locked at the end of function}} \
+ // expected-warning {{mutex 'mu2_' is still locked at the end of function}}
+
+
+ void unlockBad2() UNLOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}}
+ mu2_.Unlock(); // expected-warning {{unlocking 'mu2_' that was not locked}}
+ } // expected-warning {{mutex 'mu_' is still locked at the end of function}}
+
+private:
+ Mutex mu_;
+ Mutex mu2_;
+};
+
+} // end namespace LockUnlockFunctionTest
+
diff --git a/test/SemaCXX/warn-unused-filescoped.cpp b/test/SemaCXX/warn-unused-filescoped.cpp
index e12668bf2a..9fb601130d 100644
--- a/test/SemaCXX/warn-unused-filescoped.cpp
+++ b/test/SemaCXX/warn-unused-filescoped.cpp
@@ -133,6 +133,27 @@ namespace test6 {
};
}
+namespace test7
+{
+ template<typename T>
+ static inline void foo(T) { }
+
+ // This should not emit an unused-function warning since it inherits
+ // the static storage type from the base template.
+ template<>
+ inline void foo(int) { }
+
+ // Partial specialization
+ template<typename T, typename U>
+ static inline void bar(T, U) { }
+
+ template<typename U>
+ inline void bar(int, U) { }
+
+ template<>
+ inline void bar(int, int) { }
+};
+
namespace pr14776 {
namespace {
struct X {};
diff --git a/test/SemaCXX/warn-unused-variables-error.cpp b/test/SemaCXX/warn-unused-variables-error.cpp
new file mode 100644
index 0000000000..6386c4b682
--- /dev/null
+++ b/test/SemaCXX/warn-unused-variables-error.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -Wunused-variable -verify %s
+
+namespace PR6948 {
+ template<typename T> class X; // expected-note{{template is declared here}}
+
+ void f() {
+ X<char> str (read_from_file()); // expected-error{{use of undeclared identifier 'read_from_file'}} \
+ expected-error{{implicit instantiation of undefined template 'PR6948::X<char>'}}
+ }
+}
diff --git a/test/SemaCXX/warn-unused-variables.cpp b/test/SemaCXX/warn-unused-variables.cpp
index 4e8d51d319..00597f929b 100644
--- a/test/SemaCXX/warn-unused-variables.cpp
+++ b/test/SemaCXX/warn-unused-variables.cpp
@@ -41,15 +41,6 @@ void test_dependent_init(T *p) {
(void)i;
}
-namespace PR6948 {
- template<typename T> class X; // expected-note{{template is declared here}}
-
- void f() {
- X<char> str (read_from_file()); // expected-error{{use of undeclared identifier 'read_from_file'}} \
- expected-error{{implicit instantiation of undefined template 'PR6948::X<char>'}}
- }
-}
-
void unused_local_static() {
static int x = 0;
static int y = 0; // expected-warning{{unused variable 'y'}}
@@ -135,3 +126,5 @@ namespace ctor_with_cleanups {
S2 s((S1()));
}
}
+
+#include "Inputs/warn-unused-variables.h"
diff --git a/test/SemaObjC/arc-repeated-weak.mm b/test/SemaObjC/arc-repeated-weak.mm
index e652bee82d..b5d9002130 100644
--- a/test/SemaObjC/arc-repeated-weak.mm
+++ b/test/SemaObjC/arc-repeated-weak.mm
@@ -327,6 +327,32 @@ void doWhileLoop(Test *a) {
}
@end
+@interface Base1
+@end
+@interface Sub1 : Base1
+@end
+@interface Sub1(cat)
+-(id)prop;
+@end
+
+void test1(Sub1 *s) {
+ use([s prop]);
+ use([s prop]);
+}
+
+@interface Base1(cat)
+@property (weak) id prop;
+@end
+
+void test2(Sub1 *s) {
+ // This does not warn because the "prop" in "Base1(cat)" was introduced
+ // after the method declaration and we don't find it as overridden.
+ // Always looking for overridden methods after the method declaration is expensive
+ // and it's not clear it is worth it currently.
+ use([s prop]);
+ use([s prop]);
+}
+
class Wrapper {
Test *a;
diff --git a/test/SemaObjC/arc-system-header.m b/test/SemaObjC/arc-system-header.m
index 3443bda99b..d9392ed73f 100644
--- a/test/SemaObjC/arc-system-header.m
+++ b/test/SemaObjC/arc-system-header.m
@@ -1,30 +1,30 @@
-// silly workaround expected-note {{marked unavailable here}}
// RUN: %clang_cc1 -fobjc-arc -isystem %S/Inputs %s -DNO_USE
// RUN: %clang_cc1 -fobjc-arc -isystem %S/Inputs %s -verify
-// another silly workaround expected-note {{marked unavailable here}}
#include <arc-system-header.h>
#ifndef NO_USE
void test(id op, void *cp) {
cp = test0(op); // expected-error {{'test0' is unavailable: converts between Objective-C and C pointers in -fobjc-arc}}
cp = *test1(&op); // expected-error {{'test1' is unavailable: converts between Objective-C and C pointers in -fobjc-arc}}
+// expected-note@arc-system-header.h:1 {{marked unavailable here}}
+// expected-note@arc-system-header.h:5 {{marked unavailable here}}
}
-// workaround expected-note {{marked unavailable here}}
void test3(struct Test3 *p) {
p->field = 0; // expected-error {{'field' is unavailable: this system declaration uses an unsupported type}}
+ // expected-note@arc-system-header.h:14 {{marked unavailable here}}
}
-// workaround expected-note {{marked unavailable here}}
void test4(Test4 *p) {
p->field1 = 0; // expected-error {{'field1' is unavailable: this system declaration uses an unsupported type}}
+ // expected-note@arc-system-header.h:19 {{marked unavailable here}}
p->field2 = 0;
}
-// workaround expected-note {{marked unavailable here}}
void test5(struct Test5 *p) {
p->field = 0; // expected-error {{'field' is unavailable: this system field has retaining ownership}}
+ // expected-note@arc-system-header.h:25 {{marked unavailable here}}
}
id test6() {
@@ -38,12 +38,13 @@ id test6() {
x = (id) (test6_helper(), kMagicConstant);
}
-// workaround expected-note 4 {{marked unavailable here}} expected-note 2 {{property 'prop' is declared unavailable here}}
void test7(Test7 *p) {
*p.prop = 0; // expected-error {{'prop' is unavailable: this system declaration uses an unsupported type}}
p.prop = 0; // expected-error {{'prop' is unavailable: this system declaration uses an unsupported type}}
*[p prop] = 0; // expected-error {{'prop' is unavailable: this system declaration uses an unsupported type}}
[p setProp: 0]; // expected-error {{'setProp:' is unavailable: this system declaration uses an unsupported type}}
+// expected-note@arc-system-header.h:41 4 {{marked unavailable here}}
+// expected-note@arc-system-header.h:41 2 {{property 'prop' is declared unavailable here}}
}
#endif
diff --git a/test/SemaObjC/arc-unavailable-for-weakref.m b/test/SemaObjC/arc-unavailable-for-weakref.m
index b140c64da7..b9b5cc516d 100644
--- a/test/SemaObjC/arc-unavailable-for-weakref.m
+++ b/test/SemaObjC/arc-unavailable-for-weakref.m
@@ -56,9 +56,33 @@ __attribute__((objc_arc_weak_reference_unavailable))
@interface I
{
}
-@property (weak) NSFont *font; // expected-note {{property declared here}}
+@property (weak) NSFont *font; // expected-error {{synthesizing __weak instance variable of type 'NSFont *', which does not support weak references}}
@end
-@implementation I
-@synthesize font = _font; // expected-error {{synthesis of a weak-unavailable property is disallowed because it requires synthesis of an instance variable of the __weak object}}
+@implementation I // expected-note {{when implemented by class I}}
+@synthesize font = _font;
+@end
+
+// rdar://13676793
+@protocol MyProtocol
+@property (weak) NSFont *font; // expected-error {{synthesizing __weak instance variable of type 'NSFont *', which does not support weak references}}
+@end
+
+@interface I1 <MyProtocol>
+@end
+
+@implementation I1 // expected-note {{when implemented by class I1}}
+@synthesize font = _font;
+@end
+
+@interface Super
+@property (weak) NSFont *font; // expected-error {{synthesizing __weak instance variable of type 'NSFont *', which does not support weak references}}
+@end
+
+
+@interface I2 : Super
+@end
+
+@implementation I2 // expected-note {{when implemented by class I2}}
+@synthesize font = _font;
@end
diff --git a/test/SemaObjC/arc.m b/test/SemaObjC/arc.m
index d89d035fca..1d4e42de64 100644
--- a/test/SemaObjC/arc.m
+++ b/test/SemaObjC/arc.m
@@ -756,3 +756,14 @@ void rdar12569201(id key, id value) {
@interface C
- (void)method:(id[])objects; // expected-error{{must explicitly describe intended ownership of an object array parameter}}
@end
+
+// rdar://13752880
+@interface NSMutableArray : NSArray @end
+
+typedef __strong NSMutableArray * PSNS;
+
+void test(NSArray *x) {
+ NSMutableArray *y = x; // expected-warning {{incompatible pointer types initializing 'NSMutableArray *' with an expression of type 'NSArray *'}}
+ __strong NSMutableArray *y1 = x; // expected-warning {{incompatible pointer types initializing 'NSMutableArray *' with an expression of type 'NSArray *'}}
+ PSNS y2 = x; // expected-warning {{incompatible pointer types initializing 'NSMutableArray *' with an expression of type 'NSArray *'}}
+}
diff --git a/test/SemaObjC/attr-availability.m b/test/SemaObjC/attr-availability.m
index bf7ef19bea..fddcd506d4 100644
--- a/test/SemaObjC/attr-availability.m
+++ b/test/SemaObjC/attr-availability.m
@@ -17,7 +17,7 @@
// rdar://11475360
@interface B : A
-- (void)method; // expected-note {{method 'method' declared here}}
+- (void)method; // NOTE: we expect 'method' to *not* inherit availability.
- (void)overridden __attribute__((availability(macosx,introduced=10.4))); // expected-warning{{overriding method introduced after overridden method on OS X (10.4 vs. 10.3)}}
- (void)overridden2 __attribute__((availability(macosx,introduced=10.2)));
- (void)overridden3 __attribute__((availability(macosx,deprecated=10.4)));
@@ -28,7 +28,35 @@
void f(A *a, B *b) {
[a method]; // expected-warning{{'method' is deprecated: first deprecated in OS X 10.2}}
- [b method]; // expected-warning {{'method' is deprecated: first deprecated in OS X 10.2}}
+ [b method]; // no-warning
[a proto_method]; // expected-warning{{'proto_method' is deprecated: first deprecated in OS X 10.2}}
[b proto_method]; // expected-warning{{'proto_method' is deprecated: first deprecated in OS X 10.2}}
}
+
+// Test case for <rdar://problem/11627873>. Warn about
+// using a deprecated method when that method is re-implemented in a
+// subclass where the redeclared method is not deprecated.
+@interface C
+- (void) method __attribute__((availability(macosx,introduced=10.1,deprecated=10.2))); // expected-note {{method 'method' declared here}}
+@end
+
+@interface D : C
+- (void) method;
+@end
+
+@interface E : D
+- (void) method;
+@end
+
+@implementation D
+- (void) method {
+ [super method]; // expected-warning {{'method' is deprecated: first deprecated in OS X 10.2}}
+}
+@end
+
+@implementation E
+- (void) method {
+ [super method]; // no-warning
+}
+@end
+
diff --git a/test/SemaObjC/attr-deprecated.m b/test/SemaObjC/attr-deprecated.m
index c0aa9fc070..aa4b479e00 100644
--- a/test/SemaObjC/attr-deprecated.m
+++ b/test/SemaObjC/attr-deprecated.m
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s
+// RUN: %clang_cc1 -x objective-c++ -fsyntax-only -verify -Wno-objc-root-class %s
@interface A {
int X __attribute__((deprecated)); // expected-note 2 {{declared here}}
@@ -135,3 +136,21 @@ typedef struct {
@property footype c; // expected-warning {{'footype' is deprecated}}
@property footype d __attribute((deprecated));
@end
+
+// rdar://13569424
+@interface NewI
++(void)cmeth;
+@end
+
+typedef NewI DeprI __attribute__((deprecated("blah"))); // expected-note 4 {{'DeprI' declared here}}
+
+@interface SI : DeprI // expected-warning {{'DeprI' is deprecated: blah}}
+-(DeprI*)meth; // expected-warning {{'DeprI' is deprecated: blah}}
+@end
+
+@implementation SI
+-(DeprI*)meth { // expected-warning {{'DeprI' is deprecated: blah}}
+ [DeprI cmeth]; // expected-warning {{'DeprI' is deprecated: blah}}
+ return 0;
+}
+@end
diff --git a/test/SemaObjC/blocks.m b/test/SemaObjC/blocks.m
index dd659addef..b523e4c916 100644
--- a/test/SemaObjC/blocks.m
+++ b/test/SemaObjC/blocks.m
@@ -196,8 +196,8 @@ typedef short (^short_block_t)();
void testAnonymousEnumTypes(int arg) {
int_block_t IB;
IB = ^{ return AnonymousValue; };
- IB = ^{ if (arg) return TDE_Value; else return getTDE(); }; // expected-error {{incompatible block pointer}}
- IB = ^{ if (arg) return getTDE(); else return TDE_Value; }; // expected-error {{incompatible block pointer}}
+ IB = ^{ if (arg) return TDE_Value; else return getTDE(); };
+ IB = ^{ if (arg) return getTDE(); else return TDE_Value; };
// Since we fixed the underlying type of the enum, these are considered
// compatible block types anyway.
diff --git a/test/SemaObjC/category-1.m b/test/SemaObjC/category-1.m
index a7e69651ad..18b872aa8b 100644
--- a/test/SemaObjC/category-1.m
+++ b/test/SemaObjC/category-1.m
@@ -71,8 +71,7 @@
@interface MultipleCat_I() <MultipleCat_P> @end
-@implementation MultipleCat_I // expected-warning {{incomplete implementation}} \
- // expected-warning {{method 'im0' in protocol not implemented}}
+@implementation MultipleCat_I // expected-warning {{method 'im0' in protocol not implemented}}
@end
// <rdar://problem/7680391> - Handle nameless categories with no name that refer
diff --git a/test/SemaObjC/compare-qualified-id.m b/test/SemaObjC/compare-qualified-id.m
index d31dfae86e..82868f8a16 100644
--- a/test/SemaObjC/compare-qualified-id.m
+++ b/test/SemaObjC/compare-qualified-id.m
@@ -23,8 +23,7 @@ extern NSString * const NSTaskDidTerminateNotification;
- (NSString *)evaluateAsStringInContext:(XCPropertyExpansionContext *)context withNestingState:(const void *)state;
@end
-@implementation XCPropertyExpansionContext // expected-warning {{incomplete implementation}} \
- // expected-warning {{method 'copyWithZone:' in protocol not implemented}}
+@implementation XCPropertyExpansionContext // expected-warning {{method 'copyWithZone:' in protocol not implemented}}
- (NSString *)expandedValueForProperty:(NSString *)property {
id <XCPropertyValues> cachedValueNode = [_propNamesToPropValuesCache objectForKey:property]; // expected-warning {{method '-objectForKey:' not found (return type defaults to 'id')}}
if (cachedValueNode == ((void *)0)) { }
diff --git a/test/SemaObjC/conditional-expr.m b/test/SemaObjC/conditional-expr.m
index e0a3210deb..ec1305dbe8 100644
--- a/test/SemaObjC/conditional-expr.m
+++ b/test/SemaObjC/conditional-expr.m
@@ -21,10 +21,10 @@
@end
@interface DTFilterOutputStream2
-- nextOutputStream; // expected-note {{method definition for 'nextOutputStream' not found}}
+- nextOutputStream; // expected-note {{method 'nextOutputStream' declared here}}
@end
-@implementation DTFilterOutputStream2 // expected-warning {{incomplete implementation}}
+@implementation DTFilterOutputStream2 // expected-warning {{method definition for 'nextOutputStream' not found}}
- (id)initWithNextOutputStream:(id <DTOutputStreams>) outputStream {
id <DTOutputStreams> nextOutputStream = [self nextOutputStream];
self = nextOutputStream; // expected-warning {{assigning to 'DTFilterOutputStream2 *' from incompatible type 'id<DTOutputStreams>'}}
diff --git a/test/SemaObjC/default-synthesize-3.m b/test/SemaObjC/default-synthesize-3.m
index 606ece33af..82f968da00 100644
--- a/test/SemaObjC/default-synthesize-3.m
+++ b/test/SemaObjC/default-synthesize-3.m
@@ -39,3 +39,75 @@ __attribute ((objc_requires_property_definitions))
__attribute ((objc_requires_property_definitions)) // expected-error {{objc_requires_property_definitions attribute may only be specified on a class}}
@protocol P @end
+
+// rdar://13388503
+@interface NSObject @end
+@protocol Foo
+@property (readonly) char isFoo; // expected-note {{property declared here}}
+@property (readonly) char isNotFree;
+@end
+
+@interface Bar : NSObject <Foo>
+@end
+
+@implementation Bar
+- (char)isFoo {
+ return 0;
+}
+- (char)isNotFree {
+ return 0;
+}
+@end
+
+@interface Baz : Bar
+@end
+
+@interface Baz ()
+@property (readwrite) char isFoo; // expected-warning {{auto property synthesis will not synthesize property 'isFoo' because it is 'readwrite' but it will be synthesized 'readonly' via another property}}
+@property char Property1; // expected-warning {{auto property synthesis will not synthesize property 'Property1' because it cannot share an ivar with another synthesized property}}
+@property char Property2;
+@property (readwrite) char isNotFree;
+@end
+
+@implementation Baz {
+ char _isFoo;
+ char _isNotFree;
+}
+@synthesize Property2 = Property1; // expected-note {{property synthesized here}}
+
+- (void) setIsNotFree : (char)Arg {
+ _isNotFree = Arg;
+}
+
+@end
+
+// More test where such warnings should not be issued.
+@protocol MyProtocol
+-(void)setProp1:(id)x;
+@end
+
+@protocol P1 <MyProtocol>
+@end
+
+@interface B
+@property (readonly) id prop;
+@property (readonly) id prop1;
+@property (readonly) id prop2;
+@end
+
+@interface B()
+-(void)setProp:(id)x;
+@end
+
+@interface B(cat)
+@property (readwrite) id prop2;
+@end
+
+@interface S : B<P1>
+@property (assign,readwrite) id prop;
+@property (assign,readwrite) id prop1;
+@property (assign,readwrite) id prop2;
+@end
+
+@implementation S
+@end
diff --git a/test/SemaObjC/warn-isa-ref.m b/test/SemaObjC/deprecated-objc-introspection.m
index 39a5e45496..faaef254d5 100644
--- a/test/SemaObjC/warn-isa-ref.m
+++ b/test/SemaObjC/deprecated-objc-introspection.m
@@ -1,4 +1,10 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple=x86_64-apple-darwin -fsyntax-only -verify %s
+
+//====------------------------------------------------------------====//
+// Test deprecated direct usage of the 'isa' pointer.
+//====------------------------------------------------------------====//
+
+typedef unsigned long NSUInteger;
typedef struct objc_object {
struct objc_class *isa;
@@ -18,8 +24,8 @@ static void func() {
id x;
// rdar://8290002
- [(*x).isa self]; // expected-warning {{direct access to Objective-C's isa is deprecated in favor of object_setClass() and object_getClass()}}
- [x->isa self]; // expected-warning {{direct access to Objective-C's isa is deprecated in favor of object_setClass() and object_getClass()}}
+ [(*x).isa self]; // expected-warning {{direct access to Objective-C's isa is deprecated in favor of object_getClass()}}
+ [x->isa self]; // expected-warning {{direct access to Objective-C's isa is deprecated in favor of object_getClass()}}
Whatever *y;
@@ -39,7 +45,7 @@ static void func() {
@interface BaseClass {
@public
- Class isa; // expected-note 3 {{instance variable is declared here}}
+ Class isa; // expected-note 4 {{instance variable is declared here}}
}
@end
@@ -70,12 +76,22 @@ static void func() {
Subclass *x;
SiblingClass *y;
OtherClass *z;
- (void)v->isa; // expected-warning {{direct access to Objective-C's isa is deprecated}}
- (void)w->isa; // expected-warning {{direct access to Objective-C's isa is deprecated}}
- (void)x->isa; // expected-warning {{direct access to Objective-C's isa is deprecated}}
- (void)y->isa; // expected-warning {{direct access to Objective-C's isa is deprecated}}
+ (void)v->isa; // expected-warning {{direct access to Objective-C's isa is deprecated in favor of object_getClass()}}
+ (void)w->isa; // expected-warning {{direct access to Objective-C's isa is deprecated in favor of object_getClass()}}
+ (void)x->isa; // expected-warning {{direct access to Objective-C's isa is deprecated in favor of object_getClass()}}
+ (void)y->isa; // expected-warning {{direct access to Objective-C's isa is deprecated in favor of object_getClass()}}
(void)z->isa;
(void)u->isa;
+
+ w->isa = 0; // expected-warning {{assignment to Objective-C's isa is deprecated in favor of object_setClass()}}
}
@end
+// Test for introspection of Objective-C pointers via bitmasking.
+
+void testBitmasking(NSObject *p) {
+ (void) (((NSUInteger) p) & 0x1); // expected-warning {{bitmasking for introspection of Objective-C object pointers is strongly discouraged}}
+ (void) (0x1 & ((NSUInteger) p)); // expected-warning {{bitmasking for introspection of Objective-C object pointers is strongly discouraged}}
+ (void) (((NSUInteger) p) ^ 0x1); // no-warning
+ (void) (0x1 ^ ((NSUInteger) p)); // no-warning
+} \ No newline at end of file
diff --git a/test/SemaObjC/enum-fixed-type.m b/test/SemaObjC/enum-fixed-type.m
index 6fd400a637..c00e45a03e 100644
--- a/test/SemaObjC/enum-fixed-type.m
+++ b/test/SemaObjC/enum-fixed-type.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -pedantic -verify %s
#if !__has_feature(objc_fixed_enum)
# error Enumerations with a fixed underlying type are not supported
@@ -28,9 +28,9 @@ void test() {
// <rdar://10381507>
typedef enum : long { Foo } IntegerEnum;
-int arr[(sizeof(typeof(Foo)) == sizeof(typeof(IntegerEnum))) - 1];
-int arr1[(sizeof(typeof(Foo)) == sizeof(typeof(long))) - 1];
-int arr2[(sizeof(typeof(IntegerEnum)) == sizeof(typeof(long))) - 1];
+int arr[(sizeof(__typeof__(Foo)) == sizeof(__typeof__(IntegerEnum)))? 1 : -1];
+int arr1[(sizeof(__typeof__(Foo)) == sizeof(__typeof__(long)))? 1 : -1];
+int arr2[(sizeof(__typeof__(IntegerEnum)) == sizeof(__typeof__(long)))? 1 : -1];
// <rdar://problem/10760113>
typedef enum : long long { Bar = -1 } LongLongEnum;
diff --git a/test/SemaObjC/format-arg-attribute.m b/test/SemaObjC/format-arg-attribute.m
index 6edb8fd99b..dede433f37 100644
--- a/test/SemaObjC/format-arg-attribute.m
+++ b/test/SemaObjC/format-arg-attribute.m
@@ -14,7 +14,7 @@ union u1 { int i; } __attribute__((format_arg(1))); // expected-warning {{'form
enum e1 { E1V0 } __attribute__((format_arg(1))); // expected-warning {{'format_arg' attribute only applies to functions}}
extern NSString *ff3 (const NSString *) __attribute__((format_arg(3-2)));
-extern NSString *ff4 (const NSString *) __attribute__((format_arg(foo))); // expected-error {{attribute takes one argument}}
+extern NSString *ff4 (const NSString *) __attribute__((format_arg(foo))); // expected-error {{use of undeclared identifier 'foo'}}
/* format_arg formats must take and return a string. */
extern NSString *fi0 (int) __attribute__((format_arg(1))); // expected-error {{format argument not a string type}}
diff --git a/test/SemaObjC/format-strings-objc.m b/test/SemaObjC/format-strings-objc.m
index bd33ad41a5..8490130224 100644
--- a/test/SemaObjC/format-strings-objc.m
+++ b/test/SemaObjC/format-strings-objc.m
@@ -13,6 +13,7 @@
typedef signed char BOOL;
typedef unsigned int NSUInteger;
+typedef long NSInteger;
@class NSString, Protocol;
extern void NSLog(NSString *format, ...);
extern void NSLogv(NSString *format, va_list args);
@@ -235,3 +236,8 @@ void testByValueObjectInFormat(Foo *obj) {
[Bar log2:@"%d", *obj]; // expected-error {{cannot pass object with interface type 'Foo' by value to variadic method; expected type from format string was 'int'}}
}
+// <rdar://problem/13557053>
+void testTypeOf(NSInteger dW, NSInteger dH) {
+ NSLog(@"dW %d dH %d",({ __typeof__(dW) __a = (dW); __a < 0 ? -__a : __a; }),({ __typeof__(dH) __a = (dH); __a < 0 ? -__a : __a; })); // expected-warning 2 {{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
+}
+
diff --git a/test/SemaObjC/forward-protocol-incomplete-impl-warn.m b/test/SemaObjC/forward-protocol-incomplete-impl-warn.m
index 1010cd75cd..01fedec3cf 100644
--- a/test/SemaObjC/forward-protocol-incomplete-impl-warn.m
+++ b/test/SemaObjC/forward-protocol-incomplete-impl-warn.m
@@ -16,6 +16,5 @@
@end
@implementation IBImageCatalogDocument // expected-warning {{auto property synthesis will not synthesize property declared in a protocol}} \
- // expected-warning {{incomplete implementation}} \
// expected-warning {{method 'invalidate' in protocol not implemented}}
@end
diff --git a/test/SemaObjC/gcc-cast-ext.m b/test/SemaObjC/gcc-cast-ext.m
index 30e0dce4bd..5858393b41 100644
--- a/test/SemaObjC/gcc-cast-ext.m
+++ b/test/SemaObjC/gcc-cast-ext.m
@@ -5,8 +5,8 @@ typedef struct _NSRange { } NSRange;
@class PBXFileReference;
@interface PBXDocBookmark
-+ alloc; // expected-note {{method definition for 'alloc' not found}}
-- autorelease; // expected-note {{method definition for 'autorelease' not found}}
++ alloc; // expected-note {{method 'alloc' declared here}}
+- autorelease; // expected-note {{method 'autorelease' declared here}}
@end
// GCC allows pointer expressions in integer constant expressions.
@@ -14,7 +14,8 @@ struct {
char control[((int)(char *)2)];
} xx;
-@implementation PBXDocBookmark // expected-warning {{incomplete implementation}}
+@implementation PBXDocBookmark // expected-warning {{method definition for 'autorelease' not found}}\
+ // expected-warning {{method definition for 'alloc' not found}}
+ (id)bookmarkWithFileReference:(PBXFileReference *)fileRef gylphRange:(NSRange)range anchor:(NSString *)htmlAnchor
{
diff --git a/test/SemaObjC/illegal-nonarc-bridged-cast.m b/test/SemaObjC/illegal-nonarc-bridged-cast.m
index a5bb01ffe0..f3406ef983 100644
--- a/test/SemaObjC/illegal-nonarc-bridged-cast.m
+++ b/test/SemaObjC/illegal-nonarc-bridged-cast.m
@@ -18,17 +18,16 @@ NSString *CreateNSString();
void from_cf() {
id obj1 = (__bridge_transfer id)CFCreateSomething(); // expected-warning {{'__bridge_transfer' casts have no effect when not using ARC}}
id obj2 = (__bridge_transfer NSString*)CFCreateString(); // expected-warning {{'__bridge_transfer' casts have no effect when not using ARC}}
- (__bridge int*)CFCreateSomething(); // expected-warning {{'__bridge' casts have no effect when not using ARC}} \
- // expected-warning {{expression result unused}}
- id obj3 = (__bridge id)CFGetSomething(); // expected-warning {{'__bridge' casts have no effect when not using ARC}}
- id obj4 = (__bridge NSString*)CFGetString(); // expected-warning {{'__bridge' casts have no effect when not using ARC}}
+ (__bridge int*)CFCreateSomething(); // expected-warning {{expression result unused}}
+ id obj3 = (__bridge id)CFGetSomething();
+ id obj4 = (__bridge NSString*)CFGetString();
}
void to_cf(id obj) {
CFTypeRef cf1 = (__bridge_retained CFTypeRef)CreateSomething(); // expected-warning {{'__bridge_retained' casts have no effect when not using ARC}}
CFStringRef cf2 = (__bridge_retained CFStringRef)CreateNSString(); // expected-warning {{'__bridge_retained' casts have no effect when not using ARC}}
- CFTypeRef cf3 = (__bridge CFTypeRef)CreateSomething(); // expected-warning {{'__bridge' casts have no effect when not using ARC}}
- CFStringRef cf4 = (__bridge CFStringRef)CreateNSString(); // expected-warning {{'__bridge' casts have no effect when not using ARC}}
+ CFTypeRef cf3 = (__bridge CFTypeRef)CreateSomething();
+ CFStringRef cf4 = (__bridge CFStringRef)CreateNSString();
}
void fixits() {
diff --git a/test/SemaObjC/incomplete-implementation.m b/test/SemaObjC/incomplete-implementation.m
index 69e355cb9a..4b8d600cb8 100644
--- a/test/SemaObjC/incomplete-implementation.m
+++ b/test/SemaObjC/incomplete-implementation.m
@@ -1,13 +1,12 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -fsyntax-only -verify -Wno-objc-root-class %s
@interface I
-- Meth; // expected-note{{method definition for 'Meth' not found}} \
- // expected-note{{method 'Meth' declared here}}
+- Meth; // expected-note 2 {{method 'Meth' declared here}}
- unavailableMeth __attribute__((availability(macosx,unavailable)));
- unavailableMeth2 __attribute__((unavailable));
@end
-@implementation I // expected-warning{{incomplete implementation}}
+@implementation I // expected-warning {{method definition for 'Meth' not found}}
@end
@implementation I(CAT)
diff --git a/test/SemaObjC/instancetype.m b/test/SemaObjC/instancetype.m
index 40f35d93b2..8137964737 100644
--- a/test/SemaObjC/instancetype.m
+++ b/test/SemaObjC/instancetype.m
@@ -5,9 +5,9 @@
#endif
@interface Root
-+ (instancetype)alloc;
++ (instancetype)alloc; // expected-note {{explicitly declared 'instancetype'}}
- (instancetype)init; // expected-note{{overridden method is part of the 'init' method family}}
-- (instancetype)self;
+- (instancetype)self; // expected-note {{explicitly declared 'instancetype'}}
- (Class)class;
@property (assign) Root *selfProp;
@@ -143,7 +143,7 @@ void test_instancetype_narrow_method_search() {
@implementation Subclass4
+ (id)alloc {
- return self; // expected-warning{{incompatible pointer types casting 'Class' to type 'Subclass4 *'}}
+ return self; // expected-warning{{incompatible pointer types returning 'Class' from a function with result type 'Subclass4 *'}}
}
- (Subclass3 *)init { return 0; } // don't complain: we lost the related return type
@@ -164,14 +164,14 @@ void test_instancetype_inherited() {
// Check that related return types tighten up the semantics of
// Objective-C method implementations.
@implementation Subclass2
-- (instancetype)initSubclass2 {
+- (instancetype)initSubclass2 { // expected-note {{explicitly declared 'instancetype'}}
Subclass1 *sc1 = [[Subclass1 alloc] init];
- return sc1; // expected-warning{{incompatible pointer types casting 'Subclass1 *' to type 'Subclass2 *'}}
+ return sc1; // expected-warning{{incompatible pointer types returning 'Subclass1 *' from a function with result type 'Subclass2 *'}}
}
- (void)methodOnSubclass2 {}
- (id)self {
Subclass1 *sc1 = [[Subclass1 alloc] init];
- return sc1; // expected-warning{{incompatible pointer types casting 'Subclass1 *' to type 'Subclass2 *'}}
+ return sc1; // expected-warning{{incompatible pointer types returning 'Subclass1 *' from a function with result type 'Subclass2 *'}}
}
@end
@@ -188,3 +188,29 @@ void test_instancetype_inherited() {
@end
+// rdar://12493140
+@protocol P4
+- (instancetype) foo; // expected-note {{current method is explicitly declared 'instancetype' and is expected to return an instance of its class type}}
+@end
+@interface A4 : Root <P4>
+- (instancetype) bar; // expected-note {{current method is explicitly declared 'instancetype' and is expected to return an instance of its class type}}
+- (instancetype) baz; // expected-note {{overridden method returns an instance of its class type}} expected-note {{previous definition is here}}
+@end
+@interface B4 : Root @end
+
+@implementation A4 {
+ B4 *_b;
+}
+- (id) foo {
+ return _b; // expected-warning {{incompatible pointer types returning 'B4 *' from a function with result type 'A4 *'}}
+}
+- (id) bar {
+ return _b; // expected-warning {{incompatible pointer types returning 'B4 *' from a function with result type 'A4 *'}}
+}
+
+// This is really just to ensure that we don't crash.
+// FIXME: only one diagnostic, please
+- (float) baz { // expected-warning {{method is expected to return an instance of its class type 'A4', but is declared to return 'float'}} expected-warning {{conflicting return type in implementation}}
+ return 0;
+}
+@end
diff --git a/test/SemaObjC/message.m b/test/SemaObjC/message.m
index f43bdf9885..40fa102f35 100644
--- a/test/SemaObjC/message.m
+++ b/test/SemaObjC/message.m
@@ -106,3 +106,15 @@ void foo5(id p) {
// expected-note {{to match this '['}} \
// expected-warning {{instance method '-bar' not found}}
}
+
+@interface I1
+-(void)unavail_meth __attribute__((unavailable)); // expected-note {{marked unavailable here}}
+@end
+
+// rdar://13620447
+void foo6(I1 *p) {
+ [p
+ bar]; // expected-warning {{instance method '-bar' not found}}
+ [p
+ unavail_meth]; // expected-error {{unavailable}}
+}
diff --git a/test/SemaObjC/method-conflict-2.m b/test/SemaObjC/method-conflict-2.m
index df59f242ce..ec80a433cc 100644
--- a/test/SemaObjC/method-conflict-2.m
+++ b/test/SemaObjC/method-conflict-2.m
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -Wmethod-signatures -fsyntax-only -verify -Wno-objc-root-class %s
+// RUN: %clang_cc1 -x objective-c++ -Wmethod-signatures -fsyntax-only -verify -Wno-objc-root-class %s
@interface A @end
@interface B : A @end
@@ -42,3 +43,24 @@
- (A*) test1 { return 0; } // id -> A* is rdar://problem/8596987
- (id) test2 { return 0; }
@end
+
+// rdar://12522752
+typedef int int32_t;
+typedef long long int64_t;
+
+@interface NSObject @end
+
+@protocol CKMessage
+@property (nonatomic,readonly,assign) int64_t sequenceNumber; // expected-note {{previous definition is here}}
+@end
+
+@protocol CKMessage;
+
+@interface CKIMMessage : NSObject<CKMessage>
+@end
+
+@implementation CKIMMessage
+- (int32_t)sequenceNumber { // expected-warning {{conflicting return type in implementation of 'sequenceNumber': 'int64_t' (aka 'long long') vs 'int32_t' (aka 'int')}}
+ return 0;
+}
+@end
diff --git a/test/SemaObjC/method-undef-category-warn-1.m b/test/SemaObjC/method-undef-category-warn-1.m
index 2548cbd241..98d732babb 100644
--- a/test/SemaObjC/method-undef-category-warn-1.m
+++ b/test/SemaObjC/method-undef-category-warn-1.m
@@ -4,25 +4,25 @@
@end
@protocol P
-- (void) Pmeth; // expected-note {{method 'Pmeth' declared here}}
-- (void) Pmeth1; // expected-note {{method 'Pmeth1' declared here}}
+- (void) Pmeth; // expected-note {{method 'Pmeth' declared here}}
+- (void) Pmeth1; // expected-note {{method 'Pmeth1' declared here}}
@end
@interface MyClass1(CAT) <P> // expected-note {{required for direct or indirect protocol 'P'}}
-- (void) meth2; // expected-note {{method definition for 'meth2' not found}}
+- (void) meth2; // expected-note {{method 'meth2' declared here}}
@end
-@implementation MyClass1(CAT) // expected-warning {{incomplete implementation}} \
- // expected-warning {{method 'Pmeth' in protocol not implemented}}
+@implementation MyClass1(CAT) // expected-warning {{method 'Pmeth' in protocol not implemented}} \
+ // expected-warning {{method definition for 'meth2' not found}}
- (void) Pmeth1{}
@end
@interface MyClass1(DOG) <P> // expected-note {{required for direct or indirect protocol 'P'}}
-- (void)ppp; // expected-note {{method definition for 'ppp' not found}}
+- (void)ppp; // expected-note {{method 'ppp' declared here}}
@end
-@implementation MyClass1(DOG) // expected-warning {{incomplete implementation}} \
- // expected-warning {{method 'Pmeth1' in protocol not implemented}}
+@implementation MyClass1(DOG) // expected-warning {{method 'Pmeth1' in protocol not implemented}} \
+ // expected-warning {{method definition for 'ppp' not found}}
- (void) Pmeth {}
@end
diff --git a/test/SemaObjC/method-undef-extension-warn-1.m b/test/SemaObjC/method-undef-extension-warn-1.m
index c092f24828..fbc21bd39f 100644
--- a/test/SemaObjC/method-undef-extension-warn-1.m
+++ b/test/SemaObjC/method-undef-extension-warn-1.m
@@ -10,7 +10,7 @@
// Class extension
@interface MyClass () <P>
-- (void)meth2; // expected-note {{method definition for 'meth2' not found}}
+- (void)meth2; // expected-note {{method 'meth2' declared here}}
@end
// Add a category to test that clang does not emit warning for this method.
@@ -18,7 +18,7 @@
- (void)categoryMethod;
@end
-@implementation MyClass // expected-warning {{incomplete implementation}} \
- // expected-warning {{method 'Pmeth1' in protocol not implemented}}
+@implementation MyClass // expected-warning {{method 'Pmeth1' in protocol not implemented}} \
+ // expected-warning {{method definition for 'meth2' not found}}
- (void)Pmeth {}
@end
diff --git a/test/SemaObjC/method-undefined-warn-1.m b/test/SemaObjC/method-undefined-warn-1.m
index 27d645e73b..e22140d446 100644
--- a/test/SemaObjC/method-undefined-warn-1.m
+++ b/test/SemaObjC/method-undefined-warn-1.m
@@ -3,12 +3,14 @@
@interface INTF
- (void) meth;
- (void) meth : (int) arg1;
-- (int) int_meth; // expected-note {{method definition for 'int_meth' not found}}
-+ (int) cls_meth; // expected-note {{method definition for 'cls_meth' not found}}
-+ (void) cls_meth1 : (int) arg1; // expected-note {{method definition for 'cls_meth1:' not found}}
+- (int) int_meth; // expected-note {{method 'int_meth' declared here}}
++ (int) cls_meth; // expected-note {{method 'cls_meth' declared here}}
++ (void) cls_meth1 : (int) arg1; // expected-note {{method 'cls_meth1:' declared here}}
@end
-@implementation INTF // expected-warning {{incomplete implementation}}
+@implementation INTF // expected-warning {{method definition for 'int_meth' not found}} \
+ // expected-warning {{method definition for 'cls_meth' not found}} \
+ // expected-warning {{method definition for 'cls_meth1:' not found}}
- (void) meth {}
- (void) meth : (int) arg2{}
- (void) cls_meth1 : (int) arg2{}
@@ -17,12 +19,14 @@
@interface INTF1
- (void) meth;
- (void) meth : (int) arg1;
-- (int) int_meth; // expected-note {{method definition for 'int_meth' not found}}
-+ (int) cls_meth; // expected-note {{method definition for 'cls_meth' not found}}
-+ (void) cls_meth1 : (int) arg1; // expected-note {{method definition for 'cls_meth1:' not found}}
+- (int) int_meth; // expected-note {{method 'int_meth' declared here}}
++ (int) cls_meth; // expected-note {{method 'cls_meth' declared here}}
++ (void) cls_meth1 : (int) arg1; // expected-note {{method 'cls_meth1:' declared here}}
@end
-@implementation INTF1 // expected-warning {{incomplete implementation}}
+@implementation INTF1 // expected-warning {{method definition for 'int_meth' not found}} \
+ // expected-warning {{method definition for 'cls_meth' not found}} \
+ // expected-warning {{method definition for 'cls_meth1:' not found}}
- (void) meth {}
- (void) meth : (int) arg2{}
- (void) cls_meth1 : (int) arg2{}
diff --git a/test/SemaObjC/no-protocol-option-tests.m b/test/SemaObjC/no-protocol-option-tests.m
index dbd2a14e91..605cf9f1bf 100644
--- a/test/SemaObjC/no-protocol-option-tests.m
+++ b/test/SemaObjC/no-protocol-option-tests.m
@@ -17,9 +17,9 @@
// Test2
@interface super - PMeth; @end
@interface J : super <P>
-- PMeth; // expected-note {{method definition for 'PMeth' not found}}
+- PMeth; // expected-note {{method 'PMeth' declared here}}
@end
-@implementation J @end // expected-warning {{incomplete implementation}}
+@implementation J @end // expected-warning {{method definition for 'PMeth' not found}}
// Test3
@interface K : super <P>
diff --git a/test/SemaObjC/property-category-4.m b/test/SemaObjC/property-category-4.m
index e7939b32c1..ccf5e9b2a8 100644
--- a/test/SemaObjC/property-category-4.m
+++ b/test/SemaObjC/property-category-4.m
@@ -16,3 +16,108 @@
@dynamic d_selectedObjects; // expected-error {{property declared in category 'CAT' cannot be implemented in class implementation}}
@end
+
+// rdar://13713098
+// Test1
+@interface NSArray
+- (int)count;
+@end
+
+@protocol MyCountable
+@property (readonly) int count;
+@end
+
+
+@interface NSArray(Additions) <MyCountable>
+@end
+
+@implementation NSArray(Additions)
+@end
+
+// Test2
+@protocol NSProtocol
+- (int)count;
+@end
+
+@interface NSArray1 <NSProtocol>
+@end
+
+@interface NSArray1(Additions) <MyCountable>
+@end
+
+@implementation NSArray1(Additions)
+@end
+
+// Test3
+@interface Super <NSProtocol>
+@end
+
+@interface NSArray2 : Super @end
+
+@interface NSArray2(Additions) <MyCountable>
+@end
+
+@implementation NSArray2(Additions)
+@end
+
+// Test3
+@interface Super1 <NSProtocol>
+@property (readonly) int count;
+@end
+
+@protocol MyCountable1
+@end
+
+@interface NSArray3 : Super1 <MyCountable1>
+@end
+
+@implementation NSArray3
+@end
+
+// Test4
+@interface I
+@property int d1;
+@end
+
+@interface I(CAT)
+@property int d1;
+@end
+
+@implementation I(CAT)
+@end
+
+// Test5
+@interface C @end
+
+@interface C (CAT)
+- (int) p;
+@end
+
+
+@interface C (Category)
+@property (readonly) int p; // no warning for this property - a getter is declared in another category
+@property (readonly) int p1; // expected-note {{property declared here}}
+@property (readonly) int p2; // no warning for this property - a getter is declared in this category
+- (int) p2;
+@end
+
+@implementation C (Category) // expected-warning {{property 'p1' requires method 'p1' to be defined - use @dynamic or provide a method implementation in this category}}
+@end
+
+// Test6
+@protocol MyProtocol
+@property (readonly) float anotherFloat; // expected-note {{property declared here}}
+@property (readonly) float Float; // no warning for this property - a getter is declared in this protocol
+- (float) Float;
+@end
+
+@interface MyObject
+{ float anotherFloat; }
+@end
+
+@interface MyObject (CAT) <MyProtocol>
+@end
+
+@implementation MyObject (CAT) // expected-warning {{property 'anotherFloat' requires method 'anotherFloat' to be defined - use @dynamic or provide a method implementation in this category}}
+@end
+
diff --git a/test/SemaObjC/property-category-impl.m b/test/SemaObjC/property-category-impl.m
index be42deaf90..135b005761 100644
--- a/test/SemaObjC/property-category-impl.m
+++ b/test/SemaObjC/property-category-impl.m
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s
+// expected-no-diagnostics
/* This test is for categories which don't implement the accessors but some accessors are
implemented in their base class implementation. In this case,no warning must be issued.
@@ -24,10 +25,10 @@
@end
@interface MyClass (public)
-@property(readwrite) int foo; // expected-note {{property declared here}}
+@property(readwrite) int foo;
@end
-@implementation MyClass (public)// expected-warning {{property 'foo' requires method 'setFoo:' to be defined }}
+@implementation MyClass (public)
@end
// rdar://12568064
diff --git a/test/SemaObjC/property-deprecated-warning.m b/test/SemaObjC/property-deprecated-warning.m
index aa7b764fab..7e10356ac5 100644
--- a/test/SemaObjC/property-deprecated-warning.m
+++ b/test/SemaObjC/property-deprecated-warning.m
@@ -5,37 +5,51 @@
typedef signed char BOOL;
@protocol P
-@property(nonatomic,assign) id ptarget __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note 2 {{property 'ptarget' is declared deprecated here}}
+@property(nonatomic,assign) id ptarget __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note {{property 'ptarget' is declared deprecated here}} expected-note {{method 'ptarget' declared here}}
@end
@protocol P1<P>
-- (void)setPtarget:(id)arg; // expected-note {{method 'setPtarget:' declared here}}
+- (void)setPtarget:(id)arg;
@end
@interface UITableViewCell<P1>
-@property(nonatomic,assign) id target __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note {{property 'target' is declared deprecated here}}
+@property(nonatomic,assign) id target __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note {{property 'target' is declared deprecated here}} expected-note {{method 'setTarget:' declared here}}
@end
@interface PSTableCell : UITableViewCell
- - (void)setTarget:(id)target; // expected-note {{method 'setTarget:' declared here}}
+ - (void)setTarget:(id)target;
@end
@interface UITableViewCell(UIDeprecated)
-@property(nonatomic,assign) id dep_target __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note {{method 'dep_target' declared here}} \
- // expected-note 2 {{property 'dep_target' is declared deprecated here}} \
- // expected-note {{method 'setDep_target:' declared here}}
+@property(nonatomic,assign) id dep_target __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note 2 {{method 'dep_target' declared here}} \
+ // expected-note 4 {{property 'dep_target' is declared deprecated here}} \
+ // expected-note 2 {{method 'setDep_target:' declared here}}
@end
@implementation PSTableCell
- (void)setTarget:(id)target {};
- (void)setPtarget:(id)val {};
- (void) Meth {
+ [self setTarget: (id)0]; // no-warning
+ [self setDep_target: [self dep_target]]; // expected-warning {{'dep_target' is deprecated: first deprecated in iOS 3.0}} \
+ // expected-warning {{'setDep_target:' is deprecated: first deprecated in iOS 3.0}}
+
+ [self setPtarget: (id)0]; // no-warning
+}
+@end
+
+@implementation UITableViewCell
+@synthesize target;
+@synthesize ptarget;
+- (void)setPtarget:(id)val {};
+- (void)setTarget:(id)target {};
+- (void) Meth {
[self setTarget: (id)0]; // expected-warning {{'setTarget:' is deprecated: first deprecated in iOS 3.0}}
[self setDep_target: [self dep_target]]; // expected-warning {{'dep_target' is deprecated: first deprecated in iOS 3.0}} \
// expected-warning {{'setDep_target:' is deprecated: first deprecated in iOS 3.0}}
- [self setPtarget: (id)0]; // expected-warning {{setPtarget:' is deprecated: first deprecated in iOS 3.0}}
+ [self setPtarget: (id)0]; // no-warning
}
@end
@@ -56,9 +70,11 @@ void testCustomAccessorNames(CustomAccessorNames *obj) {
@end
@interface ProtocolInCategory (TheCategory) <P1>
-- (id)ptarget; // expected-note {{method 'ptarget' declared here}}
+- (id)ptarget;
@end
-id useDeprecatedProperty(ProtocolInCategory *obj) {
- return [obj ptarget]; // expected-warning {{'ptarget' is deprecated: first deprecated in iOS 3.0}}
+id useDeprecatedProperty(ProtocolInCategory *obj, id<P> obj2, int flag) {
+ if (flag)
+ return [obj ptarget]; // no-warning
+ return [obj2 ptarget]; // expected-warning {{'ptarget' is deprecated: first deprecated in iOS 3.0}}
}
diff --git a/test/SemaObjC/property-in-class-extension.m b/test/SemaObjC/property-in-class-extension.m
index a7b5130752..022a487ec6 100644
--- a/test/SemaObjC/property-in-class-extension.m
+++ b/test/SemaObjC/property-in-class-extension.m
@@ -37,11 +37,12 @@ void FUNC () {
@interface rdar8747333 ()
- (NSObject *)bam;
-- (NSObject *)warn; // expected-note {{method definition for 'warn' not found}}
-- (void)setWarn : (NSObject *)val; // expected-note {{method definition for 'setWarn:' not found}}
+- (NSObject *)warn; // expected-note {{method 'warn' declared here}}
+- (void)setWarn : (NSObject *)val; // expected-note {{method 'setWarn:' declared here}}
@end
-@implementation rdar8747333 // expected-warning {{incomplete implementation}}
+@implementation rdar8747333 // expected-warning {{method definition for 'warn' not found}} \
+ // expected-warning {{method definition for 'setWarn:' not found}}
@synthesize bar = _bar;
@synthesize baz = _baz;
@synthesize bam = _bam;
diff --git a/test/SemaObjC/property-noninherited-availability-attr.m b/test/SemaObjC/property-noninherited-availability-attr.m
new file mode 100644
index 0000000000..0c2a5d3853
--- /dev/null
+++ b/test/SemaObjC/property-noninherited-availability-attr.m
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.8.0 -fsyntax-only -verify %s
+
+// This test case shows that 'availablity' and 'deprecated' does not inherit
+// when a property is redeclared in a subclass. This is intentional.
+
+@interface NSObject @end
+@protocol myProtocol
+@property int myProtocolProperty __attribute__((availability(macosx,introduced=10.7,deprecated=10.8))); // expected-note {{method 'myProtocolProperty' declared here}} \
+ // expected-note {{property 'myProtocolProperty' is declared deprecated here}}
+@end
+
+@interface Foo : NSObject
+@property int myProperty __attribute__((availability(macosx,introduced=10.7,deprecated=10.8))); // expected-note {{'myProperty' declared here}} \
+ // expected-note {{method 'myProperty' declared here}} \
+ // expected-note {{property 'myProperty' is declared deprecated here}}
+@end
+
+@interface Bar : Foo <myProtocol>
+@property int myProperty;
+@property int myProtocolProperty;
+@end
+
+void test(Foo *y, Bar *x, id<myProtocol> z) {
+ y.myProperty = 0; // expected-warning {{'myProperty' is deprecated: first deprecated in OS X 10.8}}
+ [y myProperty]; // expected-warning {{'myProperty' is deprecated: first deprecated in OS X 10.8}}
+
+ x.myProperty = 1; // no-warning
+ [x myProperty]; // no-warning
+
+ x.myProtocolProperty = 0; // no-warning
+
+ [x myProtocolProperty]; // no-warning
+ [z myProtocolProperty]; // expected-warning {{'myProtocolProperty' is deprecated: first deprecated in OS X 10.8}}
+}
diff --git a/test/SemaObjC/property-user-setter.m b/test/SemaObjC/property-user-setter.m
index cda983c9ec..e84fad2394 100644
--- a/test/SemaObjC/property-user-setter.m
+++ b/test/SemaObjC/property-user-setter.m
@@ -85,7 +85,7 @@ static int g_val;
- (void)setFoo:(int)value;
@end
-void g(int); // expected-note {{passing argument to parameter here}}
+void g(int);
void f(C *c) {
c.Foo = 17; // OK
diff --git a/test/SemaObjC/property.m b/test/SemaObjC/property.m
index 76fdf5b242..7485447173 100644
--- a/test/SemaObjC/property.m
+++ b/test/SemaObjC/property.m
@@ -11,7 +11,7 @@
@end
@interface I(CAT)
-@property int d1; // expected-note 2 {{property declared here}}
+@property int d1;
@end
@implementation I
@@ -22,8 +22,7 @@
@synthesize name; // OK! property with same name as an accessible ivar of same name
@end
-@implementation I(CAT) // expected-warning {{property 'd1' requires method 'd1' to be defined }} \
- // expected-warning {{property 'd1' requires method 'setD1:' to be defined }}
+@implementation I(CAT)
@synthesize d1; // expected-error {{@synthesize not allowed in a category's implementation}}
@dynamic bad; // expected-error {{property implementation must have its declaration in the category 'CAT'}}
@end
diff --git a/test/SemaObjC/protocol-lookup-2.m b/test/SemaObjC/protocol-lookup-2.m
index 9e8ed8a627..90f6db0c84 100644
--- a/test/SemaObjC/protocol-lookup-2.m
+++ b/test/SemaObjC/protocol-lookup-2.m
@@ -32,3 +32,26 @@
}
@end
+
+
+@protocol ProtC
+-document;
+@end
+
+@interface I1 : NSObject
+@end
+
+@interface I1(cat)
+-document;
+@end
+
+@interface I2 : NSObject
+-document;
+@end
+
+@interface I2() <ProtC>
+@end
+
+@implementation I2
+- document { return 0; }
+@end
diff --git a/test/SemaObjC/related-result-type-inference.m b/test/SemaObjC/related-result-type-inference.m
index b1d77dc172..50aaf2da4d 100644
--- a/test/SemaObjC/related-result-type-inference.m
+++ b/test/SemaObjC/related-result-type-inference.m
@@ -175,7 +175,7 @@ void test_inference() {
@implementation Fail
- (id<X>) initWithX
{
- return (id)self; // expected-warning {{returning 'Fail *' from a function with incompatible result type 'id<X>'}}
+ return (id)self; // expected-warning {{casting 'Fail *' to incompatible type 'id<X>'}}
}
@end
diff --git a/test/SemaObjC/typo-correction.m b/test/SemaObjC/typo-correction.m
new file mode 100644
index 0000000000..893e31294a
--- /dev/null
+++ b/test/SemaObjC/typo-correction.m
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+
+@interface B
+@property int x;
+@end
+
+@interface S : B
+@end
+
+// Spell-checking 'undefined' is ok.
+undefined var; // expected-error {{unknown type name}}
+
+typedef int super1;
+@implementation S
+-(void)foo {
+ // Spell-checking 'super' is not ok.
+ super.x = 0;
+ self.x = 0;
+}
+@end
diff --git a/test/SemaObjC/undef-protocol-methods-1.m b/test/SemaObjC/undef-protocol-methods-1.m
index 15ba1a1eb2..25b1dadb7c 100644
--- a/test/SemaObjC/undef-protocol-methods-1.m
+++ b/test/SemaObjC/undef-protocol-methods-1.m
@@ -28,10 +28,7 @@
// expected-note 2 {{required for direct or indirect protocol 'P2'}}
@end
-@implementation INTF // expected-warning {{incomplete implementation}} \
- // expected-warning 9 {{in protocol not implemented}}
+@implementation INTF // expected-warning 9 {{in protocol not implemented}}
- (void) DefP1proto{}
-
+ (void) DefClsP3Proto{}
-
@end
diff --git a/test/SemaObjC/warn-missing-super.m b/test/SemaObjC/warn-missing-super.m
index 02b81651d7..e9769a9db1 100644
--- a/test/SemaObjC/warn-missing-super.m
+++ b/test/SemaObjC/warn-missing-super.m
@@ -54,5 +54,5 @@ __attribute__((objc_root_class))
// CHECK-GC-ONLY: 1 warning generated.
// RUN: %clang_cc1 -fsyntax-only -triple x86_64-apple-darwin10 -fobjc-arc %s 2>&1 | FileCheck --check-prefix=CHECK-ARC %s
-// CHECK-ARC: warn-missing-super.m:36:4: error: ARC forbids explicit message send of 'dealloc'
+// CHECK-ARC: warn-missing-super.m:36:10: error: ARC forbids explicit message send of 'dealloc'
// CHECK-ARC: 1 error generated.
diff --git a/test/SemaObjC/warning-missing-selector-name.m b/test/SemaObjC/warning-missing-selector-name.m
index d43031eee0..a335e0266a 100644
--- a/test/SemaObjC/warning-missing-selector-name.m
+++ b/test/SemaObjC/warning-missing-selector-name.m
@@ -15,11 +15,11 @@
- method:(id) second:(id)second; // expected-warning {{'second' used as the name of the previous parameter rather than as part of the selector}} \
// expected-note {{introduce a parameter name to make 'second' part of the selector}} \
// expected-note {{or insert whitespace before ':' to use 'second' as parameter name and have an empty entry in the selector}} \
- // expected-note {{method definition for 'method::' not found}}
+ // expected-note {{method 'method::' declared here}}
@end
-@implementation INTF // expected-warning {{incomplete implementation}}
+@implementation INTF // expected-warning {{method definition for 'method::' not found}}
-(void) Name1:(id)Arg1 Name2:(id)Arg2{}
-(void) Name1:(id) Name2:(id)Arg2 {} // expected-warning {{'Name2' used as the name of the previous parameter rather than as part of the selector}} \
// expected-note {{introduce a parameter name to make 'Name2' part of the selector}} \
diff --git a/test/SemaObjCXX/arc-system-header.mm b/test/SemaObjCXX/arc-system-header.mm
index 107b5b5a53..3358e5fc12 100644
--- a/test/SemaObjCXX/arc-system-header.mm
+++ b/test/SemaObjCXX/arc-system-header.mm
@@ -6,5 +6,4 @@ void f(A* a) {
a->data.void_ptr = 0;
a->data.a_b.b = 0; // expected-error{{'a_b' is unavailable: this system field has retaining ownership}}
}
-// Silly location below
-// expected-note{{declaration has been explicitly marked unavailable here}}
+// expected-note@arc-system-header.h:10{{declaration has been explicitly marked unavailable here}}
diff --git a/test/SemaObjCXX/foreach.mm b/test/SemaObjCXX/foreach.mm
index 3c4b908eab..d1302c19a5 100644
--- a/test/SemaObjCXX/foreach.mm
+++ b/test/SemaObjCXX/foreach.mm
@@ -12,8 +12,18 @@ void f(NSArray *a) {
// expected-warning {{expression result unused}}
for (id thisKey : keys);
+
+ for (auto thisKey : keys) { } // expected-warning{{'auto' deduced as 'id' in declaration of 'thisKey'}}
+}
+
+template<typename Collection>
+void ft(Collection col) {
+ for (id x : col) { }
+ for (auto x : col) { }
}
+template void ft(NSArray *);
+
/* // rdar://9072298 */
@protocol NSObject @end
@@ -59,3 +69,9 @@ void test2(NSObject<NSFastEnumeration> *collection) {
// expected-warning {{property access result unused - getters should not be used for side effects}}
}
}
+
+void testErrors(NSArray *array) {
+ typedef int fn(int);
+
+ for (fn x in array) { } // expected-error{{non-variable declaration in 'for' loop}}
+}
diff --git a/test/SemaObjCXX/instancetype.mm b/test/SemaObjCXX/instancetype.mm
new file mode 100644
index 0000000000..bbf100ef04
--- /dev/null
+++ b/test/SemaObjCXX/instancetype.mm
@@ -0,0 +1,216 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+#if !__has_feature(objc_instancetype)
+# error Missing 'instancetype' feature macro.
+#endif
+
+@interface Root
++ (instancetype)alloc;
+- (instancetype)init; // expected-note{{overridden method is part of the 'init' method family}}
+- (instancetype)self; // expected-note {{explicitly declared 'instancetype'}}
+- (Class)class;
+
+@property (assign) Root *selfProp;
+- (instancetype)selfProp;
+@end
+
+@protocol Proto1
+@optional
+- (instancetype)methodInProto1;
+@end
+
+@protocol Proto2
+@optional
+- (instancetype)methodInProto2; // expected-note{{overridden method returns an instance of its class type}}
+- (instancetype)otherMethodInProto2; // expected-note{{overridden method returns an instance of its class type}}
+@end
+
+@interface Subclass1 : Root
+- (instancetype)initSubclass1;
+- (void)methodOnSubclass1;
++ (instancetype)allocSubclass1;
+@end
+
+@interface Subclass2 : Root
+- (instancetype)initSubclass2;
+- (void)methodOnSubclass2;
+@end
+
+// Sanity check: the basic initialization pattern.
+void test_instancetype_alloc_init_simple() {
+ Root *r1 = [[Root alloc] init];
+ Subclass1 *sc1 = [[Subclass1 alloc] init];
+}
+
+// Test that message sends to instancetype methods have the right type.
+void test_instancetype_narrow_method_search() {
+ // instancetype on class methods
+ Subclass1 *sc1 = [[Subclass1 alloc] initSubclass2]; // expected-warning{{'Subclass1' may not respond to 'initSubclass2'}}
+ Subclass2 *sc2 = [[Subclass2 alloc] initSubclass2]; // okay
+
+ // instancetype on instance methods
+ [[[Subclass1 alloc] init] methodOnSubclass2]; // expected-warning{{'Subclass1' may not respond to 'methodOnSubclass2'}}
+ [[[Subclass2 alloc] init] methodOnSubclass2];
+
+ // instancetype on class methods using protocols
+ typedef Subclass1<Proto1> SC1Proto1;
+ typedef Subclass1<Proto2> SC1Proto2;
+ [[SC1Proto1 alloc] methodInProto2]; // expected-warning{{method '-methodInProto2' not found (return type defaults to 'id')}}
+ [[SC1Proto2 alloc] methodInProto2];
+
+ // instancetype on instance methods
+ Subclass1<Proto1> *sc1proto1 = 0;
+ [[sc1proto1 self] methodInProto2]; // expected-warning{{method '-methodInProto2' not found (return type defaults to 'id')}}
+ Subclass1<Proto2> *sc1proto2 = 0;
+ [[sc1proto2 self] methodInProto2];
+
+ // Exact type checks
+ typeof([[Subclass1 alloc] init]) *ptr1 = (Subclass1 **)0;
+ typeof([[Subclass2 alloc] init]) *ptr2 = (Subclass2 **)0;
+
+ // Message sends to Class.
+ Subclass1<Proto1> *sc1proto1_2 = [[[sc1proto1 class] alloc] init];
+
+ // Property access
+ [sc1proto1.self methodInProto2]; // expected-warning{{method '-methodInProto2' not found (return type defaults to 'id')}}
+ [sc1proto2.self methodInProto2];
+ [Subclass1.alloc initSubclass2]; // expected-warning{{'Subclass1' may not respond to 'initSubclass2'}}
+ [Subclass2.alloc initSubclass2];
+
+ [sc1proto1.selfProp methodInProto2]; // expected-warning{{method '-methodInProto2' not found (return type defaults to 'id')}}
+ [sc1proto2.selfProp methodInProto2];
+}
+
+// Test that message sends to super methods have the right type.
+@interface Subsubclass1 : Subclass1
+- (instancetype)initSubclass1;
++ (instancetype)allocSubclass1;
+
+- (void)onlyInSubsubclass1;
+@end
+
+@implementation Subsubclass1
+- (instancetype)initSubclass1 {
+ // Check based on method search.
+ [[super initSubclass1] methodOnSubclass2]; // expected-warning{{'Subsubclass1' may not respond to 'methodOnSubclass2'}}
+ [super.initSubclass1 methodOnSubclass2]; // expected-warning{{'Subsubclass1' may not respond to 'methodOnSubclass2'}}
+
+ self = [super init]; // common pattern
+
+ // Exact type check.
+ typeof([super initSubclass1]) *ptr1 = (Subsubclass1**)0;
+
+ return self;
+}
+
++ (instancetype)allocSubclass1 {
+ // Check based on method search.
+ [[super allocSubclass1] methodOnSubclass2]; // expected-warning{{'Subsubclass1' may not respond to 'methodOnSubclass2'}}
+
+ // The ASTs don't model super property accesses well enough to get this right
+ [super.allocSubclass1 methodOnSubclass2]; // expected-warning{{'Subsubclass1' may not respond to 'methodOnSubclass2'}}
+
+ // Exact type check.
+ typeof([super allocSubclass1]) *ptr1 = (Subsubclass1**)0;
+
+ return [super allocSubclass1];
+}
+
+- (void)onlyInSubsubclass1 {}
+@end
+
+// Check compatibility rules for inheritance of related return types.
+@class Subclass4;
+
+@interface Subclass3 <Proto1, Proto2>
+- (Subclass3 *)methodInProto1;
+- (Subclass4 *)methodInProto2; // expected-warning{{method is expected to return an instance of its class type 'Subclass3', but is declared to return 'Subclass4 *'}}
+@end
+
+@interface Subclass4 : Root
++ (Subclass4 *)alloc; // okay
+- (Subclass3 *)init; // expected-warning{{method is expected to return an instance of its class type 'Subclass4', but is declared to return 'Subclass3 *'}}
+- (id)self; // expected-note{{overridden method is part of the 'self' method family}}
+- (instancetype)initOther;
+@end
+
+@protocol Proto3 <Proto1, Proto2>
+@optional
+- (id)methodInProto1;
+- (Subclass1 *)methodInProto2;
+- (int)otherMethodInProto2; // expected-warning{{protocol method is expected to return an instance of the implementing class, but is declared to return 'int'}}
+@end
+
+@implementation Subclass4
++ (id)alloc {
+ return self; // FIXME: we accept this in ObjC++ but not ObjC?
+}
+
+- (Subclass3 *)init { return 0; } // don't complain: we lost the related return type
+
+- (Subclass3 *)self { return 0; } // expected-warning{{method is expected to return an instance of its class type 'Subclass4', but is declared to return 'Subclass3 *'}}
+
+- (Subclass4 *)initOther { return 0; }
+
+@end
+
+// Check that inherited related return types influence the types of
+// message sends.
+void test_instancetype_inherited() {
+ [[Subclass4 alloc] initSubclass1]; // expected-warning{{'Subclass4' may not respond to 'initSubclass1'}}
+ [[Subclass4 alloc] initOther];
+}
+
+// Check that related return types tighten up the semantics of
+// Objective-C method implementations.
+@implementation Subclass2
+- (instancetype)initSubclass2 { // expected-note {{explicitly declared 'instancetype'}}
+ Subclass1 *sc1 = [[Subclass1 alloc] init];
+ return sc1; // expected-error{{cannot initialize return object of type 'Subclass2 *' with an lvalue of type 'Subclass1 *'}}
+}
+- (void)methodOnSubclass2 {}
+- (id)self {
+ Subclass1 *sc1 = [[Subclass1 alloc] init];
+ return sc1; // expected-error{{cannot initialize return object of type 'Subclass2 *' with an lvalue of type 'Subclass1 *'}}
+}
+@end
+
+@interface MyClass : Root
++ (int)myClassMethod;
+@end
+
+@implementation MyClass
++ (int)myClassMethod { return 0; }
+
+- (void)blah {
+ int i = [[MyClass self] myClassMethod];
+}
+
+@end
+
+// rdar://12493140
+@protocol P4
+- (instancetype) foo; // expected-note {{current method is explicitly declared 'instancetype' and is expected to return an instance of its class type}}
+@end
+@interface A4 : Root <P4>
+- (instancetype) bar; // expected-note {{current method is explicitly declared 'instancetype' and is expected to return an instance of its class type}}
+- (instancetype) baz; // expected-note {{overridden method returns an instance of its class type}} expected-note {{previous definition is here}}
+@end
+@interface B4 : Root @end
+
+@implementation A4 {
+ B4 *_b;
+}
+- (id) foo {
+ return _b; // expected-error {{cannot initialize return object of type 'A4 *' with an lvalue of type 'B4 *'}}
+}
+- (id) bar {
+ return _b; // expected-error {{cannot initialize return object of type 'A4 *' with an lvalue of type 'B4 *'}}
+}
+
+// This is really just to ensure that we don't crash.
+// FIXME: only one diagnostic, please
+- (float) baz { // expected-warning {{method is expected to return an instance of its class type 'A4', but is declared to return 'float'}} expected-warning {{conflicting return type in implementation}}
+ return 0;
+}
+@end
diff --git a/test/SemaObjCXX/instantiate-expr.mm b/test/SemaObjCXX/instantiate-expr.mm
index 071bf6bced..e9d296db8f 100644
--- a/test/SemaObjCXX/instantiate-expr.mm
+++ b/test/SemaObjCXX/instantiate-expr.mm
@@ -21,7 +21,7 @@ void f(U value, V value2) {
get_an_A(N)->ivar = value; // expected-error{{assigning to 'int' from incompatible type 'int *'}}
get_an_A(N).prop = value2; // expected-error{{assigning to 'int' from incompatible type 'double *'}}
T c = get_an_id(N)->isa; // expected-error{{cannot initialize a variable of type 'int' with an lvalue of type 'Class'}} \
- // expected-warning 5 {{direct access to Objective-C's isa is deprecated in favor of object_setClass() and object_getClass()}}
+ // expected-warning 3 {{direct access to Objective-C's isa is deprecated in favor of object_getClass()}}
}
template void f<6, Class>(int, int); // expected-note{{in instantiation of}}
@@ -46,7 +46,7 @@ template void f2(A*, int, double*); // expected-note{{instantiation of}}
template<typename T, typename U>
void f3(U ptr) {
T c = ptr->isa; // expected-error{{cannot initialize a variable of type 'int' with an lvalue of type 'Class'}} \
- // expected-warning 2 {{direct access to Objective-C's isa is deprecated in favor of object_setClass() and object_getClass()}}
+ // expected-warning 1 {{direct access to Objective-C's isa is deprecated in favor of object_getClass()}}
}
template void f3<Class>(id); // expected-note{{in instantiation of}}
diff --git a/test/SemaObjCXX/parameters.mm b/test/SemaObjCXX/parameters.mm
index 1a7869dc7a..363675a0dd 100644
--- a/test/SemaObjCXX/parameters.mm
+++ b/test/SemaObjCXX/parameters.mm
@@ -15,3 +15,6 @@ struct test2 { virtual void foo() = 0; }; // expected-note {{unimplemented}}
@interface Test2
- (void) foo: (test2) foo; // expected-error {{parameter type 'test2' is an abstract class}}
@end
+
+template<typename T> void r1(__restrict T);
+void r2(__restrict id x) { r1(x); }
diff --git a/test/SemaObjCXX/property-reference.mm b/test/SemaObjCXX/property-reference.mm
index b86ae5e9f5..cfac9f30db 100644
--- a/test/SemaObjCXX/property-reference.mm
+++ b/test/SemaObjCXX/property-reference.mm
@@ -57,3 +57,21 @@ template<typename T> void f() {
}
template void f<int>();
+
+// rdar://13602832
+//
+// Make sure that the default-argument checker looks through
+// pseudo-object expressions correctly. The default argument
+// needs to force l2r to test this effectively because the checker
+// is syntactic and runs before placeholders are handled.
+@interface Test13602832
+- (int) x;
+@end
+namespace test13602832 {
+ template <int N> void foo(Test13602832 *a, int limit = a.x + N) {} // expected-error {{default argument references parameter 'a'}}
+
+ void test(Test13602832 *a) {
+ // FIXME: this is a useless cascade error.
+ foo<1024>(a); // expected-error {{no matching function}}
+ }
+}
diff --git a/test/SemaObjCXX/references.mm b/test/SemaObjCXX/references.mm
index f63e17d98e..fa552076fb 100644
--- a/test/SemaObjCXX/references.mm
+++ b/test/SemaObjCXX/references.mm
@@ -1,5 +1,7 @@
-// RUN: %clang_cc1 -verify -emit-llvm -o - %s
-// expected-no-diagnostics
+// RUN: %clang_cc1 -verify -o - %s
+
+__attribute__((objc_root_class))
+@interface Root @end
// Test reference binding.
@@ -8,7 +10,7 @@ typedef struct {
int f1;
} T;
-@interface A
+@interface A : Root
@property (assign) T p0;
@property (assign) T& p1;
@end
@@ -61,3 +63,14 @@ void f6(baz* x) {
f5d(ToBar());
(void)((foo&)ToBar());
}
+
+// rdar://13794269
+@interface B : Root @end
+@implementation B {
+ unsigned bf : 4; // expected-note {{declared here}}
+}
+
+- (void) foo {
+ unsigned &i = bf; // expected-error {{non-const reference cannot bind to bit-field 'bf'}}
+}
+@end
diff --git a/test/SemaOpenCL/endian-attr.cl b/test/SemaOpenCL/endian-attr.cl
new file mode 100644
index 0000000000..e851cdf90b
--- /dev/null
+++ b/test/SemaOpenCL/endian-attr.cl
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -verify %s
+
+constant long a __attribute__((endian(host))) = 100;
+
+constant long b __attribute__((endian(device))) = 100;
+
+constant long c __attribute__((endian(none))) = 100; // expected-warning {{unknown endian 'none'}}
+
+void func() __attribute__((endian(host))); // expected-warning {{endian attribute only applies to variables}}
diff --git a/test/SemaOpenCL/event_t.cl b/test/SemaOpenCL/event_t.cl
index 57a0981cf1..06197d0c17 100644
--- a/test/SemaOpenCL/event_t.cl
+++ b/test/SemaOpenCL/event_t.cl
@@ -2,7 +2,7 @@
event_t glb_evt; // expected-error {{the event_t type cannot be used to declare a program scope variable}}
-struct evt_s {
+constant struct evt_s {
event_t evt; // expected-error {{the event_t type cannot be used to declare a structure or union field}}
} evt_str;
diff --git a/test/SemaOpenCL/storageclass.cl b/test/SemaOpenCL/storageclass.cl
index fdfe134621..d2678f2010 100644
--- a/test/SemaOpenCL/storageclass.cl
+++ b/test/SemaOpenCL/storageclass.cl
@@ -2,6 +2,8 @@
static constant int A = 0;
+int X = 0; // expected-error{{global variables must have a constant address space qualifier}}
+
// static is not allowed at local scope.
void kernel foo() {
static int X = 5; // expected-error{{variables in function scope cannot be declared static}}
diff --git a/test/SemaTemplate/attributes.cpp b/test/SemaTemplate/attributes.cpp
index 495f4a7ad3..5a06a706aa 100644
--- a/test/SemaTemplate/attributes.cpp
+++ b/test/SemaTemplate/attributes.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=gnu++11 -fsyntax-only -verify %s
namespace attribute_aligned {
template<int N>
@@ -18,6 +18,26 @@ namespace attribute_aligned {
check_alignment<2>::t c2;
check_alignment<3>::t c3; // expected-note 2 {{in instantiation}}
check_alignment<4>::t c4;
+
+ template<unsigned Size, unsigned Align>
+ class my_aligned_storage
+ {
+ __attribute__((align(Align))) char storage[Size];
+ };
+
+ template<typename T>
+ class C {
+ public:
+ C() {
+ static_assert(sizeof(t) == sizeof(T), "my_aligned_storage size wrong");
+ static_assert(alignof(t) == alignof(T), "my_aligned_storage align wrong"); // expected-warning{{'alignof' applied to an expression is a GNU extension}}
+ }
+
+ private:
+ my_aligned_storage<sizeof(T), alignof(T)> t;
+ };
+
+ C<double> cd;
}
namespace PR9049 {
diff --git a/test/SemaTemplate/dependent-names.cpp b/test/SemaTemplate/dependent-names.cpp
index eb75e69ef4..fa47ef5358 100644
--- a/test/SemaTemplate/dependent-names.cpp
+++ b/test/SemaTemplate/dependent-names.cpp
@@ -264,7 +264,7 @@ namespace PR10053 {
}
namespace PR10187 {
- namespace A {
+ namespace A1 {
template<typename T>
struct S {
void f() {
@@ -278,6 +278,25 @@ namespace PR10187 {
}
}
+ namespace A2 {
+ template<typename T>
+ struct S {
+ void f() {
+ for (auto &a : e)
+ __range(a); // expected-error {{undeclared identifier '__range'}}
+ }
+ T e[10];
+ };
+ void g() {
+ S<int>().f(); // expected-note {{here}}
+ }
+ struct X {};
+ void __range(X);
+ void h() {
+ S<X>().f();
+ }
+ }
+
namespace B {
template<typename T> void g(); // expected-note {{not viable}}
template<typename T> void f() {
diff --git a/test/SemaTemplate/derived.cpp b/test/SemaTemplate/derived.cpp
index 1fb9401c94..7b91f9a3ed 100644
--- a/test/SemaTemplate/derived.cpp
+++ b/test/SemaTemplate/derived.cpp
@@ -10,3 +10,21 @@ void test() {
Foo2(vector2<int*>()); // expected-error{{no matching function for call to 'Foo2'}}
Foo(vector<int*>()); // expected-error{{no matching function for call to 'Foo'}}
}
+
+namespace rdar13267210 {
+ template < typename T > class A {
+ BaseTy; // expected-error{{C++ requires a type specifier for all declarations}}
+ };
+
+ template < typename T, int N > class C: A < T > {};
+
+ class B {
+ C<long, 16> ExternalDefinitions;
+ C<long, 64> &Record;
+
+ void AddSourceLocation(A<long> &R); // expected-note{{passing argument to parameter 'R' here}}
+ void AddTemplateKWAndArgsInfo() {
+ AddSourceLocation(Record); // expected-error{{non-const lvalue reference to type}}
+ }
+ };
+}
diff --git a/test/SemaTemplate/example-dynarray.cpp b/test/SemaTemplate/example-dynarray.cpp
deleted file mode 100644
index 999521e91e..0000000000
--- a/test/SemaTemplate/example-dynarray.cpp
+++ /dev/null
@@ -1,177 +0,0 @@
-// RUN: %clangxx -emit-llvm -c -o - %s
-#include <stddef.h>
-#include <stdlib.h>
-#include <assert.h>
-
-// Placement new requires <new> to be included, but we don't support that yet.
-void* operator new(size_t, void* ptr) throw() {
- return ptr;
-}
-void operator delete(void*, void*) throw() {
-}
-
-template<typename T>
-class dynarray {
-public:
- dynarray() { Start = Last = End = 0; }
-
- dynarray(const dynarray &other) {
- Start = (T*)malloc(sizeof(T) * other.size());
- Last = End = Start + other.size();
-
- for (unsigned I = 0, N = other.size(); I != N; ++I)
- new (Start + I) T(other[I]);
- }
-
- ~dynarray() {
- for (unsigned I = 0, N = size(); I != N; ++I)
- Start[I].~T();
-
- free(Start);
- }
-
- dynarray &operator=(const dynarray &other) {
- T* NewStart = (T*)malloc(sizeof(T) * other.size());
-
- for (unsigned I = 0, N = other.size(); I != N; ++I)
- new (NewStart + I) T(other[I]);
-
- for (unsigned I = 0, N = size(); I != N; ++I)
- Start[I].~T();
-
- free(Start);
- Start = NewStart;
- Last = End = NewStart + other.size();
- return *this;
- }
-
- unsigned size() const { return Last - Start; }
- unsigned capacity() const { return End - Start; }
-
- void push_back(const T& value);
-
- void pop_back() {
- --Last;
- Last->~T();
- }
-
- T& operator[](unsigned Idx) {
- return Start[Idx];
- }
-
- const T& operator[](unsigned Idx) const {
- return Start[Idx];
- }
-
- typedef T* iterator;
- typedef const T* const_iterator;
-
- iterator begin() { return Start; }
- const_iterator begin() const { return Start; }
-
- iterator end() { return Last; }
- const_iterator end() const { return Last; }
-
- bool operator==(const dynarray &other) const {
- if (size() != other.size())
- return false;
-
- for (unsigned I = 0, N = size(); I != N; ++I)
- if ((*this)[I] != other[I])
- return false;
-
- return true;
- }
-
- bool operator!=(const dynarray &other) const {
- return !(*this == other);
- }
-
-public:
- T* Start, *Last, *End;
-};
-
-template<typename T>
-void dynarray<T>::push_back(const T& value) {
- if (Last == End) {
- unsigned NewCapacity = capacity() * 2;
- if (NewCapacity == 0)
- NewCapacity = 4;
-
- T* NewStart = (T*)malloc(sizeof(T) * NewCapacity);
-
- unsigned Size = size();
- for (unsigned I = 0; I != Size; ++I)
- new (NewStart + I) T(Start[I]);
-
- for (unsigned I = 0, N = size(); I != N; ++I)
- Start[I].~T();
- free(Start);
-
- Start = NewStart;
- Last = Start + Size;
- End = Start + NewCapacity;
- }
-
- new (Last) T(value);
- ++Last;
-}
-
-struct Point {
- Point() { x = y = z = 0.0; }
- Point(const Point& other) : x(other.x), y(other.y), z(other.z) { }
-
- float x, y, z;
-};
-
-int main() {
- dynarray<int> di;
- di.push_back(0);
- di.push_back(1);
- di.push_back(2);
- di.push_back(3);
- di.push_back(4);
- assert(di.size() == 5);
- for (dynarray<int>::iterator I = di.begin(), IEnd = di.end(); I != IEnd; ++I)
- assert(*I == I - di.begin());
-
- for (int I = 0, N = di.size(); I != N; ++I)
- assert(di[I] == I);
-
- di.pop_back();
- assert(di.size() == 4);
- di.push_back(4);
-
- dynarray<int> di2 = di;
- assert(di2.size() == 5);
- assert(di.begin() != di2.begin());
- for (dynarray<int>::iterator I = di2.begin(), IEnd = di2.end();
- I != IEnd; ++I)
- assert(*I == I - di2.begin());
-
- dynarray<int> di3(di);
- assert(di3.size() == 5);
- assert(di.begin() != di3.begin());
- for (dynarray<int>::iterator I = di3.begin(), IEnd = di3.end();
- I != IEnd; ++I)
- assert(*I == I - di3.begin());
-
- dynarray<int> di4;
- assert(di4.size() == 0);
- di4 = di;
- assert(di4.size() == 5);
- assert(di.begin() != di4.begin());
- for (dynarray<int>::iterator I = di4.begin(), IEnd = di4.end();
- I != IEnd; ++I)
- assert(*I == I - di4.begin());
-
- assert(di4 == di);
- di4[3] = 17;
- assert(di4 != di);
-
- dynarray<Point> dp;
- dp.push_back(Point());
- assert(dp.size() == 1);
-
- return 0;
-}
diff --git a/test/SemaTemplate/friend-template.cpp b/test/SemaTemplate/friend-template.cpp
index 9acbfdcea2..8a478777eb 100644
--- a/test/SemaTemplate/friend-template.cpp
+++ b/test/SemaTemplate/friend-template.cpp
@@ -302,3 +302,23 @@ namespace PR12585 {
H<int> h1; // ok
H<char> h2; // expected-note {{instantiation}}
}
+
+// Ensure that we can still instantiate a friend function template
+// after the friend declaration is instantiated during the delayed
+// parsing of a member function, but before the friend function has
+// been parsed.
+namespace rdar12350696 {
+ template <class T> struct A {
+ void foo() {
+ A<int> a;
+ }
+ template <class U> friend void foo(const A<U> & a) {
+ int array[sizeof(T) == sizeof(U) ? -1 : 1]; // expected-error {{negative size}}
+ }
+ };
+
+ void test() {
+ A<int> b;
+ foo(b); // expected-note {{in instantiation}}
+ }
+}
diff --git a/test/SemaTemplate/fun-template-def.cpp b/test/SemaTemplate/fun-template-def.cpp
index 0427781218..2d515b4b15 100644
--- a/test/SemaTemplate/fun-template-def.cpp
+++ b/test/SemaTemplate/fun-template-def.cpp
@@ -46,3 +46,11 @@ T f1(T t1, U u1, int i1)
return u1;
}
+
+template<typename T>
+void f2(__restrict T x) {} // expected-note {{substitution failure [with T = int]: restrict requires a pointer or reference ('int' is invalid}}
+
+void f3() {
+ f2<int*>(0);
+ f2<int>(0); // expected-error {{no matching function for call to 'f2'}}
+}
diff --git a/test/SemaTemplate/local-member-templates.cpp b/test/SemaTemplate/local-member-templates.cpp
new file mode 100644
index 0000000000..3cdf5df8d1
--- /dev/null
+++ b/test/SemaTemplate/local-member-templates.cpp
@@ -0,0 +1,76 @@
+// RUN: %clang_cc1 -std=c++1y -verify %s
+// RUN: %clang_cc1 -std=c++1y -verify %s -fdelayed-template-parsing
+
+namespace nested_local_templates_1 {
+
+template <class T> struct Outer {
+ template <class U> int outer_mem(T t, U u) {
+ struct Inner {
+ template <class V> int inner_mem(T t, U u, V v) {
+ struct InnerInner {
+ template <class W> int inner_inner_mem(W w, T t, U u, V v) {
+ return 0;
+ }
+ };
+ InnerInner().inner_inner_mem("abc", t, u, v);
+ return 0;
+ }
+ };
+ Inner i;
+ i.inner_mem(t, u, 3.14);
+ return 0;
+ }
+
+ template <class U> int outer_mem(T t, U *u);
+};
+
+template int Outer<int>::outer_mem(int, char);
+
+template <class T> template <class U> int Outer<T>::outer_mem(T t, U *u) {
+ struct Inner {
+ template <class V>
+ int inner_mem(T t, U u, V v) { //expected-note{{candidate function}}
+ struct InnerInner {
+ template <class W> int inner_inner_mem(W w, T t, U u, V v) { return 0; }
+ };
+ InnerInner().inner_inner_mem("abc", t, u, v);
+ return 0;
+ }
+ };
+ Inner i;
+ i.inner_mem(t, U{}, i);
+ i.inner_mem(t, u, 3.14); //expected-error{{no matching member function for call to 'inner}}
+ return 0;
+}
+
+template int Outer<int>::outer_mem(int, char *); //expected-note{{in instantiation of function}}
+
+} // end ns
+
+namespace nested_local_templates_2 {
+
+template <class T> struct Outer {
+ template <class U> void outer_mem(T t, U u) {
+ struct Inner {
+ template <class V> struct InnerTemplateClass {
+ template <class W>
+ void itc_mem(T t, U u, V v, W w) { //expected-note{{candidate function}}
+ struct InnerInnerInner {
+ template <class X> void iii_mem(X x) {}
+ };
+ InnerInnerInner i;
+ i.iii_mem("abc");
+ }
+ };
+ };
+ Inner i;
+ typename Inner::template InnerTemplateClass<Inner> ii;
+ ii.itc_mem(t, u, i, "jim");
+ ii.itc_mem(t, u, 0, "abd"); //expected-error{{no matching member function}}
+ }
+};
+
+template void
+Outer<int>::outer_mem(int, char); //expected-note{{in instantiation of}}
+
+}
diff --git a/test/SemaTemplate/ms-function-specialization-class-scope.cpp b/test/SemaTemplate/ms-function-specialization-class-scope.cpp
index 131922bbfb..9efb02ce5f 100644
--- a/test/SemaTemplate/ms-function-specialization-class-scope.cpp
+++ b/test/SemaTemplate/ms-function-specialization-class-scope.cpp
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -fms-extensions -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fms-extensions -fdelayed-template-parsing -fsyntax-only -verify %s
class A {
diff --git a/test/SemaTemplate/ms-lookup-template-base-classes.cpp b/test/SemaTemplate/ms-lookup-template-base-classes.cpp
index 8f80cb59e8..cb1a7f50b7 100644
--- a/test/SemaTemplate/ms-lookup-template-base-classes.cpp
+++ b/test/SemaTemplate/ms-lookup-template-base-classes.cpp
@@ -8,7 +8,6 @@ public:
void g();// expected-note {{must qualify identifier to find this declaration in dependent base class}}
};
-
template <class T>
class B : public A<T> {
public:
@@ -28,6 +27,31 @@ void test()
b.z(3);
}
+struct A2 {
+ template<class T> void f(T) {
+ XX; //expected-error {{use of undeclared identifier 'XX'}}
+ A2::XX; //expected-error {{no member named 'XX' in 'A2'}}
+ }
+};
+template void A2::f(int);
+
+template<class T0>
+struct A3 {
+ template<class T1> void f(T1) {
+ XX; //expected-error {{use of undeclared identifier 'XX'}}
+ }
+};
+template void A3<int>::f(int);
+
+template<class T0>
+struct A4 {
+ void f(char) {
+ XX; //expected-error {{use of undeclared identifier 'XX'}}
+ }
+};
+template class A4<int>;
+
+
namespace lookup_dependent_bases_id_expr {
template<class T> class A {
diff --git a/test/SemaTemplate/overload-candidates.cpp b/test/SemaTemplate/overload-candidates.cpp
index dc6d2a51ec..ad65397865 100644
--- a/test/SemaTemplate/overload-candidates.cpp
+++ b/test/SemaTemplate/overload-candidates.cpp
@@ -62,3 +62,20 @@ template<typename T> struct NonTemplateFunction {
typename boost::enable_if<sizeof(T) == 4, int>::type f(); // expected-error{{no type named 'type' in 'boost::enable_if<false, int>'; 'enable_if' cannot be used to disable this declaration}}
};
NonTemplateFunction<char> NTFC; // expected-note{{here}}
+
+namespace NS1 {
+ template <class A>
+ class array {};
+}
+
+namespace NS2 {
+ template <class A>
+ class array {};
+}
+
+template <class A>
+void foo(NS2::array<A>); // expected-note{{candidate template ignored: could not match 'NS2::array' against 'NS1::array'}}
+
+void test() {
+ foo(NS1::array<int>()); // expected-error{{no matching function for call to 'foo'}}
+}
diff --git a/test/SemaTemplate/temp_arg_nontype.cpp b/test/SemaTemplate/temp_arg_nontype.cpp
index 210b5e463f..24509524b2 100644
--- a/test/SemaTemplate/temp_arg_nontype.cpp
+++ b/test/SemaTemplate/temp_arg_nontype.cpp
@@ -337,3 +337,12 @@ namespace rdar13000548 {
}
}
+
+namespace rdar13806270 {
+ template <unsigned N> class X { };
+ const unsigned value = 32;
+ struct Y {
+ X<value + 1> x;
+ };
+ void foo() {}
+}
diff --git a/test/Tooling/auto-detect-from-source-parent-of-cwd.cpp b/test/Tooling/auto-detect-from-source-parent-of-cwd.cpp
index 9692edcd4f..6b632b0a0d 100644
--- a/test/Tooling/auto-detect-from-source-parent-of-cwd.cpp
+++ b/test/Tooling/auto-detect-from-source-parent-of-cwd.cpp
@@ -8,3 +8,5 @@
invalid;
// REQUIRES: shell
+// PR15590
+// XFAIL: win64
diff --git a/test/Tooling/auto-detect-from-source-parent.cpp b/test/Tooling/auto-detect-from-source-parent.cpp
index ea7eb158be..f1dbc0fa67 100644
--- a/test/Tooling/auto-detect-from-source-parent.cpp
+++ b/test/Tooling/auto-detect-from-source-parent.cpp
@@ -8,3 +8,5 @@
invalid;
// REQUIRES: shell
+// PR15590
+// XFAIL: win64
diff --git a/test/Tooling/auto-detect-from-source.cpp b/test/Tooling/auto-detect-from-source.cpp
index d8e82e7754..77e06e781c 100644
--- a/test/Tooling/auto-detect-from-source.cpp
+++ b/test/Tooling/auto-detect-from-source.cpp
@@ -8,3 +8,5 @@
invalid;
// REQUIRES: shell
+// PR15590
+// XFAIL: win64
diff --git a/test/Tooling/clang-check-args.cpp b/test/Tooling/clang-check-args.cpp
index 9ba5d45f50..66950ae103 100644
--- a/test/Tooling/clang-check-args.cpp
+++ b/test/Tooling/clang-check-args.cpp
@@ -2,6 +2,3 @@
// CHECK: C++ requires
invalid;
-
-// FIXME: This is incompatible to -fms-compatibility.
-// XFAIL: win32
diff --git a/test/Tooling/clang-check-autodetect-dir.cpp b/test/Tooling/clang-check-autodetect-dir.cpp
index 2c395043bf..39a0c386fe 100644
--- a/test/Tooling/clang-check-autodetect-dir.cpp
+++ b/test/Tooling/clang-check-autodetect-dir.cpp
@@ -9,3 +9,5 @@
invalid;
// REQUIRES: shell
+// PR15590
+// XFAIL: win64
diff --git a/test/Tooling/clang-check-builtin-headers.cpp b/test/Tooling/clang-check-builtin-headers.cpp
index 504d197ea9..ed2bea0d65 100644
--- a/test/Tooling/clang-check-builtin-headers.cpp
+++ b/test/Tooling/clang-check-builtin-headers.cpp
@@ -10,6 +10,3 @@
// CHECK: C++ requires
invalid;
-
-// FIXME: This is incompatible to -fms-compatibility.
-// XFAIL: win32
diff --git a/test/Tooling/clang-check-chdir.cpp b/test/Tooling/clang-check-chdir.cpp
index 29b5abb4c9..c8113233fa 100644
--- a/test/Tooling/clang-check-chdir.cpp
+++ b/test/Tooling/clang-check-chdir.cpp
@@ -12,6 +12,3 @@
// CHECK: C++ requires
invalid;
-
-// FIXME: This is incompatible to -fms-compatibility.
-// XFAIL: win32
diff --git a/test/Tooling/clang-check-pwd.cpp b/test/Tooling/clang-check-pwd.cpp
index 374c579245..463ed40b3e 100644
--- a/test/Tooling/clang-check-pwd.cpp
+++ b/test/Tooling/clang-check-pwd.cpp
@@ -9,3 +9,5 @@
invalid;
// REQUIRES: shell
+// PR15590
+// XFAIL: win64
diff --git a/test/Tooling/clang-check.cpp b/test/Tooling/clang-check.cpp
index 91ab01b01b..56835b3bf9 100644
--- a/test/Tooling/clang-check.cpp
+++ b/test/Tooling/clang-check.cpp
@@ -7,6 +7,3 @@
// CHECK: C++ requires
invalid;
-
-// FIXME: This is incompatible to -fms-compatibility.
-// XFAIL: win32
diff --git a/test/Tooling/multi-jobs.cpp b/test/Tooling/multi-jobs.cpp
index a3eb7039c0..1e6bce113f 100644
--- a/test/Tooling/multi-jobs.cpp
+++ b/test/Tooling/multi-jobs.cpp
@@ -2,6 +2,3 @@
// CHECK: C++ requires
invalid;
-
-// FIXME: This is incompatible to -fms-compatibility.
-// XFAIL: win32
diff --git a/test/Tooling/pch.cpp b/test/Tooling/pch.cpp
index 715c95dd55..40bc1e9731 100644
--- a/test/Tooling/pch.cpp
+++ b/test/Tooling/pch.cpp
@@ -6,12 +6,10 @@
// RUN: %clang -x c++-header %S/Inputs/pch.h -o %t1
// Use the generated pch and enforce a subsequent stat miss by using
-// the test file with an unrelated include as second translation unit:
-// Do not directly pipe into FileCheck, as that would hide errors from
-// valgrind due to pipefail not being set in lit.
-// RUN: clang-check "%S/Inputs/pch.cpp" "%s" -- -include-pch %t1 -I "%S" -c >%t2 2>&1
-// RUN: FileCheck %s < %t2
+// the test file with an unrelated include as second translation unit.
+// Test for an non-empty file after clang-check is executed.
+// RUN: clang-check -ast-dump "%S/Inputs/pch.cpp" "%s" -- -include-pch %t1 -I "%S" -c >%t2 2>&1
+// REQUIRES: shell
+// RUN: test -s %t2
#include "Inputs/pch-fail.h"
-
-// CHECK: Processing
diff --git a/test/Unit/lit.cfg b/test/Unit/lit.cfg
index 8f27781523..d58337c8f7 100644
--- a/test/Unit/lit.cfg
+++ b/test/Unit/lit.cfg
@@ -28,6 +28,11 @@ if 'TMP' in os.environ:
if 'TEMP' in os.environ:
config.environment['TEMP'] = os.environ['TEMP']
+# Propagate path to symbolizer for ASan/MSan.
+for symbolizer in ['ASAN_SYMBOLIZER_PATH', 'MSAN_SYMBOLIZER_PATH']:
+ if symbolizer in os.environ:
+ config.environment[symbolizer] = os.environ[symbolizer]
+
###
# Check that the object root is known.
diff --git a/test/lit.cfg b/test/lit.cfg
index f22b0376b4..6b0ad59c9f 100644
--- a/test/lit.cfg
+++ b/test/lit.cfg
@@ -24,12 +24,21 @@ if platform.system() == 'Windows':
config.environment['PATH']))
config.environment['PATH'] = path
+# Choose between lit's internal shell pipeline runner and a real shell. If
+# LIT_USE_INTERNAL_SHELL is in the environment, we use that as an override.
+use_lit_shell = os.environ.get("LIT_USE_INTERNAL_SHELL")
+if use_lit_shell:
+ # 0 is external, "" is default, and everything else is internal.
+ execute_external = (use_lit_shell == "0")
+else:
+ # Otherwise we default to internal on Windows and external elsewhere, as
+ # bash on Windows is usually very slow.
+ execute_external = (not sys.platform in ['win32'])
+
# testFormat: The test format to use to interpret tests.
#
# For now we require '&&' between commands, until they get globally killed and
# the test runner updated.
-execute_external = (platform.system() != 'Windows'
- or lit.getBashPath() not in [None, ""])
config.test_format = lit.formats.ShTest(execute_external)
# suffixes: A list of file extensions to treat as test files.
@@ -83,7 +92,6 @@ if clang_obj_root is not None:
lit.fatal('No LLVM tools dir set!')
path = os.path.pathsep.join((llvm_tools_dir, config.environment['PATH']))
config.environment['PATH'] = path
-
llvm_libs_dir = getattr(config, 'llvm_libs_dir', None)
if not llvm_libs_dir:
lit.fatal('No LLVM libs dir set!')
@@ -91,6 +99,11 @@ if clang_obj_root is not None:
config.environment.get('LD_LIBRARY_PATH','')))
config.environment['LD_LIBRARY_PATH'] = path
+# Propagate path to symbolizer for ASan/MSan.
+for symbolizer in ['ASAN_SYMBOLIZER_PATH', 'MSAN_SYMBOLIZER_PATH']:
+ if symbolizer in os.environ:
+ config.environment[symbolizer] = os.environ[symbolizer]
+
###
# Check that the object root is known.
@@ -215,17 +228,13 @@ if platform.system() not in ['FreeBSD']:
config.available_features.add('crash-recovery')
# Shell execution
-if platform.system() not in ['Windows'] or lit.getBashPath() != '':
+if execute_external:
config.available_features.add('shell')
# Exclude MSYS due to transforming '/' to 'X:/mingwroot/'.
if not platform.system() in ['Windows'] or lit.getBashPath() == '':
config.available_features.add('shell-preserves-root')
-# For tests that require Darwin to run.
-if platform.system() in ['Darwin']:
- config.available_features.add('system-darwin')
-
# ANSI escape sequences in non-dumb terminal
if platform.system() not in ['Windows']:
config.available_features.add('ansi-escape-sequences')
@@ -290,3 +299,9 @@ if llc_props['enable_assertions']:
if lit.util.which('xmllint'):
config.available_features.add('xmllint')
+# Sanitizers.
+if config.llvm_use_sanitizer == "Address":
+ config.available_features.add("asan")
+if (config.llvm_use_sanitizer == "Memory" or
+ config.llvm_use_sanitizer == "MemoryWithOrigins"):
+ config.available_features.add("msan")
diff --git a/test/lit.site.cfg.in b/test/lit.site.cfg.in
index df90b81055..23eb8e228c 100644
--- a/test/lit.site.cfg.in
+++ b/test/lit.site.cfg.in
@@ -7,6 +7,7 @@ config.llvm_libs_dir = "@LLVM_LIBS_DIR@"
config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@"
config.clang_obj_root = "@CLANG_BINARY_DIR@"
config.target_triple = "@TARGET_TRIPLE@"
+config.llvm_use_sanitizer = "@LLVM_USE_SANITIZER@"
# Support substitution of the tools and libs dirs with user parameters. This is
# used when we can't determine the tool dir at configuration time.