From 222e2a7620e6520ffaf4fc4e69d79c18da31542e Mon Sep 17 00:00:00 2001 From: "Zancanaro; Carlo" Date: Mon, 24 Sep 2012 09:58:17 +1000 Subject: Add the clang library to the repo (with some of my changes, too). --- clang/test/CodeGenCXX/2003-11-02-WeakLinkage.cpp | 13 + .../2003-11-18-PtrMemConstantInitializer.cpp | 13 + .../2003-11-27-MultipleInheritanceThunk.cpp | 28 + .../2003-11-29-DuplicatedCleanupTest.cpp | 41 + .../2003-12-08-ArrayOfPtrToMemberFunc.cpp | 12 + .../2004-01-11-DynamicInitializedConstant.cpp | 6 + .../CodeGenCXX/2004-03-08-ReinterpretCastCopy.cpp | 21 + .../2004-03-09-UnmangledBuiltinMethods.cpp | 8 + .../CodeGenCXX/2004-03-15-CleanupsAndGotos.cpp | 14 + .../2004-06-08-LateTemplateInstantiation.cpp | 18 + .../CodeGenCXX/2004-09-27-DidntEmitTemplate.cpp | 22 + .../2004-11-27-ExceptionCleanupAssertion.cpp | 14 + .../2004-11-27-FriendDefaultArgCrash.cpp | 9 + .../CodeGenCXX/2005-01-03-StaticInitializers.cpp | 8 + .../test/CodeGenCXX/2005-02-11-AnonymousUnion.cpp | 32 + .../test/CodeGenCXX/2005-02-13-BadDynamicInit.cpp | 9 + .../test/CodeGenCXX/2005-02-14-BitFieldOffset.cpp | 12 + .../CodeGenCXX/2005-02-19-BitfieldStructCrash.cpp | 14 + .../2005-02-19-UnnamedVirtualThunkArgument.cpp | 22 + .../CodeGenCXX/2005-02-20-BrokenReferenceTest.cpp | 10 + clang/test/CodeGenCXX/2006-03-01-GimplifyCrash.cpp | 14 + .../test/CodeGenCXX/2006-03-06-C++RecurseCrash.cpp | 23 + .../CodeGenCXX/2006-09-12-OpaqueStructCrash.cpp | 27 + clang/test/CodeGenCXX/2006-10-30-ClassBitfield.cpp | 16 + clang/test/CodeGenCXX/2006-11-20-GlobalSymbols.cpp | 11 + .../CodeGenCXX/2006-11-30-ConstantExprCrash.cpp | 21 + .../test/CodeGenCXX/2007-01-02-UnboundedArray.cpp | 14 + clang/test/CodeGenCXX/2007-01-06-PtrMethodInit.cpp | 75 + .../CodeGenCXX/2007-04-05-PackedBitFields-1.cpp | 22 + .../2007-04-05-PackedBitFieldsOverlap-2.cpp | 23 + .../2007-04-05-PackedBitFieldsOverlap.cpp | 23 + .../CodeGenCXX/2007-04-05-PackedBitFieldsSmall.cpp | 27 + .../2007-04-05-StructPackedFieldUnpacked.cpp | 24 + clang/test/CodeGenCXX/2007-04-10-PackedUnion.cpp | 41 + clang/test/CodeGenCXX/2007-04-14-FNoBuiltin.cpp | 8 + clang/test/CodeGenCXX/2007-05-03-VectorInit.cpp | 17 + .../test/CodeGenCXX/2007-07-29-RestrictPtrArg.cpp | 7 + .../test/CodeGenCXX/2007-07-29-RestrictRefArg.cpp | 7 + .../2007-09-10-RecursiveTypeResolution.cpp | 87 + clang/test/CodeGenCXX/2007-10-01-StructResize.cpp | 13 + clang/test/CodeGenCXX/2008-01-12-VecInit.cpp | 5 + clang/test/CodeGenCXX/2008-05-07-CrazyOffsetOf.cpp | 8 + clang/test/CodeGenCXX/2009-03-17-dbg.cpp | 15 + clang/test/CodeGenCXX/2009-04-23-bool2.cpp | 15 + .../CodeGenCXX/2009-05-04-PureConstNounwind.cpp | 15 + .../test/CodeGenCXX/2009-06-16-DebugInfoCrash.cpp | 10 + clang/test/CodeGenCXX/2009-07-16-Using.cpp | 8 + clang/test/CodeGenCXX/2009-08-05-ZeroInitWidth.cpp | 11 + clang/test/CodeGenCXX/2009-08-11-VectorRetTy.cpp | 13 + clang/test/CodeGenCXX/2009-09-09-packed-layout.cpp | 18 + clang/test/CodeGenCXX/2009-10-27-crash.cpp | 43 + clang/test/CodeGenCXX/2009-12-23-MissingSext.cpp | 16 + clang/test/CodeGenCXX/2010-03-09-AnonAggregate.cpp | 12 + clang/test/CodeGenCXX/2010-05-10-Var-DbgInfo.cpp | 42 + .../2010-05-11-alwaysinlineinstantiation.cpp | 33 + .../test/CodeGenCXX/2010-05-12-PtrToMember-Dbg.cpp | 17 + clang/test/CodeGenCXX/2010-06-21-LocalVarDbg.cpp | 14 + clang/test/CodeGenCXX/2010-06-22-BitfieldInit.cpp | 20 + clang/test/CodeGenCXX/2010-06-22-ZeroBitfield.cpp | 5 + clang/test/CodeGenCXX/2010-07-23-DeclLoc.cpp | 86 + .../test/CodeGenCXX/2011-12-19-init-list-ctor.cpp | 26 + .../CodeGenCXX/2012-02-06-VecInitialization.cpp | 8 + clang/test/CodeGenCXX/2012-03-16-StoreAlign.cpp | 36 + clang/test/CodeGenCXX/DynArrayInit.cpp | 15 + clang/test/CodeGenCXX/PR4827-cast.cpp | 5 + .../CodeGenCXX/PR4983-constructor-conversion.cpp | 16 + .../CodeGenCXX/PR5050-constructor-conversion.cpp | 19 + .../CodeGenCXX/PR5093-static-member-function.cpp | 9 + .../CodeGenCXX/PR5834-constructor-conversion.cpp | 14 + clang/test/CodeGenCXX/PR5863-unreachable-block.cpp | 13 + clang/test/CodeGenCXX/PR6474.cpp | 31 + clang/test/CodeGenCXX/__null.cpp | 9 + .../test/CodeGenCXX/abstract-class-ctors-dtors.cpp | 16 + clang/test/CodeGenCXX/address-of-fntemplate.cpp | 27 + clang/test/CodeGenCXX/alloca-align.cpp | 28 + clang/test/CodeGenCXX/anonymous-namespaces.cpp | 68 + .../anonymous-union-member-initializer.cpp | 181 ++ .../test/CodeGenCXX/apple-kext-guard-variable.cpp | 9 + clang/test/CodeGenCXX/apple-kext-indirect-call-2.C | 77 + clang/test/CodeGenCXX/apple-kext-indirect-call.C | 14 + .../apple-kext-indirect-virtual-dtor-call.cpp | 19 + clang/test/CodeGenCXX/apple-kext-linkage.C | 33 + .../CodeGenCXX/apple-kext-no-staticinit-section.C | 20 + clang/test/CodeGenCXX/apple-kext.cpp | 22 + clang/test/CodeGenCXX/arm-cc.cpp | 20 + clang/test/CodeGenCXX/arm.cpp | 369 +++++ clang/test/CodeGenCXX/array-construction.cpp | 37 + .../test/CodeGenCXX/array-operator-delete-call.cpp | 64 + clang/test/CodeGenCXX/array-pointer-decay.cpp | 7 + clang/test/CodeGenCXX/array-value-initialize.cpp | 52 + clang/test/CodeGenCXX/asm.cpp | 14 + clang/test/CodeGenCXX/assign-operator.cpp | 30 + clang/test/CodeGenCXX/atomic.cpp | 17 + clang/test/CodeGenCXX/atomicinit.cpp | 48 + clang/test/CodeGenCXX/attr-used.cpp | 9 + clang/test/CodeGenCXX/attr.cpp | 28 + clang/test/CodeGenCXX/bitfield-layout.cpp | 43 + clang/test/CodeGenCXX/block-byref-cxx-objc.cpp | 35 + clang/test/CodeGenCXX/block-destruct.cpp | 9 + clang/test/CodeGenCXX/block-in-ctor-dtor.cpp | 48 + clang/test/CodeGenCXX/block.cpp | 19 + clang/test/CodeGenCXX/blocks-cxx11.cpp | 84 + clang/test/CodeGenCXX/blocks.cpp | 228 +++ clang/test/CodeGenCXX/builtins.cpp | 21 + clang/test/CodeGenCXX/c-linkage.cpp | 13 + .../test/CodeGenCXX/c99-variable-length-array.cpp | 37 + clang/test/CodeGenCXX/call-arg-zero-temp.cpp | 23 + clang/test/CodeGenCXX/cast-conversion.cpp | 33 + clang/test/CodeGenCXX/casts.cpp | 20 + clang/test/CodeGenCXX/class-layout.cpp | 79 + clang/test/CodeGenCXX/compound-literals.cpp | 44 + clang/test/CodeGenCXX/condition.cpp | 317 ++++ clang/test/CodeGenCXX/conditional-expr-lvalue.cpp | 20 + clang/test/CodeGenCXX/conditional-gnu-ext.cpp | 150 ++ clang/test/CodeGenCXX/conditional-temporaries.cpp | 55 + clang/test/CodeGenCXX/const-base-cast.cpp | 10 + clang/test/CodeGenCXX/const-global-linkage.cpp | 13 + clang/test/CodeGenCXX/const-init-cxx11.cpp | 428 +++++ clang/test/CodeGenCXX/const-init.cpp | 78 + clang/test/CodeGenCXX/constructor-attr.cpp | 12 + clang/test/CodeGenCXX/constructor-conversion.cpp | 55 + clang/test/CodeGenCXX/constructor-convert.cpp | 20 + clang/test/CodeGenCXX/constructor-default-arg.cpp | 40 + clang/test/CodeGenCXX/constructor-direct-call.cpp | 60 + .../CodeGenCXX/constructor-for-array-members.cpp | 44 + .../test/CodeGenCXX/constructor-init-reference.cpp | 9 + clang/test/CodeGenCXX/constructor-init.cpp | 222 +++ clang/test/CodeGenCXX/constructor-template.cpp | 54 + clang/test/CodeGenCXX/constructors.cpp | 115 ++ clang/test/CodeGenCXX/conversion-function.cpp | 120 ++ clang/test/CodeGenCXX/conversion-operator-base.cpp | 7 + clang/test/CodeGenCXX/convert-to-fptr.cpp | 47 + clang/test/CodeGenCXX/copy-assign-synthesis-1.cpp | 109 ++ clang/test/CodeGenCXX/copy-assign-synthesis-2.cpp | 4 + clang/test/CodeGenCXX/copy-assign-synthesis-3.cpp | 24 + clang/test/CodeGenCXX/copy-assign-synthesis.cpp | 79 + .../CodeGenCXX/copy-assign-volatile-synthesis.cpp | 43 + clang/test/CodeGenCXX/copy-constructor-elim-2.cpp | 77 + clang/test/CodeGenCXX/copy-constructor-elim.cpp | 42 + .../CodeGenCXX/copy-constructor-synthesis-2.cpp | 7 + .../test/CodeGenCXX/copy-constructor-synthesis.cpp | 156 ++ clang/test/CodeGenCXX/copy-in-cplus-object.cpp | 28 + clang/test/CodeGenCXX/copy-initialization.cpp | 29 + clang/test/CodeGenCXX/cxx-apple-kext.cpp | 36 + clang/test/CodeGenCXX/cxx-block-objects.cpp | 33 + .../test/CodeGenCXX/cxx0x-defaulted-templates.cpp | 19 + clang/test/CodeGenCXX/cxx0x-delegating-ctors.cpp | 56 + clang/test/CodeGenCXX/cxx0x-initializer-array.cpp | 10 + .../CodeGenCXX/cxx0x-initializer-references.cpp | 69 + .../test/CodeGenCXX/cxx0x-initializer-scalars.cpp | 7 + ...xx0x-initializer-stdinitializerlist-pr12086.cpp | 37 + ...x0x-initializer-stdinitializerlist-startend.cpp | 85 + .../cxx0x-initializer-stdinitializerlist.cpp | 252 +++ clang/test/CodeGenCXX/cxx11-exception-spec.cpp | 120 ++ clang/test/CodeGenCXX/cxx11-unrestricted-union.cpp | 76 + .../test/CodeGenCXX/cxx11-user-defined-literal.cpp | 69 + .../test/CodeGenCXX/debug-info-artificial-arg.cpp | 30 + clang/test/CodeGenCXX/debug-info-byval.cpp | 31 + clang/test/CodeGenCXX/debug-info-char16.cpp | 6 + clang/test/CodeGenCXX/debug-info-class.cpp | 12 + clang/test/CodeGenCXX/debug-info-context.cpp | 17 + clang/test/CodeGenCXX/debug-info-ctor.cpp | 14 + clang/test/CodeGenCXX/debug-info-ctor2.cpp | 15 + clang/test/CodeGenCXX/debug-info-cxx0x.cpp | 8 + clang/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp | 24 + clang/test/CodeGenCXX/debug-info-enum.cpp | 8 + clang/test/CodeGenCXX/debug-info-fn-template.cpp | 15 + clang/test/CodeGenCXX/debug-info-friend.cpp | 11 + clang/test/CodeGenCXX/debug-info-fwd-ref.cpp | 26 + .../test/CodeGenCXX/debug-info-large-constant.cpp | 8 + clang/test/CodeGenCXX/debug-info-limit-type.cpp | 24 + clang/test/CodeGenCXX/debug-info-limit.cpp | 14 + clang/test/CodeGenCXX/debug-info-member.cpp | 6 + clang/test/CodeGenCXX/debug-info-method-spec.cpp | 10 + clang/test/CodeGenCXX/debug-info-method.cpp | 6 + clang/test/CodeGenCXX/debug-info-method2.cpp | 19 + clang/test/CodeGenCXX/debug-info-namespace.cpp | 12 + clang/test/CodeGenCXX/debug-info-nullptr.cpp | 7 + clang/test/CodeGenCXX/debug-info-pubtypes.cpp | 17 + clang/test/CodeGenCXX/debug-info-static-fns.cpp | 10 + .../test/CodeGenCXX/debug-info-template-limit.cpp | 15 + .../test/CodeGenCXX/debug-info-template-member.cpp | 21 + .../CodeGenCXX/debug-info-template-recursive.cpp | 13 + clang/test/CodeGenCXX/debug-info-template.cpp | 46 + clang/test/CodeGenCXX/debug-info-this.cpp | 15 + .../test/CodeGenCXX/debug-info-use-after-free.cpp | 312 ++++ clang/test/CodeGenCXX/debug-info-wchar.cpp | 5 + clang/test/CodeGenCXX/debug-info.cpp | 69 + clang/test/CodeGenCXX/debug-lambda-expressions.cpp | 71 + clang/test/CodeGenCXX/decl-ref-init.cpp | 31 + clang/test/CodeGenCXX/default-arg-temps.cpp | 73 + clang/test/CodeGenCXX/default-arguments.cpp | 76 + .../default-constructor-default-argument.cpp | 8 + .../CodeGenCXX/default-constructor-for-members.cpp | 24 + .../default-constructor-template-member.cpp | 10 + .../test/CodeGenCXX/default-destructor-nested.cpp | 13 + .../CodeGenCXX/default-destructor-synthesis.cpp | 36 + clang/test/CodeGenCXX/deferred-global-init.cpp | 16 + clang/test/CodeGenCXX/delete-two-arg.cpp | 70 + clang/test/CodeGenCXX/delete.cpp | 135 ++ .../CodeGenCXX/dependent-type-member-pointer.cpp | 18 + clang/test/CodeGenCXX/derived-to-base-conv.cpp | 85 + clang/test/CodeGenCXX/derived-to-base.cpp | 47 + .../derived-to-virtual-base-class-calls-final.cpp | 16 + clang/test/CodeGenCXX/destructor-calls.cpp | 41 + clang/test/CodeGenCXX/destructor-debug-info.cpp | 21 + clang/test/CodeGenCXX/destructors.cpp | 403 +++++ .../devirtualize-virtual-function-calls-final.cpp | 51 + .../devirtualize-virtual-function-calls.cpp | 55 + clang/test/CodeGenCXX/dynamic-cast-always-null.cpp | 19 + clang/test/CodeGenCXX/dynamic-cast.cpp | 18 + clang/test/CodeGenCXX/eh.cpp | 446 +++++ clang/test/CodeGenCXX/elide-call-reference.cpp | 11 + clang/test/CodeGenCXX/empty-classes.cpp | 82 + clang/test/CodeGenCXX/empty-union.cpp | 7 + clang/test/CodeGenCXX/enum.cpp | 4 + clang/test/CodeGenCXX/eval-recursive-constant.cpp | 5 + clang/test/CodeGenCXX/exceptions-no-rtti.cpp | 51 + clang/test/CodeGenCXX/exceptions.cpp | 416 +++++ clang/test/CodeGenCXX/explicit-instantiation.cpp | 45 + clang/test/CodeGenCXX/expr.cpp | 37 + clang/test/CodeGenCXX/extern-c.cpp | 16 + clang/test/CodeGenCXX/field-access-debug-info.cpp | 14 + clang/test/CodeGenCXX/for-range-temporaries.cpp | 146 ++ clang/test/CodeGenCXX/for-range.cpp | 128 ++ clang/test/CodeGenCXX/forward-enum.cpp | 11 + clang/test/CodeGenCXX/fp16-mangle.cpp | 12 + clang/test/CodeGenCXX/fp16-overload.cpp | 10 + clang/test/CodeGenCXX/friend-redecl.cpp | 18 + .../function-template-explicit-specialization.cpp | 13 + .../function-template-specialization.cpp | 26 + clang/test/CodeGenCXX/global-array-destruction.cpp | 34 + clang/test/CodeGenCXX/global-dtor-no-atexit.cpp | 44 + clang/test/CodeGenCXX/global-init-darwin.cpp | 23 + clang/test/CodeGenCXX/global-init.cpp | 122 ++ clang/test/CodeGenCXX/global-llvm-constant.cpp | 32 + clang/test/CodeGenCXX/goto.cpp | 43 + .../CodeGenCXX/implicit-copy-assign-operator.cpp | 56 + .../test/CodeGenCXX/implicit-copy-constructor.cpp | 82 + clang/test/CodeGenCXX/implicit-instantiation-1.cpp | 28 + .../incomplete-member-function-pointer.cpp | 10 + clang/test/CodeGenCXX/incomplete-types.cpp | 43 + clang/test/CodeGenCXX/inheriting-constructor.cpp | 11 + clang/test/CodeGenCXX/init-invariant.cpp | 60 + clang/test/CodeGenCXX/inline-functions.cpp | 55 + clang/test/CodeGenCXX/instantiate-blocks.cpp | 59 + clang/test/CodeGenCXX/instantiate-init-list.cpp | 13 + clang/test/CodeGenCXX/instantiate-temporaries.cpp | 37 + clang/test/CodeGenCXX/instrument-functions.cpp | 30 + clang/test/CodeGenCXX/internal-linkage.cpp | 64 + clang/test/CodeGenCXX/key-function-vtable.cpp | 52 + clang/test/CodeGenCXX/lambda-expressions.cpp | 78 + clang/test/CodeGenCXX/lvalue-bitcasts.cpp | 163 ++ clang/test/CodeGenCXX/m64-ptr.cpp | 18 + clang/test/CodeGenCXX/mangle-98.cpp | 12 + clang/test/CodeGenCXX/mangle-abi-examples.cpp | 27 + clang/test/CodeGenCXX/mangle-address-space.cpp | 12 + clang/test/CodeGenCXX/mangle-alias-template.cpp | 48 + clang/test/CodeGenCXX/mangle-exprs.cpp | 193 +++ clang/test/CodeGenCXX/mangle-extern-local.cpp | 45 + clang/test/CodeGenCXX/mangle-extreme.cpp | 47 + clang/test/CodeGenCXX/mangle-lambdas.cpp | 202 +++ clang/test/CodeGenCXX/mangle-local-class-names.cpp | 57 + .../test/CodeGenCXX/mangle-local-class-vtables.cpp | 61 + .../CodeGenCXX/mangle-local-classes-nested.cpp | 81 + clang/test/CodeGenCXX/mangle-ms.cpp | 105 ++ clang/test/CodeGenCXX/mangle-neon-vectors.cpp | 32 + clang/test/CodeGenCXX/mangle-nullptr-arg.cpp | 13 + clang/test/CodeGenCXX/mangle-ref-qualifiers.cpp | 16 + clang/test/CodeGenCXX/mangle-std-externc.cpp | 27 + clang/test/CodeGenCXX/mangle-subst-std.cpp | 112 ++ clang/test/CodeGenCXX/mangle-subst.cpp | 82 + clang/test/CodeGenCXX/mangle-system-header.cpp | 11 + clang/test/CodeGenCXX/mangle-template.cpp | 172 ++ clang/test/CodeGenCXX/mangle-this-cxx11.cpp | 20 + .../CodeGenCXX/mangle-unnameable-conversions.cpp | 14 + clang/test/CodeGenCXX/mangle-unnamed.cpp | 92 ++ .../test/CodeGenCXX/mangle-variadic-templates.cpp | 67 + clang/test/CodeGenCXX/mangle.cpp | 854 ++++++++++ clang/test/CodeGenCXX/member-alignment.cpp | 20 + clang/test/CodeGenCXX/member-call-parens.cpp | 12 + clang/test/CodeGenCXX/member-expressions.cpp | 86 + .../CodeGenCXX/member-function-pointer-calls.cpp | 23 + clang/test/CodeGenCXX/member-function-pointers.cpp | 274 ++++ clang/test/CodeGenCXX/member-functions.cpp | 63 + clang/test/CodeGenCXX/member-init-anon-union.cpp | 35 + clang/test/CodeGenCXX/member-init-assignment.cpp | 17 + clang/test/CodeGenCXX/member-init-ctor.cpp | 14 + clang/test/CodeGenCXX/member-init-struct.cpp | 18 + clang/test/CodeGenCXX/member-init-union.cpp | 10 + clang/test/CodeGenCXX/member-initializers.cpp | 34 + .../CodeGenCXX/member-pointer-type-convert.cpp | 11 + clang/test/CodeGenCXX/member-templates.cpp | 31 + clang/test/CodeGenCXX/multi-dim-operator-new.cpp | 49 + clang/test/CodeGenCXX/namespace-aliases.cpp | 9 + .../test/CodeGenCXX/nested-base-member-access.cpp | 52 + .../test/CodeGenCXX/new-array-init-exceptions.cpp | 41 + clang/test/CodeGenCXX/new-array-init.cpp | 33 + clang/test/CodeGenCXX/new-operator-phi.cpp | 11 + clang/test/CodeGenCXX/new-overflow.cpp | 209 +++ clang/test/CodeGenCXX/new-with-default-arg.cpp | 33 + clang/test/CodeGenCXX/new.cpp | 252 +++ clang/test/CodeGenCXX/no-exceptions.cpp | 12 + clang/test/CodeGenCXX/noinline-template.cpp | 16 + clang/test/CodeGenCXX/nonconst-init.cpp | 5 + clang/test/CodeGenCXX/nrvo-noreturn.cc | 17 + clang/test/CodeGenCXX/nrvo.cpp | 161 ++ clang/test/CodeGenCXX/nullptr.cpp | 24 + clang/test/CodeGenCXX/operator-new.cpp | 29 + .../CodeGenCXX/overload-binop-implicitconvert.cpp | 22 + clang/test/CodeGenCXX/override-layout.cpp | 64 + clang/test/CodeGenCXX/partial-destruction.cpp | 172 ++ clang/test/CodeGenCXX/pointers-to-data-members.cpp | 242 +++ clang/test/CodeGenCXX/pr11676.cpp | 17 + clang/test/CodeGenCXX/pr11797.cpp | 8 + clang/test/CodeGenCXX/pr12104.cpp | 7 + clang/test/CodeGenCXX/pr12104.h | 9 + clang/test/CodeGenCXX/pr12251.cpp | 146 ++ clang/test/CodeGenCXX/pr9130.cpp | 14 + clang/test/CodeGenCXX/pr9965.cpp | 14 + clang/test/CodeGenCXX/pragma-pack-2.cpp | 17 + clang/test/CodeGenCXX/pragma-pack.cpp | 16 + clang/test/CodeGenCXX/pragma-visibility.cpp | 62 + clang/test/CodeGenCXX/predefined-expr-sizeof.cpp | 30 + clang/test/CodeGenCXX/predefined-expr.cpp | 517 ++++++ clang/test/CodeGenCXX/ptr-to-datamember.cpp | 99 ++ clang/test/CodeGenCXX/ptr-to-member-function.cpp | 71 + .../CodeGenCXX/reference-bind-default-argument.cpp | 6 + clang/test/CodeGenCXX/reference-cast.cpp | 194 +++ clang/test/CodeGenCXX/reference-field.cpp | 6 + clang/test/CodeGenCXX/reference-in-block-args.cpp | 29 + clang/test/CodeGenCXX/reference-in-blocks.cpp | 43 + clang/test/CodeGenCXX/reference-init.cpp | 24 + clang/test/CodeGenCXX/references.cpp | 313 ++++ clang/test/CodeGenCXX/regparm.cpp | 6 + clang/test/CodeGenCXX/reinterpret-cast.cpp | 17 + clang/test/CodeGenCXX/rtti-fundamental.cpp | 116 ++ clang/test/CodeGenCXX/rtti-layout.cpp | 205 +++ clang/test/CodeGenCXX/rtti-linkage.cpp | 140 ++ clang/test/CodeGenCXX/rtti-visibility.cpp | 35 + clang/test/CodeGenCXX/rvalue-references.cpp | 111 ++ clang/test/CodeGenCXX/scoped-enums.cpp | 9 + clang/test/CodeGenCXX/sel-address.mm | 14 + clang/test/CodeGenCXX/sizeof-unwind-exception.cpp | 28 + .../skip-vtable-pointer-initialization.cpp | 200 +++ .../specialized-static-data-mem-init.cpp | 29 + clang/test/CodeGenCXX/static-assert.cpp | 7 + clang/test/CodeGenCXX/static-data-member.cpp | 104 ++ clang/test/CodeGenCXX/static-init-1.cpp | 23 + clang/test/CodeGenCXX/static-init-2.cpp | 6 + clang/test/CodeGenCXX/static-init-3.cpp | 28 + clang/test/CodeGenCXX/static-init.cpp | 154 ++ .../CodeGenCXX/static-local-in-local-class.cpp | 33 + ...tic-member-variable-explicit-specialization.cpp | 11 + clang/test/CodeGenCXX/static-mutable.cpp | 12 + clang/test/CodeGenCXX/stmtexpr.cpp | 75 + clang/test/CodeGenCXX/switch-case-folding-1.cpp | 22 + clang/test/CodeGenCXX/switch-case-folding-2.cpp | 21 + clang/test/CodeGenCXX/switch-case-folding.cpp | 18 + clang/test/CodeGenCXX/temp-order.cpp | 226 +++ clang/test/CodeGenCXX/template-anonymous-types.cpp | 37 + ...template-anonymous-union-member-initializer.cpp | 11 + .../template-dependent-bind-temporary.cpp | 24 + .../template-inner-struct-visibility-hidden.cpp | 24 + clang/test/CodeGenCXX/template-instantiation.cpp | 190 +++ clang/test/CodeGenCXX/template-linkage.cpp | 44 + .../test/CodeGenCXX/template-static-var-defer.cpp | 12 + clang/test/CodeGenCXX/temporaries.cpp | 539 ++++++ clang/test/CodeGenCXX/thiscall-struct-return.cpp | 41 + .../CodeGenCXX/threadsafe-statics-exceptions.cpp | 28 + clang/test/CodeGenCXX/threadsafe-statics.cpp | 23 + clang/test/CodeGenCXX/throw-expression-dtor.cpp | 13 + clang/test/CodeGenCXX/throw-expressions.cpp | 20 + clang/test/CodeGenCXX/thunk-linkonce-odr.cpp | 33 + clang/test/CodeGenCXX/thunk-use-after-free.cpp | 42 + .../CodeGenCXX/thunks-available-externally.cpp | 88 + clang/test/CodeGenCXX/thunks.cpp | 308 ++++ clang/test/CodeGenCXX/trivial-constructor-init.cpp | 20 + clang/test/CodeGenCXX/try-catch.cpp | 13 + clang/test/CodeGenCXX/typeid-cxx11.cpp | 30 + clang/test/CodeGenCXX/typeid.cpp | 44 + clang/test/CodeGenCXX/typeinfo | 16 + clang/test/CodeGenCXX/unary-type-trait.cpp | 3 + clang/test/CodeGenCXX/uncode-string.cpp | 6 + clang/test/CodeGenCXX/union-dtor.cpp | 42 + clang/test/CodeGenCXX/unknown-anytype.cpp | 99 ++ clang/test/CodeGenCXX/value-init.cpp | 262 +++ clang/test/CodeGenCXX/vararg-conversion-ctor.cpp | 23 + clang/test/CodeGenCXX/vararg-non-pod.cpp | 16 + clang/test/CodeGenCXX/varargs.cpp | 43 + clang/test/CodeGenCXX/variadic-templates.cpp | 23 + clang/test/CodeGenCXX/virt-call-offsets.cpp | 8 + clang/test/CodeGenCXX/virt-canonical-decl.cpp | 19 + clang/test/CodeGenCXX/virt-dtor-gen.cpp | 10 + clang/test/CodeGenCXX/virt-dtor-key.cpp | 9 + clang/test/CodeGenCXX/virt-template-vtable.cpp | 22 + clang/test/CodeGenCXX/virt-thunk-reference.cpp | 7 + clang/test/CodeGenCXX/virtual-base-cast.cpp | 33 + clang/test/CodeGenCXX/virtual-base-ctor.cpp | 11 + .../CodeGenCXX/virtual-base-destructor-call.cpp | 51 + clang/test/CodeGenCXX/virtual-bases.cpp | 48 + clang/test/CodeGenCXX/virtual-destructor-calls.cpp | 48 + .../CodeGenCXX/virtual-destructor-synthesis.cpp | 16 + clang/test/CodeGenCXX/virtual-function-calls.cpp | 38 + .../virtual-functions-incomplete-types.cpp | 30 + .../virtual-implicit-copy-assignment.cpp | 11 + .../virtual-implicit-move-assignment.cpp | 12 + .../CodeGenCXX/virtual-inherited-destructor.cpp | 8 + clang/test/CodeGenCXX/virtual-operator-call.cpp | 10 + .../CodeGenCXX/virtual-pseudo-destructor-call.cpp | 14 + .../visibility-hidden-extern-templates.cpp | 26 + .../test/CodeGenCXX/visibility-inlines-hidden.cpp | 110 ++ clang/test/CodeGenCXX/visibility.cpp | 607 +++++++ clang/test/CodeGenCXX/vla.cpp | 56 + clang/test/CodeGenCXX/volatile-1.cpp | 352 ++++ clang/test/CodeGenCXX/volatile.cpp | 33 + .../CodeGenCXX/vtable-available-externally.cpp | 171 ++ clang/test/CodeGenCXX/vtable-cast-crash.cpp | 21 + clang/test/CodeGenCXX/vtable-debug-info.cpp | 319 ++++ clang/test/CodeGenCXX/vtable-key-function.cpp | 33 + .../test/CodeGenCXX/vtable-layout-abi-examples.cpp | 322 ++++ clang/test/CodeGenCXX/vtable-layout-extreme.cpp | 210 +++ clang/test/CodeGenCXX/vtable-layout.cpp | 1729 ++++++++++++++++++++ clang/test/CodeGenCXX/vtable-linkage.cpp | 216 +++ .../CodeGenCXX/vtable-pointer-initialization.cpp | 57 + clang/test/CodeGenCXX/vtt-layout.cpp | 64 + clang/test/CodeGenCXX/warn-padded-packed.cpp | 76 + clang/test/CodeGenCXX/weak-extern-typeinfo.cpp | 47 + clang/test/CodeGenCXX/weak-external.cpp | 66 + clang/test/CodeGenCXX/x86_32-arguments.cpp | 116 ++ clang/test/CodeGenCXX/x86_64-arguments.cpp | 183 +++ 431 files changed, 26690 insertions(+) create mode 100644 clang/test/CodeGenCXX/2003-11-02-WeakLinkage.cpp create mode 100644 clang/test/CodeGenCXX/2003-11-18-PtrMemConstantInitializer.cpp create mode 100644 clang/test/CodeGenCXX/2003-11-27-MultipleInheritanceThunk.cpp create mode 100644 clang/test/CodeGenCXX/2003-11-29-DuplicatedCleanupTest.cpp create mode 100644 clang/test/CodeGenCXX/2003-12-08-ArrayOfPtrToMemberFunc.cpp create mode 100644 clang/test/CodeGenCXX/2004-01-11-DynamicInitializedConstant.cpp create mode 100644 clang/test/CodeGenCXX/2004-03-08-ReinterpretCastCopy.cpp create mode 100644 clang/test/CodeGenCXX/2004-03-09-UnmangledBuiltinMethods.cpp create mode 100644 clang/test/CodeGenCXX/2004-03-15-CleanupsAndGotos.cpp create mode 100644 clang/test/CodeGenCXX/2004-06-08-LateTemplateInstantiation.cpp create mode 100644 clang/test/CodeGenCXX/2004-09-27-DidntEmitTemplate.cpp create mode 100644 clang/test/CodeGenCXX/2004-11-27-ExceptionCleanupAssertion.cpp create mode 100644 clang/test/CodeGenCXX/2004-11-27-FriendDefaultArgCrash.cpp create mode 100644 clang/test/CodeGenCXX/2005-01-03-StaticInitializers.cpp create mode 100644 clang/test/CodeGenCXX/2005-02-11-AnonymousUnion.cpp create mode 100644 clang/test/CodeGenCXX/2005-02-13-BadDynamicInit.cpp create mode 100644 clang/test/CodeGenCXX/2005-02-14-BitFieldOffset.cpp create mode 100644 clang/test/CodeGenCXX/2005-02-19-BitfieldStructCrash.cpp create mode 100644 clang/test/CodeGenCXX/2005-02-19-UnnamedVirtualThunkArgument.cpp create mode 100644 clang/test/CodeGenCXX/2005-02-20-BrokenReferenceTest.cpp create mode 100644 clang/test/CodeGenCXX/2006-03-01-GimplifyCrash.cpp create mode 100644 clang/test/CodeGenCXX/2006-03-06-C++RecurseCrash.cpp create mode 100644 clang/test/CodeGenCXX/2006-09-12-OpaqueStructCrash.cpp create mode 100644 clang/test/CodeGenCXX/2006-10-30-ClassBitfield.cpp create mode 100644 clang/test/CodeGenCXX/2006-11-20-GlobalSymbols.cpp create mode 100644 clang/test/CodeGenCXX/2006-11-30-ConstantExprCrash.cpp create mode 100644 clang/test/CodeGenCXX/2007-01-02-UnboundedArray.cpp create mode 100644 clang/test/CodeGenCXX/2007-01-06-PtrMethodInit.cpp create mode 100644 clang/test/CodeGenCXX/2007-04-05-PackedBitFields-1.cpp create mode 100644 clang/test/CodeGenCXX/2007-04-05-PackedBitFieldsOverlap-2.cpp create mode 100644 clang/test/CodeGenCXX/2007-04-05-PackedBitFieldsOverlap.cpp create mode 100644 clang/test/CodeGenCXX/2007-04-05-PackedBitFieldsSmall.cpp create mode 100644 clang/test/CodeGenCXX/2007-04-05-StructPackedFieldUnpacked.cpp create mode 100644 clang/test/CodeGenCXX/2007-04-10-PackedUnion.cpp create mode 100644 clang/test/CodeGenCXX/2007-04-14-FNoBuiltin.cpp create mode 100644 clang/test/CodeGenCXX/2007-05-03-VectorInit.cpp create mode 100644 clang/test/CodeGenCXX/2007-07-29-RestrictPtrArg.cpp create mode 100644 clang/test/CodeGenCXX/2007-07-29-RestrictRefArg.cpp create mode 100644 clang/test/CodeGenCXX/2007-09-10-RecursiveTypeResolution.cpp create mode 100644 clang/test/CodeGenCXX/2007-10-01-StructResize.cpp create mode 100644 clang/test/CodeGenCXX/2008-01-12-VecInit.cpp create mode 100644 clang/test/CodeGenCXX/2008-05-07-CrazyOffsetOf.cpp create mode 100644 clang/test/CodeGenCXX/2009-03-17-dbg.cpp create mode 100644 clang/test/CodeGenCXX/2009-04-23-bool2.cpp create mode 100644 clang/test/CodeGenCXX/2009-05-04-PureConstNounwind.cpp create mode 100644 clang/test/CodeGenCXX/2009-06-16-DebugInfoCrash.cpp create mode 100644 clang/test/CodeGenCXX/2009-07-16-Using.cpp create mode 100644 clang/test/CodeGenCXX/2009-08-05-ZeroInitWidth.cpp create mode 100644 clang/test/CodeGenCXX/2009-08-11-VectorRetTy.cpp create mode 100644 clang/test/CodeGenCXX/2009-09-09-packed-layout.cpp create mode 100644 clang/test/CodeGenCXX/2009-10-27-crash.cpp create mode 100644 clang/test/CodeGenCXX/2009-12-23-MissingSext.cpp create mode 100644 clang/test/CodeGenCXX/2010-03-09-AnonAggregate.cpp create mode 100644 clang/test/CodeGenCXX/2010-05-10-Var-DbgInfo.cpp create mode 100644 clang/test/CodeGenCXX/2010-05-11-alwaysinlineinstantiation.cpp create mode 100644 clang/test/CodeGenCXX/2010-05-12-PtrToMember-Dbg.cpp create mode 100644 clang/test/CodeGenCXX/2010-06-21-LocalVarDbg.cpp create mode 100644 clang/test/CodeGenCXX/2010-06-22-BitfieldInit.cpp create mode 100644 clang/test/CodeGenCXX/2010-06-22-ZeroBitfield.cpp create mode 100644 clang/test/CodeGenCXX/2010-07-23-DeclLoc.cpp create mode 100644 clang/test/CodeGenCXX/2011-12-19-init-list-ctor.cpp create mode 100644 clang/test/CodeGenCXX/2012-02-06-VecInitialization.cpp create mode 100644 clang/test/CodeGenCXX/2012-03-16-StoreAlign.cpp create mode 100644 clang/test/CodeGenCXX/DynArrayInit.cpp create mode 100644 clang/test/CodeGenCXX/PR4827-cast.cpp create mode 100644 clang/test/CodeGenCXX/PR4983-constructor-conversion.cpp create mode 100644 clang/test/CodeGenCXX/PR5050-constructor-conversion.cpp create mode 100644 clang/test/CodeGenCXX/PR5093-static-member-function.cpp create mode 100644 clang/test/CodeGenCXX/PR5834-constructor-conversion.cpp create mode 100644 clang/test/CodeGenCXX/PR5863-unreachable-block.cpp create mode 100644 clang/test/CodeGenCXX/PR6474.cpp create mode 100644 clang/test/CodeGenCXX/__null.cpp create mode 100644 clang/test/CodeGenCXX/abstract-class-ctors-dtors.cpp create mode 100644 clang/test/CodeGenCXX/address-of-fntemplate.cpp create mode 100644 clang/test/CodeGenCXX/alloca-align.cpp create mode 100644 clang/test/CodeGenCXX/anonymous-namespaces.cpp create mode 100644 clang/test/CodeGenCXX/anonymous-union-member-initializer.cpp create mode 100644 clang/test/CodeGenCXX/apple-kext-guard-variable.cpp create mode 100644 clang/test/CodeGenCXX/apple-kext-indirect-call-2.C create mode 100644 clang/test/CodeGenCXX/apple-kext-indirect-call.C create mode 100644 clang/test/CodeGenCXX/apple-kext-indirect-virtual-dtor-call.cpp create mode 100644 clang/test/CodeGenCXX/apple-kext-linkage.C create mode 100644 clang/test/CodeGenCXX/apple-kext-no-staticinit-section.C create mode 100644 clang/test/CodeGenCXX/apple-kext.cpp create mode 100644 clang/test/CodeGenCXX/arm-cc.cpp create mode 100644 clang/test/CodeGenCXX/arm.cpp create mode 100644 clang/test/CodeGenCXX/array-construction.cpp create mode 100644 clang/test/CodeGenCXX/array-operator-delete-call.cpp create mode 100644 clang/test/CodeGenCXX/array-pointer-decay.cpp create mode 100644 clang/test/CodeGenCXX/array-value-initialize.cpp create mode 100644 clang/test/CodeGenCXX/asm.cpp create mode 100644 clang/test/CodeGenCXX/assign-operator.cpp create mode 100644 clang/test/CodeGenCXX/atomic.cpp create mode 100644 clang/test/CodeGenCXX/atomicinit.cpp create mode 100644 clang/test/CodeGenCXX/attr-used.cpp create mode 100644 clang/test/CodeGenCXX/attr.cpp create mode 100644 clang/test/CodeGenCXX/bitfield-layout.cpp create mode 100644 clang/test/CodeGenCXX/block-byref-cxx-objc.cpp create mode 100644 clang/test/CodeGenCXX/block-destruct.cpp create mode 100644 clang/test/CodeGenCXX/block-in-ctor-dtor.cpp create mode 100644 clang/test/CodeGenCXX/block.cpp create mode 100644 clang/test/CodeGenCXX/blocks-cxx11.cpp create mode 100644 clang/test/CodeGenCXX/blocks.cpp create mode 100644 clang/test/CodeGenCXX/builtins.cpp create mode 100644 clang/test/CodeGenCXX/c-linkage.cpp create mode 100644 clang/test/CodeGenCXX/c99-variable-length-array.cpp create mode 100644 clang/test/CodeGenCXX/call-arg-zero-temp.cpp create mode 100644 clang/test/CodeGenCXX/cast-conversion.cpp create mode 100644 clang/test/CodeGenCXX/casts.cpp create mode 100644 clang/test/CodeGenCXX/class-layout.cpp create mode 100644 clang/test/CodeGenCXX/compound-literals.cpp create mode 100644 clang/test/CodeGenCXX/condition.cpp create mode 100644 clang/test/CodeGenCXX/conditional-expr-lvalue.cpp create mode 100644 clang/test/CodeGenCXX/conditional-gnu-ext.cpp create mode 100644 clang/test/CodeGenCXX/conditional-temporaries.cpp create mode 100644 clang/test/CodeGenCXX/const-base-cast.cpp create mode 100644 clang/test/CodeGenCXX/const-global-linkage.cpp create mode 100644 clang/test/CodeGenCXX/const-init-cxx11.cpp create mode 100644 clang/test/CodeGenCXX/const-init.cpp create mode 100644 clang/test/CodeGenCXX/constructor-attr.cpp create mode 100644 clang/test/CodeGenCXX/constructor-conversion.cpp create mode 100644 clang/test/CodeGenCXX/constructor-convert.cpp create mode 100644 clang/test/CodeGenCXX/constructor-default-arg.cpp create mode 100644 clang/test/CodeGenCXX/constructor-direct-call.cpp create mode 100644 clang/test/CodeGenCXX/constructor-for-array-members.cpp create mode 100644 clang/test/CodeGenCXX/constructor-init-reference.cpp create mode 100644 clang/test/CodeGenCXX/constructor-init.cpp create mode 100644 clang/test/CodeGenCXX/constructor-template.cpp create mode 100644 clang/test/CodeGenCXX/constructors.cpp create mode 100644 clang/test/CodeGenCXX/conversion-function.cpp create mode 100644 clang/test/CodeGenCXX/conversion-operator-base.cpp create mode 100644 clang/test/CodeGenCXX/convert-to-fptr.cpp create mode 100644 clang/test/CodeGenCXX/copy-assign-synthesis-1.cpp create mode 100644 clang/test/CodeGenCXX/copy-assign-synthesis-2.cpp create mode 100644 clang/test/CodeGenCXX/copy-assign-synthesis-3.cpp create mode 100644 clang/test/CodeGenCXX/copy-assign-synthesis.cpp create mode 100644 clang/test/CodeGenCXX/copy-assign-volatile-synthesis.cpp create mode 100644 clang/test/CodeGenCXX/copy-constructor-elim-2.cpp create mode 100644 clang/test/CodeGenCXX/copy-constructor-elim.cpp create mode 100644 clang/test/CodeGenCXX/copy-constructor-synthesis-2.cpp create mode 100644 clang/test/CodeGenCXX/copy-constructor-synthesis.cpp create mode 100644 clang/test/CodeGenCXX/copy-in-cplus-object.cpp create mode 100644 clang/test/CodeGenCXX/copy-initialization.cpp create mode 100644 clang/test/CodeGenCXX/cxx-apple-kext.cpp create mode 100644 clang/test/CodeGenCXX/cxx-block-objects.cpp create mode 100644 clang/test/CodeGenCXX/cxx0x-defaulted-templates.cpp create mode 100644 clang/test/CodeGenCXX/cxx0x-delegating-ctors.cpp create mode 100644 clang/test/CodeGenCXX/cxx0x-initializer-array.cpp create mode 100644 clang/test/CodeGenCXX/cxx0x-initializer-references.cpp create mode 100644 clang/test/CodeGenCXX/cxx0x-initializer-scalars.cpp create mode 100644 clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-pr12086.cpp create mode 100644 clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-startend.cpp create mode 100644 clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp create mode 100644 clang/test/CodeGenCXX/cxx11-exception-spec.cpp create mode 100644 clang/test/CodeGenCXX/cxx11-unrestricted-union.cpp create mode 100644 clang/test/CodeGenCXX/cxx11-user-defined-literal.cpp create mode 100644 clang/test/CodeGenCXX/debug-info-artificial-arg.cpp create mode 100644 clang/test/CodeGenCXX/debug-info-byval.cpp create mode 100644 clang/test/CodeGenCXX/debug-info-char16.cpp create mode 100644 clang/test/CodeGenCXX/debug-info-class.cpp create mode 100644 clang/test/CodeGenCXX/debug-info-context.cpp create mode 100644 clang/test/CodeGenCXX/debug-info-ctor.cpp create mode 100644 clang/test/CodeGenCXX/debug-info-ctor2.cpp create mode 100644 clang/test/CodeGenCXX/debug-info-cxx0x.cpp create mode 100644 clang/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp create mode 100644 clang/test/CodeGenCXX/debug-info-enum.cpp create mode 100644 clang/test/CodeGenCXX/debug-info-fn-template.cpp create mode 100644 clang/test/CodeGenCXX/debug-info-friend.cpp create mode 100644 clang/test/CodeGenCXX/debug-info-fwd-ref.cpp create mode 100644 clang/test/CodeGenCXX/debug-info-large-constant.cpp create mode 100644 clang/test/CodeGenCXX/debug-info-limit-type.cpp create mode 100644 clang/test/CodeGenCXX/debug-info-limit.cpp create mode 100644 clang/test/CodeGenCXX/debug-info-member.cpp create mode 100644 clang/test/CodeGenCXX/debug-info-method-spec.cpp create mode 100644 clang/test/CodeGenCXX/debug-info-method.cpp create mode 100644 clang/test/CodeGenCXX/debug-info-method2.cpp create mode 100644 clang/test/CodeGenCXX/debug-info-namespace.cpp create mode 100644 clang/test/CodeGenCXX/debug-info-nullptr.cpp create mode 100644 clang/test/CodeGenCXX/debug-info-pubtypes.cpp create mode 100644 clang/test/CodeGenCXX/debug-info-static-fns.cpp create mode 100644 clang/test/CodeGenCXX/debug-info-template-limit.cpp create mode 100644 clang/test/CodeGenCXX/debug-info-template-member.cpp create mode 100644 clang/test/CodeGenCXX/debug-info-template-recursive.cpp create mode 100644 clang/test/CodeGenCXX/debug-info-template.cpp create mode 100644 clang/test/CodeGenCXX/debug-info-this.cpp create mode 100644 clang/test/CodeGenCXX/debug-info-use-after-free.cpp create mode 100644 clang/test/CodeGenCXX/debug-info-wchar.cpp create mode 100644 clang/test/CodeGenCXX/debug-info.cpp create mode 100644 clang/test/CodeGenCXX/debug-lambda-expressions.cpp create mode 100644 clang/test/CodeGenCXX/decl-ref-init.cpp create mode 100644 clang/test/CodeGenCXX/default-arg-temps.cpp create mode 100644 clang/test/CodeGenCXX/default-arguments.cpp create mode 100644 clang/test/CodeGenCXX/default-constructor-default-argument.cpp create mode 100644 clang/test/CodeGenCXX/default-constructor-for-members.cpp create mode 100644 clang/test/CodeGenCXX/default-constructor-template-member.cpp create mode 100644 clang/test/CodeGenCXX/default-destructor-nested.cpp create mode 100644 clang/test/CodeGenCXX/default-destructor-synthesis.cpp create mode 100644 clang/test/CodeGenCXX/deferred-global-init.cpp create mode 100644 clang/test/CodeGenCXX/delete-two-arg.cpp create mode 100644 clang/test/CodeGenCXX/delete.cpp create mode 100644 clang/test/CodeGenCXX/dependent-type-member-pointer.cpp create mode 100644 clang/test/CodeGenCXX/derived-to-base-conv.cpp create mode 100644 clang/test/CodeGenCXX/derived-to-base.cpp create mode 100644 clang/test/CodeGenCXX/derived-to-virtual-base-class-calls-final.cpp create mode 100644 clang/test/CodeGenCXX/destructor-calls.cpp create mode 100644 clang/test/CodeGenCXX/destructor-debug-info.cpp create mode 100644 clang/test/CodeGenCXX/destructors.cpp create mode 100644 clang/test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp create mode 100644 clang/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp create mode 100644 clang/test/CodeGenCXX/dynamic-cast-always-null.cpp create mode 100644 clang/test/CodeGenCXX/dynamic-cast.cpp create mode 100644 clang/test/CodeGenCXX/eh.cpp create mode 100644 clang/test/CodeGenCXX/elide-call-reference.cpp create mode 100644 clang/test/CodeGenCXX/empty-classes.cpp create mode 100644 clang/test/CodeGenCXX/empty-union.cpp create mode 100644 clang/test/CodeGenCXX/enum.cpp create mode 100644 clang/test/CodeGenCXX/eval-recursive-constant.cpp create mode 100644 clang/test/CodeGenCXX/exceptions-no-rtti.cpp create mode 100644 clang/test/CodeGenCXX/exceptions.cpp create mode 100644 clang/test/CodeGenCXX/explicit-instantiation.cpp create mode 100644 clang/test/CodeGenCXX/expr.cpp create mode 100644 clang/test/CodeGenCXX/extern-c.cpp create mode 100644 clang/test/CodeGenCXX/field-access-debug-info.cpp create mode 100644 clang/test/CodeGenCXX/for-range-temporaries.cpp create mode 100644 clang/test/CodeGenCXX/for-range.cpp create mode 100644 clang/test/CodeGenCXX/forward-enum.cpp create mode 100644 clang/test/CodeGenCXX/fp16-mangle.cpp create mode 100644 clang/test/CodeGenCXX/fp16-overload.cpp create mode 100644 clang/test/CodeGenCXX/friend-redecl.cpp create mode 100644 clang/test/CodeGenCXX/function-template-explicit-specialization.cpp create mode 100644 clang/test/CodeGenCXX/function-template-specialization.cpp create mode 100644 clang/test/CodeGenCXX/global-array-destruction.cpp create mode 100644 clang/test/CodeGenCXX/global-dtor-no-atexit.cpp create mode 100644 clang/test/CodeGenCXX/global-init-darwin.cpp create mode 100644 clang/test/CodeGenCXX/global-init.cpp create mode 100644 clang/test/CodeGenCXX/global-llvm-constant.cpp create mode 100644 clang/test/CodeGenCXX/goto.cpp create mode 100644 clang/test/CodeGenCXX/implicit-copy-assign-operator.cpp create mode 100644 clang/test/CodeGenCXX/implicit-copy-constructor.cpp create mode 100644 clang/test/CodeGenCXX/implicit-instantiation-1.cpp create mode 100644 clang/test/CodeGenCXX/incomplete-member-function-pointer.cpp create mode 100644 clang/test/CodeGenCXX/incomplete-types.cpp create mode 100644 clang/test/CodeGenCXX/inheriting-constructor.cpp create mode 100644 clang/test/CodeGenCXX/init-invariant.cpp create mode 100644 clang/test/CodeGenCXX/inline-functions.cpp create mode 100644 clang/test/CodeGenCXX/instantiate-blocks.cpp create mode 100644 clang/test/CodeGenCXX/instantiate-init-list.cpp create mode 100644 clang/test/CodeGenCXX/instantiate-temporaries.cpp create mode 100644 clang/test/CodeGenCXX/instrument-functions.cpp create mode 100644 clang/test/CodeGenCXX/internal-linkage.cpp create mode 100644 clang/test/CodeGenCXX/key-function-vtable.cpp create mode 100644 clang/test/CodeGenCXX/lambda-expressions.cpp create mode 100644 clang/test/CodeGenCXX/lvalue-bitcasts.cpp create mode 100644 clang/test/CodeGenCXX/m64-ptr.cpp create mode 100644 clang/test/CodeGenCXX/mangle-98.cpp create mode 100644 clang/test/CodeGenCXX/mangle-abi-examples.cpp create mode 100644 clang/test/CodeGenCXX/mangle-address-space.cpp create mode 100644 clang/test/CodeGenCXX/mangle-alias-template.cpp create mode 100644 clang/test/CodeGenCXX/mangle-exprs.cpp create mode 100644 clang/test/CodeGenCXX/mangle-extern-local.cpp create mode 100644 clang/test/CodeGenCXX/mangle-extreme.cpp create mode 100644 clang/test/CodeGenCXX/mangle-lambdas.cpp create mode 100644 clang/test/CodeGenCXX/mangle-local-class-names.cpp create mode 100644 clang/test/CodeGenCXX/mangle-local-class-vtables.cpp create mode 100644 clang/test/CodeGenCXX/mangle-local-classes-nested.cpp create mode 100644 clang/test/CodeGenCXX/mangle-ms.cpp create mode 100644 clang/test/CodeGenCXX/mangle-neon-vectors.cpp create mode 100644 clang/test/CodeGenCXX/mangle-nullptr-arg.cpp create mode 100644 clang/test/CodeGenCXX/mangle-ref-qualifiers.cpp create mode 100644 clang/test/CodeGenCXX/mangle-std-externc.cpp create mode 100644 clang/test/CodeGenCXX/mangle-subst-std.cpp create mode 100644 clang/test/CodeGenCXX/mangle-subst.cpp create mode 100644 clang/test/CodeGenCXX/mangle-system-header.cpp create mode 100644 clang/test/CodeGenCXX/mangle-template.cpp create mode 100644 clang/test/CodeGenCXX/mangle-this-cxx11.cpp create mode 100644 clang/test/CodeGenCXX/mangle-unnameable-conversions.cpp create mode 100644 clang/test/CodeGenCXX/mangle-unnamed.cpp create mode 100644 clang/test/CodeGenCXX/mangle-variadic-templates.cpp create mode 100644 clang/test/CodeGenCXX/mangle.cpp create mode 100644 clang/test/CodeGenCXX/member-alignment.cpp create mode 100644 clang/test/CodeGenCXX/member-call-parens.cpp create mode 100644 clang/test/CodeGenCXX/member-expressions.cpp create mode 100644 clang/test/CodeGenCXX/member-function-pointer-calls.cpp create mode 100644 clang/test/CodeGenCXX/member-function-pointers.cpp create mode 100644 clang/test/CodeGenCXX/member-functions.cpp create mode 100644 clang/test/CodeGenCXX/member-init-anon-union.cpp create mode 100644 clang/test/CodeGenCXX/member-init-assignment.cpp create mode 100644 clang/test/CodeGenCXX/member-init-ctor.cpp create mode 100644 clang/test/CodeGenCXX/member-init-struct.cpp create mode 100644 clang/test/CodeGenCXX/member-init-union.cpp create mode 100644 clang/test/CodeGenCXX/member-initializers.cpp create mode 100644 clang/test/CodeGenCXX/member-pointer-type-convert.cpp create mode 100644 clang/test/CodeGenCXX/member-templates.cpp create mode 100644 clang/test/CodeGenCXX/multi-dim-operator-new.cpp create mode 100644 clang/test/CodeGenCXX/namespace-aliases.cpp create mode 100644 clang/test/CodeGenCXX/nested-base-member-access.cpp create mode 100644 clang/test/CodeGenCXX/new-array-init-exceptions.cpp create mode 100644 clang/test/CodeGenCXX/new-array-init.cpp create mode 100644 clang/test/CodeGenCXX/new-operator-phi.cpp create mode 100644 clang/test/CodeGenCXX/new-overflow.cpp create mode 100644 clang/test/CodeGenCXX/new-with-default-arg.cpp create mode 100644 clang/test/CodeGenCXX/new.cpp create mode 100644 clang/test/CodeGenCXX/no-exceptions.cpp create mode 100644 clang/test/CodeGenCXX/noinline-template.cpp create mode 100644 clang/test/CodeGenCXX/nonconst-init.cpp create mode 100644 clang/test/CodeGenCXX/nrvo-noreturn.cc create mode 100644 clang/test/CodeGenCXX/nrvo.cpp create mode 100644 clang/test/CodeGenCXX/nullptr.cpp create mode 100644 clang/test/CodeGenCXX/operator-new.cpp create mode 100644 clang/test/CodeGenCXX/overload-binop-implicitconvert.cpp create mode 100644 clang/test/CodeGenCXX/override-layout.cpp create mode 100644 clang/test/CodeGenCXX/partial-destruction.cpp create mode 100644 clang/test/CodeGenCXX/pointers-to-data-members.cpp create mode 100644 clang/test/CodeGenCXX/pr11676.cpp create mode 100644 clang/test/CodeGenCXX/pr11797.cpp create mode 100644 clang/test/CodeGenCXX/pr12104.cpp create mode 100644 clang/test/CodeGenCXX/pr12104.h create mode 100644 clang/test/CodeGenCXX/pr12251.cpp create mode 100644 clang/test/CodeGenCXX/pr9130.cpp create mode 100644 clang/test/CodeGenCXX/pr9965.cpp create mode 100644 clang/test/CodeGenCXX/pragma-pack-2.cpp create mode 100644 clang/test/CodeGenCXX/pragma-pack.cpp create mode 100644 clang/test/CodeGenCXX/pragma-visibility.cpp create mode 100644 clang/test/CodeGenCXX/predefined-expr-sizeof.cpp create mode 100644 clang/test/CodeGenCXX/predefined-expr.cpp create mode 100644 clang/test/CodeGenCXX/ptr-to-datamember.cpp create mode 100644 clang/test/CodeGenCXX/ptr-to-member-function.cpp create mode 100644 clang/test/CodeGenCXX/reference-bind-default-argument.cpp create mode 100644 clang/test/CodeGenCXX/reference-cast.cpp create mode 100644 clang/test/CodeGenCXX/reference-field.cpp create mode 100644 clang/test/CodeGenCXX/reference-in-block-args.cpp create mode 100644 clang/test/CodeGenCXX/reference-in-blocks.cpp create mode 100644 clang/test/CodeGenCXX/reference-init.cpp create mode 100644 clang/test/CodeGenCXX/references.cpp create mode 100644 clang/test/CodeGenCXX/regparm.cpp create mode 100644 clang/test/CodeGenCXX/reinterpret-cast.cpp create mode 100644 clang/test/CodeGenCXX/rtti-fundamental.cpp create mode 100644 clang/test/CodeGenCXX/rtti-layout.cpp create mode 100644 clang/test/CodeGenCXX/rtti-linkage.cpp create mode 100644 clang/test/CodeGenCXX/rtti-visibility.cpp create mode 100644 clang/test/CodeGenCXX/rvalue-references.cpp create mode 100644 clang/test/CodeGenCXX/scoped-enums.cpp create mode 100644 clang/test/CodeGenCXX/sel-address.mm create mode 100644 clang/test/CodeGenCXX/sizeof-unwind-exception.cpp create mode 100644 clang/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp create mode 100644 clang/test/CodeGenCXX/specialized-static-data-mem-init.cpp create mode 100644 clang/test/CodeGenCXX/static-assert.cpp create mode 100644 clang/test/CodeGenCXX/static-data-member.cpp create mode 100644 clang/test/CodeGenCXX/static-init-1.cpp create mode 100644 clang/test/CodeGenCXX/static-init-2.cpp create mode 100644 clang/test/CodeGenCXX/static-init-3.cpp create mode 100644 clang/test/CodeGenCXX/static-init.cpp create mode 100644 clang/test/CodeGenCXX/static-local-in-local-class.cpp create mode 100644 clang/test/CodeGenCXX/static-member-variable-explicit-specialization.cpp create mode 100644 clang/test/CodeGenCXX/static-mutable.cpp create mode 100644 clang/test/CodeGenCXX/stmtexpr.cpp create mode 100644 clang/test/CodeGenCXX/switch-case-folding-1.cpp create mode 100644 clang/test/CodeGenCXX/switch-case-folding-2.cpp create mode 100644 clang/test/CodeGenCXX/switch-case-folding.cpp create mode 100644 clang/test/CodeGenCXX/temp-order.cpp create mode 100644 clang/test/CodeGenCXX/template-anonymous-types.cpp create mode 100644 clang/test/CodeGenCXX/template-anonymous-union-member-initializer.cpp create mode 100644 clang/test/CodeGenCXX/template-dependent-bind-temporary.cpp create mode 100644 clang/test/CodeGenCXX/template-inner-struct-visibility-hidden.cpp create mode 100644 clang/test/CodeGenCXX/template-instantiation.cpp create mode 100644 clang/test/CodeGenCXX/template-linkage.cpp create mode 100644 clang/test/CodeGenCXX/template-static-var-defer.cpp create mode 100644 clang/test/CodeGenCXX/temporaries.cpp create mode 100644 clang/test/CodeGenCXX/thiscall-struct-return.cpp create mode 100644 clang/test/CodeGenCXX/threadsafe-statics-exceptions.cpp create mode 100644 clang/test/CodeGenCXX/threadsafe-statics.cpp create mode 100644 clang/test/CodeGenCXX/throw-expression-dtor.cpp create mode 100644 clang/test/CodeGenCXX/throw-expressions.cpp create mode 100644 clang/test/CodeGenCXX/thunk-linkonce-odr.cpp create mode 100644 clang/test/CodeGenCXX/thunk-use-after-free.cpp create mode 100644 clang/test/CodeGenCXX/thunks-available-externally.cpp create mode 100644 clang/test/CodeGenCXX/thunks.cpp create mode 100644 clang/test/CodeGenCXX/trivial-constructor-init.cpp create mode 100644 clang/test/CodeGenCXX/try-catch.cpp create mode 100644 clang/test/CodeGenCXX/typeid-cxx11.cpp create mode 100644 clang/test/CodeGenCXX/typeid.cpp create mode 100644 clang/test/CodeGenCXX/typeinfo create mode 100644 clang/test/CodeGenCXX/unary-type-trait.cpp create mode 100644 clang/test/CodeGenCXX/uncode-string.cpp create mode 100644 clang/test/CodeGenCXX/union-dtor.cpp create mode 100644 clang/test/CodeGenCXX/unknown-anytype.cpp create mode 100644 clang/test/CodeGenCXX/value-init.cpp create mode 100644 clang/test/CodeGenCXX/vararg-conversion-ctor.cpp create mode 100644 clang/test/CodeGenCXX/vararg-non-pod.cpp create mode 100644 clang/test/CodeGenCXX/varargs.cpp create mode 100644 clang/test/CodeGenCXX/variadic-templates.cpp create mode 100644 clang/test/CodeGenCXX/virt-call-offsets.cpp create mode 100644 clang/test/CodeGenCXX/virt-canonical-decl.cpp create mode 100644 clang/test/CodeGenCXX/virt-dtor-gen.cpp create mode 100644 clang/test/CodeGenCXX/virt-dtor-key.cpp create mode 100644 clang/test/CodeGenCXX/virt-template-vtable.cpp create mode 100644 clang/test/CodeGenCXX/virt-thunk-reference.cpp create mode 100644 clang/test/CodeGenCXX/virtual-base-cast.cpp create mode 100644 clang/test/CodeGenCXX/virtual-base-ctor.cpp create mode 100644 clang/test/CodeGenCXX/virtual-base-destructor-call.cpp create mode 100644 clang/test/CodeGenCXX/virtual-bases.cpp create mode 100644 clang/test/CodeGenCXX/virtual-destructor-calls.cpp create mode 100644 clang/test/CodeGenCXX/virtual-destructor-synthesis.cpp create mode 100644 clang/test/CodeGenCXX/virtual-function-calls.cpp create mode 100644 clang/test/CodeGenCXX/virtual-functions-incomplete-types.cpp create mode 100644 clang/test/CodeGenCXX/virtual-implicit-copy-assignment.cpp create mode 100644 clang/test/CodeGenCXX/virtual-implicit-move-assignment.cpp create mode 100644 clang/test/CodeGenCXX/virtual-inherited-destructor.cpp create mode 100644 clang/test/CodeGenCXX/virtual-operator-call.cpp create mode 100644 clang/test/CodeGenCXX/virtual-pseudo-destructor-call.cpp create mode 100644 clang/test/CodeGenCXX/visibility-hidden-extern-templates.cpp create mode 100644 clang/test/CodeGenCXX/visibility-inlines-hidden.cpp create mode 100644 clang/test/CodeGenCXX/visibility.cpp create mode 100644 clang/test/CodeGenCXX/vla.cpp create mode 100644 clang/test/CodeGenCXX/volatile-1.cpp create mode 100644 clang/test/CodeGenCXX/volatile.cpp create mode 100644 clang/test/CodeGenCXX/vtable-available-externally.cpp create mode 100644 clang/test/CodeGenCXX/vtable-cast-crash.cpp create mode 100644 clang/test/CodeGenCXX/vtable-debug-info.cpp create mode 100644 clang/test/CodeGenCXX/vtable-key-function.cpp create mode 100644 clang/test/CodeGenCXX/vtable-layout-abi-examples.cpp create mode 100644 clang/test/CodeGenCXX/vtable-layout-extreme.cpp create mode 100644 clang/test/CodeGenCXX/vtable-layout.cpp create mode 100644 clang/test/CodeGenCXX/vtable-linkage.cpp create mode 100644 clang/test/CodeGenCXX/vtable-pointer-initialization.cpp create mode 100644 clang/test/CodeGenCXX/vtt-layout.cpp create mode 100644 clang/test/CodeGenCXX/warn-padded-packed.cpp create mode 100644 clang/test/CodeGenCXX/weak-extern-typeinfo.cpp create mode 100644 clang/test/CodeGenCXX/weak-external.cpp create mode 100644 clang/test/CodeGenCXX/x86_32-arguments.cpp create mode 100644 clang/test/CodeGenCXX/x86_64-arguments.cpp (limited to 'clang/test/CodeGenCXX') diff --git a/clang/test/CodeGenCXX/2003-11-02-WeakLinkage.cpp b/clang/test/CodeGenCXX/2003-11-02-WeakLinkage.cpp new file mode 100644 index 0000000..02f9fc6 --- /dev/null +++ b/clang/test/CodeGenCXX/2003-11-02-WeakLinkage.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s +// The template should compile to linkonce linkage, not weak linkage. + +// CHECK-NOT: weak +template +void thefunc(); + +template +inline void thefunc() {} + +void test() { + thefunc(); +} diff --git a/clang/test/CodeGenCXX/2003-11-18-PtrMemConstantInitializer.cpp b/clang/test/CodeGenCXX/2003-11-18-PtrMemConstantInitializer.cpp new file mode 100644 index 0000000..9cecf48 --- /dev/null +++ b/clang/test/CodeGenCXX/2003-11-18-PtrMemConstantInitializer.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - + +struct Gfx { + void opMoveSetShowText(); +}; + +struct Operator { + void (Gfx::*func)(); +}; + +Operator opTab[] = { + {&Gfx::opMoveSetShowText}, +}; diff --git a/clang/test/CodeGenCXX/2003-11-27-MultipleInheritanceThunk.cpp b/clang/test/CodeGenCXX/2003-11-27-MultipleInheritanceThunk.cpp new file mode 100644 index 0000000..3e53397 --- /dev/null +++ b/clang/test/CodeGenCXX/2003-11-27-MultipleInheritanceThunk.cpp @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - + + +struct CallSite { + int X; + + CallSite(const CallSite &CS); +}; + +struct AliasAnalysis { + int TD; + + virtual int getModRefInfo(CallSite CS); +}; + + +struct Pass { + int X; + virtual int foo(); +}; + +struct AliasAnalysisCounter : public Pass, public AliasAnalysis { + int getModRefInfo(CallSite CS) { + return 0; + } +}; + +AliasAnalysisCounter AAC; diff --git a/clang/test/CodeGenCXX/2003-11-29-DuplicatedCleanupTest.cpp b/clang/test/CodeGenCXX/2003-11-29-DuplicatedCleanupTest.cpp new file mode 100644 index 0000000..45325bc --- /dev/null +++ b/clang/test/CodeGenCXX/2003-11-29-DuplicatedCleanupTest.cpp @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - + + +void doesntThrow() throw(); +struct F { + ~F() { doesntThrow(); } +}; + +void atest() { + F A; +lab: + F B; + goto lab; +} + +void test(int val) { +label: { + F A; + F B; + if (val == 0) goto label; + if (val == 1) goto label; +} +} + +void test3(int val) { +label: { + F A; + F B; + if (val == 0) { doesntThrow(); goto label; } + if (val == 1) { doesntThrow(); goto label; } +} +} + +void test4(int val) { +label: { + F A; + F B; + if (val == 0) { F C; goto label; } + if (val == 1) { F D; goto label; } +} +} diff --git a/clang/test/CodeGenCXX/2003-12-08-ArrayOfPtrToMemberFunc.cpp b/clang/test/CodeGenCXX/2003-12-08-ArrayOfPtrToMemberFunc.cpp new file mode 100644 index 0000000..38de271 --- /dev/null +++ b/clang/test/CodeGenCXX/2003-12-08-ArrayOfPtrToMemberFunc.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - + +struct Evil { + void fun (); +}; +int foo(); +typedef void (Evil::*memfunptr) (); +static memfunptr jumpTable[] = { &Evil::fun }; + +void Evil::fun() { + (this->*jumpTable[foo()]) (); +} diff --git a/clang/test/CodeGenCXX/2004-01-11-DynamicInitializedConstant.cpp b/clang/test/CodeGenCXX/2004-01-11-DynamicInitializedConstant.cpp new file mode 100644 index 0000000..0c9333f --- /dev/null +++ b/clang/test/CodeGenCXX/2004-01-11-DynamicInitializedConstant.cpp @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s + +// CHECK-NOT: constant +extern int X; +const int Y = X; +const int* foo() { return &Y; } diff --git a/clang/test/CodeGenCXX/2004-03-08-ReinterpretCastCopy.cpp b/clang/test/CodeGenCXX/2004-03-08-ReinterpretCastCopy.cpp new file mode 100644 index 0000000..a6e2e30 --- /dev/null +++ b/clang/test/CodeGenCXX/2004-03-08-ReinterpretCastCopy.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - + +struct A { + virtual void Method() = 0; +}; + +struct B : public A { + virtual void Method() { } +}; + +typedef void (A::*fn_type_a)(void); +typedef void (B::*fn_type_b)(void); + +int main(int argc, char **argv) +{ + fn_type_a f = reinterpret_cast(&B::Method); + fn_type_b g = reinterpret_cast(f); + B b; + (b.*g)(); + return 0; +} diff --git a/clang/test/CodeGenCXX/2004-03-09-UnmangledBuiltinMethods.cpp b/clang/test/CodeGenCXX/2004-03-09-UnmangledBuiltinMethods.cpp new file mode 100644 index 0000000..5d8c8b0 --- /dev/null +++ b/clang/test/CodeGenCXX/2004-03-09-UnmangledBuiltinMethods.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s + +// CHECK: _ZN11AccessFlags6strlenEv +struct AccessFlags { + void strlen(); +}; + +void AccessFlags::strlen() { } diff --git a/clang/test/CodeGenCXX/2004-03-15-CleanupsAndGotos.cpp b/clang/test/CodeGenCXX/2004-03-15-CleanupsAndGotos.cpp new file mode 100644 index 0000000..01350c0 --- /dev/null +++ b/clang/test/CodeGenCXX/2004-03-15-CleanupsAndGotos.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - + +// Testcase from Bug 291 + +struct X { + ~X(); +}; + +void foo() { + X v; + +TryAgain: + goto TryAgain; +} diff --git a/clang/test/CodeGenCXX/2004-06-08-LateTemplateInstantiation.cpp b/clang/test/CodeGenCXX/2004-06-08-LateTemplateInstantiation.cpp new file mode 100644 index 0000000..97254c1 --- /dev/null +++ b/clang/test/CodeGenCXX/2004-06-08-LateTemplateInstantiation.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - + + +template +struct normal_iterator { + int FIELD; +}; + +void foo(normal_iterator); +normal_iterator baz(); + +void bar() { + foo(baz()); +} + +void *bar2() { + return (void*)foo; +} diff --git a/clang/test/CodeGenCXX/2004-09-27-DidntEmitTemplate.cpp b/clang/test/CodeGenCXX/2004-09-27-DidntEmitTemplate.cpp new file mode 100644 index 0000000..618894f --- /dev/null +++ b/clang/test/CodeGenCXX/2004-09-27-DidntEmitTemplate.cpp @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s + +// This is a testcase for LLVM PR445, which was a problem where the +// instantiation of callDefaultCtor was not being emitted correctly. + +// CHECK-NOT: declare{{.*}}callDefaultCtor +struct Pass {}; + +template +Pass *callDefaultCtor() { return new Pass(); } + +void foo(Pass *(*C)()); + +struct basic_string { + bool empty() const { return true; } +}; + + +bool foo2(basic_string &X) { + return X.empty(); +} +void baz() { foo(callDefaultCtor); } diff --git a/clang/test/CodeGenCXX/2004-11-27-ExceptionCleanupAssertion.cpp b/clang/test/CodeGenCXX/2004-11-27-ExceptionCleanupAssertion.cpp new file mode 100644 index 0000000..ebcce77 --- /dev/null +++ b/clang/test/CodeGenCXX/2004-11-27-ExceptionCleanupAssertion.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 %s -emit-llvm -o /dev/null + +// This is PR421 + +struct Strongbad { + Strongbad(const char *str ); + ~Strongbad(); + operator const char *() const; +}; + +void TheCheat () { + Strongbad foo(0); + Strongbad dirs[] = { Strongbad(0) + 1}; +} diff --git a/clang/test/CodeGenCXX/2004-11-27-FriendDefaultArgCrash.cpp b/clang/test/CodeGenCXX/2004-11-27-FriendDefaultArgCrash.cpp new file mode 100644 index 0000000..3bfecd5 --- /dev/null +++ b/clang/test/CodeGenCXX/2004-11-27-FriendDefaultArgCrash.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +// PR447 + +namespace nm { + struct str { + friend int foo(int arg = 0); + }; +} diff --git a/clang/test/CodeGenCXX/2005-01-03-StaticInitializers.cpp b/clang/test/CodeGenCXX/2005-01-03-StaticInitializers.cpp new file mode 100644 index 0000000..875c412 --- /dev/null +++ b/clang/test/CodeGenCXX/2005-01-03-StaticInitializers.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s + +struct S { + int A[2]; +}; + +// CHECK-NOT: llvm.global_ctor +int XX = (int)(long)&(((struct S*)0)->A[1]); diff --git a/clang/test/CodeGenCXX/2005-02-11-AnonymousUnion.cpp b/clang/test/CodeGenCXX/2005-02-11-AnonymousUnion.cpp new file mode 100644 index 0000000..dee5817 --- /dev/null +++ b/clang/test/CodeGenCXX/2005-02-11-AnonymousUnion.cpp @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - + +// Test anonymous union with members of the same size. +int test1(float F) { + union { + float G; + int i; + }; + G = F; + return i; +} + +// test anonymous union with members of differing size. +int test2(short F) { + volatile union { + short G; + int i; + }; + G = F; + return i; +} + +// Make sure that normal unions work. duh :) +volatile union U_t { + short S; + int i; +} U; + +int test3(short s) { + U.S = s; + return U.i; +} diff --git a/clang/test/CodeGenCXX/2005-02-13-BadDynamicInit.cpp b/clang/test/CodeGenCXX/2005-02-13-BadDynamicInit.cpp new file mode 100644 index 0000000..b1db67a --- /dev/null +++ b/clang/test/CodeGenCXX/2005-02-13-BadDynamicInit.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s +// This testcase corresponds to PR509 +struct Data { + unsigned *data; + unsigned array[1]; +}; + +// CHECK-NOT: llvm.global_ctors +Data shared_null = { shared_null.array }; diff --git a/clang/test/CodeGenCXX/2005-02-14-BitFieldOffset.cpp b/clang/test/CodeGenCXX/2005-02-14-BitFieldOffset.cpp new file mode 100644 index 0000000..c37f5dc --- /dev/null +++ b/clang/test/CodeGenCXX/2005-02-14-BitFieldOffset.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s + +// CHECK-NOT: i32 6 +struct QVectorTypedData { + int size; + unsigned int sharable : 1; + unsigned short array[1]; +}; + +void foo(QVectorTypedData *X) { + X->array[0] = 123; +} diff --git a/clang/test/CodeGenCXX/2005-02-19-BitfieldStructCrash.cpp b/clang/test/CodeGenCXX/2005-02-19-BitfieldStructCrash.cpp new file mode 100644 index 0000000..937a300 --- /dev/null +++ b/clang/test/CodeGenCXX/2005-02-19-BitfieldStructCrash.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - + +struct QChar {unsigned short X; QChar(unsigned short); } ; + +struct Command { + Command(QChar c) : c(c) {} + unsigned int type : 4; + QChar c; + }; + +Command X(QChar('c')); + +void Foo(QChar ); +void bar() { Foo(X.c); } diff --git a/clang/test/CodeGenCXX/2005-02-19-UnnamedVirtualThunkArgument.cpp b/clang/test/CodeGenCXX/2005-02-19-UnnamedVirtualThunkArgument.cpp new file mode 100644 index 0000000..986001a --- /dev/null +++ b/clang/test/CodeGenCXX/2005-02-19-UnnamedVirtualThunkArgument.cpp @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +struct Foo { + Foo(); + virtual ~Foo(); +}; + +struct Bar { + Bar(); + virtual ~Bar(); + virtual bool test(bool) const; +}; + +struct Baz : public Foo, public Bar { + Baz(); + virtual ~Baz(); + virtual bool test(bool) const; +}; + +bool Baz::test(bool) const { + return true; +} diff --git a/clang/test/CodeGenCXX/2005-02-20-BrokenReferenceTest.cpp b/clang/test/CodeGenCXX/2005-02-20-BrokenReferenceTest.cpp new file mode 100644 index 0000000..36f911e --- /dev/null +++ b/clang/test/CodeGenCXX/2005-02-20-BrokenReferenceTest.cpp @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +void test(unsigned char *b, int rb) { + typedef unsigned char imgfoo[10][rb]; + imgfoo &br = *(imgfoo *)b; + + br[0][0] = 1; + + rb = br[0][0]; +} diff --git a/clang/test/CodeGenCXX/2006-03-01-GimplifyCrash.cpp b/clang/test/CodeGenCXX/2006-03-01-GimplifyCrash.cpp new file mode 100644 index 0000000..b809751 --- /dev/null +++ b/clang/test/CodeGenCXX/2006-03-01-GimplifyCrash.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - + +struct PrefMapElem { + virtual ~PrefMapElem(); + unsigned int fPrefId; +}; + +int foo() { + PrefMapElem* fMap; + if (fMap[0].fPrefId == 1) + return 1; + + return 0; +} diff --git a/clang/test/CodeGenCXX/2006-03-06-C++RecurseCrash.cpp b/clang/test/CodeGenCXX/2006-03-06-C++RecurseCrash.cpp new file mode 100644 index 0000000..01476b7 --- /dev/null +++ b/clang/test/CodeGenCXX/2006-03-06-C++RecurseCrash.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - +namespace std { + class exception { }; + + class type_info { + public: + virtual ~type_info(); + }; + +} + +namespace __cxxabiv1 { + class __si_class_type_info : public std::type_info { + ~__si_class_type_info(); + }; +} + +class recursive_init: public std::exception { +public: + virtual ~recursive_init() throw (); +}; + +recursive_init::~recursive_init() throw() { } diff --git a/clang/test/CodeGenCXX/2006-09-12-OpaqueStructCrash.cpp b/clang/test/CodeGenCXX/2006-09-12-OpaqueStructCrash.cpp new file mode 100644 index 0000000..bd270dd --- /dev/null +++ b/clang/test/CodeGenCXX/2006-09-12-OpaqueStructCrash.cpp @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s + +struct A { + virtual ~A(); +}; + +template +struct B : public A { + ~B () { delete [] val; } +private: + Ty* val; +}; + +template +struct C : public A { + C (); + ~C (); +}; + +template +struct D : public A { + D () {} + private: + B > blocks; +}; + +template class D; diff --git a/clang/test/CodeGenCXX/2006-10-30-ClassBitfield.cpp b/clang/test/CodeGenCXX/2006-10-30-ClassBitfield.cpp new file mode 100644 index 0000000..8f61f7b --- /dev/null +++ b/clang/test/CodeGenCXX/2006-10-30-ClassBitfield.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - +// PR954 + +struct _Refcount_Base { + unsigned long _M_ref_count; + int _M_ref_count_lock; + _Refcount_Base() : _M_ref_count(0) {} +}; + +struct _Rope_RopeRep : public _Refcount_Base +{ +public: + int _M_tag:8; +}; + +int foo(_Rope_RopeRep* r) { return r->_M_tag; } diff --git a/clang/test/CodeGenCXX/2006-11-20-GlobalSymbols.cpp b/clang/test/CodeGenCXX/2006-11-20-GlobalSymbols.cpp new file mode 100644 index 0000000..34594f4 --- /dev/null +++ b/clang/test/CodeGenCXX/2006-11-20-GlobalSymbols.cpp @@ -0,0 +1,11 @@ +// PR1013 +// Check to make sure debug symbols use the correct name for globals and +// functions. Will not assemble if it fails to. +// RUN: %clang_cc1 -emit-llvm -g -o - %s | FileCheck %s + +// CHECK: f\01oo" +int foo __asm__("f\001oo"); + +int bar() { + return foo; +} diff --git a/clang/test/CodeGenCXX/2006-11-30-ConstantExprCrash.cpp b/clang/test/CodeGenCXX/2006-11-30-ConstantExprCrash.cpp new file mode 100644 index 0000000..2088e63 --- /dev/null +++ b/clang/test/CodeGenCXX/2006-11-30-ConstantExprCrash.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - +// PR1027 + +struct sys_var { + unsigned name_length; + + bool no_support_one_shot; + sys_var() {} +}; + + +struct sys_var_thd : public sys_var { +}; + +extern sys_var_thd sys_auto_is_null; + +sys_var *getsys_variables() { + return &sys_auto_is_null; +} + +sys_var *sys_variables = &sys_auto_is_null; diff --git a/clang/test/CodeGenCXX/2007-01-02-UnboundedArray.cpp b/clang/test/CodeGenCXX/2007-01-02-UnboundedArray.cpp new file mode 100644 index 0000000..0cd83fa --- /dev/null +++ b/clang/test/CodeGenCXX/2007-01-02-UnboundedArray.cpp @@ -0,0 +1,14 @@ +// Make sure unbounded arrays compile with debug information. +// +// RUN: %clang_cc1 -emit-llvm -g %s -o - + +// PR1068 + +struct Object { + char buffer[]; +}; + +int main(int argc, char** argv) { + new Object; + return 0; +} diff --git a/clang/test/CodeGenCXX/2007-01-06-PtrMethodInit.cpp b/clang/test/CodeGenCXX/2007-01-06-PtrMethodInit.cpp new file mode 100644 index 0000000..37005c5 --- /dev/null +++ b/clang/test/CodeGenCXX/2007-01-06-PtrMethodInit.cpp @@ -0,0 +1,75 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - -triple i386-apple-macosx10.7.2 +// PR1084 + +extern "C" +{ + typedef unsigned char PRUint8; + typedef unsigned int PRUint32; +} +typedef PRUint32 nsresult; +struct nsID +{ +}; +typedef nsID nsIID; +class nsISupports +{ +}; +extern "C++" +{ + template < class T > struct nsCOMTypeInfo + { + static const nsIID & GetIID () + { + } + }; +} + +class nsIDOMEvent:public nsISupports +{ +}; +class nsIDOMEventListener:public nsISupports +{ +public:static const nsIID & GetIID () + { + } + virtual nsresult + __attribute__ ((regparm (0), cdecl)) HandleEvent (nsIDOMEvent * event) = + 0; +}; +class nsIDOMMouseListener:public nsIDOMEventListener +{ +public:static const nsIID & GetIID () + { + static const nsIID iid = { + }; + } + virtual nsresult + __attribute__ ((regparm (0), + cdecl)) MouseDown (nsIDOMEvent * aMouseEvent) = 0; +}; +typedef +typeof (&nsIDOMEventListener::HandleEvent) + GenericHandler; + struct EventDispatchData + { + PRUint32 message; + GenericHandler method; + PRUint8 bits; + }; + struct EventTypeData + { + const EventDispatchData *events; + int numEvents; + const nsIID *iid; + }; + static const EventDispatchData sMouseEvents[] = { + { + (300 + 2), + reinterpret_cast < GenericHandler > (&nsIDOMMouseListener::MouseDown), + 0x01} + }; +static const EventTypeData sEventTypes[] = { + { + sMouseEvents, (sizeof (sMouseEvents) / sizeof (sMouseEvents[0])), + &nsCOMTypeInfo < nsIDOMMouseListener >::GetIID ()} +}; diff --git a/clang/test/CodeGenCXX/2007-04-05-PackedBitFields-1.cpp b/clang/test/CodeGenCXX/2007-04-05-PackedBitFields-1.cpp new file mode 100644 index 0000000..6c39b55 --- /dev/null +++ b/clang/test/CodeGenCXX/2007-04-05-PackedBitFields-1.cpp @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - + +#ifdef PACKED +#define P __attribute__((packed)) +#else +#define P +#endif + +struct P M_Packed { + unsigned int l_Packed; + unsigned short k_Packed : 6, + i_Packed : 15, + j_Packed : 11; + +}; + +struct M_Packed sM_Packed; + +int testM_Packed (void) { + struct M_Packed x; + return (x.i_Packed != 0); +} diff --git a/clang/test/CodeGenCXX/2007-04-05-PackedBitFieldsOverlap-2.cpp b/clang/test/CodeGenCXX/2007-04-05-PackedBitFieldsOverlap-2.cpp new file mode 100644 index 0000000..d7b0eae --- /dev/null +++ b/clang/test/CodeGenCXX/2007-04-05-PackedBitFieldsOverlap-2.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - + +#ifdef PACKED +#define P __attribute__((packed)) +#else +#define P +#endif + +struct P M_Packed { + unsigned long sorted : 1; + unsigned long from_array : 1; + unsigned long mixed_encoding : 1; + unsigned long encoding : 8; + unsigned long count : 21; + +}; + +struct M_Packed sM_Packed; + +int testM_Packed (void) { + struct M_Packed x; + return (x.count != 0); +} diff --git a/clang/test/CodeGenCXX/2007-04-05-PackedBitFieldsOverlap.cpp b/clang/test/CodeGenCXX/2007-04-05-PackedBitFieldsOverlap.cpp new file mode 100644 index 0000000..6911767 --- /dev/null +++ b/clang/test/CodeGenCXX/2007-04-05-PackedBitFieldsOverlap.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - + + +#ifdef PACKED +#define P __attribute__((packed)) +#else +#define P +#endif + +struct P M_Packed { + unsigned int l_Packed; + unsigned short k_Packed : 6, + i_Packed : 15; + char c; + +}; + +struct M_Packed sM_Packed; + +int testM_Packed (void) { + struct M_Packed x; + return (x.i_Packed != 0); +} diff --git a/clang/test/CodeGenCXX/2007-04-05-PackedBitFieldsSmall.cpp b/clang/test/CodeGenCXX/2007-04-05-PackedBitFieldsSmall.cpp new file mode 100644 index 0000000..b31f95f --- /dev/null +++ b/clang/test/CodeGenCXX/2007-04-05-PackedBitFieldsSmall.cpp @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - + + +#ifdef PACKED +// This is an example where size of Packed struct is smaller then +// the size of bit field type. +#define P __attribute__((packed)) +#else +#define P +#endif + +struct P M_Packed { + unsigned long long X:50; + unsigned Y:2; +}; + +struct M_Packed sM_Packed; + +int testM_Packed (void) { + struct M_Packed x; + return (0 != x.Y); +} + +int testM_Packed2 (void) { + struct M_Packed x; + return (0 != x.X); +} diff --git a/clang/test/CodeGenCXX/2007-04-05-StructPackedFieldUnpacked.cpp b/clang/test/CodeGenCXX/2007-04-05-StructPackedFieldUnpacked.cpp new file mode 100644 index 0000000..c848e7c --- /dev/null +++ b/clang/test/CodeGenCXX/2007-04-05-StructPackedFieldUnpacked.cpp @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - + +#ifdef PACKED +#define P __attribute__((packed)) +#else +#define P +#endif + +struct UnPacked { + int X; + int Y; +}; + +struct P M_Packed { + unsigned char A; + struct UnPacked B; +}; + +struct M_Packed sM_Packed; + +int testM_Packed (void) { + struct M_Packed x; + return (x.B.Y != 0); +} diff --git a/clang/test/CodeGenCXX/2007-04-10-PackedUnion.cpp b/clang/test/CodeGenCXX/2007-04-10-PackedUnion.cpp new file mode 100644 index 0000000..863fc82 --- /dev/null +++ b/clang/test/CodeGenCXX/2007-04-10-PackedUnion.cpp @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null +extern "C" { + +#pragma pack(push, 2) + typedef struct ABC* abc; + + struct ABCS { + float red; + float green; + float blue; + float alpha; + }; + + typedef void (*XYZ)(); +#pragma pack(pop) +} + + +union ABCU { + ABCS color; + XYZ bg; +}; + +struct AData { + ABCU data; +}; + +class L { + public: + L() {} + L(const L& other); + + private: + AData fdata; +}; + + +L::L(const L& other) +{ + fdata = other.fdata; +} diff --git a/clang/test/CodeGenCXX/2007-04-14-FNoBuiltin.cpp b/clang/test/CodeGenCXX/2007-04-14-FNoBuiltin.cpp new file mode 100644 index 0000000..4475fda --- /dev/null +++ b/clang/test/CodeGenCXX/2007-04-14-FNoBuiltin.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -emit-llvm %s -fno-builtin -o - | FileCheck %s +// Check that -fno-builtin is honored. + +extern "C" int printf(const char*, ...); +void foo(const char *msg) { + // CHECK: call{{.*}}printf + printf("%s\n",msg); +} diff --git a/clang/test/CodeGenCXX/2007-05-03-VectorInit.cpp b/clang/test/CodeGenCXX/2007-05-03-VectorInit.cpp new file mode 100644 index 0000000..5bc196f --- /dev/null +++ b/clang/test/CodeGenCXX/2007-05-03-VectorInit.cpp @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -emit-llvm %s -O0 -o - +// PR1378 + +typedef float v4sf __attribute__((vector_size(16))); + +typedef v4sf float4; + +static float4 splat4(float a) +{ + float4 tmp = {a,a,a,a}; + return tmp; +} + +float4 foo(float a) +{ + return splat4(a); +} diff --git a/clang/test/CodeGenCXX/2007-07-29-RestrictPtrArg.cpp b/clang/test/CodeGenCXX/2007-07-29-RestrictPtrArg.cpp new file mode 100644 index 0000000..d7c96f5 --- /dev/null +++ b/clang/test/CodeGenCXX/2007-07-29-RestrictPtrArg.cpp @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s + +void foo(int * __restrict myptr1, int * myptr2) { + // CHECK: noalias + myptr1[0] = 0; + myptr2[0] = 0; +} diff --git a/clang/test/CodeGenCXX/2007-07-29-RestrictRefArg.cpp b/clang/test/CodeGenCXX/2007-07-29-RestrictRefArg.cpp new file mode 100644 index 0000000..aa9f48b --- /dev/null +++ b/clang/test/CodeGenCXX/2007-07-29-RestrictRefArg.cpp @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s + +void foo(int & __restrict myptr1, int & myptr2) { + // CHECK: noalias + myptr1 = 0; + myptr2 = 0; +} diff --git a/clang/test/CodeGenCXX/2007-09-10-RecursiveTypeResolution.cpp b/clang/test/CodeGenCXX/2007-09-10-RecursiveTypeResolution.cpp new file mode 100644 index 0000000..ec8a516 --- /dev/null +++ b/clang/test/CodeGenCXX/2007-09-10-RecursiveTypeResolution.cpp @@ -0,0 +1,87 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - +// PR1634 + +namespace Manta +{ + class CallbackHandle + { + protected:virtual ~ CallbackHandle (void) + { + } + }; +template < typename Data1 > class CallbackBase_1Data:public CallbackHandle + { + }; +} + +namespace __gnu_cxx +{ + template < typename _Iterator, typename _Container > + class __normal_iterator + { + _Iterator _M_current; + }; +} + +namespace std +{ + template < typename _Tp > struct allocator + { + typedef _Tp *pointer; + }; + template < typename _InputIterator, + typename _Tp > inline void find (_InputIterator __last, + const _Tp & __val) + { + }; +} + +namespace Manta +{ + template < typename _Tp, typename _Alloc> struct _Vector_base + { + struct _Vector_impl + { + _Tp *_M_start; + }; + public: + _Vector_impl _M_impl; + }; + template < typename _Tp, typename _Alloc = std::allocator < _Tp > > + class vector:protected _Vector_base < _Tp,_Alloc > + { + public: + typedef __gnu_cxx::__normal_iterator < typename _Alloc::pointer, + vector < _Tp, _Alloc > > iterator; + iterator end () + { + } + }; + class MantaInterface + { + }; + class RTRT + { + virtual CallbackHandle *registerTerminationCallback (CallbackBase_1Data < + MantaInterface * >*); + virtual void unregisterCallback (CallbackHandle *); + typedef vector < CallbackBase_1Data < int >*>PRCallbackMapType; + PRCallbackMapType parallelPreRenderCallbacks; + }; +} +using namespace Manta; +CallbackHandle * +RTRT::registerTerminationCallback (CallbackBase_1Data < MantaInterface * >*cb) +{ + return cb; +} + +void +RTRT::unregisterCallback (CallbackHandle * callback) +{ + { + typedef CallbackBase_1Data < int > callback_t; + callback_t *cb = static_cast < callback_t * >(callback); + find (parallelPreRenderCallbacks.end (), cb); + } +} diff --git a/clang/test/CodeGenCXX/2007-10-01-StructResize.cpp b/clang/test/CodeGenCXX/2007-10-01-StructResize.cpp new file mode 100644 index 0000000..8e5750d --- /dev/null +++ b/clang/test/CodeGenCXX/2007-10-01-StructResize.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +#pragma pack(4) + +struct Bork { + unsigned int f1 : 3; + unsigned int f2 : 30; +}; + +int Foo(Bork *hdr) { + hdr->f1 = 7; + hdr->f2 = 927; +} diff --git a/clang/test/CodeGenCXX/2008-01-12-VecInit.cpp b/clang/test/CodeGenCXX/2008-01-12-VecInit.cpp new file mode 100644 index 0000000..92bfd51 --- /dev/null +++ b/clang/test/CodeGenCXX/2008-01-12-VecInit.cpp @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - +// rdar://5685492 + +typedef int __attribute__((vector_size(16))) v; +v vt = {1, 2, 3, 4}; diff --git a/clang/test/CodeGenCXX/2008-05-07-CrazyOffsetOf.cpp b/clang/test/CodeGenCXX/2008-05-07-CrazyOffsetOf.cpp new file mode 100644 index 0000000..f842f95 --- /dev/null +++ b/clang/test/CodeGenCXX/2008-05-07-CrazyOffsetOf.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - +// rdar://5914926 + +struct bork { + struct bork *next_local; + char * query; +}; +int offset = (char *) &(((struct bork *) 0x10)->query) - (char *) 0x10; diff --git a/clang/test/CodeGenCXX/2009-03-17-dbg.cpp b/clang/test/CodeGenCXX/2009-03-17-dbg.cpp new file mode 100644 index 0000000..e2e6c5a --- /dev/null +++ b/clang/test/CodeGenCXX/2009-03-17-dbg.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null -g + +template +inline void f(const T1&,const T2&) { } + +template +struct A { + template void g(T& i) { } +}; + +int main() { + int i; + A a; + a.g(i); +} diff --git a/clang/test/CodeGenCXX/2009-04-23-bool2.cpp b/clang/test/CodeGenCXX/2009-04-23-bool2.cpp new file mode 100644 index 0000000..cf81cc4 --- /dev/null +++ b/clang/test/CodeGenCXX/2009-04-23-bool2.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null +// g++.old-deja/g++.jason/bool2.C from gcc testsuite. +// Crashed before 67975 went in. +struct F { + bool b1 : 1; + bool b2 : 7; +}; + +int main() +{ + F f = { true, true }; + + if (int (f.b1) != 1) + return 1; +} diff --git a/clang/test/CodeGenCXX/2009-05-04-PureConstNounwind.cpp b/clang/test/CodeGenCXX/2009-05-04-PureConstNounwind.cpp new file mode 100644 index 0000000..8361680 --- /dev/null +++ b/clang/test/CodeGenCXX/2009-05-04-PureConstNounwind.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -fexceptions -emit-llvm %s -o - | FileCheck %s +int c(void) __attribute__((const)); +int p(void) __attribute__((pure)); +int t(void); + +// CHECK: define i32 @_Z1fv() { +int f(void) { + // CHECK: call i32 @_Z1cv() nounwind readnone + // CHECK: call i32 @_Z1pv() nounwind readonly + return c() + p() + t(); +} + +// CHECK: declare i32 @_Z1cv() nounwind readnone +// CHECK: declare i32 @_Z1pv() nounwind readonly +// CHECK-NOT: declare i32 @_Z1tv() nounwind diff --git a/clang/test/CodeGenCXX/2009-06-16-DebugInfoCrash.cpp b/clang/test/CodeGenCXX/2009-06-16-DebugInfoCrash.cpp new file mode 100644 index 0000000..500520b --- /dev/null +++ b/clang/test/CodeGenCXX/2009-06-16-DebugInfoCrash.cpp @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null -g +// This crashes if we try to emit debug info for TEMPLATE_DECL members. +template class K2PtrVectorBase {}; +template class K2Vector {}; +template class K2Vector : public K2PtrVectorBase {}; +class ScriptInfoManager { + void PostRegister() ; + template short ReplaceExistingElement(K2Vector& v); +}; +void ScriptInfoManager::PostRegister() {} diff --git a/clang/test/CodeGenCXX/2009-07-16-Using.cpp b/clang/test/CodeGenCXX/2009-07-16-Using.cpp new file mode 100644 index 0000000..a692d4d --- /dev/null +++ b/clang/test/CodeGenCXX/2009-07-16-Using.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +namespace A { + typedef int B; +} +struct B { +}; +using ::A::B; diff --git a/clang/test/CodeGenCXX/2009-08-05-ZeroInitWidth.cpp b/clang/test/CodeGenCXX/2009-08-05-ZeroInitWidth.cpp new file mode 100644 index 0000000..4404d4a --- /dev/null +++ b/clang/test/CodeGenCXX/2009-08-05-ZeroInitWidth.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - +// rdar://7114564 +struct A { + unsigned long long : (sizeof(unsigned long long) * 8) - 16; +}; +struct B { + A a; +}; +struct B b = { + {} +}; diff --git a/clang/test/CodeGenCXX/2009-08-11-VectorRetTy.cpp b/clang/test/CodeGenCXX/2009-08-11-VectorRetTy.cpp new file mode 100644 index 0000000..21b88c9 --- /dev/null +++ b/clang/test/CodeGenCXX/2009-08-11-VectorRetTy.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 %s -emit-llvm -o /dev/null +// +typedef void (*Func) (); +typedef long long m64 __attribute__((__vector_size__(8), __may_alias__)); +static inline m64 __attribute__((__always_inline__, __nodebug__)) _mm_set1_pi16() {} +template +static void Bork() { + const m64 mmx_0x00ff = _mm_set1_pi16(); +} +struct A {}; +Func arr[] = { + Bork +}; diff --git a/clang/test/CodeGenCXX/2009-09-09-packed-layout.cpp b/clang/test/CodeGenCXX/2009-09-09-packed-layout.cpp new file mode 100644 index 0000000..9de2f61 --- /dev/null +++ b/clang/test/CodeGenCXX/2009-09-09-packed-layout.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -emit-llvm -triple i386-apple-darwin11 %s -o /dev/null +class X { + public: + virtual ~X(); + short y; +}; +#pragma pack(push, 1) +class Z : public X { + public: enum { foo = ('x') }; + virtual int y() const; +}; +#pragma pack(pop) +class Y : public X { +public: enum { foo = ('y'), bar = 0 }; +}; +X x; +Y y; +Z z; diff --git a/clang/test/CodeGenCXX/2009-10-27-crash.cpp b/clang/test/CodeGenCXX/2009-10-27-crash.cpp new file mode 100644 index 0000000..482bb75 --- /dev/null +++ b/clang/test/CodeGenCXX/2009-10-27-crash.cpp @@ -0,0 +1,43 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null +// Radar 7328944 + +typedef struct +{ + unsigned short a : 1; + unsigned short b : 2; + unsigned short c : 1; + unsigned short d : 1; + unsigned short e : 1; + unsigned short f : 1; + unsigned short g : 2; + unsigned short : 7; + union + { + struct + { + unsigned char h : 1; + unsigned char i : 1; + unsigned char j : 1; + unsigned char : 5; + }; + struct + { + unsigned char k : 3; + unsigned char : 5; + }; + }; + unsigned char : 8; +} tt; + +typedef struct +{ + unsigned char s; + tt t; + unsigned int u; +} ttt; + +ttt X = { + 4, + { 0 }, + 55, +}; diff --git a/clang/test/CodeGenCXX/2009-12-23-MissingSext.cpp b/clang/test/CodeGenCXX/2009-12-23-MissingSext.cpp new file mode 100644 index 0000000..e6ff7b3 --- /dev/null +++ b/clang/test/CodeGenCXX/2009-12-23-MissingSext.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s +// The store of p.y into the temporary was not +// getting extended to 32 bits, so uninitialized +// bits of the temporary were used. 7366161. +struct foo { + char x:8; + signed int y:24; +}; +int bar(struct foo p, int x) { +// CHECK: bar +// CHECK: and {{.*}} 16777215 +// CHECK: and {{.*}} 16777215 + x = (p.y > x ? x : p.y); + return x; +// CHECK: ret +} diff --git a/clang/test/CodeGenCXX/2010-03-09-AnonAggregate.cpp b/clang/test/CodeGenCXX/2010-03-09-AnonAggregate.cpp new file mode 100644 index 0000000..99883d8 --- /dev/null +++ b/clang/test/CodeGenCXX/2010-03-09-AnonAggregate.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -g -S -o %t %s +// PR: 6554 +// More then one anonymous aggregates on one line creates chaos when MDNode uniquness is +// combined with RAUW operation. +// This test case causes crashes if malloc is configured to trip buffer overruns. +class MO { + + union { struct { union { int BA; } Val; int Offset; } OffsetedInfo; } Contents; + +}; + +class MO m; diff --git a/clang/test/CodeGenCXX/2010-05-10-Var-DbgInfo.cpp b/clang/test/CodeGenCXX/2010-05-10-Var-DbgInfo.cpp new file mode 100644 index 0000000..7c05535 --- /dev/null +++ b/clang/test/CodeGenCXX/2010-05-10-Var-DbgInfo.cpp @@ -0,0 +1,42 @@ +// RUN: %clang_cc1 -emit-llvm -O0 -g %s -o /dev/null +// PR 7104 + +struct A { + int Ai; +}; + +struct B : public A {}; +struct C : public B {}; + +const char * f(int C::*){ return ""; } +int f(int B::*) { return 1; } + +struct D : public C {}; + +const char * g(int B::*){ return ""; } +int g(int D::*) { return 1; } + +void test() +{ + int i = f(&A::Ai); + + const char * str = g(&A::Ai); +} + +// conversion of B::* to C::* is better than conversion of A::* to C::* +typedef void (A::*pmfa)(); +typedef void (B::*pmfb)(); +typedef void (C::*pmfc)(); + +struct X { + operator pmfa(); + operator pmfb(); +}; + + +void g(pmfc); + +void test2(X x) +{ + g(x); +} diff --git a/clang/test/CodeGenCXX/2010-05-11-alwaysinlineinstantiation.cpp b/clang/test/CodeGenCXX/2010-05-11-alwaysinlineinstantiation.cpp new file mode 100644 index 0000000..fe0740b --- /dev/null +++ b/clang/test/CodeGenCXX/2010-05-11-alwaysinlineinstantiation.cpp @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s + +// CHECK-NOT: ZN12basic_stringIcEC1Ev +// CHECK: ZN12basic_stringIcED1Ev +// CHECK: ZN12basic_stringIcED1Ev +template +class basic_string +{ +public: + basic_string(); + ~basic_string(); +}; + +template +__attribute__ ((__visibility__("hidden"), __always_inline__)) inline +basic_string::basic_string() +{ +} + +template +inline +basic_string::~basic_string() +{ +} + +typedef basic_string string; + +extern template class basic_string; + +int main() +{ + string s; +} diff --git a/clang/test/CodeGenCXX/2010-05-12-PtrToMember-Dbg.cpp b/clang/test/CodeGenCXX/2010-05-12-PtrToMember-Dbg.cpp new file mode 100644 index 0000000..048811f --- /dev/null +++ b/clang/test/CodeGenCXX/2010-05-12-PtrToMember-Dbg.cpp @@ -0,0 +1,17 @@ +//RUN: %clang_cc1 -emit-llvm -g -o - %s | FileCheck %s +//CHECK: DW_TAG_auto_variable +class Foo +{ + public: + int x; + int y; + Foo (int i, int j) { x = i; y = j; } +}; + + +Foo foo(10, 11); + +int main() { + int Foo::* pmi = &Foo::y; + return foo.*pmi; +} diff --git a/clang/test/CodeGenCXX/2010-06-21-LocalVarDbg.cpp b/clang/test/CodeGenCXX/2010-06-21-LocalVarDbg.cpp new file mode 100644 index 0000000..2542378 --- /dev/null +++ b/clang/test/CodeGenCXX/2010-06-21-LocalVarDbg.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -g -emit-llvm %s -o - | FileCheck %s +// Do not use function name to create named metadata used to hold +// local variable info. For example. llvm.dbg.lv.~A is an invalid name. + +// CHECK-NOT: llvm.dbg.lv.~A +class A { +public: + ~A() { int i = 0; i++; } +}; + +int foo(int i) { + A a; + return 0; +} diff --git a/clang/test/CodeGenCXX/2010-06-22-BitfieldInit.cpp b/clang/test/CodeGenCXX/2010-06-22-BitfieldInit.cpp new file mode 100644 index 0000000..f82e527 --- /dev/null +++ b/clang/test/CodeGenCXX/2010-06-22-BitfieldInit.cpp @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -emit-llvm -g %s -o - +struct TEST2 +{ + int subid:32; + int :0; +}; + +typedef struct _TEST3 +{ + TEST2 foo; + TEST2 foo2; +} TEST3; + +TEST3 test = + { + {0}, + {0} + }; + +int main() { return 0; } diff --git a/clang/test/CodeGenCXX/2010-06-22-ZeroBitfield.cpp b/clang/test/CodeGenCXX/2010-06-22-ZeroBitfield.cpp new file mode 100644 index 0000000..c2f37f7 --- /dev/null +++ b/clang/test/CodeGenCXX/2010-06-22-ZeroBitfield.cpp @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -emit-llvm -g %s -o - +struct s8_0 { unsigned : 0; }; +struct s8_1 { double x; }; +struct s8 { s8_0 a; s8_1 b; }; +s8 f8() { return s8(); } diff --git a/clang/test/CodeGenCXX/2010-07-23-DeclLoc.cpp b/clang/test/CodeGenCXX/2010-07-23-DeclLoc.cpp new file mode 100644 index 0000000..7405448 --- /dev/null +++ b/clang/test/CodeGenCXX/2010-07-23-DeclLoc.cpp @@ -0,0 +1,86 @@ +// 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]+]], +// Second: Require that filehandle refer to the correct filename: +// CHECK: {{^!}}[[filehandle]] = metadata {{![{].*}} metadata !"decl_should_be_here.hpp", +typedef long unsigned int __darwin_size_t; +typedef __darwin_size_t size_t; +typedef unsigned char uint8_t; +typedef unsigned int uint32_t; +typedef unsigned long long uint64_t; +namespace std { + template class auto_ptr { + _Tp* _M_ptr; + public: + typedef _Tp element_type; + auto_ptr(element_type* __p = 0) throw() : _M_ptr(__p) { } + element_type& operator*() const throw() { } + }; +} +class Pointer32 { +public: + typedef uint32_t ptr_t; + typedef uint32_t size_t; +}; +class Pointer64 { +public: + typedef uint64_t ptr_t; + typedef uint64_t size_t; +}; +class BigEndian {}; +class LittleEndian {}; +template class SizeAndEndianness { +public: + typedef _SIZE SIZE; +}; +typedef SizeAndEndianness ISA32Little; +typedef SizeAndEndianness ISA32Big; +typedef SizeAndEndianness ISA64Little; +typedef SizeAndEndianness ISA64Big; +template class TRange { +protected: + typename SIZE::ptr_t _location; + typename SIZE::size_t _length; + TRange(typename SIZE::ptr_t location, typename SIZE::size_t length) : _location(location), _length(length) { } +}; +template class TRangeValue : public TRange { + T _value; +public: + TRangeValue(typename SIZE::ptr_t location, typename SIZE::size_t length, T value) : TRange(location, length), _value(value) {}; +}; +template class TAddressRelocator {}; +class CSCppSymbolOwner{}; +class CSCppSymbolOwnerData{}; +template class TRawSymbolOwnerData +{ + TRangeValue< SIZE, uint8_t* > _TEXT_text_section; + const char* _dsym_path; + uint32_t _dylib_current_version; + uint32_t _dylib_compatibility_version; +public: + TRawSymbolOwnerData() : + _TEXT_text_section(0, 0, __null), _dsym_path(__null), _dylib_current_version(0), _dylib_compatibility_version(0) {} +}; +template class TExtendedMachOHeader {}; +# 16 "decl_should_be_here.hpp" +template void extract_dwarf_data_from_header(TExtendedMachOHeader& header, + TRawSymbolOwnerData& symbol_owner_data, + TAddressRelocator* address_relocator) {} +struct CSCppSymbolOwnerHashFunctor { + size_t operator()(const CSCppSymbolOwner& symbol_owner) const { +# 97 "wrong_place_for_decl.cpp" + } +}; +template CSCppSymbolOwnerData* create_symbol_owner_data_arch_specific(CSCppSymbolOwner* symbol_owner, const char* dsym_path) { + typedef typename SIZE_AND_ENDIANNESS::SIZE SIZE; + std::auto_ptr< TRawSymbolOwnerData > data(new TRawSymbolOwnerData()); + std::auto_ptr< TExtendedMachOHeader > header; + extract_dwarf_data_from_header(*header, *data, (TAddressRelocator*)__null); +} +CSCppSymbolOwnerData* create_symbol_owner_data2(CSCppSymbolOwner* symbol_owner, const char* dsym_path) { + create_symbol_owner_data_arch_specific< ISA32Little >(symbol_owner, dsym_path); + create_symbol_owner_data_arch_specific< ISA32Big >(symbol_owner, dsym_path); + create_symbol_owner_data_arch_specific< ISA64Little >(symbol_owner, dsym_path); + create_symbol_owner_data_arch_specific< ISA64Big >(symbol_owner, dsym_path); +} diff --git a/clang/test/CodeGenCXX/2011-12-19-init-list-ctor.cpp b/clang/test/CodeGenCXX/2011-12-19-init-list-ctor.cpp new file mode 100644 index 0000000..a853a57 --- /dev/null +++ b/clang/test/CodeGenCXX/2011-12-19-init-list-ctor.cpp @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - -triple x86_64-linux-gnu | FileCheck %s + +struct A { + A(const char *); +}; + +// CHECK: @arr = global [3 x %struct.S] zeroinitializer +// CHECK: @.str = {{.*}}constant [6 x i8] c"hello\00" +// CHECK: @.str1 = {{.*}}constant [6 x i8] c"world\00" +// CHECK: @.str2 = {{.*}}constant [8 x i8] c"goodbye\00" + +struct S { + int n; + A s; +} arr[] = { + { 0, "hello" }, + { 1, "world" }, + { 2, "goodbye" } +}; + +// CHECK: store i32 0, i32* getelementptr inbounds ([3 x %struct.S]* @arr, i64 0, i64 0, i32 0) +// CHECK: call void @_ZN1AC1EPKc(%struct.A* getelementptr inbounds ([3 x %struct.S]* @arr, i64 0, i64 0, i32 1), i8* getelementptr inbounds ([6 x i8]* @.str, i32 0, i32 0)) +// CHECK: store i32 1, i32* getelementptr inbounds ([3 x %struct.S]* @arr, i64 0, i64 1, i32 0) +// CHECK: call void @_ZN1AC1EPKc(%struct.A* getelementptr inbounds ([3 x %struct.S]* @arr, i64 0, i64 1, i32 1), i8* getelementptr inbounds ([6 x i8]* @.str1, i32 0, i32 0)) +// CHECK: store i32 2, i32* getelementptr inbounds ([3 x %struct.S]* @arr, i64 0, i64 2, i32 0) +// CHECK: call void @_ZN1AC1EPKc(%struct.A* getelementptr inbounds ([3 x %struct.S]* @arr, i64 0, i64 2, i32 1), i8* getelementptr inbounds ([8 x i8]* @.str2, i32 0, i32 0)) diff --git a/clang/test/CodeGenCXX/2012-02-06-VecInitialization.cpp b/clang/test/CodeGenCXX/2012-02-06-VecInitialization.cpp new file mode 100644 index 0000000..720420e --- /dev/null +++ b/clang/test/CodeGenCXX/2012-02-06-VecInitialization.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -emit-llvm -o - -triple i386-apple-darwin %s | FileCheck %s +// PR11930 + +typedef char vec_t __attribute__ ((__ext_vector_type__ (8))); +void h() { +// CHECK: store <8 x i8> + vec_t v(0); +} diff --git a/clang/test/CodeGenCXX/2012-03-16-StoreAlign.cpp b/clang/test/CodeGenCXX/2012-03-16-StoreAlign.cpp new file mode 100644 index 0000000..a6375f8 --- /dev/null +++ b/clang/test/CodeGenCXX/2012-03-16-StoreAlign.cpp @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -emit-llvm -o - -triple x86_64-apple-darwin %s | FileCheck %s +// + +struct Length { + Length(double v) { + m_floatValue = static_cast(v); + } + + bool operator==(const Length& o) const { + return getFloatValue() == o.getFloatValue(); + } + bool operator!=(const Length& o) const { return !(*this == o); } +private: + float getFloatValue() const { + return m_floatValue; + } + float m_floatValue; +}; + + +struct Foo { + static Length inchLength(double inch); + static bool getPageSizeFromName(const Length &A) { + static const Length legalWidth = inchLength(8.5); + if (A != legalWidth) return true; + return false; + } +}; + +// CHECK: @_ZZN3Foo19getPageSizeFromNameERK6LengthE10legalWidth = linkonce_odr global %struct.Length zeroinitializer, align 4 +// CHECK: store float %{{.*}}, float* getelementptr inbounds (%struct.Length* @_ZZN3Foo19getPageSizeFromNameERK6LengthE10legalWidth, i32 0, i32 0), align 1 + +bool bar(Length &b) { + Foo f; + return f.getPageSizeFromName(b); +} diff --git a/clang/test/CodeGenCXX/DynArrayInit.cpp b/clang/test/CodeGenCXX/DynArrayInit.cpp new file mode 100644 index 0000000..4b4c2ec --- /dev/null +++ b/clang/test/CodeGenCXX/DynArrayInit.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -O3 -emit-llvm -o - %s | FileCheck %s +// PR7490 + +// CHECK: define signext i8 @_Z2f0v +// CHECK: ret i8 0 +// CHECK: } +inline void* operator new[](unsigned long, void* __p) { return __p; } +static void f0_a(char *a) { + new (a) char[4](); +} +char f0() { + char a[4]; + f0_a(a); + return a[0] + a[1] + a[2] + a[3]; +} diff --git a/clang/test/CodeGenCXX/PR4827-cast.cpp b/clang/test/CodeGenCXX/PR4827-cast.cpp new file mode 100644 index 0000000..34a840c --- /dev/null +++ b/clang/test/CodeGenCXX/PR4827-cast.cpp @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s +struct A; +struct B; +extern A *f(); +void a() { (B *) f(); } diff --git a/clang/test/CodeGenCXX/PR4983-constructor-conversion.cpp b/clang/test/CodeGenCXX/PR4983-constructor-conversion.cpp new file mode 100644 index 0000000..797a1ba --- /dev/null +++ b/clang/test/CodeGenCXX/PR4983-constructor-conversion.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -emit-llvm-only %s + +struct A { + A(const char *s){} +}; + +struct B { + A a; + + B() : a("test") { } +}; + +void f() { + A a("test"); +} + diff --git a/clang/test/CodeGenCXX/PR5050-constructor-conversion.cpp b/clang/test/CodeGenCXX/PR5050-constructor-conversion.cpp new file mode 100644 index 0000000..c50dafb --- /dev/null +++ b/clang/test/CodeGenCXX/PR5050-constructor-conversion.cpp @@ -0,0 +1,19 @@ +// REQUIRES: x86-registered-target,x86-64-registered-target +// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -S %s -o %t-64.s +// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s +// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -S %s -o %t-32.s +// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s + +struct A { A(const A&, int i1 = 1); }; + +struct B : A { }; + +A f(const B &b) { + return b; +} + +// CHECK-LP64: callq __ZN1AC1ERKS_i + +// CHECK-LP32: calll L__ZN1AC1ERKS_i + + diff --git a/clang/test/CodeGenCXX/PR5093-static-member-function.cpp b/clang/test/CodeGenCXX/PR5093-static-member-function.cpp new file mode 100644 index 0000000..ceab852 --- /dev/null +++ b/clang/test/CodeGenCXX/PR5093-static-member-function.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s +struct a { + static void f(); +}; + +void g(a *a) { + // CHECK: call void @_ZN1a1fEv() + a->f(); +} diff --git a/clang/test/CodeGenCXX/PR5834-constructor-conversion.cpp b/clang/test/CodeGenCXX/PR5834-constructor-conversion.cpp new file mode 100644 index 0000000..044d8e5 --- /dev/null +++ b/clang/test/CodeGenCXX/PR5834-constructor-conversion.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s + +// PR5834 +struct ASTMultiMover {}; +struct ASTMultiPtr { + ASTMultiPtr(); + ASTMultiPtr(ASTMultiPtr&); + ASTMultiPtr(ASTMultiMover mover); + operator ASTMultiMover(); +}; +void f1() { + extern void f0(ASTMultiPtr); + f0(ASTMultiPtr()); +} diff --git a/clang/test/CodeGenCXX/PR5863-unreachable-block.cpp b/clang/test/CodeGenCXX/PR5863-unreachable-block.cpp new file mode 100644 index 0000000..3f32d75 --- /dev/null +++ b/clang/test/CodeGenCXX/PR5863-unreachable-block.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -emit-llvm-only %s + +// PR5863 +class E { }; + +void P1() { + try { + int a=0, b=0; + if (a > b) // simply filling in 0 or 1 doesn't trigger the assertion + throw E(); // commenting out 'if' or 'throw' 'fixes' the assertion failure + try { } catch (...) { } // empty try/catch block needed for failure + } catch (...) { } // this try/catch block needed for failure +} diff --git a/clang/test/CodeGenCXX/PR6474.cpp b/clang/test/CodeGenCXX/PR6474.cpp new file mode 100644 index 0000000..0b155ce --- /dev/null +++ b/clang/test/CodeGenCXX/PR6474.cpp @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 %s -emit-llvm-only + +namespace test0 { +template struct X { + virtual void foo(); + virtual void bar(); + virtual void baz(); +}; + +template void X::foo() {} +template void X::bar() {} +template void X::baz() {} + +template <> void X::foo() {} +template <> void X::bar() {} +} + +namespace test1 { +template struct X { + virtual void foo(); + virtual void bar(); + virtual void baz(); +}; + +template void X::foo() {} +template void X::bar() {} +template void X::baz() {} + +template <> void X::bar() {} +template <> void X::foo() {} +} diff --git a/clang/test/CodeGenCXX/__null.cpp b/clang/test/CodeGenCXX/__null.cpp new file mode 100644 index 0000000..8a17797 --- /dev/null +++ b/clang/test/CodeGenCXX/__null.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 %s -emit-llvm -o %t + +int* a = __null; +int b = __null; + +void f() { + int* c = __null; + int d = __null; +} diff --git a/clang/test/CodeGenCXX/abstract-class-ctors-dtors.cpp b/clang/test/CodeGenCXX/abstract-class-ctors-dtors.cpp new file mode 100644 index 0000000..012c223 --- /dev/null +++ b/clang/test/CodeGenCXX/abstract-class-ctors-dtors.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s + +// Check that we dont emit the complete constructor/destructor for this class. +struct A { + virtual void f() = 0; + A(); + ~A(); +}; + +// CHECK-NOT: define void @_ZN1AC1Ev +// CHECK: define void @_ZN1AC2Ev +// CHECK: define void @_ZN1AD1Ev +// CHECK: define void @_ZN1AD2Ev +A::A() { } + +A::~A() { } diff --git a/clang/test/CodeGenCXX/address-of-fntemplate.cpp b/clang/test/CodeGenCXX/address-of-fntemplate.cpp new file mode 100644 index 0000000..162c6e5 --- /dev/null +++ b/clang/test/CodeGenCXX/address-of-fntemplate.cpp @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s +template void f(T) {} +template void f() { } + +void test() { + // CHECK: @_Z1fIiEvT_ + void (*p)(int) = &f; + + // CHECK: @_Z1fIiEvv + void (*p2)() = f; +} +// CHECK: define linkonce_odr void @_Z1fIiEvT_ +// CHECK: define linkonce_odr void @_Z1fIiEvv + +namespace PR6973 { + template + struct X { + void f(const T&); + }; + + template + int g(); + + void h(X xf) { + xf.f(&g); + } +} diff --git a/clang/test/CodeGenCXX/alloca-align.cpp b/clang/test/CodeGenCXX/alloca-align.cpp new file mode 100644 index 0000000..99d6ab5 --- /dev/null +++ b/clang/test/CodeGenCXX/alloca-align.cpp @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s + +struct s0 { + int Start, End; + unsigned Alignment; + int TheStores __attribute__((aligned(16))); +}; + +// CHECK: define void @f0 +// CHECK: alloca %struct.s0, align 16 +extern "C" void f0() { + (void) s0(); +} + +// CHECK: define void @f1 +// CHECK: alloca %struct.s0, align 16 +extern "C" void f1() { + (void) (struct s0) { 0, 0, 0, 0 }; +} + +// CHECK: define i32 @f2 +// CHECK: alloca %struct.s1, align 2 +struct s1 { short x; short y; }; +extern "C" struct s1 f2(int a, struct s1 *x, struct s1 *y) { + if (a) + return *x; + return *y; +} diff --git a/clang/test/CodeGenCXX/anonymous-namespaces.cpp b/clang/test/CodeGenCXX/anonymous-namespaces.cpp new file mode 100644 index 0000000..32e17a3 --- /dev/null +++ b/clang/test/CodeGenCXX/anonymous-namespaces.cpp @@ -0,0 +1,68 @@ +// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -triple x86_64-apple-darwin10 -emit-llvm %s -o - > %t +// RUN: FileCheck %s -check-prefix=1 < %t +// RUN: FileCheck %s -check-prefix=2 < %t + +int f(); + +namespace { + // CHECK-1: @_ZN12_GLOBAL__N_11bE = internal global i32 0 + // CHECK-1: @_ZN12_GLOBAL__N_1L1cE = internal global i32 0 + // CHECK-1: @_ZN12_GLOBAL__N_11D1dE = internal global i32 0 + // CHECK-1: @_ZN12_GLOBAL__N_11aE = internal global i32 0 + int a = 0; + + int b = f(); + + static int c = f(); + + class D { + static int d; + }; + + int D::d = f(); + + // Check for generation of a VTT with internal linkage + // CHECK-1: @_ZTSN12_GLOBAL__N_11X1EE = internal constant + struct X { + struct EBase { }; + struct E : public virtual EBase { virtual ~E() {} }; + }; + + // CHECK-1: define internal i32 @_ZN12_GLOBAL__N_13fooEv() + int foo() { + return 32; + } + + // CHECK-1: define internal i32 @_ZN12_GLOBAL__N_11A3fooEv() + namespace A { + int foo() { + return 45; + } + } +} + +int concrete() { + return a + foo() + A::foo(); +} + +void test_XE() { throw X::E(); } + +// Miscompile on llvmc plugins. +namespace test2 { + struct A { + template struct B { + static void foo() {} + }; + }; + namespace { + struct C; + } + + // CHECK-2: define void @_ZN5test24testEv() + // CHECK-2: call void @_ZN5test21A1BINS_12_GLOBAL__N_11CEE3fooEv() + void test() { + A::B::foo(); + } + + // CHECK-2: define internal void @_ZN5test21A1BINS_12_GLOBAL__N_11CEE3fooEv() +} diff --git a/clang/test/CodeGenCXX/anonymous-union-member-initializer.cpp b/clang/test/CodeGenCXX/anonymous-union-member-initializer.cpp new file mode 100644 index 0000000..a12ae53 --- /dev/null +++ b/clang/test/CodeGenCXX/anonymous-union-member-initializer.cpp @@ -0,0 +1,181 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s + +// rdar://8818236 +namespace rdar8818236 { +struct S { + char c2; + union { + char c; + int i; + }; +}; + +// CHECK: @_ZN11rdar88182363fooE = global i64 4 +char S::*foo = &S::c; +} + +struct A { + union { + int a; + void* b; + }; + + A() : a(0) { } +}; + +A a; + +namespace PR7021 { + struct X + { + union { long l; }; + }; + + // CHECK: define void @_ZN6PR70211fENS_1XES0_ + void f(X x, X z) { + X x1; + + // CHECK: store i64 1, i64 + x1.l = 1; + + // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64 + X x2(x1); + + X x3; + // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64 + x3 = x1; + + // CHECK: ret void + } +} + +namespace test2 { + struct A { + struct { + union { + int b; + }; + }; + + A(); + }; + + A::A() : b(10) { } + // CHECK: define void @_ZN5test21AC2Ev( + // CHECK-NOT: } + // CHECK: store i32 10 + // CHECK: } +} + +namespace PR10512 { + struct A { + A(); + A(int); + A(long); + + struct { + struct {int x;}; + struct {int y;}; + }; + }; + + // CHECK: define void @_ZN7PR105121AC2Ev + // CHECK: [[THISADDR:%[a-zA-z0-9.]+]] = alloca [[A:%"struct[A-Za-z0-9:.]+"]] + // CHECK-NEXT: store [[A]]* [[THIS:%[a-zA-z0-9.]+]], [[A]]** [[THISADDR]] + // CHECK-NEXT: [[THIS1:%[a-zA-z0-9.]+]] = load [[A]]** [[THISADDR]] + // CHECK-NEXT: ret void + A::A() {} + + // CHECK: define void @_ZN7PR105121AC2Ei + // CHECK: [[THISADDR:%[a-zA-z0-9.]+]] = alloca [[A:%"struct[A-Za-z0-9:.]+"]] + // CHECK-NEXT: [[XADDR:%[a-zA-z0-9.]+]] = alloca i32 + // CHECK-NEXT: store [[A]]* [[THIS:%[a-zA-z0-9.]+]], [[A]]** [[THISADDR]] + // CHECK-NEXT: store i32 [[X:%[a-zA-z0-9.]+]], i32* [[XADDR]] + // CHECK-NEXT: [[THIS1:%[a-zA-z0-9.]+]] = load [[A]]** [[THISADDR]] + // CHECK-NEXT: {{getelementptr inbounds.*i32 0, i32 0}} + // CHECK-NEXT: {{getelementptr inbounds.*i32 0, i32 0}} + // CHECK-NEXT: {{getelementptr inbounds.*i32 0, i32 0}} + // CHECK-NEXT: [[TMP:%[a-zA-z0-9.]+]] = load i32* [[XADDR]] + // CHECK-NEXT: store i32 [[TMP]] + // CHECK-NEXT: ret void + A::A(int x) : x(x) { } + + // CHECK: define void @_ZN7PR105121AC2El + // CHECK: [[THISADDR:%[a-zA-z0-9.]+]] = alloca [[A:%"struct[A-Za-z0-9:.]+"]] + // CHECK-NEXT: [[XADDR:%[a-zA-z0-9.]+]] = alloca i64 + // CHECK-NEXT: store [[A]]* [[THIS:%[a-zA-z0-9.]+]], [[A]]** [[THISADDR]] + // CHECK-NEXT: store i64 [[X:%[a-zA-z0-9.]+]], i64* [[XADDR]] + // CHECK-NEXT: [[THIS1:%[a-zA-z0-9.]+]] = load [[A]]** [[THISADDR]] + // CHECK-NEXT: {{getelementptr inbounds.*i32 0, i32 0}} + // CHECK-NEXT: {{getelementptr inbounds.*i32 0, i32 1}} + // CHECK-NEXT: {{getelementptr inbounds.*i32 0, i32 0}} + // CHECK-NEXT: [[TMP:%[a-zA-z0-9.]+]] = load i64* [[XADDR]] + // CHECK-NEXT: [[CONV:%[a-zA-z0-9.]+]] = trunc i64 [[TMP]] to i32 + // CHECK-NEXT: store i32 [[CONV]] + // CHECK-NEXT: ret void + A::A(long y) : y(y) { } +} + +namespace test3 { + struct A { + union { + mutable char fibers[100]; + struct { + void (*callback)(void*); + void *callback_value; + }; + }; + + A(); + }; + + A::A() : callback(0), callback_value(0) {} + // CHECK: define void @_ZN5test31AC2Ev( + // CHECK: [[THIS:%.*]] = load + // CHECK-NEXT: [[UNION:%.*]] = getelementptr inbounds {{.*}} [[THIS]], i32 0, i32 0 + // CHECK-NEXT: [[STRUCT:%.*]] = bitcast {{.*}}* [[UNION]] to + // CHECK-NEXT: [[CALLBACK:%.*]] = getelementptr inbounds {{.*}} [[STRUCT]], i32 0, i32 0 + // CHECK: store + // CHECK-NEXT: [[UNION:%.*]] = getelementptr inbounds {{.*}} [[THIS]], i32 0, i32 0 + // CHECK-NEXT: [[STRUCT:%.*]] = bitcast {{.*}}* [[UNION]] to + // CHECK-NEXT: [[CVALUE:%.*]] = getelementptr inbounds {{.*}} [[STRUCT]], i32 0, i32 1 + // CHECK-NEXT: store i8* null, i8** [[CVALUE]] +} + +struct S { + // CHECK: store i32 42 + // CHECK: store i32 55 + S() : x(42), y(55) {} + union { + struct { + int x; + union { int y; }; + }; + }; +} s; + + +//PR8760 +template struct Foo { + Foo() : ptr(__nullptr) {} + union { + T *ptr; + }; +}; +Foo f; + +namespace PR9683 { + struct QueueEntry { + union { + struct { + void* mPtr; + union { + unsigned mSubmissionTag; + }; + }; + unsigned mValue; + }; + QueueEntry() {} + }; + QueueEntry QE; +} diff --git a/clang/test/CodeGenCXX/apple-kext-guard-variable.cpp b/clang/test/CodeGenCXX/apple-kext-guard-variable.cpp new file mode 100644 index 0000000..76875a0 --- /dev/null +++ b/clang/test/CodeGenCXX/apple-kext-guard-variable.cpp @@ -0,0 +1,9 @@ +// RUN: %clang -target x86_64-apple-darwin10 -S -o %t.s -mkernel -Xclang -verify %s + +// rdar://problem/9143356 + +int foo(); +void test() { + static int y = 0; + static int x = foo(); // expected-error {{this initialization requires a guard variable, which the kernel does not support}} +} diff --git a/clang/test/CodeGenCXX/apple-kext-indirect-call-2.C b/clang/test/CodeGenCXX/apple-kext-indirect-call-2.C new file mode 100644 index 0000000..7e25200 --- /dev/null +++ b/clang/test/CodeGenCXX/apple-kext-indirect-call-2.C @@ -0,0 +1,77 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fapple-kext -fno-rtti -emit-llvm -o - %s | FileCheck %s + +// CHECK: @_ZTV1A = unnamed_addr constant [4 x i8*] [i8* null, i8* null, i8* bitcast (i8* (%struct.A*)* @_ZNK1A3abcEv to i8*), i8* null] +// CHECK: @_ZTV4Base = unnamed_addr constant [4 x i8*] [i8* null, i8* null, i8* bitcast (i8* (%struct.A*)* @_ZNK4Base3abcEv to i8*), i8* null] +// CHECK: @_ZTV8Derived2 = unnamed_addr constant [5 x i8*] [i8* null, i8* null, i8* null, i8* bitcast (i8* (%struct.A*)* @_ZNK8Derived23efgEv to i8*), i8* null] +// CHECK: @_ZTV2D2 = unnamed_addr constant [5 x i8*] [i8* null, i8* null, i8* null, i8* bitcast (i8* (%struct.A*)* @_ZNK2D23abcEv to i8*), i8* null] + +struct A { + virtual const char* abc(void) const; +}; + +const char* A::abc(void) const {return "A"; }; + +struct B : virtual A { + virtual void VF(); +}; + +void B::VF() {} + +void FUNC(B* p) { +// CHECK: [[T1:%.*]] = load i8* (%struct.A*)** getelementptr inbounds (i8* (%struct.A*)** bitcast ([4 x i8*]* @_ZTV1A to i8* (%struct.A*)**), i64 2) +// CHECK-NEXT: [[T2:%.*]] = call i8* [[T1]] + const char* c = p->A::abc(); +} + + +// Test2 +struct Base { virtual char* abc(void) const; }; + +char* Base::abc() const { return 0; } + +struct Derived : public Base { +}; + +void FUNC1(Derived* p) { +// CHECK: [[U1:%.*]] = load i8* (%struct.A*)** getelementptr inbounds (i8* (%struct.A*)** bitcast ([4 x i8*]* @_ZTV4Base to i8* (%struct.A*)**), i64 2) +// CHECK-NEXT: [[U2:%.*]] = call i8* [[U1]] + char* c = p->Base::abc(); +} + + +// Test3 +struct Base2 { }; + +struct Derived2 : virtual Base2 { + virtual char* efg(void) const; +}; + +char* Derived2::efg(void) const { return 0; } + +void FUNC2(Derived2* p) { +// CHECK: [[V1:%.*]] = load i8* (%struct.A*)** getelementptr inbounds (i8* (%struct.A*)** bitcast ([5 x i8*]* @_ZTV8Derived2 to i8* (%struct.A*)**), i64 3) +// CHECK-NEXT: [[V2:%.*]] = call i8* [[V1]] + char* c = p->Derived2::efg(); +} + +// Test4 +struct Base3 { }; + +struct D1 : virtual Base3 { +}; + +struct D2 : virtual Base3 { + virtual char *abc(void) const; +}; + +struct Sub : D1, D2 { +}; + +char* D2::abc(void) const { return 0; } + +void FUNC3(Sub* p) { +// CHECK: [[W1:%.*]] = load i8* (%struct.A*)** getelementptr inbounds (i8* (%struct.A*)** bitcast ([5 x i8*]* @_ZTV2D2 to i8* (%struct.A*)**), i64 3) +// CHECK-NEXT: [[W2:%.*]] = call i8* [[W1]] + char* c = p->D2::abc(); +} + diff --git a/clang/test/CodeGenCXX/apple-kext-indirect-call.C b/clang/test/CodeGenCXX/apple-kext-indirect-call.C new file mode 100644 index 0000000..2dbb0b8 --- /dev/null +++ b/clang/test/CodeGenCXX/apple-kext-indirect-call.C @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fapple-kext -emit-llvm -o - %s | FileCheck %s + +struct Base { + virtual void abc(void) const; +}; + +void Base::abc(void) const {} + +void FUNC(Base* p) { + p->Base::abc(); +} + +// CHECK: getelementptr inbounds (void (%struct.Base*)** bitcast ([3 x i8*]* @_ZTV4Base to void (%struct.Base*)**), i64 2) +// CHECK-NOT: call void @_ZNK4Base3abcEv diff --git a/clang/test/CodeGenCXX/apple-kext-indirect-virtual-dtor-call.cpp b/clang/test/CodeGenCXX/apple-kext-indirect-virtual-dtor-call.cpp new file mode 100644 index 0000000..bd275f1 --- /dev/null +++ b/clang/test/CodeGenCXX/apple-kext-indirect-virtual-dtor-call.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fapple-kext -fno-rtti -emit-llvm -o - %s | FileCheck %s + +// CHECK: define void @_ZN2B1D0Ev +// CHECK: [[T1:%.*]] = load void (%struct.B1*)** getelementptr inbounds (void (%struct.B1*)** bitcast ([5 x i8*]* @_ZTV2B1 to void (%struct.B1*)**), i64 2) +// CHECK-NEXT: call void [[T1]](%struct.B1* [[T2:%.*]]) +// CHECK: define void @_Z6DELETEP2B1 +// CHECK: [[T3:%.*]] = load void (%struct.B1*)** getelementptr inbounds (void (%struct.B1*)** bitcast ([5 x i8*]* @_ZTV2B1 to void (%struct.B1*)**), i64 2) +// CHECK-NEXT: call void [[T3]](%struct.B1* [[T4:%.*]]) + + +struct B1 { + virtual ~B1(); +}; + +B1::~B1() {} + +void DELETE(B1 *pb1) { + pb1->B1::~B1(); +} diff --git a/clang/test/CodeGenCXX/apple-kext-linkage.C b/clang/test/CodeGenCXX/apple-kext-linkage.C new file mode 100644 index 0000000..59d228e --- /dev/null +++ b/clang/test/CodeGenCXX/apple-kext-linkage.C @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fapple-kext -emit-llvm -o - %s | FileCheck %s + +struct Base { + virtual ~Base(); +} ; + +struct Derived : Base { + void operator delete(void *) { } + Derived(); +}; + +void foo() { + Derived d1; // ok +} + +// CHECK: define internal i32 @_Z1fj( +inline unsigned f(unsigned n) { return n == 0 ? 0 : n + f(n-1); } + +unsigned g(unsigned n) { return f(n); } + +// rdar://problem/10133200: give explicit instantiations external linkage in kernel mode +// CHECK: define void @_Z3barIiEvv() +template void bar() {} +template void bar(); + +// CHECK: define internal i32 @_Z5identIiET_S0_( +template X ident(X x) { return x; } + +int foo(int n) { return ident(n); } + +// CHECK: define internal void @_ZN7DerivedD1Ev( +// CHECK: define internal void @_ZN7DerivedD0Ev( +// CHECK: define internal void @_ZN7DeriveddlEPv( diff --git a/clang/test/CodeGenCXX/apple-kext-no-staticinit-section.C b/clang/test/CodeGenCXX/apple-kext-no-staticinit-section.C new file mode 100644 index 0000000..0401d49 --- /dev/null +++ b/clang/test/CodeGenCXX/apple-kext-no-staticinit-section.C @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fapple-kext -fno-rtti -emit-llvm -o - %s | FileCheck %s +// rdar://8825235 +/** +1) Normally, global object construction code ends up in __StaticInit segment of text section + .section __TEXT,__StaticInit,regular,pure_instructions + In kext mode, they end up in the __text segment. +*/ + +class foo { +public: + foo(); + virtual ~foo(); +}; + +foo a; +foo b; +foo c; +foo::~foo() {} + +// CHECK-NOT: __TEXT,__StaticInit,regular,pure_instructions diff --git a/clang/test/CodeGenCXX/apple-kext.cpp b/clang/test/CodeGenCXX/apple-kext.cpp new file mode 100644 index 0000000..03506a8 --- /dev/null +++ b/clang/test/CodeGenCXX/apple-kext.cpp @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fno-use-cxa-atexit -fapple-kext -emit-llvm -o - %s | FileCheck %s + +// CHECK: @_ZN5test01aE = global [[A:%.*]] zeroinitializer +// CHECK: @llvm.global_ctors = appending global {{.*}} { i32 65535, void ()* [[CTOR0:@.*]] } +// CHECK: @llvm.global_dtors = appending global {{.*}} { i32 65535, void ()* [[DTOR0:@.*]] } + +// rdar://11241230 +namespace test0 { + struct A { A(); ~A(); }; + A a; +} +// CHECK: define internal void [[CTOR0_:@.*]]() +// CHECK: call void @_ZN5test01AC1Ev([[A]]* @_ZN5test01aE) +// CHECK-NEXT: ret void + +// CHECK: define internal void [[CTOR0]]() +// CHECK: call void [[CTOR0_]]() +// CHECK-NEXT: ret void + +// CHECK: define internal void [[DTOR0]]() +// CHECK: call void @_ZN5test01AD1Ev([[A]]* @_ZN5test01aE) +// CHECK-NEXT: ret void diff --git a/clang/test/CodeGenCXX/arm-cc.cpp b/clang/test/CodeGenCXX/arm-cc.cpp new file mode 100644 index 0000000..6027746 --- /dev/null +++ b/clang/test/CodeGenCXX/arm-cc.cpp @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 %s -triple=arm-unknown-linux-gnueabi -target-abi aapcs -emit-llvm -o - | FileCheck %s + +class SMLoc { + const char *Ptr; +public: + SMLoc(); + SMLoc(const SMLoc &RHS); +}; +SMLoc foo(void *p); +void bar(void *x) { + foo(x); +} +void zed(SMLoc x); +void baz() { + SMLoc a; + zed(a); +} + +// CHECK: declare void @_Z3fooPv(%class.SMLoc* sret, i8*) +// CHECK: declare void @_Z3zed5SMLoc(%class.SMLoc*) diff --git a/clang/test/CodeGenCXX/arm.cpp b/clang/test/CodeGenCXX/arm.cpp new file mode 100644 index 0000000..6c60f30 --- /dev/null +++ b/clang/test/CodeGenCXX/arm.cpp @@ -0,0 +1,369 @@ +// RUN: %clang_cc1 %s -triple=thumbv7-apple-ios3.0 -fno-use-cxa-atexit -target-abi apcs-gnu -emit-llvm -o - -fexceptions | FileCheck %s + +// CHECK: @_ZZN5test74testEvE1x = internal global i32 0, align 4 +// CHECK: @_ZGVZN5test74testEvE1x = internal global i32 0 +// CHECK: @_ZZN5test84testEvE1x = internal global [[TEST8A:.*]] zeroinitializer, align 1 +// CHECK: @_ZGVZN5test84testEvE1x = internal global i32 0 + +typedef typeof(sizeof(int)) size_t; + +class foo { +public: + foo(); + virtual ~foo(); +}; + +class bar : public foo { +public: + bar(); +}; + +// The global dtor needs the right calling conv with -fno-use-cxa-atexit +// rdar://7817590 +bar baz; + +// PR9593 +// Make sure atexit(3) is used for global dtors. + +// CHECK: call [[BAR:%.*]]* @_ZN3barC1Ev( +// CHECK-NEXT: call i32 @atexit(void ()* @__dtor_baz) + +// CHECK: define internal void @__dtor_baz() +// CHECK: call [[BAR]]* @_ZN3barD1Ev([[BAR]]* @baz) + +// Destructors and constructors must return this. +namespace test1 { + void foo(); + + struct A { + A(int i) { foo(); } + ~A() { foo(); } + void bar() { foo(); } + }; + + // CHECK: define void @_ZN5test14testEv() + void test() { + // CHECK: [[AV:%.*]] = alloca [[A:%.*]], align 1 + // CHECK: call [[A]]* @_ZN5test11AC1Ei([[A]]* [[AV]], i32 10) + // CHECK: invoke void @_ZN5test11A3barEv([[A]]* [[AV]]) + // CHECK: call [[A]]* @_ZN5test11AD1Ev([[A]]* [[AV]]) + // CHECK: ret void + A a = 10; + a.bar(); + } + + // CHECK: define linkonce_odr [[A]]* @_ZN5test11AC1Ei([[A]]* %this, i32 %i) unnamed_addr + // 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: 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]] +} + +// Awkward virtual cases. +namespace test2 { + void foo(); + + struct A { + int x; + + A(int); + virtual ~A() { foo(); } + }; + + struct B { + int y; + int z; + + B(int); + virtual ~B() { foo(); } + }; + + struct C : A, virtual B { + int q; + + C(int i) : A(i), B(i) { foo(); } + ~C() { foo(); } + }; + + void test() { + C c = 10; + } + + // Tests at eof +} + +namespace test3 { + struct A { + int x; + ~A(); + }; + + void a() { + // CHECK: define void @_ZN5test31aEv() + // CHECK: call noalias i8* @_Znam(i32 48) + // CHECK: store i32 4 + // CHECK: store i32 10 + A *x = new A[10]; + } + + void b(int n) { + // CHECK: define void @_ZN5test31bEi( + // CHECK: [[N:%.*]] = load i32* + // CHECK: @llvm.umul.with.overflow.i32(i32 [[N]], i32 4) + // CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8) + // CHECK: [[OR:%.*]] = or i1 + // CHECK: [[SZ:%.*]] = select i1 [[OR]] + // CHECK: call noalias i8* @_Znam(i32 [[SZ]]) + // CHECK: store i32 4 + // CHECK: store i32 [[N]] + A *x = new A[n]; + } + + void c() { + // CHECK: define void @_ZN5test31cEv() + // CHECK: call noalias i8* @_Znam(i32 808) + // CHECK: store i32 4 + // CHECK: store i32 200 + A (*x)[20] = new A[10][20]; + } + + void d(int n) { + // CHECK: define void @_ZN5test31dEi( + // CHECK: [[N:%.*]] = load i32* + // CHECK: @llvm.umul.with.overflow.i32(i32 [[N]], i32 80) + // CHECK: [[NE:%.*]] = mul i32 [[N]], 20 + // CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8) + // CHECK: [[SZ:%.*]] = select + // CHECK: call noalias i8* @_Znam(i32 [[SZ]]) + // CHECK: store i32 4 + // CHECK: store i32 [[NE]] + A (*x)[20] = new A[n][20]; + } + + void e(A *x) { + // CHECK: define void @_ZN5test31eEPNS_1AE( + // CHECK: icmp eq {{.*}}, null + // CHECK: getelementptr {{.*}}, i64 -8 + // CHECK: getelementptr {{.*}}, i64 4 + // CHECK: bitcast {{.*}} to i32* + // CHECK: load + // CHECK: invoke {{.*}} @_ZN5test31AD1Ev + // CHECK: call void @_ZdaPv + delete [] x; + } + + void f(A (*x)[20]) { + // CHECK: define void @_ZN5test31fEPA20_NS_1AE( + // CHECK: icmp eq {{.*}}, null + // CHECK: getelementptr {{.*}}, i64 -8 + // CHECK: getelementptr {{.*}}, i64 4 + // CHECK: bitcast {{.*}} to i32* + // CHECK: load + // CHECK: invoke {{.*}} @_ZN5test31AD1Ev + // CHECK: call void @_ZdaPv + delete [] x; + } +} + +namespace test4 { + struct A { + int x; + void operator delete[](void *, size_t sz); + }; + + void a() { + // CHECK: define void @_ZN5test41aEv() + // CHECK: call noalias i8* @_Znam(i32 48) + // CHECK: store i32 4 + // CHECK: store i32 10 + A *x = new A[10]; + } + + void b(int n) { + // CHECK: define void @_ZN5test41bEi( + // CHECK: [[N:%.*]] = load i32* + // CHECK: @llvm.umul.with.overflow.i32(i32 [[N]], i32 4) + // CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8) + // CHECK: [[SZ:%.*]] = select + // CHECK: call noalias i8* @_Znam(i32 [[SZ]]) + // CHECK: store i32 4 + // CHECK: store i32 [[N]] + A *x = new A[n]; + } + + void c() { + // CHECK: define void @_ZN5test41cEv() + // CHECK: call noalias i8* @_Znam(i32 808) + // CHECK: store i32 4 + // CHECK: store i32 200 + A (*x)[20] = new A[10][20]; + } + + void d(int n) { + // CHECK: define void @_ZN5test41dEi( + // CHECK: [[N:%.*]] = load i32* + // CHECK: @llvm.umul.with.overflow.i32(i32 [[N]], i32 80) + // CHECK: [[NE:%.*]] = mul i32 [[N]], 20 + // CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8) + // CHECK: [[SZ:%.*]] = select + // CHECK: call noalias i8* @_Znam(i32 [[SZ]]) + // CHECK: store i32 4 + // CHECK: store i32 [[NE]] + A (*x)[20] = new A[n][20]; + } + + void e(A *x) { + // CHECK: define void @_ZN5test41eEPNS_1AE( + // CHECK: [[ALLOC:%.*]] = getelementptr inbounds {{.*}}, i64 -8 + // CHECK: getelementptr inbounds {{.*}}, i64 4 + // CHECK: bitcast + // CHECK: [[T0:%.*]] = load i32* + // CHECK: [[T1:%.*]] = mul i32 4, [[T0]] + // CHECK: [[T2:%.*]] = add i32 [[T1]], 8 + // CHECK: call void @_ZN5test41AdaEPvm(i8* [[ALLOC]], i32 [[T2]]) + delete [] x; + } + + void f(A (*x)[20]) { + // CHECK: define void @_ZN5test41fEPA20_NS_1AE( + // CHECK: [[ALLOC:%.*]] = getelementptr inbounds {{.*}}, i64 -8 + // CHECK: getelementptr inbounds {{.*}}, i64 4 + // CHECK: bitcast + // CHECK: [[T0:%.*]] = load i32* + // CHECK: [[T1:%.*]] = mul i32 4, [[T0]] + // CHECK: [[T2:%.*]] = add i32 [[T1]], 8 + // CHECK: call void @_ZN5test41AdaEPvm(i8* [[ALLOC]], i32 [[T2]]) + delete [] x; + } +} + +// : don't crash +namespace test5 { + struct A { + ~A(); + }; + + // CHECK: define void @_ZN5test54testEPNS_1AE + void test(A *a) { + // CHECK: [[PTR:%.*]] = alloca [[A:%.*]]*, align 4 + // CHECK-NEXT: store [[A]]* {{.*}}, [[A]]** [[PTR]], align 4 + // CHECK-NEXT: [[TMP:%.*]] = load [[A]]** [[PTR]], align 4 + // CHECK-NEXT: call [[A]]* @_ZN5test51AD1Ev([[A]]* [[TMP]]) + // CHECK-NEXT: ret void + a->~A(); + } +} + +namespace test6 { + struct A { + virtual ~A(); + }; + + // CHECK: define void @_ZN5test64testEPNS_1AE + void test(A *a) { + // CHECK: [[AVAR:%.*]] = alloca [[A:%.*]]*, align 4 + // CHECK-NEXT: store [[A]]* {{.*}}, [[A]]** [[AVAR]], align 4 + // CHECK-NEXT: [[V:%.*]] = load [[A]]** [[AVAR]], align 4 + // CHECK-NEXT: [[ISNULL:%.*]] = icmp eq [[A]]* [[V]], null + // CHECK-NEXT: br i1 [[ISNULL]] + // CHECK: [[T0:%.*]] = bitcast [[A]]* [[V]] to [[A]]* ([[A]]*)*** + // CHECK-NEXT: [[T1:%.*]] = load [[A]]* ([[A]]*)*** [[T0]] + // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[A]]* ([[A]]*)** [[T1]], i64 1 + // CHECK-NEXT: [[T3:%.*]] = load [[A]]* ([[A]]*)** [[T2]] + // CHECK-NEXT: call [[A]]* [[T3]]([[A]]* [[V]]) + // CHECK-NEXT: br label + // CHECK: ret void + delete a; + } +} + +namespace test7 { + int foo(); + + // Static and guard tested at top of file + + // CHECK: define void @_ZN5test74testEv() + void test() { + // CHECK: [[T0:%.*]] = load i32* @_ZGVZN5test74testEvE1x + // CHECK-NEXT: [[T1:%.*]] = and i32 [[T0]], 1 + // CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0 + // CHECK-NEXT: br i1 [[T2]] + // -> fallthrough, end + // CHECK: [[T3:%.*]] = call i32 @__cxa_guard_acquire(i32* @_ZGVZN5test74testEvE1x) + // CHECK-NEXT: [[T4:%.*]] = icmp ne i32 [[T3]], 0 + // CHECK-NEXT: br i1 [[T4]] + // -> fallthrough, end + // CHECK: [[INIT:%.*]] = invoke i32 @_ZN5test73fooEv() + // CHECK: store i32 [[INIT]], i32* @_ZZN5test74testEvE1x, align 4 + // CHECK-NEXT: call void @__cxa_guard_release(i32* @_ZGVZN5test74testEvE1x) + // CHECK-NEXT: br label + // -> end + // end: + // CHECK: ret void + static int x = foo(); + + // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + // CHECK-NEXT: cleanup + // CHECK: call void @__cxa_guard_abort(i32* @_ZGVZN5test74testEvE1x) + // CHECK: resume { i8*, i32 } + } +} + +namespace test8 { + struct A { + A(); + ~A(); + }; + + // Static and guard tested at top of file + + // CHECK: define void @_ZN5test84testEv() + void test() { + // CHECK: [[T0:%.*]] = load i32* @_ZGVZN5test84testEvE1x + // CHECK-NEXT: [[T1:%.*]] = and i32 [[T0]], 1 + // CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0 + // CHECK-NEXT: br i1 [[T2]] + // -> fallthrough, end + // CHECK: [[T3:%.*]] = call i32 @__cxa_guard_acquire(i32* @_ZGVZN5test84testEvE1x) + // CHECK-NEXT: [[T4:%.*]] = icmp ne i32 [[T3]], 0 + // CHECK-NEXT: br i1 [[T4]] + // -> fallthrough, end + // CHECK: [[INIT:%.*]] = invoke [[TEST8A]]* @_ZN5test81AC1Ev([[TEST8A]]* @_ZZN5test84testEvE1x) + + // FIXME: Here we register a global destructor that + // unconditionally calls the destructor. That's what we've always + // done for -fno-use-cxa-atexit here, but that's really not + // semantically correct at all. + + // CHECK: call void @__cxa_guard_release(i32* @_ZGVZN5test84testEvE1x) + // CHECK-NEXT: br label + // -> end + // end: + // CHECK: ret void + static A x; + + // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + // CHECK-NEXT: cleanup + // CHECK: call void @__cxa_guard_abort(i32* @_ZGVZN5test84testEvE1x) + // CHECK: resume { i8*, i32 } + } +} + + // CHECK: define linkonce_odr [[C:%.*]]* @_ZTv0_n12_N5test21CD1Ev( + // CHECK: call [[C]]* @_ZN5test21CD1Ev( + // CHECK: ret [[C]]* undef + + // CHECK: define linkonce_odr void @_ZTv0_n12_N5test21CD0Ev( + // CHECK: call void @_ZN5test21CD0Ev( + // CHECK: ret void + +// CH_ECK: @_GLOBAL__D_a() +// CH_ECK: call %class.bar* @_ZN3barD1Ev(%class.bar* @baz) diff --git a/clang/test/CodeGenCXX/array-construction.cpp b/clang/test/CodeGenCXX/array-construction.cpp new file mode 100644 index 0000000..7b565a4 --- /dev/null +++ b/clang/test/CodeGenCXX/array-construction.cpp @@ -0,0 +1,37 @@ +// REQUIRES: x86-registered-target,x86-64-registered-target +// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -S %s -o %t-64.s +// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s +// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -S %s -o %t-32.s +// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s + +extern "C" int printf(...); + +static int count; +static float fcount; + +class xpto { +public: + xpto() : i(count++), f(fcount++) { + printf("xpto::xpto()\n"); + } + int i; + float f; + + ~xpto() { + printf("xpto::~xpto()\n"); + } +}; + +int main() { + xpto array[2][3][4]; + for (int h = 0; h < 2; h++) + for (int i = 0; i < 3; i++) + for (int j = 0; j < 4; j++) + printf("array[%d][%d][%d] = {%d, %f}\n", + h, i, j, array[h][i][j].i, array[h][i][j].f); +} + +// CHECK-LP64: callq __ZN4xptoC1Ev + +// CHECK-LP32: calll L__ZN4xptoC1Ev + diff --git a/clang/test/CodeGenCXX/array-operator-delete-call.cpp b/clang/test/CodeGenCXX/array-operator-delete-call.cpp new file mode 100644 index 0000000..1b23c4d --- /dev/null +++ b/clang/test/CodeGenCXX/array-operator-delete-call.cpp @@ -0,0 +1,64 @@ +// REQUIRES: x86-registered-target,x86-64-registered-target +// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -S %s -o %t-64.s +// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s +// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -S %s -o %t-32.s +// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s + +extern "C" int printf(...); + +int count; + +struct S { + S() : iS (++count) { printf("S::S(%d)\n", iS); } + ~S() { printf("S::~S(%d)\n", iS); } + int iS; +}; + +struct V { + V() : iV (++count) { printf("V::V(%d)\n", iV); } + virtual ~V() { printf("V::~V(%d)\n", iV); } + int iV; +}; + +struct COST +{ + S *cost; + V *vcost; + unsigned *cost_val; + + ~COST(); + COST(); +}; + + +COST::COST() +{ + cost = new S[3]; + vcost = new V[4]; + cost_val = new unsigned[10]; +} + +COST::~COST() +{ + if (cost) { + delete [] cost; + } + if (vcost) { + delete [] vcost; + } + if (cost_val) + delete [] cost_val; +} + +COST c1; + +int main() +{ + COST c3; +} +COST c2; + +// CHECK-LP64: callq __ZdaPv + +// CHECK-LP32: calll L__ZdaPv + diff --git a/clang/test/CodeGenCXX/array-pointer-decay.cpp b/clang/test/CodeGenCXX/array-pointer-decay.cpp new file mode 100644 index 0000000..3fe6b72 --- /dev/null +++ b/clang/test/CodeGenCXX/array-pointer-decay.cpp @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - + +void f(const char*); + +void g() { + f("hello"); +} diff --git a/clang/test/CodeGenCXX/array-value-initialize.cpp b/clang/test/CodeGenCXX/array-value-initialize.cpp new file mode 100644 index 0000000..27607c1 --- /dev/null +++ b/clang/test/CodeGenCXX/array-value-initialize.cpp @@ -0,0 +1,52 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o - %s +// RUN: %clang_cc1 -triple i386-apple-darwin -emit-llvm -o - %s + +// PR5463 +extern "C" int printf(...); + +struct S { + double filler; +}; + +struct Foo { + Foo(void) : bar_(), dbar_(), sbar_() { + for (int i = 0; i < 5; i++) { + printf("bar_[%d] = %d\n", i, bar_[i]); + printf("dbar_[%d] = %f\n", i, dbar_[i]); + printf("sbar_[%d].filler = %f\n", i, sbar_[i].filler); + } + } + + int bar_[5]; + double dbar_[5]; + S sbar_[5]; +}; + +int test1(void) { + Foo a; +} + +// PR7063 + + +struct Unit +{ + Unit() {} + Unit(const Unit& v) {} +}; + + +struct Stuff +{ + Unit leafPos[1]; +}; + + +int main() +{ + + Stuff a; + Stuff b = a; + + return 0; +} diff --git a/clang/test/CodeGenCXX/asm.cpp b/clang/test/CodeGenCXX/asm.cpp new file mode 100644 index 0000000..3b745a7 --- /dev/null +++ b/clang/test/CodeGenCXX/asm.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s + +struct A +{ + ~A(); +}; +int foo(A); + +void bar(A &a) +{ + // CHECK: call void asm + asm("" : : "r"(foo(a)) ); // rdar://8540491 + // CHECK: call void @_ZN1AD1Ev +} diff --git a/clang/test/CodeGenCXX/assign-operator.cpp b/clang/test/CodeGenCXX/assign-operator.cpp new file mode 100644 index 0000000..e19df27 --- /dev/null +++ b/clang/test/CodeGenCXX/assign-operator.cpp @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -verify -o - |FileCheck %s + +class x { +public: int operator=(int); +}; +void a() { + x a; + a = 1u; +} + +void f(int i, int j) { + // CHECK: load i32 + // CHECK: load i32 + // CHECK: add nsw i32 + // CHECK: store i32 + // CHECK: store i32 17, i32 + // CHECK: ret + (i += j) = 17; +} + +// Taken from g++.old-deja/g++.jason/net.C +namespace test1 { + template void fn (T t) { } + template struct A { + void (*p)(T); + A() { p = fn; } + }; + + A a; +} diff --git a/clang/test/CodeGenCXX/atomic.cpp b/clang/test/CodeGenCXX/atomic.cpp new file mode 100644 index 0000000..36bb4ef --- /dev/null +++ b/clang/test/CodeGenCXX/atomic.cpp @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - -triple=i686-apple-darwin9 | FileCheck %s + +namespace PR11411 { + template struct Ptr { + void f(); + }; + + // CHECK: define linkonce_odr void @_ZN7PR114113PtrIiE1fEv + // CHECK-NOT: ret + template inline void Ptr<_Tp>::f() { + int* _refcount; + // CHECK: atomicrmw add i32* + __sync_fetch_and_add(_refcount, 1); + // CHECK-NEXT: ret void + } + void f(Ptr *a) { a->f(); } +} diff --git a/clang/test/CodeGenCXX/atomicinit.cpp b/clang/test/CodeGenCXX/atomicinit.cpp new file mode 100644 index 0000000..38d012e --- /dev/null +++ b/clang/test/CodeGenCXX/atomicinit.cpp @@ -0,0 +1,48 @@ +// RUN: %clang_cc1 %s -emit-llvm -O1 -o - -triple=i686-apple-darwin9 | FileCheck %s +struct A { + _Atomic(int) i; + A(int j); + void v(int j); +}; +// Storing to atomic values should be atomic +// CHECK: store atomic i32 +void A::v(int j) { i = j; } +// Initialising atomic values should not be atomic +// CHECK-NOT: store atomic +A::A(int j) : i(j) {} + +struct B { + int i; + B(int x) : i(x) {} +}; + +_Atomic(B) b; + +// CHECK: define void @_Z11atomic_initR1Ai +void atomic_init(A& a, int i) { + // CHECK-NOT: atomic + // CHECK: tail call void @_ZN1BC1Ei + __c11_atomic_init(&b, B(i)); + // CHECK-NEXT: ret void +} + +// CHECK: define void @_Z16atomic_init_boolPU7_Atomicbb +void atomic_init_bool(_Atomic(bool) *ab, bool b) { + // CHECK-NOT: atomic + // CHECK: {{zext i1.*to i8}} + // CHECK-NEXT: store i8 + __c11_atomic_init(ab, b); + // CHECK-NEXT: ret void +} + +struct AtomicBoolMember { + _Atomic(bool) ab; + AtomicBoolMember(bool b); +}; + +// CHECK: define void @_ZN16AtomicBoolMemberC2Eb +// CHECK: {{zext i1.*to i8}} +// CHECK-NEXT: store i8 +// CHECK-NEXT: ret void +AtomicBoolMember::AtomicBoolMember(bool b) : ab(b) { } + diff --git a/clang/test/CodeGenCXX/attr-used.cpp b/clang/test/CodeGenCXX/attr-used.cpp new file mode 100644 index 0000000..2c82184 --- /dev/null +++ b/clang/test/CodeGenCXX/attr-used.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s + +// : clang++ not respecting __attribute__((used)) on destructors +struct X0 { + // CHECK: define linkonce_odr {{.*}} @_ZN2X0C1Ev + __attribute__((used)) X0() {} + // CHECK: define linkonce_odr {{.*}} @_ZN2X0D1Ev + __attribute__((used)) ~X0() {} +}; diff --git a/clang/test/CodeGenCXX/attr.cpp b/clang/test/CodeGenCXX/attr.cpp new file mode 100644 index 0000000..9e8740e --- /dev/null +++ b/clang/test/CodeGenCXX/attr.cpp @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-llvm -o - %s | FileCheck %s + +// CHECK: @test2 = alias i32 ()* @_Z5test1v + +// CHECK: define i32 @_Z3foov() nounwind align 1024 +int foo() __attribute__((aligned(1024))); +int foo() { } + +class C { + virtual void bar1() __attribute__((aligned(1))); + virtual void bar2() __attribute__((aligned(2))); + virtual void bar3() __attribute__((aligned(1024))); +} c; + +// CHECK: define void @_ZN1C4bar1Ev(%class.C* %this) nounwind align 2 +void C::bar1() { } + +// CHECK: define void @_ZN1C4bar2Ev(%class.C* %this) nounwind align 2 +void C::bar2() { } + +// CHECK: define void @_ZN1C4bar3Ev(%class.C* %this) nounwind align 1024 +void C::bar3() { } + +// PR6635 +// CHECK: define i32 @_Z5test1v() +int test1() { return 10; } +// CHECK at top of file +extern "C" int test2() __attribute__((alias("_Z5test1v"))); diff --git a/clang/test/CodeGenCXX/bitfield-layout.cpp b/clang/test/CodeGenCXX/bitfield-layout.cpp new file mode 100644 index 0000000..15f33d2 --- /dev/null +++ b/clang/test/CodeGenCXX/bitfield-layout.cpp @@ -0,0 +1,43 @@ +// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - -O3 | FileCheck -check-prefix LP64 %s +// RUN: %clang_cc1 %s -triple=i386-apple-darwin10 -emit-llvm -o - -O3 | FileCheck -check-prefix LP32 %s + +// CHECK-LP64: %union.Test1 = type { i32, [4 x i8] } +union Test1 { + int a; + int b: 39; +} t1; + +// CHECK-LP64: %union.Test2 = type { i8 } +union Test2 { + int : 6; +} t2; + +// CHECK-LP64: %union.Test3 = type { [2 x i8] } +union Test3 { + int : 9; +} t3; + + +#define CHECK(x) if (!(x)) return __LINE__ + +int f() { + struct { + int a; + + unsigned long long b : 65; + + int c; + } c; + + c.a = 0; + c.b = (unsigned long long)-1; + c.c = 0; + + CHECK(c.a == 0); + CHECK(c.b == (unsigned long long)-1); + CHECK(c.c == 0); + +// CHECK-LP64: ret i32 0 +// CHECK-LP32: ret i32 0 + return 0; +} diff --git a/clang/test/CodeGenCXX/block-byref-cxx-objc.cpp b/clang/test/CodeGenCXX/block-byref-cxx-objc.cpp new file mode 100644 index 0000000..30f1f07 --- /dev/null +++ b/clang/test/CodeGenCXX/block-byref-cxx-objc.cpp @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - -fblocks | FileCheck %s +// rdar://8594790 + +struct A { + int x; + A(const A &); + A(); + ~A(); +}; + +int main() +{ + __block A BYREF_VAR; + ^{ BYREF_VAR.x = 1234; }; + return 0; +} + +// CHECK: define internal void @__Block_byref_object_copy_ +// CHECK: call {{.*}} @_ZN1AC1ERKS_ +// CHECK: define internal void @__Block_byref_object_dispose_ +// CHECK: call {{.*}} @_ZN1AD1Ev +// CHECK: define internal void @__copy_helper_block_ +// CHECK: call void @_Block_object_assign +// CHECK: define internal void @__destroy_helper_block_ +// CHECK: call void @_Block_object_dispose + +// rdar://problem/11135650 +namespace test1 { + struct A { int x; A(); ~A(); }; + + void test() { + return; + __block A a; + } +} diff --git a/clang/test/CodeGenCXX/block-destruct.cpp b/clang/test/CodeGenCXX/block-destruct.cpp new file mode 100644 index 0000000..f809ca2 --- /dev/null +++ b/clang/test/CodeGenCXX/block-destruct.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 %s -fblocks -triple x86_64-apple-darwin -emit-llvm -o - | FileCheck %s + +struct A { ~A(); }; + +void f() { + __block A a; +} + +// CHECK: call void @_ZN1AD1Ev diff --git a/clang/test/CodeGenCXX/block-in-ctor-dtor.cpp b/clang/test/CodeGenCXX/block-in-ctor-dtor.cpp new file mode 100644 index 0000000..e4389a4 --- /dev/null +++ b/clang/test/CodeGenCXX/block-in-ctor-dtor.cpp @@ -0,0 +1,48 @@ +// RUN: %clang_cc1 %s -fblocks -triple x86_64-apple-darwin -emit-llvm -o - | FileCheck %s + +typedef void (^dispatch_block_t)(void); + +void dispatch_once(dispatch_block_t); + +class Zone { +public: + Zone(); + ~Zone(); +}; + +Zone::Zone() { + dispatch_once(^{}); + dispatch_once(^{}); +} + +Zone::~Zone() { + dispatch_once(^{}); + dispatch_once(^{}); +} + +class X : public virtual Zone { + X(); + ~X(); +}; + +X::X() { + dispatch_once(^{}); + dispatch_once(^{}); +}; + +X::~X() { + dispatch_once(^{}); + dispatch_once(^{}); +}; + + +// CHECK: define internal void @___ZN4ZoneC2Ev_block_invoke_ +// CHECK: define internal void @___ZN4ZoneC2Ev_block_invoke_ +// CHECK: define internal void @___ZN4ZoneD2Ev_block_invoke_ +// CHECK: define internal void @___ZN4ZoneD2Ev_block_invoke_ +// CHECK: define internal void @___ZN1XC1Ev_block_invoke_ +// CHECK: define internal void @___ZN1XC1Ev_block_invoke_ +// CHECK: define internal void @___ZN1XC2Ev_block_invoke_ +// CHECK: define internal void @___ZN1XC2Ev_block_invoke_ +// CHECK: define internal void @___ZN1XD2Ev_block_invoke_ +// CHECK: define internal void @___ZN1XD2Ev_block_invoke_ diff --git a/clang/test/CodeGenCXX/block.cpp b/clang/test/CodeGenCXX/block.cpp new file mode 100644 index 0000000..619d8b0 --- /dev/null +++ b/clang/test/CodeGenCXX/block.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - -fblocks +// Just test that this doesn't crash the compiler... + +void func(void*); + +struct Test +{ + virtual void use() { func((void*)this); } + Test(Test&c) { func((void*)this); } + Test() { func((void*)this); } +}; + +void useBlock(void (^)(void)); + +int main (void) { + __block Test t; + useBlock(^(void) { t.use(); }); +} + diff --git a/clang/test/CodeGenCXX/blocks-cxx11.cpp b/clang/test/CodeGenCXX/blocks-cxx11.cpp new file mode 100644 index 0000000..996db1a --- /dev/null +++ b/clang/test/CodeGenCXX/blocks-cxx11.cpp @@ -0,0 +1,84 @@ +// RUN: %clang_cc1 %s -fblocks -triple x86_64-apple-darwin -std=c++11 -emit-llvm -o - | FileCheck %s + +template void takeItByValue(T); +void takeABlock(void (^)()); + +// rdar://problem/11022704 +namespace test_int { + void test() { + const int x = 100; + takeABlock(^{ takeItByValue(x); }); + // CHECK: call void @_Z13takeItByValueIiEvT_(i32 100) + } +} + +namespace test_int_ref { + void test() { + const int y = 200; + const int &x = y; + takeABlock(^{ takeItByValue(x); }); + + // TODO: there's no good reason that this isn't foldable. + // CHECK: call void @_Z13takeItByValueIiEvT_(i32 {{%.*}}) + } +} + +namespace test_float { + void test() { + const float x = 1; + takeABlock(^{ takeItByValue(x); }); + // CHECK: call void @_Z13takeItByValueIfEvT_(float 1.0 + } +} + +namespace test_float_ref { + void test() { + const float y = 100; + const float &x = y; + takeABlock(^{ takeItByValue(x); }); + + // TODO: there's no good reason that this isn't foldable. + // CHECK: call void @_Z13takeItByValueIfEvT_(float {{%.*}}) + } +} + +namespace test_complex_int { + void test() { + constexpr _Complex int x = 500; + takeABlock(^{ takeItByValue(x); }); + // CHECK: store i32 500, + + // CHECK: store i32 500, + // CHECK-NEXT: store i32 0, + // CHECK-NEXT: [[COERCE:%.*]] = bitcast + // CHECK-NEXT: [[CVAL:%.*]] = load i64* [[COERCE]] + // CHECK-NEXT: call void @_Z13takeItByValueICiEvT_(i64 [[CVAL]]) + } +} + +namespace test_complex_int_ref { + void test() { + const _Complex int y = 100; + const _Complex int &x = y; + takeABlock(^{ takeItByValue(x); }); + // CHECK: call void @_Z13takeItByValueICiEvT_(i64 + } +} + +namespace test_complex_int_ref_mutable { + _Complex int y = 100; + void test() { + const _Complex int &x = y; + takeABlock(^{ takeItByValue(x); }); + // CHECK: [[R:%.*]] = load i32* getelementptr inbounds ({ i32, i32 }* @_ZN28test_complex_int_ref_mutable1yE, i32 0, i32 0) + // CHECK-NEXT: [[I:%.*]] = load i32* getelementptr inbounds ({ i32, i32 }* @_ZN28test_complex_int_ref_mutable1yE, i32 0, i32 1) + // CHECK-NEXT: [[RSLOT:%.*]] = getelementptr inbounds { i32, i32 }* [[CSLOT:%.*]], i32 0, i32 0 + // CHECK-NEXT: [[ISLOT:%.*]] = getelementptr inbounds { i32, i32 }* [[CSLOT]], i32 0, i32 1 + // CHECK-NEXT: store i32 [[R]], i32* [[RSLOT]] + // CHECK-NEXT: store i32 [[I]], i32* [[ISLOT]] + // CHECK-NEXT: [[COERCE:%.*]] = bitcast { i32, i32 }* [[CSLOT]] to i64* + // CHECK-NEXT: [[CVAL:%.*]] = load i64* [[COERCE]], + // CHECK-NEXT: call void @_Z13takeItByValueICiEvT_(i64 [[CVAL]]) + } +} + diff --git a/clang/test/CodeGenCXX/blocks.cpp b/clang/test/CodeGenCXX/blocks.cpp new file mode 100644 index 0000000..eb54478 --- /dev/null +++ b/clang/test/CodeGenCXX/blocks.cpp @@ -0,0 +1,228 @@ +// RUN: %clang_cc1 %s -fblocks -triple x86_64-apple-darwin -emit-llvm -o - | FileCheck %s + +namespace test0 { + // CHECK: define void @_ZN5test04testEi( + // CHECK: define internal void @__test_block_invoke_{{.*}}( + // CHECK: define internal void @__block_global_{{.*}}( + void test(int x) { + ^{ ^{ (void) x; }; }; + } +} + +extern void (^out)(); + +namespace test1 { + // Capturing const objects doesn't require a local block. + // CHECK: define void @_ZN5test15test1Ev() + // CHECK: store void ()* bitcast ({{.*}} @__block_literal_global{{.*}} to void ()*), void ()** @out + void test1() { + const int NumHorsemen = 4; + out = ^{ (void) NumHorsemen; }; + } + + // That applies to structs too... + // CHECK: define void @_ZN5test15test2Ev() + // CHECK: store void ()* bitcast ({{.*}} @__block_literal_global{{.*}} to void ()*), void ()** @out + struct loc { double x, y; }; + void test2() { + const loc target = { 5, 6 }; + out = ^{ (void) target; }; + } + + // ...unless they have mutable fields... + // CHECK: define void @_ZN5test15test3Ev() + // CHECK: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]], + // CHECK: [[T0:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to void ()* + // CHECK: store void ()* [[T0]], void ()** @out + struct mut { mutable int x; }; + void test3() { + const mut obj = { 5 }; + out = ^{ (void) obj; }; + } + + // ...or non-trivial destructors... + // CHECK: define void @_ZN5test15test4Ev() + // CHECK: [[OBJ:%.*]] = alloca + // CHECK: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]], + // CHECK: [[T0:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to void ()* + // CHECK: store void ()* [[T0]], void ()** @out + struct scope { int x; ~scope(); }; + void test4() { + const scope obj = { 5 }; + out = ^{ (void) obj; }; + } + + // ...or non-trivial copy constructors, but it's not clear how to do + // that and still have a constant initializer in '03. +} + +namespace test2 { + struct A { + A(); + A(const A &); + ~A(); + }; + + struct B { + B(); + B(const B &); + ~B(); + }; + + // CHECK: define void @_ZN5test24testEv() + void test() { + __block A a; + __block B b; + } + + // CHECK: define internal void @__Block_byref_object_copy + // CHECK: call void @_ZN5test21AC1ERKS0_( + + // CHECK: define internal void @__Block_byref_object_dispose + // CHECK: call void @_ZN5test21AD1Ev( + + // CHECK: define internal void @__Block_byref_object_copy + // CHECK: call void @_ZN5test21BC1ERKS0_( + + // CHECK: define internal void @__Block_byref_object_dispose + // CHECK: call void @_ZN5test21BD1Ev( +} + +// rdar://problem/9334739 +// Make sure we mark destructors for parameters captured in blocks. +namespace test3 { + struct A { + A(const A&); + ~A(); + }; + + struct B : A { + }; + + void test(B b) { + extern void consume(void(^)()); + consume(^{ (void) b; }); + } +} + +// rdar://problem/9971485 +namespace test4 { + struct A { + A(); + ~A(); + }; + + void foo(A a); + + void test() { + extern void consume(void(^)()); + consume(^{ return foo(A()); }); + } + // CHECK: define void @_ZN5test44testEv() + // CHECK: define internal void @__test_block_invoke + // CHECK: [[TMP:%.*]] = alloca [[A:%.*]], align 1 + // CHECK-NEXT: bitcast i8* + // CHECK-NEXT: call void @_ZN5test41AC1Ev([[A]]* [[TMP]]) + // CHECK-NEXT: call void @_ZN5test43fooENS_1AE([[A]]* [[TMP]]) + // CHECK-NEXT: call void @_ZN5test41AD1Ev([[A]]* [[TMP]]) + // CHECK-NEXT: ret void +} + +namespace test5 { + struct A { + unsigned afield; + A(); + A(const A&); + ~A(); + void foo() const; + }; + + void doWithBlock(void(^)()); + + void test(bool cond) { + A x; + void (^b)() = (cond ? ^{ x.foo(); } : (void(^)()) 0); + doWithBlock(b); + } + + // CHECK: define void @_ZN5test54testEb( + // CHECK: [[COND:%.*]] = alloca i8 + // CHECK-NEXT: [[X:%.*]] = alloca [[A:%.*]], align 4 + // CHECK-NEXT: [[B:%.*]] = alloca void ()*, align 8 + // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:.*]], align 8 + // CHECK-NEXT: [[CLEANUP_ACTIVE:%.*]] = alloca i1 + // CHECK-NEXT: [[T0:%.*]] = zext i1 + // CHECK-NEXT: store i8 [[T0]], i8* [[COND]], align 1 + // CHECK-NEXT: call void @_ZN5test51AC1Ev([[A]]* [[X]]) + // CHECK-NEXT: [[CLEANUP_ADDR:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5 + // CHECK-NEXT: [[T0:%.*]] = load i8* [[COND]], align 1 + // CHECK-NEXT: [[T1:%.*]] = trunc i8 [[T0]] to i1 + // CHECK-NEXT: store i1 false, i1* [[CLEANUP_ACTIVE]] + // CHECK-NEXT: br i1 [[T1]], + + // CHECK-NOT: br + // CHECK: [[CAPTURE:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5 + // CHECK-NEXT: call void @_ZN5test51AC1ERKS0_([[A]]* [[CAPTURE]], [[A]]* [[X]]) + // CHECK-NEXT: store i1 true, i1* [[CLEANUP_ACTIVE]] + // CHECK-NEXT: bitcast [[BLOCK_T]]* [[BLOCK]] to void ()* + // CHECK-NEXT: br label + // CHECK: br label + // CHECK: phi + // CHECK-NEXT: store + // CHECK-NEXT: load + // CHECK-NEXT: call void @_ZN5test511doWithBlockEU13block_pointerFvvE( + // CHECK-NEXT: [[T0:%.*]] = load i1* [[CLEANUP_ACTIVE]] + // CHECK-NEXT: br i1 [[T0]] + // CHECK: call void @_ZN5test51AD1Ev([[A]]* [[CLEANUP_ADDR]]) + // CHECK-NEXT: br label + // CHECK: call void @_ZN5test51AD1Ev([[A]]* [[X]]) + // CHECK-NEXT: ret void +} + +namespace test6 { + struct A { + A(); + ~A(); + }; + + void foo(const A &, void (^)()); + void bar(); + + void test() { + // Make sure that the temporary cleanup isn't somehow captured + // within the block. + foo(A(), ^{ bar(); }); + bar(); + } + + // CHECK: define void @_ZN5test64testEv() + // CHECK: [[TEMP:%.*]] = alloca [[A:%.*]], align 1 + // CHECK-NEXT: call void @_ZN5test61AC1Ev([[A]]* [[TEMP]]) + // CHECK-NEXT: call void @_ZN5test63fooERKNS_1AEU13block_pointerFvvE( + // CHECK-NEXT: call void @_ZN5test61AD1Ev([[A]]* [[TEMP]]) + // CHECK-NEXT: call void @_ZN5test63barEv() + // CHECK-NEXT: ret void +} + +namespace test7 { + int f() { + static int n; + int *const p = &n; + return ^{ return *p; }(); + } +} + +namespace test8 { + // : failure to capture this after skipping rebuild + // of the 'this' pointer. + struct X { + int x; + + template + int foo() { + return ^ { return x; }(); + } + }; + + template int X::foo(); +} diff --git a/clang/test/CodeGenCXX/builtins.cpp b/clang/test/CodeGenCXX/builtins.cpp new file mode 100644 index 0000000..4542563 --- /dev/null +++ b/clang/test/CodeGenCXX/builtins.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s + +// PR8839 +extern "C" char memmove(); + +int main() { + // CHECK: call signext i8 @memmove() + return memmove(); +} + +// + +template +int equal(const char *s1, const char *s2) { + return Compare(s1, s2) == 0; +} + +// CHECK: define weak_odr i32 @_Z5equalIXadL_Z16__builtin_strcmpPKcS1_EEEiS1_S1_ +// CHECK: call i32 @strcmp +template int equal<&__builtin_strcmp>(const char*, const char*); + diff --git a/clang/test/CodeGenCXX/c-linkage.cpp b/clang/test/CodeGenCXX/c-linkage.cpp new file mode 100644 index 0000000..b1f07b7 --- /dev/null +++ b/clang/test/CodeGenCXX/c-linkage.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s +// pr6644 + +extern "C" { + namespace N { + struct X { + virtual void f(); + }; + void X::f() { } + } +} + +// CHECK: define void @_ZN1N1X1fEv diff --git a/clang/test/CodeGenCXX/c99-variable-length-array.cpp b/clang/test/CodeGenCXX/c99-variable-length-array.cpp new file mode 100644 index 0000000..d486f9b --- /dev/null +++ b/clang/test/CodeGenCXX/c99-variable-length-array.cpp @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s +struct X { + X(); + ~X(); +}; + +struct Y { + Y(); + ~Y(); +}; + +// CHECK: define void @_Z1fiPPKc( +void f(int argc, const char* argv[]) { + // CHECK: call void @_ZN1XC1Ev + X x; + // CHECK: call i8* @llvm.stacksave( + const char *argv2[argc]; + // CHECK: call void @_ZN1YC1Ev + Y y; + for (int i = 0; i != argc; ++i) + argv2[i] = argv[i]; + + // CHECK: call void @_ZN1YD1Ev + // CHECK: call void @llvm.stackrestore + // CHECK: call void @_ZN1XD1Ev + // CHECK: ret void +} + +namespace PR11744 { + // Make sure this doesn't crash; there was a use-after-free issue + // for this testcase. + template int f(int n) { + T arr[3][n]; + return 3; + } + int test = f(0); +} diff --git a/clang/test/CodeGenCXX/call-arg-zero-temp.cpp b/clang/test/CodeGenCXX/call-arg-zero-temp.cpp new file mode 100644 index 0000000..101e81f --- /dev/null +++ b/clang/test/CodeGenCXX/call-arg-zero-temp.cpp @@ -0,0 +1,23 @@ +// REQUIRES: x86-registered-target,x86-64-registered-target +// RUN: %clang_cc1 -triple x86_64-apple-darwin -S %s -o %t-64.s +// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s +// RUN: %clang_cc1 -triple i386-apple-darwin -S %s -o %t-32.s +// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s + + +extern "C" int printf(...); + +struct obj{ int a; float b; double d; }; + +void foo(obj o) { + printf("%d %f %f\n", o.a, o.b, o.d); +} + +int main() { + obj o = obj(); + foo(obj()); +} + +// CHECK-LP64: callq __Z3foo3obj + +// CHECK-LP32: calll __Z3foo3obj diff --git a/clang/test/CodeGenCXX/cast-conversion.cpp b/clang/test/CodeGenCXX/cast-conversion.cpp new file mode 100644 index 0000000..d023b9a --- /dev/null +++ b/clang/test/CodeGenCXX/cast-conversion.cpp @@ -0,0 +1,33 @@ +// REQUIRES: x86-registered-target,x86-64-registered-target +// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -S %s -o %t-64.s +// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s +// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -S %s -o %t-32.s +// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s + +struct A { + A(int); +}; + +struct B { + B(A); +}; + +int main () { + (B)10; + B(10); + static_cast(10); +} + +// CHECK-LP64: callq __ZN1AC1Ei +// CHECK-LP64: callq __ZN1BC1E1A +// CHECK-LP64: callq __ZN1AC1Ei +// CHECK-LP64: callq __ZN1BC1E1A +// CHECK-LP64: callq __ZN1AC1Ei +// CHECK-LP64: callq __ZN1BC1E1A + +// CHECK-LP32: calll L__ZN1AC1Ei +// CHECK-LP32: calll L__ZN1BC1E1A +// CHECK-LP32: calll L__ZN1AC1Ei +// CHECK-LP32: calll L__ZN1BC1E1A +// CHECK-LP32: calll L__ZN1AC1Ei +// CHECK-LP32: calll L__ZN1BC1E1A diff --git a/clang/test/CodeGenCXX/casts.cpp b/clang/test/CodeGenCXX/casts.cpp new file mode 100644 index 0000000..436b722 --- /dev/null +++ b/clang/test/CodeGenCXX/casts.cpp @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 %s -emit-llvm -o %t + +// PR5248 +namespace PR5248 { +struct A { + void copyFrom(const A &src); + void addRef(void); + + A& operator=(int); +}; + +void A::copyFrom(const A &src) { + ((A &)src).addRef(); +} +} + +// reinterpret_cast to self +void test(PR5248::A* a) { + reinterpret_cast(*a) = 17; +} diff --git a/clang/test/CodeGenCXX/class-layout.cpp b/clang/test/CodeGenCXX/class-layout.cpp new file mode 100644 index 0000000..dac0a0a --- /dev/null +++ b/clang/test/CodeGenCXX/class-layout.cpp @@ -0,0 +1,79 @@ +// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s + +// An extra byte should be allocated for an empty class. +namespace Test1 { + // CHECK: %"struct.Test1::A" = type { i8 } + struct A { } *a; +} + +namespace Test2 { + // No need to add tail padding here. + // CHECK: %"struct.Test2::A" = type { i8*, i32 } + struct A { void *a; int b; } *a; +} + +namespace Test3 { + // C should have a vtable pointer. + // CHECK: %"struct.Test3::A" = type { i32 (...)**, i32 } + struct A { virtual void f(); int a; } *a; +} + +namespace Test4 { + // Test from PR5589. + // CHECK: %"struct.Test4::B" = type { %"struct.Test4::A", i16, double } + // CHECK: %"struct.Test4::A" = type { i32, i8, float } + struct A { + int a; + char c; + float b; + }; + struct B : public A { + short d; + double e; + } *b; +} + +namespace Test5 { + struct A { + virtual void f(); + char a; + }; + + // CHECK: %"struct.Test5::B" = type { [9 x i8], i8, i8, [5 x i8] } + struct B : A { + char b : 1; + char c; + } *b; +} + +// PR10912: don't crash +namespace Test6 { + template class A { + // If T is complete, IR-gen will want to translate it recursively + // when translating T*. + T *foo; + }; + + class B; + + // This causes IR-gen to have an incomplete translation of A + // sitting around. + A *a; + + class C {}; + class B : public C { + // This forces Sema to instantiate A, which triggers a callback + // to IR-gen. Because of the previous, incomplete translation, + // IR-gen actually cares, and it immediately tries to complete + // A's IR type. That, in turn, causes the translation of B*. + // B isn't complete yet, but it has a definition, and if we try to + // compute a record layout for that definition then we'll really + // regret it later. + A a; + }; + + // The derived class E and empty base class C are required to + // provoke the original assertion. + class E : public B {}; + E *e; +} diff --git a/clang/test/CodeGenCXX/compound-literals.cpp b/clang/test/CodeGenCXX/compound-literals.cpp new file mode 100644 index 0000000..17a3114 --- /dev/null +++ b/clang/test/CodeGenCXX/compound-literals.cpp @@ -0,0 +1,44 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s + +struct X { + X(); + X(const X&); + X(const char*); + ~X(); +}; + +struct Y { + int i; + X x; +}; + +// CHECK: define i32 @_Z1fv() +int f() { + // CHECK: [[LVALUE:%[a-z0-9.]+]] = alloca + // CHECK-NEXT: [[I:%[a-z0-9]+]] = getelementptr inbounds {{.*}}* [[LVALUE]], i32 0, i32 0 + // CHECK-NEXT: store i32 17, i32* [[I]] + // CHECK-NEXT: [[X:%[a-z0-9]+]] = getelementptr inbounds {{.*}} [[LVALUE]], i32 0, i32 1 + // CHECK-NEXT: call void @_ZN1XC1EPKc({{.*}}[[X]] + // CHECK-NEXT: [[I:%[a-z0-9]+]] = getelementptr inbounds {{.*}} [[LVALUE]], i32 0, i32 0 + // CHECK-NEXT: [[RESULT:%[a-z0-9]+]] = load i32* + // CHECK-NEXT: call void @_ZN1YD1Ev + // CHECK-NEXT: ret i32 [[RESULT]] + return ((Y){17, "seventeen"}).i; +} + +// CHECK: define i32 @_Z1gv() +int g() { + // CHECK: store [2 x i32]* %{{[a-z0-9.]+}}, [2 x i32]** [[V:%[a-z0-9.]+]] + const int (&v)[2] = (int [2]) {1,2}; + + // CHECK: [[A:%[a-z0-9.]+]] = load [2 x i32]** [[V]] + // CHECK-NEXT: [[A0ADDR:%[a-z0-9.]+]] = getelementptr inbounds [2 x i32]* [[A]], i32 0, {{.*}} 0 + // CHECK-NEXT: [[A0:%[a-z0-9.]+]] = load i32* [[A0ADDR]] + // CHECK-NEXT: ret i32 [[A0]] + return v[0]; +} + +struct Z { int i[3]; }; +int *p = (Z){ {1, 2, 3} }.i; +// CHECK: define {{.*}}__cxx_global_var_init() +// CHECK: store i32* getelementptr inbounds (%struct.Z* @.compoundliteral, i32 0, i32 0, i32 0), i32** @p diff --git a/clang/test/CodeGenCXX/condition.cpp b/clang/test/CodeGenCXX/condition.cpp new file mode 100644 index 0000000..cc2eaf5 --- /dev/null +++ b/clang/test/CodeGenCXX/condition.cpp @@ -0,0 +1,317 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s +void *f(); + +template T* g() { + if (T* t = f()) + return t; + + return 0; +} + +void h() { + void *a = g(); +} + +struct X { + X(); + X(const X&); + ~X(); + operator bool(); +}; + +struct Y { + Y(); + ~Y(); +}; + +X getX(); + +// CHECK: define void @_Z11if_destructi( +void if_destruct(int z) { + // Verify that the condition variable is destroyed at the end of the + // "if" statement. + // CHECK: call void @_ZN1XC1Ev + // CHECK: call zeroext i1 @_ZN1XcvbEv + if (X x = X()) { + // CHECK: store i32 18 + z = 18; + } + // CHECK: call void @_ZN1XD1Ev + // CHECK: store i32 17 + z = 17; + + // CHECK: call void @_ZN1XC1Ev + if (X x = X()) + Y y; + // CHECK: br + // CHECK: call void @_ZN1YC1Ev + // CHECK: call void @_ZN1YD1Ev + // CHECK: br + // CHECK: call void @_ZN1XD1Ev + + // CHECK: call void @_Z4getXv + // CHECK: call zeroext i1 @_ZN1XcvbEv + // CHECK: call void @_ZN1XD1Ev + // CHECK: br + if (getX()) { } + + // CHECK: ret +} + +struct ConvertibleToInt { + ConvertibleToInt(); + ~ConvertibleToInt(); + operator int(); +}; + +ConvertibleToInt getConvToInt(); + +void switch_destruct(int z) { + // CHECK: call void @_ZN16ConvertibleToIntC1Ev + switch (ConvertibleToInt conv = ConvertibleToInt()) { + case 0: + break; + + default: + // CHECK: store i32 19 + z = 19; + break; + } + // CHECK: call void @_ZN16ConvertibleToIntD1Ev + // CHECK: store i32 20 + z = 20; + + // CHECK: call void @_Z12getConvToIntv + // CHECK: call i32 @_ZN16ConvertibleToIntcviEv + // CHECK: call void @_ZN16ConvertibleToIntD1Ev + switch(getConvToInt()) { + case 0: + break; + } + // CHECK: store i32 27 + z = 27; + // CHECK: ret +} + +int foo(); + +// CHECK: define void @_Z14while_destructi +void while_destruct(int z) { + // CHECK: [[Z:%.*]] = alloca i32 + // CHECK: [[CLEANUPDEST:%.*]] = alloca i32 + while (X x = X()) { + // CHECK: call void @_ZN1XC1Ev + // CHECK-NEXT: [[COND:%.*]] = call zeroext i1 @_ZN1XcvbEv + // CHECK-NEXT: br i1 [[COND]] + + // Loop-exit staging block. + // CHECK: store i32 3, i32* [[CLEANUPDEST]] + // CHECK-NEXT: br + + // While body. + // CHECK: store i32 21, i32* [[Z]] + // CHECK: store i32 0, i32* [[CLEANUPDEST]] + // CHECK-NEXT: br + z = 21; + + // Cleanup. + // CHECK: call void @_ZN1XD1Ev + // CHECK-NEXT: [[DEST:%.*]] = load i32* [[CLEANUPDEST]] + // CHECK-NEXT: switch i32 [[DEST]] + } + + // CHECK: store i32 22, i32* [[Z]] + z = 22; + + // CHECK: call void @_Z4getXv + // CHECK-NEXT: call zeroext i1 @_ZN1XcvbEv + // CHECK-NEXT: call void @_ZN1XD1Ev + // CHECK-NEXT: br + while(getX()) { } + + // CHECK: store i32 25, i32* [[Z]] + z = 25; + + // CHECK: ret +} + +// CHECK: define void @_Z12for_destructi( +void for_destruct(int z) { + // CHECK: [[Z:%.*]] = alloca i32 + // CHECK: [[CLEANUPDEST:%.*]] = alloca i32 + // CHECK: [[I:%.*]] = alloca i32 + // CHECK: call void @_ZN1YC1Ev + // CHECK-NEXT: br + // -> %for.cond + + for(Y y = Y(); X x = X(); ++z) { + // %for.cond: The loop condition. + // CHECK: call void @_ZN1XC1Ev + // CHECK-NEXT: [[COND:%.*]] = call zeroext i1 @_ZN1XcvbEv( + // CHECK-NEXT: br i1 [[COND]] + // -> %for.body, %for.cond.cleanup + + // %for.cond.cleanup: Exit cleanup staging. + // CHECK: store i32 2, i32* [[CLEANUPDEST]] + // CHECK-NEXT: br + // -> %cleanup + + // %for.body: + // CHECK: store i32 23, i32* [[Z]] + // CHECK-NEXT: br + // -> %for.inc + z = 23; + + // %for.inc: + // CHECK: [[TMP:%.*]] = load i32* [[Z]] + // CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[TMP]], 1 + // CHECK-NEXT: store i32 [[INC]], i32* [[Z]] + // CHECK-NEXT: store i32 0, i32* [[CLEANUPDEST]] + // CHECK-NEXT: br + // -> %cleanup + + // %cleanup: Destroys X. + // CHECK: call void @_ZN1XD1Ev + // CHECK-NEXT: [[YDESTTMP:%.*]] = load i32* [[CLEANUPDEST]] + // CHECK-NEXT: switch i32 [[YDESTTMP]] + // 0 -> %cleanup.cont, default -> %cleanup1 + + // %cleanup.cont: (eliminable) + // CHECK: br + // -> %for.cond + + // %cleanup1: Destroys Y. + // CHECK: call void @_ZN1YD1Ev( + // CHECK-NEXT: br + // -> %for.end + } + + // %for.end: + // CHECK: store i32 24 + z = 24; + + // CHECK-NEXT: store i32 0, i32* [[I]] + // CHECK-NEXT: br + // -> %for.cond6 + + // %for.cond6: + // CHECK: call void @_Z4getXv + // CHECK-NEXT: call zeroext i1 @_ZN1XcvbEv + // CHECK-NEXT: call void @_ZN1XD1Ev + // CHECK-NEXT: br + // -> %for.body10, %for.end16 + + // %for.body10: + // CHECK: br + // -> %for.inc11 + + // %for.inc11: + // CHECK: call void @_Z4getXv + // CHECK-NEXT: load i32* [[I]] + // CHECK-NEXT: add + // CHECK-NEXT: store + // CHECK-NEXT: call void @_ZN1XD1Ev + // CHECK-NEXT: br + // -> %for.cond6 + int i = 0; + for(; getX(); getX(), ++i) { } + + // %for.end16 + // CHECK: store i32 26 + z = 26; + + // CHECK-NEXT: ret void +} + +void do_destruct(int z) { + // CHECK: define void @_Z11do_destruct + do { + // CHECK: store i32 77 + z = 77; + // CHECK: call void @_Z4getXv + // CHECK: call zeroext i1 @_ZN1XcvbEv + // CHECK: call void @_ZN1XD1Ev + // CHECK: br + } while (getX()); + // CHECK: store i32 99 + z = 99; + // CHECK: ret +} + +int f(X); + +template +int instantiated(T x) { + int result; + + // CHECK: call void @_ZN1XC1ERKS_ + // CHECK: call i32 @_Z1f1X + // CHECK: call void @_ZN1XD1Ev + // CHECK: br + // CHECK: store i32 2 + // CHECK: br + // CHECK: store i32 3 + if (f(x)) { result = 2; } else { result = 3; } + + // CHECK: call void @_ZN1XC1ERKS_ + // CHECK: call i32 @_Z1f1X + // CHECK: call void @_ZN1XD1Ev + // CHECK: br + // CHECK: store i32 4 + // CHECK: br + while (f(x)) { result = 4; } + + // CHECK: call void @_ZN1XC1ERKS_ + // CHECK: call i32 @_Z1f1X + // CHECK: call void @_ZN1XD1Ev + // CHECK: br + // CHECK: store i32 6 + // CHECK: br + // CHECK: call void @_ZN1XC1ERKS_ + // CHECK: call i32 @_Z1f1X + // CHECK: store i32 5 + // CHECK: call void @_ZN1XD1Ev + // CHECK: br + for (; f(x); f(x), result = 5) { + result = 6; + } + + // CHECK: call void @_ZN1XC1ERKS_ + // CHECK: call i32 @_Z1f1X + // CHECK: call void @_ZN1XD1Ev + // CHECK: switch i32 + // CHECK: store i32 7 + // CHECK: store i32 8 + switch (f(x)) { + case 0: + result = 7; + break; + + case 1: + result = 8; + } + + // CHECK: store i32 9 + // CHECK: br + // CHECK: call void @_ZN1XC1ERKS_ + // CHECK: call i32 @_Z1f1X + // CHECK: call void @_ZN1XD1Ev + // CHECK: br + do { + result = 9; + } while (f(x)); + + // CHECK: store i32 10 + // CHECK: call void @_ZN1XC1ERKS_ + // CHECK: call zeroext i1 @_ZN1XcvbEv + // CHECK: call void @_ZN1XD1Ev + // CHECK: br + do { + result = 10; + } while (X(x)); + + // CHECK: ret i32 + return result; +} + +template int instantiated(X); diff --git a/clang/test/CodeGenCXX/conditional-expr-lvalue.cpp b/clang/test/CodeGenCXX/conditional-expr-lvalue.cpp new file mode 100644 index 0000000..96aa8b0 --- /dev/null +++ b/clang/test/CodeGenCXX/conditional-expr-lvalue.cpp @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -emit-llvm-only %s +void f(bool flag) { + int a = 1; + int b = 2; + + (flag ? a : b) = 3; +} + +// PR10756 +namespace test0 { + struct A { + A(const A &); + A &operator=(const A &); + A sub() const; + void foo() const; + }; + void foo(bool cond, const A &a) { + (cond ? a : a.sub()).foo(); + } +} diff --git a/clang/test/CodeGenCXX/conditional-gnu-ext.cpp b/clang/test/CodeGenCXX/conditional-gnu-ext.cpp new file mode 100644 index 0000000..104a91d --- /dev/null +++ b/clang/test/CodeGenCXX/conditional-gnu-ext.cpp @@ -0,0 +1,150 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s +// rdar: // 8353567 +// pr7726 + +extern "C" int printf(...); + +void test0() { +// CHECK: call i32 (...)* @printf({{.*}}, i8* inttoptr (i64 3735928559 to i8*)) + printf("%p\n", (void *)0xdeadbeef ? : (void *)0xaaaaaa); +} + +// rdar://8446940 +namespace radar8446940 { +extern "C" void abort(); + +int main () { + char x[1]; + char *y = x ? : 0; + + if (x != y) + abort(); +} +} + +namespace radar8453812 { +extern "C" void abort(); +_Complex int getComplex(_Complex int val) { + static int count; + if (count++) + abort(); + return val; +} + +_Complex int cmplx() { + _Complex int cond; + _Complex int rhs; + + return getComplex(1+2i) ? : rhs; +} + +// lvalue test +void foo (int& lv) { + ++lv; +} + +int global = 1; + +int &cond() { + static int count; + if (count++) + abort(); + return global; +} + + +int main() { + cmplx(); + int rhs = 10; + foo (cond()? : rhs); + return global-2; +} +} + +namespace test3 { + struct A { + A(); + A(const A&); + ~A(); + }; + + struct B { + B(); + B(const B&); + ~B(); + operator bool(); + operator A(); + }; + + B test0(B &x) { + // CHECK: define void @_ZN5test35test0ERNS_1BE( + // CHECK: [[X:%.*]] = alloca [[B:%.*]]*, + // CHECK-NEXT: store [[B]]* {{%.*}}, [[B]]** [[X]] + // CHECK-NEXT: [[T0:%.*]] = load [[B]]** [[X]] + // CHECK-NEXT: [[BOOL:%.*]] = call zeroext i1 @_ZN5test31BcvbEv([[B]]* [[T0]]) + // CHECK-NEXT: br i1 [[BOOL]] + // CHECK: call void @_ZN5test31BC1ERKS0_([[B]]* [[RESULT:%.*]], [[B]]* [[T0]]) + // CHECK-NEXT: br label + // CHECK: call void @_ZN5test31BC1Ev([[B]]* [[RESULT]]) + // CHECK-NEXT: br label + // CHECK: ret void + return x ?: B(); + } + + B test1() { + // CHECK: define void @_ZN5test35test1Ev( + // CHECK: [[TEMP:%.*]] = alloca [[B]], + // CHECK-NEXT: call void @_ZN5test312test1_helperEv([[B]]* sret [[TEMP]]) + // CHECK-NEXT: [[BOOL:%.*]] = call zeroext i1 @_ZN5test31BcvbEv([[B]]* [[TEMP]]) + // CHECK-NEXT: br i1 [[BOOL]] + // CHECK: call void @_ZN5test31BC1ERKS0_([[B]]* [[RESULT:%.*]], [[B]]* [[TEMP]]) + // CHECK-NEXT: br label + // CHECK: call void @_ZN5test31BC1Ev([[B]]* [[RESULT]]) + // CHECK-NEXT: br label + // CHECK: call void @_ZN5test31BD1Ev([[B]]* [[TEMP]]) + // CHECK-NEXT: ret void + extern B test1_helper(); + return test1_helper() ?: B(); + } + + + A test2(B &x) { + // CHECK: define void @_ZN5test35test2ERNS_1BE( + // CHECK: [[X:%.*]] = alloca [[B]]*, + // CHECK-NEXT: store [[B]]* {{%.*}}, [[B]]** [[X]] + // CHECK-NEXT: [[T0:%.*]] = load [[B]]** [[X]] + // CHECK-NEXT: [[BOOL:%.*]] = call zeroext i1 @_ZN5test31BcvbEv([[B]]* [[T0]]) + // CHECK-NEXT: br i1 [[BOOL]] + // CHECK: call void @_ZN5test31BcvNS_1AEEv([[A:%.*]]* sret [[RESULT:%.*]], [[B]]* [[T0]]) + // CHECK-NEXT: br label + // CHECK: call void @_ZN5test31AC1Ev([[A]]* [[RESULT]]) + // CHECK-NEXT: br label + // CHECK: ret void + return x ?: A(); + } + + A test3() { + // CHECK: define void @_ZN5test35test3Ev( + // CHECK: [[TEMP:%.*]] = alloca [[B]], + // CHECK-NEXT: call void @_ZN5test312test3_helperEv([[B]]* sret [[TEMP]]) + // CHECK-NEXT: [[BOOL:%.*]] = call zeroext i1 @_ZN5test31BcvbEv([[B]]* [[TEMP]]) + // CHECK-NEXT: br i1 [[BOOL]] + // CHECK: call void @_ZN5test31BcvNS_1AEEv([[A]]* sret [[RESULT:%.*]], [[B]]* [[TEMP]]) + // CHECK-NEXT: br label + // CHECK: call void @_ZN5test31AC1Ev([[A]]* [[RESULT]]) + // CHECK-NEXT: br label + // CHECK: call void @_ZN5test31BD1Ev([[B]]* [[TEMP]]) + // CHECK-NEXT: ret void + extern B test3_helper(); + return test3_helper() ?: A(); + } + +} + +namespace test4 { + // Make sure this doesn't crash. + void f() { + const int a = 10, b = 20; + const int *c = &(a ?: b); + } +} diff --git a/clang/test/CodeGenCXX/conditional-temporaries.cpp b/clang/test/CodeGenCXX/conditional-temporaries.cpp new file mode 100644 index 0000000..d538287 --- /dev/null +++ b/clang/test/CodeGenCXX/conditional-temporaries.cpp @@ -0,0 +1,55 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -O3 | FileCheck %s + +namespace { + +static int ctorcalls; +static int dtorcalls; + +struct A { + A() : i(0) { ctorcalls++; } + ~A() { dtorcalls++; } + int i; + + friend const A& operator<<(const A& a, int n) { + return a; + } +}; + +void g(int) { } +void g(const A&) { } + +void f1(bool b) { + g(b ? A().i : 0); + g(b || A().i); + g(b && A().i); + g(b ? A() << 1 : A() << 2); +} + +struct Checker { + Checker() { + f1(true); + f1(false); + } +}; + +Checker c; + +} + +// CHECK: define i32 @_Z12getCtorCallsv() +int getCtorCalls() { + // CHECK: ret i32 5 + return ctorcalls; +} + +// CHECK: define i32 @_Z12getDtorCallsv() +int getDtorCalls() { + // CHECK: ret i32 5 + return dtorcalls; +} + +// CHECK: define zeroext i1 @_Z7successv() +bool success() { + // CHECK: ret i1 true + return ctorcalls == dtorcalls; +} diff --git a/clang/test/CodeGenCXX/const-base-cast.cpp b/clang/test/CodeGenCXX/const-base-cast.cpp new file mode 100644 index 0000000..320c790 --- /dev/null +++ b/clang/test/CodeGenCXX/const-base-cast.cpp @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s + +// Check that the following construct, which is similar to one which occurs +// in Firefox, is folded correctly. +struct A { char x; }; +struct B { char y; }; +struct C : A,B {}; +unsigned char x = ((char*)(B*)(C*)0x1000) - (char*)0x1000; + +// CHECK: @x = global i8 1 diff --git a/clang/test/CodeGenCXX/const-global-linkage.cpp b/clang/test/CodeGenCXX/const-global-linkage.cpp new file mode 100644 index 0000000..d0a055b --- /dev/null +++ b/clang/test/CodeGenCXX/const-global-linkage.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s + +const int x = 10; +const int y = 20; +// CHECK-NOT: @x +// CHECK: @_ZL1y = internal constant i32 20 +const int& b() { return y; } + +const char z1[] = "asdf"; +const char z2[] = "zxcv"; +// CHECK-NOT: @z1 +// CHECK: @_ZL2z2 = internal constant +const char* b2() { return z2; } diff --git a/clang/test/CodeGenCXX/const-init-cxx11.cpp b/clang/test/CodeGenCXX/const-init-cxx11.cpp new file mode 100644 index 0000000..62a345a --- /dev/null +++ b/clang/test/CodeGenCXX/const-init-cxx11.cpp @@ -0,0 +1,428 @@ +// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin -emit-llvm -o - %s -std=c++11 | FileCheck %s + +// FIXME: The padding in all these objects should be zero-initialized. +namespace StructUnion { + struct A { + int n; + double d; + union U { + constexpr U(int x) : x(x) {} + constexpr U(const char *y) : y(y) {} + int x; + const char *y; + } u; + + constexpr A(int n, double d, int x) : n(n), d(d), u(x) {} + constexpr A(int n, double d, const char *y) : n(n), d(d), u(y) {} + }; + + // CHECK: @_ZN11StructUnion1aE = constant {{.*}} { i32 1, double 2.000000e+00, {{.*}} { i32 3, [4 x i8] undef } } + extern constexpr A a(1, 2.0, 3); + + // CHECK: @_ZN11StructUnion1bE = constant {{.*}} { i32 4, double 5.000000e+00, {{.*}} { i8* getelementptr inbounds ([6 x i8]* @{{.*}}, i32 0, i32 0) } } + extern constexpr A b(4, 5, "hello"); + + struct B { + int n; + }; + + // CHECK: @_ZN11StructUnion1cE = global {{.*}} zeroinitializer + // CHECK: @_ZN11StructUnion2c2E = global {{.*}} zeroinitializer + B c; + B c2 = B(); + + // CHECK: @_ZN11StructUnion1dE = global {{.*}} zeroinitializer + B d[10]; + + struct C { + constexpr C() : c(0) {} + int c; + }; + + // CHECK: @_ZN11StructUnion1eE = global {{.*}} zeroinitializer + C e[10]; + + struct D { + constexpr D() : d(5) {} + int d; + }; + + // CHECK: @_ZN11StructUnion1fE = global {{.*}} { i32 5 } + D f; +} + +namespace BaseClass { + template struct X : T {}; + struct C { char c = 1; }; + template struct Cs : X... {}; + struct N { int n = 3; }; + struct D { double d = 4.0; }; + + template + struct Test : Ts... { constexpr Test() : Ts()..., n(5) {} int n; }; + + using Test1 = Test, D, X>; + // CHECK: @_ZN9BaseClass2t1E = constant {{.*}} { i32 3, i8 1, i8 1, i8 1, double 4.000000e+00, i8 1, i32 5 }, align 8 + extern constexpr Test1 t1 = Test1(); + + struct DN : D, N {}; + struct DND : DN, X {}; + struct DNN : DN, X {}; + // CHECK: @_ZN9BaseClass3dndE = constant {{.*}} { double 4.000000e+00, i32 3, double 4.000000e+00 } + extern constexpr DND dnd = DND(); + // Note, N subobject is laid out in DN subobject's tail padding. + // CHECK: @_ZN9BaseClass3dnnE = constant {{.*}} { double 4.000000e+00, i32 3, i32 3 } + extern constexpr DNN dnn = DNN(); + + struct E {}; + struct Test2 : X, X, X, X {}; + // CHECK: @_ZN9BaseClass2t2E = constant {{.*}} undef + extern constexpr Test2 t2 = Test2(); + + struct __attribute((packed)) PackedD { double y = 2; }; + struct Test3 : C, PackedD { constexpr Test3() {} }; + // CHECK: @_ZN9BaseClass2t3E = constant <{ i8, double }> <{ i8 1, double 2.000000e+00 }> + extern constexpr Test3 t3 = Test3(); +} + +namespace Array { + // CHECK: @_ZN5Array3arrE = constant [2 x i32] [i32 4, i32 0] + extern constexpr int arr[2] = { 4 }; + + // CHECK: @_ZN5Array1cE = constant [6 x [4 x i8]] [{{.*}} c"foo\00", [4 x i8] c"a\00\00\00", [4 x i8] c"bar\00", [4 x i8] c"xyz\00", [4 x i8] c"b\00\00\00", [4 x i8] c"123\00"] + extern constexpr char c[6][4] = { "foo", "a", { "bar" }, { 'x', 'y', 'z' }, { "b" }, '1', '2', '3' }; + + // CHECK: @_ZN5Array2ucE = constant [4 x i8] c"foo\00" + extern constexpr unsigned char uc[] = { "foo" }; + + struct C { constexpr C() : n(5) {} int n, m = 3 * n + 1; }; + // CHECK: @_ZN5Array5ctorsE = constant [3 x {{.*}}] [{{.*}} { i32 5, i32 16 }, {{.*}} { i32 5, i32 16 }, {{.*}} { i32 5, i32 16 }] + extern const C ctors[3]; + constexpr C ctors[3]; + + // CHECK: @_ZN5Array1dE = constant {{.*}} { [2 x i32] [i32 1, i32 2], [3 x i32] [i32 3, i32 4, i32 5] } + struct D { int n[2]; int m[3]; } extern constexpr d = { 1, 2, 3, 4, 5 }; + + struct E { + char c[4]; + char d[4]; + constexpr E() : c("foo"), d("x") {} + }; + // CHECK: @_ZN5Array1eE = constant {{.*}} { [4 x i8] c"foo\00", [4 x i8] c"x\00\00\00" } + extern constexpr E e = E(); +} + +namespace MemberPtr { + struct B1 { + int a, b; + virtual void f(); + void g(); + }; + struct B2 { + int c, d; + virtual void h(); + void i(); + }; + struct C : B1 { + int e; + virtual void j(); + void k(); + }; + struct D : C, B2 { + int z; + virtual void l(); + void m(); + }; + + // CHECK: @_ZN9MemberPtr2daE = constant i64 8 + // CHECK: @_ZN9MemberPtr2dbE = constant i64 12 + // CHECK: @_ZN9MemberPtr2dcE = constant i64 32 + // CHECK: @_ZN9MemberPtr2ddE = constant i64 36 + // CHECK: @_ZN9MemberPtr2deE = constant i64 16 + // CHECK: @_ZN9MemberPtr2dzE = constant i64 40 + extern constexpr int (D::*da) = &B1::a; + extern constexpr int (D::*db) = &C::b; + extern constexpr int (D::*dc) = &B2::c; + extern constexpr int (D::*dd) = &D::d; + extern constexpr int (D::*de) = &C::e; + extern constexpr int (D::*dz) = &D::z; + + // CHECK: @_ZN9MemberPtr2baE = constant i64 8 + // CHECK: @_ZN9MemberPtr2bbE = constant i64 12 + // CHECK: @_ZN9MemberPtr2bcE = constant i64 8 + // CHECK: @_ZN9MemberPtr2bdE = constant i64 12 + // CHECK: @_ZN9MemberPtr2beE = constant i64 16 + // CHECK: @_ZN9MemberPtr3b1zE = constant i64 40 + // CHECK: @_ZN9MemberPtr3b2zE = constant i64 16 + extern constexpr int (B1::*ba) = (int(B1::*))&B1::a; + extern constexpr int (B1::*bb) = (int(B1::*))&C::b; + extern constexpr int (B2::*bc) = (int(B2::*))&B2::c; + extern constexpr int (B2::*bd) = (int(B2::*))&D::d; + extern constexpr int (B1::*be) = (int(B1::*))&C::e; + extern constexpr int (B1::*b1z) = (int(B1::*))&D::z; + extern constexpr int (B2::*b2z) = (int(B2::*))&D::z; + + // CHECK: @_ZN9MemberPtr2dfE = constant {{.*}} { i64 1, i64 0 } + // CHECK: @_ZN9MemberPtr2dgE = constant {{.*}} { i64 {{.*}}2B11gEv{{.*}}, i64 0 } + // CHECK: @_ZN9MemberPtr2dhE = constant {{.*}} { i64 1, i64 24 } + // CHECK: @_ZN9MemberPtr2diE = constant {{.*}} { i64 {{.*}}2B21iEv{{.*}}, i64 24 } + // CHECK: @_ZN9MemberPtr2djE = constant {{.*}} { i64 9, i64 0 } + // CHECK: @_ZN9MemberPtr2dkE = constant {{.*}} { i64 {{.*}}1C1kEv{{.*}}, i64 0 } + // CHECK: @_ZN9MemberPtr2dlE = constant {{.*}} { i64 17, i64 0 } + // CHECK: @_ZN9MemberPtr2dmE = constant {{.*}} { i64 {{.*}}1D1mEv{{.*}}, i64 0 } + extern constexpr void (D::*df)() = &C::f; + extern constexpr void (D::*dg)() = &B1::g; + extern constexpr void (D::*dh)() = &B2::h; + extern constexpr void (D::*di)() = &D::i; + extern constexpr void (D::*dj)() = &C::j; + extern constexpr void (D::*dk)() = &C::k; + extern constexpr void (D::*dl)() = &D::l; + extern constexpr void (D::*dm)() = &D::m; + + // CHECK: @_ZN9MemberPtr2bfE = constant {{.*}} { i64 1, i64 0 } + // CHECK: @_ZN9MemberPtr2bgE = constant {{.*}} { i64 {{.*}}2B11gEv{{.*}}, i64 0 } + // CHECK: @_ZN9MemberPtr2bhE = constant {{.*}} { i64 1, i64 0 } + // CHECK: @_ZN9MemberPtr2biE = constant {{.*}} { i64 {{.*}}2B21iEv{{.*}}, i64 0 } + // CHECK: @_ZN9MemberPtr2bjE = constant {{.*}} { i64 9, i64 0 } + // CHECK: @_ZN9MemberPtr2bkE = constant {{.*}} { i64 {{.*}}1C1kEv{{.*}}, i64 0 } + // CHECK: @_ZN9MemberPtr3b1lE = constant {{.*}} { i64 17, i64 0 } + // CHECK: @_ZN9MemberPtr3b1mE = constant {{.*}} { i64 {{.*}}1D1mEv{{.*}}, i64 0 } + // CHECK: @_ZN9MemberPtr3b2lE = constant {{.*}} { i64 17, i64 -24 } + // CHECK: @_ZN9MemberPtr3b2mE = constant {{.*}} { i64 {{.*}}1D1mEv{{.*}}, i64 -24 } + extern constexpr void (B1::*bf)() = (void(B1::*)())&C::f; + extern constexpr void (B1::*bg)() = (void(B1::*)())&B1::g; + extern constexpr void (B2::*bh)() = (void(B2::*)())&B2::h; + extern constexpr void (B2::*bi)() = (void(B2::*)())&D::i; + extern constexpr void (B1::*bj)() = (void(B1::*)())&C::j; + extern constexpr void (B1::*bk)() = (void(B1::*)())&C::k; + extern constexpr void (B1::*b1l)() = (void(B1::*)())&D::l; + extern constexpr void (B1::*b1m)() = (void(B1::*)())&D::m; + extern constexpr void (B2::*b2l)() = (void(B2::*)())&D::l; + extern constexpr void (B2::*b2m)() = (void(B2::*)())&D::m; +} + +namespace LiteralReference { + struct Lit { + constexpr Lit() : n(5) {} + int n; + }; + // FIXME: This should have static initialization, but we do not implement + // that yet. For now, just check that we don't set the (pointer) value of + // the reference to 5! + // + // CHECK: @_ZN16LiteralReference3litE = global {{.*}} null + const Lit &lit = Lit(); +} + +namespace NonLiteralConstexpr { + constexpr int factorial(int n) { + return n ? factorial(n-1) * n : 1; + } + extern void f(int *p); + + struct NonTrivialDtor { + constexpr NonTrivialDtor() : n(factorial(5)), p(&n) {} + ~NonTrivialDtor() { + f(p); + } + + int n; + int *p; + }; + static_assert(!__is_literal(NonTrivialDtor), ""); + // CHECK: @_ZN19NonLiteralConstexpr3ntdE = global {{.*}} { i32 120, i32* getelementptr + NonTrivialDtor ntd; + + struct VolatileMember { + constexpr VolatileMember() : n(5) {} + volatile int n; + }; + static_assert(!__is_literal(VolatileMember), ""); + // CHECK: @_ZN19NonLiteralConstexpr2vmE = global {{.*}} { i32 5 } + VolatileMember vm; + + struct Both { + constexpr Both() : n(10) {} + ~Both(); + volatile int n; + }; + // CHECK: @_ZN19NonLiteralConstexpr1bE = global {{.*}} { i32 10 } + Both b; + + void StaticVars() { + // CHECK: @_ZZN19NonLiteralConstexpr10StaticVarsEvE3ntd = {{.*}} { i32 120, i32* getelementptr {{.*}} + // CHECK: @_ZGVZN19NonLiteralConstexpr10StaticVarsEvE3ntd = + static NonTrivialDtor ntd; + // CHECK: @_ZZN19NonLiteralConstexpr10StaticVarsEvE2vm = {{.*}} { i32 5 } + // CHECK-NOT: @_ZGVZN19NonLiteralConstexpr10StaticVarsEvE2vm = + static VolatileMember vm; + // CHECK: @_ZZN19NonLiteralConstexpr10StaticVarsEvE1b = {{.*}} { i32 10 } + // CHECK: @_ZGVZN19NonLiteralConstexpr10StaticVarsEvE1b = + static Both b; + } +} + +// PR12067 +namespace VirtualMembers { + struct A { + constexpr A(double d) : d(d) {} + virtual void f(); + double d; + }; + struct B : A { + constexpr B() : A(2.0), c{'h', 'e', 'l', 'l', 'o'} {} + constexpr B(int n) : A(n), c{'w', 'o', 'r', 'l', 'd'} {} + virtual void g(); + char c[5]; + }; + struct C { + constexpr C() : n(64) {} + int n; + }; + struct D : C, A, B { + constexpr D() : A(1.0), B(), s(5) {} + short s; + }; + struct E : D, B { + constexpr E() : B(3), c{'b','y','e'} {} + char c[3]; + }; + + // CHECK: @_ZN14VirtualMembers1eE = global { i8**, double, i32, i8**, double, [5 x i8], i16, i8**, double, [5 x i8], [3 x i8] } { i8** getelementptr inbounds ([11 x i8*]* @_ZTVN14VirtualMembers1EE, i64 0, i64 2), double 1.000000e+00, i32 64, i8** getelementptr inbounds ([11 x i8*]* @_ZTVN14VirtualMembers1EE, i64 0, i64 5), double 2.000000e+00, [5 x i8] c"hello", i16 5, i8** getelementptr inbounds ([11 x i8*]* @_ZTVN14VirtualMembers1EE, i64 0, i64 9), double 3.000000e+00, [5 x i8] c"world", [3 x i8] c"bye" } + E e; + + struct nsMemoryImpl { + virtual void f(); + }; + // CHECK: @_ZN14VirtualMembersL13sGlobalMemoryE = internal global { i8** } { i8** getelementptr inbounds ([3 x i8*]* @_ZTVN14VirtualMembers12nsMemoryImplE, i64 0, i64 2) } + static nsMemoryImpl sGlobalMemory; +} + +// Constant initialization tests go before this point, +// dynamic initialization tests go after. + +// We must emit a constant initializer for NonLiteralConstexpr::ntd, but also +// emit an initializer to register its destructor. +// CHECK: define {{.*}}cxx_global_var_init{{.*}} +// CHECK-NOT: NonLiteralConstexpr +// CHECK: call {{.*}}cxa_atexit{{.*}} @_ZN19NonLiteralConstexpr14NonTrivialDtorD1Ev {{.*}} @_ZN19NonLiteralConstexpr3ntdE +// CHECK-NEXT: ret void + +// We don't need to emit any dynamic initialization for NonLiteralConstexpr::vm. +// CHECK-NOT: NonLiteralConstexpr2vm + +// We must emit a constant initializer for NonLiteralConstexpr::b, but also +// emit an initializer to register its destructor. +// CHECK: define {{.*}}cxx_global_var_init{{.*}} +// CHECK-NOT: NonLiteralConstexpr +// CHECK: call {{.*}}cxa_atexit{{.*}} @_ZN19NonLiteralConstexpr4BothD1Ev {{.*}} @_ZN19NonLiteralConstexpr1bE +// CHECK-NEXT: ret void + +// CHECK: define {{.*}}NonLiteralConstexpr10StaticVars +// CHECK-NOT: } +// CHECK: call {{.*}}cxa_atexit{{.*}}@_ZN19NonLiteralConstexpr14NonTrivialDtorD1Ev +// CHECK-NOT: } +// CHECK: call {{.*}}cxa_atexit{{.*}}@_ZN19NonLiteralConstexpr4BothD1Ev + +namespace CrossFuncLabelDiff { + // Make sure we refuse to constant-fold the variable b. + constexpr long a(bool x) { return x ? 0 : (long)&&lbl + (0 && ({lbl: 0;})); } + void test() { static long b = (long)&&lbl - a(false); lbl: return; } + // CHECK: sub nsw i64 ptrtoint (i8* blockaddress(@_ZN18CrossFuncLabelDiff4testEv, {{.*}}) to i64), + // CHECK: store i64 {{.*}}, i64* @_ZZN18CrossFuncLabelDiff4testEvE1b, align 8 +} + +// PR12012 +namespace VirtualBase { + struct B {}; + struct D : virtual B {}; + D d; + // CHECK: call {{.*}}@_ZN11VirtualBase1DC1Ev + + template struct X : T { + constexpr X() : T() {} + }; + X x; + // CHECK: call {{.*}}@_ZN11VirtualBase1XINS_1DEEC1Ev +} + +// PR12145 +namespace Unreferenced { + int n; + constexpr int *p = &n; + // We must not emit a load of 'p' here, since it's not odr-used. + int q = *p; + // CHECK-NOT: _ZN12Unreferenced1pE + // CHECK: = load i32* @_ZN12Unreferenced1nE + // CHECK-NEXT: store i32 {{.*}}, i32* @_ZN12Unreferenced1qE + // CHECK-NOT: _ZN12Unreferenced1pE + + // Technically, we are not required to substitute variables of reference types + // initialized by constant expressions, because the special case for odr-use + // of variables in [basic.def.odr]p2 only applies to objects. But we do so + // anyway. + + constexpr int &r = n; + // CHECK-NOT: _ZN12Unreferenced1rE + int s = r; + + const int t = 1; + const int &rt = t; + int f(int); + int u = f(rt); + // CHECK: call i32 @_ZN12Unreferenced1fEi(i32 1) +} + +namespace InitFromConst { + template void consume(T); + + const bool b = true; + const int n = 5; + constexpr double d = 4.3; + + struct S { int n = 7; S *p = 0; }; + constexpr S s = S(); + const S &r = s; + constexpr const S *p = &r; + constexpr int S::*mp = &S::n; + constexpr int a[3] = { 1, 4, 9 }; + + void test() { + // CHECK: call void @_ZN13InitFromConst7consumeIbEEvT_(i1 zeroext true) + consume(b); + + // CHECK: call void @_ZN13InitFromConst7consumeIiEEvT_(i32 5) + consume(n); + + // CHECK: call void @_ZN13InitFromConst7consumeIdEEvT_(double 4.300000e+00) + consume(d); + + // CHECK: call void @_ZN13InitFromConst7consumeIRKNS_1SEEEvT_(%"struct.InitFromConst::S"* @_ZN13InitFromConstL1sE) + consume(s); + + // FIXME CHECK-NOT: call void @_ZN13InitFromConst7consumeIRKNS_1SEEEvT_(%"struct.InitFromConst::S"* @_ZN13InitFromConstL1sE) + // There's no lvalue-to-rvalue conversion here, so 'r' is odr-used, and + // we're permitted to emit a load of it. This seems likely to be a defect + // in the standard. If we start emitting a direct reference to 's', update + // this test. + consume(r); + + // CHECK: call void @_ZN13InitFromConst7consumeIPKNS_1SEEEvT_(%"struct.InitFromConst::S"* @_ZN13InitFromConstL1sE) + consume(p); + + // CHECK: call void @_ZN13InitFromConst7consumeIMNS_1SEiEEvT_(i64 0) + consume(mp); + + // CHECK: call void @_ZN13InitFromConst7consumeIPKiEEvT_(i32* getelementptr inbounds ([3 x i32]* @_ZN13InitFromConstL1aE, i32 0, i32 0)) + consume(a); + } +} + +namespace Null { + decltype(nullptr) null(); + // CHECK: call {{.*}} @_ZN4Null4nullEv( + int *p = null(); + struct S {}; + // CHECK: call {{.*}} @_ZN4Null4nullEv( + int S::*q = null(); +} diff --git a/clang/test/CodeGenCXX/const-init.cpp b/clang/test/CodeGenCXX/const-init.cpp new file mode 100644 index 0000000..201ce8f --- /dev/null +++ b/clang/test/CodeGenCXX/const-init.cpp @@ -0,0 +1,78 @@ +// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin -emit-llvm -o - %s | FileCheck %s + +// CHECK: @a = global i32 10 +int a = 10; +// CHECK: @ar = constant i32* @a +int &ar = a; + +void f(); +// CHECK: @fr = constant void ()* @_Z1fv +void (&fr)() = f; + +struct S { int& a; }; +// CHECK: @s = global %struct.S { i32* @a } +S s = { a }; + +// PR5581 +namespace PR5581 { +class C { +public: + enum { e0, e1 }; + unsigned f; +}; + +// CHECK: @_ZN6PR55812g0E = global %"class.PR5581::C" { i32 1 } +C g0 = { C::e1 }; +} + +namespace test2 { + struct A { + static const double d = 1.0; + static const float f = d / 2; + static int g(); + } a; + + // CHECK: @_ZN5test22t0E = global double {{1\.0+e\+0+}}, align 8 + // CHECK: @_ZN5test22t1E = global [2 x double] [double {{1\.0+e\+0+}}, double {{5\.0+e-0*}}1], align 16 + // CHECK: @_ZN5test22t2E = global double* @_ZN5test21A1d + // CHECK: @_ZN5test22t3E = global {{.*}} @_ZN5test21A1g + double t0 = A::d; + double t1[] = { A::d, A::f }; + const double *t2 = &a.d; + int (*t3)() = &a.g; +} + +// We don't expect to fold this in the frontend, but make sure it doesn't crash. +// CHECK: @PR9558 = global float 0.000000e+0 +float PR9558 = reinterpret_cast("asd"); + +// An initialized const automatic variable cannot be promoted to a constant +// global if it has a mutable member. +struct MutableMember { + mutable int n; +}; +int writeToMutable() { + // CHECK-NOT: {{.*}}MM{{.*}} = {{.*}}constant + const MutableMember MM = { 0 }; + return ++MM.n; +} + +// Make sure we don't try to fold this in the frontend; the backend can't +// handle it. +// CHECK: @PR11705 = global i128 0 +__int128_t PR11705 = (__int128_t)&PR11705; + +// Make sure we don't try to fold this either. +// CHECK: @_ZZ23UnfoldableAddrLabelDiffvE1x = internal global i128 0 +void UnfoldableAddrLabelDiff() { static __int128_t x = (long)&&a-(long)&&b; a:b:return;} + +// But make sure we do fold this. +// CHECK: @_ZZ21FoldableAddrLabelDiffvE1x = internal global i64 sub (i64 ptrtoint (i8* blockaddress(@_Z21FoldableAddrLabelDiffv +void FoldableAddrLabelDiff() { static long x = (long)&&a-(long)&&b; a:b:return;} + +// CHECK: @i = constant i32* bitcast (float* @PR9558 to i32*) +int &i = reinterpret_cast(PR9558); + +int arr[2]; +// CHECK: @pastEnd = constant i32* bitcast (i8* getelementptr (i8* bitcast ([2 x i32]* @arr to i8*), i64 8) to i32*) +int &pastEnd = arr[2]; diff --git a/clang/test/CodeGenCXX/constructor-attr.cpp b/clang/test/CodeGenCXX/constructor-attr.cpp new file mode 100644 index 0000000..691795f --- /dev/null +++ b/clang/test/CodeGenCXX/constructor-attr.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s + +// CHECK: @llvm.global_ctors + +// PR6521 +void bar(); +struct Foo { + // CHECK: define linkonce_odr void @_ZN3Foo3fooEv + static void foo() __attribute__((constructor)) { + bar(); + } +}; diff --git a/clang/test/CodeGenCXX/constructor-conversion.cpp b/clang/test/CodeGenCXX/constructor-conversion.cpp new file mode 100644 index 0000000..f503463 --- /dev/null +++ b/clang/test/CodeGenCXX/constructor-conversion.cpp @@ -0,0 +1,55 @@ +// REQUIRES: x86-registered-target,x86-64-registered-target +// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -S %s -o %t-64.s +// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s +// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -S %s -o %t-32.s +// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s + +extern "C" int printf(...); + +class X { // ... +public: + X(int) : iX(2), fX(2.3) , name("HELLO\n") { } + + X(const char* arg, int ix=0) { iX = ix; fX = 6.0; name = arg+ix; } + X(): iX(100), fX(1.2) {} + int iX; + float fX; + const char *name; + void pr(void) { + printf("iX = %d fX = %f name = %s\n", iX, fX, name); + } +}; + +void g(X arg) { + arg.pr(); +} + +void f(X arg) { + X a = 1; // a = X(1) + + a.pr(); + + X b = "Jessie"; // b=X("Jessie",0) + + b.pr(); + + + a = 2; // a = X(2) + + a.pr(); +} + + +int main() { + X x; + f(x); + g(3); // g(X(3)) +} + +// CHECK-LP64: callq __ZN1XC1Ei +// CHECK-LP64: callq __ZN1XC1EPKci +// CHECK-LP64: callq __ZN1XC1Ev + +// CHECK-LP32: calll L__ZN1XC1Ei +// CHECK-LP32: calll L__ZN1XC1EPKci +// CHECK-LP32: calll L__ZN1XC1Ev diff --git a/clang/test/CodeGenCXX/constructor-convert.cpp b/clang/test/CodeGenCXX/constructor-convert.cpp new file mode 100644 index 0000000..7feeaa9 --- /dev/null +++ b/clang/test/CodeGenCXX/constructor-convert.cpp @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s + +// PR5775 +class Twine { +public: + Twine(const char *Str) { } +}; + +static void error(const Twine &Message) {} + +template +struct opt_storage { + void f() { + error("cl::location(x) specified more than once!"); + } +}; + +void f(opt_storage o) { + o.f(); +} diff --git a/clang/test/CodeGenCXX/constructor-default-arg.cpp b/clang/test/CodeGenCXX/constructor-default-arg.cpp new file mode 100644 index 0000000..32086c1 --- /dev/null +++ b/clang/test/CodeGenCXX/constructor-default-arg.cpp @@ -0,0 +1,40 @@ +// REQUIRES: x86-registered-target,x86-64-registered-target +// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -S %s -o %t-64.s +// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s +// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -S %s -o %t-32.s +// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s + +extern "C" int printf(...); + + +struct C { + C() : iC(6) {} + int iC; +}; + +int foo() { + return 6; +}; + +class X { // ... +public: + X(int) {} + X(const X&, int i = 1, int j = 2, int k = foo()) { + printf("X(const X&, %d, %d, %d)\n", i, j, k); + } +}; + +int main() { + X a(1); + X b(a, 2); + X c = b; + X d(a, 5, 6); +} + +// CHECK-LP64: callq __ZN1XC1ERKS_iii +// CHECK-LP64: callq __ZN1XC1ERKS_iii +// CHECK-LP64: callq __ZN1XC1ERKS_iii + +// CHECK-LP32: calll L__ZN1XC1ERKS_iii +// CHECK-LP32: calll L__ZN1XC1ERKS_iii +// CHECK-LP32: calll L__ZN1XC1ERKS_iii diff --git a/clang/test/CodeGenCXX/constructor-direct-call.cpp b/clang/test/CodeGenCXX/constructor-direct-call.cpp new file mode 100644 index 0000000..75e6f21 --- /dev/null +++ b/clang/test/CodeGenCXX/constructor-direct-call.cpp @@ -0,0 +1,60 @@ +// RUN: %clang_cc1 -triple i686-pc-win32 -fms-extensions -Wmicrosoft %s -emit-llvm -o - | FileCheck %s + +class Test1 { +public: + int a; +}; + +void f1() { + Test1 var; + var.Test1::Test1(); + + // CHECK: call void @llvm.memcpy.p0i8.p0i8.i32(i8* %{{.*}}, i8* %{{.*}}, i32 4, i32 4, i1 false) + var.Test1::Test1(var); +} + +class Test2 { +public: + Test2() { a = 10; b = 10; } + int a; + int b; +}; + +void f2() { + // CHECK: %var = alloca %class.Test2, align 4 + // CHECK-NEXT: call void @_ZN5Test2C1Ev(%class.Test2* %var) + Test2 var; + + // CHECK-NEXT: call void @_ZN5Test2C1Ev(%class.Test2* %var) + var.Test2::Test2(); + + // CHECK: call void @llvm.memcpy.p0i8.p0i8.i32(i8* %{{.*}}, i8* %{{.*}}, i32 8, i32 4, i1 false) + var.Test2::Test2(var); +} + + + + +class Test3 { +public: + Test3() { a = 10; b = 15; c = 20; } + Test3(const Test3& that) { a = that.a; b = that.b; c = that.c; } + int a; + int b; + int c; +}; + +void f3() { + // CHECK: call void @_ZN5Test3C1Ev(%class.Test3* %var) + Test3 var; + + // CHECK-NEXT: call void @_ZN5Test3C1Ev(%class.Test3* %var2) + Test3 var2; + + // CHECK-NEXT: call void @_ZN5Test3C1Ev(%class.Test3* %var) + var.Test3::Test3(); + + // CHECK-NEXT: call void @_ZN5Test3C1ERKS_(%class.Test3* %var, %class.Test3* %var2) + var.Test3::Test3(var2); +} + diff --git a/clang/test/CodeGenCXX/constructor-for-array-members.cpp b/clang/test/CodeGenCXX/constructor-for-array-members.cpp new file mode 100644 index 0000000..7a365cd --- /dev/null +++ b/clang/test/CodeGenCXX/constructor-for-array-members.cpp @@ -0,0 +1,44 @@ +// REQUIRES: x86-registered-target,x86-64-registered-target +// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -S %s -o %t-64.s +// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s +// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -S %s -o %t-32.s +// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s + +extern "C" int printf(...); + +int i = 1234; +float vf = 1.00; + +struct S { + S() : iS(i++), f1(vf++) {printf("S::S()\n");} + ~S(){printf("S::~S(iS = %d f1 = %f)\n", iS, f1); } + int iS; + float f1; +}; + +struct M { + double dM; + S ARR_S[3]; + void pr() { + for (int i = 0; i < 3; i++) + printf("ARR_S[%d].iS = %d ARR_S[%d].f1 = %f\n", i, ARR_S[i].iS, i, ARR_S[i].f1); + + for (int i = 0; i < 2; i++) + for (int j = 0; j < 3; j++) + for (int k = 0; k < 4; k++) + printf("MULTI_ARR[%d][%d][%d].iS = %d MULTI_ARR[%d][%d][%d].f1 = %f\n", + i,j,k, MULTI_ARR[i][j][k].iS, i,j,k, MULTI_ARR[i][j][k].f1); + + } + + S MULTI_ARR[2][3][4]; +}; + +int main() { + M m1; + m1.pr(); +} + +// CHECK-LP64: callq __ZN1SC1Ev + +// CHECK-LP32: calll L__ZN1SC1Ev diff --git a/clang/test/CodeGenCXX/constructor-init-reference.cpp b/clang/test/CodeGenCXX/constructor-init-reference.cpp new file mode 100644 index 0000000..5e75159 --- /dev/null +++ b/clang/test/CodeGenCXX/constructor-init-reference.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s | grep "store i32\* @x, i32\*\*" + +int x; +struct A { + int& y; + A() : y(x) {} +}; +A z; + diff --git a/clang/test/CodeGenCXX/constructor-init.cpp b/clang/test/CodeGenCXX/constructor-init.cpp new file mode 100644 index 0000000..9f808f6 --- /dev/null +++ b/clang/test/CodeGenCXX/constructor-init.cpp @@ -0,0 +1,222 @@ +// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 %s -emit-llvm -o %t +// RUN: FileCheck %s < %t +// RUN: FileCheck -check-prefix=CHECK-PR10720 %s < %t + +extern "C" int printf(...); + +struct M { + M() { printf("M()\n"); } + M(int i) { iM = i; printf("M(%d)\n", i); } + int iM; + void MPR() {printf("iM = %d\n", iM); }; +}; + +struct P { + P() { printf("P()\n"); } + P(int i) { iP = i; printf("P(%d)\n", i); } + int iP; + void PPR() {printf("iP = %d\n", iP); }; +}; + +struct Q { + Q() { printf("Q()\n"); } + Q(int i) { iQ = i; printf("Q(%d)\n", i); } + int iQ; + void QPR() {printf("iQ = %d\n", iQ); }; +}; + +struct N : M , P, Q { + N() : f1(1.314), P(2000), ld(00.1234+f1), M(1000), Q(3000), + d1(3.4567), i1(1234), m1(100) { printf("N()\n"); } + M m1; + M m2; + float f1; + int i1; + float d1; + void PR() { + printf("f1 = %f d1 = %f i1 = %d ld = %f \n", f1,d1,i1, ld); + MPR(); + PPR(); + QPR(); + printf("iQ = %d\n", iQ); + printf("iP = %d\n", iP); + printf("iM = %d\n", iM); + // FIXME. We don't yet support this syntax. + // printf("iQ = %d\n", (*this).iQ); + printf("iQ = %d\n", this->iQ); + printf("iP = %d\n", this->iP); + printf("iM = %d\n", this->iM); + } + float ld; + float ff; + M arr_m[3]; + P arr_p[1][3]; + Q arr_q[2][3][4]; +}; + +int main() { + M m1; + + N n1; + n1.PR(); +} + +// PR5826 +template struct A { + A() {} + A(int) {} + A(const A&) {} + ~A() {} + operator int() {return 0;} +}; + +// CHECK: define void @_Z1fv() +void f() { + // CHECK: call void @_ZN1AIsEC1Ei + A a4 = 97; + + // CHECK-NEXT: store i32 17 + int i = 17; + + // CHECK-NEXT: call void @_ZN1AIsED1Ev + // CHECK-NOT: call void @_ZN1AIsED1Ev + // CHECK: ret void +} + +// Make sure we initialize the vtable pointer if it's required by a +// base initializer. +namespace InitVTable { + struct A { A(int); }; + struct B : A { + virtual int foo(); + B(); + B(int); + }; + + // CHECK: define void @_ZN10InitVTable1BC2Ev(%"struct.InitVTable::B"* %this) unnamed_addr + // CHECK: [[T0:%.*]] = bitcast [[B:%.*]]* [[THIS:%.*]] to i8*** + // CHECK-NEXT: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN10InitVTable1BE, i64 0, i64 2), i8*** [[T0]] + // CHECK: [[VTBL:%.*]] = load i32 ([[B]]*)*** {{%.*}} + // CHECK-NEXT: [[FNP:%.*]] = getelementptr inbounds i32 ([[B]]*)** [[VTBL]], i64 0 + // CHECK-NEXT: [[FN:%.*]] = load i32 ([[B]]*)** [[FNP]] + // CHECK-NEXT: [[ARG:%.*]] = call i32 [[FN]]([[B]]* [[THIS]]) + // CHECK-NEXT: call void @_ZN10InitVTable1AC2Ei({{.*}}* {{%.*}}, i32 [[ARG]]) + // CHECK-NEXT: [[T0:%.*]] = bitcast [[B]]* [[THIS]] to i8*** + // CHECK-NEXT: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN10InitVTable1BE, i64 0, i64 2), i8*** [[T0]] + // CHECK-NEXT: ret void + B::B() : A(foo()) {} + + // CHECK: define void @_ZN10InitVTable1BC2Ei(%"struct.InitVTable::B"* %this, i32 %x) unnamed_addr + // CHECK: [[ARG:%.*]] = add nsw i32 {{%.*}}, 5 + // CHECK-NEXT: call void @_ZN10InitVTable1AC2Ei({{.*}}* {{%.*}}, i32 [[ARG]]) + // CHECK-NEXT: [[T0:%.*]] = bitcast [[B]]* {{%.*}} to i8*** + // CHECK-NEXT: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN10InitVTable1BE, i64 0, i64 2), i8*** [[T0]] + // CHECK-NEXT: ret void + B::B(int x) : A(x + 5) {} +} + +namespace rdar9694300 { + struct X { + int x; + }; + + // CHECK: define void @_ZN11rdar96943001fEv + void f() { + // CHECK: alloca + X x; + // CHECK-NEXT: [[I:%.*]] = alloca i32 + // CHECK-NEXT: store i32 17, i32* [[I]] + int i = 17; + // CHECK-NEXT: ret void + } +} + +template +struct X { + X(const X &); + + T *start; + T *end; +}; + +template struct X; + +// Make sure that the instantiated constructor initializes start and +// end properly. +// CHECK: define linkonce_odr void @_ZN1XIiEC2ERKS0_(%struct.X* %this, %struct.X* %other) unnamed_addr +// CHECK: {{store.*null}} +// CHECK: {{store.*null}} +// CHECK: ret +template +X::X(const X &other) : start(0), end(0) { } + +X get_X(X x) { return x; } + +namespace PR10720 { + struct X { + X(const X&); + X(X&&); + X& operator=(const X&); + X& operator=(X&&); + ~X(); + }; + + struct pair2 { + X second[4]; + + // CHECK-PR10720: define linkonce_odr {{.*}} @_ZN7PR107205pair2aSERKS0_ + // CHECK-PR10720: load + // CHECK-PR10720: icmp ne + // CHECK-PR10720-NEXT: br i1 + // CHECK-PR10720: call {{.*}} @_ZN7PR107201XaSERKS0_ + // CHECK-PR10720: ret + pair2 &operator=(const pair2&) = default; + + // CHECK-PR10720: define linkonce_odr {{.*}} @_ZN7PR107205pair2aSEOS0_ + // CHECK-PR10720: load + // CHECK-PR10720: icmp ne + // CHECK-PR10720-NEXT: br i1 + // CHECK-PR10720: call {{.*}} @_ZN7PR107201XaSEOS0_ + // CHECK-PR10720: ret + pair2 &operator=(pair2&&) = default; + + // CHECK-PR10720: define linkonce_odr void @_ZN7PR107205pair2C2EOS0_ + // CHECK-PR10720-NOT: ret + // CHECK-PR10720: load + // CHECK-PR10720: icmp ult + // CHECK-PR10720-NEXT: br i1 + // CHECK-PR10720: call void @_ZN7PR107201XC1EOS0_ + // CHECK-PR10720-NEXT: br label + // CHECK-PR10720: ret void + pair2(pair2&&) = default; + + // CHECK-PR10720: define linkonce_odr void @_ZN7PR107205pair2C2ERKS0_ + // CHECK-PR10720-NOT: ret + // CHECK-PR10720: load + // CHECK-PR10720: icmp ult + // CHECK-PR10720-NEXT: br i1 + // CHECK-PR10720: call void @_ZN7PR107201XC1ERKS0_ + // CHECK-PR10720-NEXT: br label + // CHECK-PR10720: ret void + pair2(const pair2&) = default; + }; + + struct pair : X { // Make the copy constructor non-trivial, so we actually generate it. + int second[4]; + // CHECK-PR10720: define linkonce_odr void @_ZN7PR107204pairC2ERKS0_ + // CHECK-PR10720-NOT: ret + // CHECK-PR10720: call void @llvm.memcpy + // CHECK-PR10720-NEXT: ret void + pair(const pair&) = default; + }; + + void foo(const pair &x, const pair2 &x2) { + pair y(x); + pair2 y2(x2); + pair2 y2m(static_cast(y2)); + + y2 = x2; + y2m = static_cast(y2); + } + +} diff --git a/clang/test/CodeGenCXX/constructor-template.cpp b/clang/test/CodeGenCXX/constructor-template.cpp new file mode 100644 index 0000000..fe4687c --- /dev/null +++ b/clang/test/CodeGenCXX/constructor-template.cpp @@ -0,0 +1,54 @@ +// REQUIRES: x86-registered-target,x86-64-registered-target +// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -S %s -o %t-64.s +// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s +// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -S %s -o %t-32.s +// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s + +// PR4826 +struct A { + A() { + } +}; + +template +struct B { + B(T) {} + + A nodes; +}; + + +// PR4853 +template class List { +public: + List(){ } // List*>::List() remains undefined. + ~List() {} +}; + +template class Node { + int i; +public: + Node(){ } // Node*>::Node() remains undefined. + ~Node() {} +}; + + +template class BinomialNode : Node*> { +public: + BinomialNode(T value) {} + List*> nodes; +}; + +int main() { + B *n = new B(4); + BinomialNode *node = new BinomialNode(1); + delete node; +} + +// CHECK-LP64: __ZN4NodeIP12BinomialNodeIiEEC2Ev: +// CHECK-LP64: __ZN4ListIP12BinomialNodeIiEEC1Ev: +// CHECK-LP64: __ZN4ListIP12BinomialNodeIiEED1Ev: + +// CHECK-LP32: __ZN4NodeIP12BinomialNodeIiEEC2Ev: +// CHECK-LP32: __ZN4ListIP12BinomialNodeIiEEC1Ev: +// CHECK-LP32: __ZN4ListIP12BinomialNodeIiEED1Ev: diff --git a/clang/test/CodeGenCXX/constructors.cpp b/clang/test/CodeGenCXX/constructors.cpp new file mode 100644 index 0000000..9e2da31 --- /dev/null +++ b/clang/test/CodeGenCXX/constructors.cpp @@ -0,0 +1,115 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -emit-llvm -o - | FileCheck %s + +struct Member { int x; Member(); Member(int); Member(const Member &); }; +struct VBase { int x; VBase(); VBase(int); VBase(const VBase &); }; + +struct ValueClass { + ValueClass(int x, int y) : x(x), y(y) {} + int x; + int y; +}; // subject to ABI trickery + + + +/* Test basic functionality. */ +struct A { + A(struct Undeclared &); + A(ValueClass); + Member mem; +}; + +A::A(struct Undeclared &ref) : mem(0) {} + +// Check that delegation works. +// CHECK: define void @_ZN1AC1ER10Undeclared(%struct.A* %this, %struct.Undeclared* %ref) unnamed_addr +// CHECK: call void @_ZN1AC2ER10Undeclared( + +// CHECK: define void @_ZN1AC2ER10Undeclared(%struct.A* %this, %struct.Undeclared* %ref) unnamed_addr +// CHECK: call void @_ZN6MemberC1Ei( + +A::A(ValueClass v) : mem(v.y - v.x) {} + +// CHECK: define void @_ZN1AC1E10ValueClass(%struct.A* %this, i64 %v.coerce) unnamed_addr +// CHECK: call void @_ZN1AC2E10ValueClass( + +// CHECK: define void @_ZN1AC2E10ValueClass(%struct.A* %this, i64 %v.coerce) unnamed_addr +// CHECK: call void @_ZN6MemberC1Ei( + + +/* Test that things work for inheritance. */ +struct B : A { + B(struct Undeclared &); + Member mem; +}; + +B::B(struct Undeclared &ref) : A(ref), mem(1) {} + +// CHECK: define void @_ZN1BC1ER10Undeclared(%struct.B* %this, %struct.Undeclared* %ref) unnamed_addr +// CHECK: call void @_ZN1BC2ER10Undeclared( + +// CHECK: define void @_ZN1BC2ER10Undeclared(%struct.B* %this, %struct.Undeclared* %ref) unnamed_addr +// CHECK: call void @_ZN1AC2ER10Undeclared( +// CHECK: call void @_ZN6MemberC1Ei( + + + +/* Test that the delegation optimization is disabled for classes with + virtual bases (for now). This is necessary because a vbase + initializer could access one of the parameter variables by + reference. That's a solvable problem, but let's not solve it right + now. */ +struct C : virtual A { + C(int); + Member mem; +}; +C::C(int x) : A(ValueClass(x, x+1)), mem(x * x) {} + +// CHECK: define void @_ZN1CC1Ei(%struct.C* %this, i32 %x) unnamed_addr +// CHECK: call void @_ZN10ValueClassC1Eii( +// CHECK: call void @_ZN1AC2E10ValueClass( +// CHECK: call void @_ZN6MemberC1Ei( + +// CHECK: define void @_ZN1CC2Ei(%struct.C* %this, i8** %vtt, i32 %x) unnamed_addr +// CHECK: call void @_ZN6MemberC1Ei( + + + +/* Test that the delegation optimization is disabled for varargs + constructors. */ +struct D : A { + D(int, ...); + Member mem; +}; + +D::D(int x, ...) : A(ValueClass(x, x+1)), mem(x*x) {} + +// CHECK: define void @_ZN1DC1Eiz(%struct.D* %this, i32 %x, ...) unnamed_addr +// CHECK: call void @_ZN10ValueClassC1Eii( +// CHECK: call void @_ZN1AC2E10ValueClass( +// CHECK: call void @_ZN6MemberC1Ei( + +// CHECK: define void @_ZN1DC2Eiz(%struct.D* %this, i32 %x, ...) unnamed_addr +// CHECK: call void @_ZN10ValueClassC1Eii( +// CHECK: call void @_ZN1AC2E10ValueClass( +// CHECK: call void @_ZN6MemberC1Ei( + + +// PR6622: this shouldn't crash +namespace test0 { + struct A {}; + struct B : virtual A { int x; }; + struct C : B {}; + + void test(C &in) { + C tmp = in; + } +} + +namespace test1 { + struct A { A(); void *ptr; }; + struct B { B(); int x; A a[0]; }; + B::B() {} + // CHECK: define void @_ZN5test11BC2Ev( + // CHECK: [[THIS:%.*]] = load [[B:%.*]]** + // CHECK-NEXT: ret void +} diff --git a/clang/test/CodeGenCXX/conversion-function.cpp b/clang/test/CodeGenCXX/conversion-function.cpp new file mode 100644 index 0000000..76d9e02 --- /dev/null +++ b/clang/test/CodeGenCXX/conversion-function.cpp @@ -0,0 +1,120 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -S %s -o %t-64.s +// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s +// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -S %s -o %t-32.s +// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s +// XFAIL: * +extern "C" int printf(...); +struct S { + operator int(); +}; + +S::operator int() { + return 10; +} + +int f(S s) { + return s; +} + +class X { // ... + public: operator int() { printf("operator int()\n"); return iX; } + public: operator float() { printf("operator float()\n"); return fX; } + X() : iX(100), fX(1.234) {} + int iX; + float fX; +}; + +X x; + +struct Z { + operator X() { printf("perator X()\n"); x.iX += iZ; x.fX += fZ; return x; } + int iZ; + float fZ; + Z() : iZ(1), fZ(1.00) {} +}; + +Z z; + +class Y { // ... + public: operator Z(){printf("perator Z()\n"); return z; } +}; + +Y y; + +int count=0; +class O { // ... +public: + operator int(){ return ++iO; } + O() : iO(count++) {} + int iO; +}; + +void g(O a, O b) { + int i = (a) ? 1+a : 0; + int j = (a&&b) ? a+b : i; + if (a) { } + printf("i = %d j = %d a.iO = %d b.iO = %d\n", i, j, a.iO, b.iO); +} + +int main() { + int c = X(Z(y)); // OK: y.operator Z().operator X().operator int() + printf("c = %d\n", c); + float f = X(Z(y)); + printf("f = %f\n", f); + int i = x; + printf("i = %d float = %f\n", i, float(x)); + i = int(X(Z(y))); + f = float(X(Z(y))); + printf("i = %d float = %f\n", i,f); + f = (float)x; + i = (int)x; + printf("i = %d float = %f\n", i,f); + + int d = (X)((Z)y); + printf("d = %d\n", d); + + int e = (int)((X)((Z)y)); + printf("e = %d\n", e); + O o1, o2; + g(o1, o2); +} + +// Test. Conversion in base class is visible in derived class. +class XB { + int a; +public: + operator int(); +}; + +class Yb : public XB { + double b; +public: + operator char(); +}; + +void f(Yb& a) { + int i = a; // OK. calls XB::operator int(); + char ch = a; // OK. calls Yb::operator char(); +} + +struct A { + operator int() const; +}; + +// CHECK-LP64: .globl __ZN1ScviEv +// CHECK-LP64-NEXT: __ZN1ScviEv: +// CHECK-LP64: callq __ZN1Ycv1ZEv +// CHECK-LP64: callq __ZN1Zcv1XEv +// CHECK-LP64: callq __ZN1XcviEv +// CHECK-LP64: callq __ZN1XcvfEv +// CHECK-LP64: callq __ZN2XBcviEv +// CHECK-LP64: callq __ZN2YbcvcEv + +// CHECK-LP32: .globl __ZN1ScviEv +// CHECK-LP32-NEXT: __ZN1ScviEv: +// CHECK-LP32: call L__ZN1Ycv1ZEv +// CHECK-LP32: call L__ZN1Zcv1XEv +// CHECK-LP32: call L__ZN1XcviEv +// CHECK-LP32: call L__ZN1XcvfEv +// CHECK-LP32: call L__ZN2XBcviEv +// CHECK-LP32: call L__ZN2YbcvcEv diff --git a/clang/test/CodeGenCXX/conversion-operator-base.cpp b/clang/test/CodeGenCXX/conversion-operator-base.cpp new file mode 100644 index 0000000..8fbeadf --- /dev/null +++ b/clang/test/CodeGenCXX/conversion-operator-base.cpp @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -emit-llvm-only %s -verify +// PR5730 + +struct A { operator int(); float y; }; +struct B : A { double z; }; +void a() { switch(B()) {} } + diff --git a/clang/test/CodeGenCXX/convert-to-fptr.cpp b/clang/test/CodeGenCXX/convert-to-fptr.cpp new file mode 100644 index 0000000..425f79d --- /dev/null +++ b/clang/test/CodeGenCXX/convert-to-fptr.cpp @@ -0,0 +1,47 @@ +// REQUIRES: x86-registered-target,x86-64-registered-target +// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -S %s -o %t-64.s +// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s +// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -S %s -o %t-32.s +// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s + +extern "C" int printf(...); + +int f1(int arg) { return arg; }; + +int f2(float arg) { return int(arg); }; + +typedef int (*fp1)(int); + +typedef int (*fp2)(float); + +struct A { + operator fp1() { return f1; } + operator fp2() { return f2; } +} a; + + +// Test for function reference. +typedef int (&fr1)(int); +typedef int (&fr2)(float); + +struct B { + operator fr1() { return f1; } + operator fr2() { return f2; } +} b; + +int main() +{ + int i = a(10); // Calls f1 via pointer returned from conversion function + printf("i = %d\n", i); + + int j = b(20); // Calls f1 via pointer returned from conversion function + printf("j = %d\n", j); + return 0; +} + +// CHECK-LP64: callq __ZN1AcvPFiiEEv +// CHECK-LP64: callq __ZN1BcvRFiiEEv + +// CHECK-LP32: calll L__ZN1AcvPFiiEEv +// CHECK-LP32: calll L__ZN1BcvRFiiEEv + diff --git a/clang/test/CodeGenCXX/copy-assign-synthesis-1.cpp b/clang/test/CodeGenCXX/copy-assign-synthesis-1.cpp new file mode 100644 index 0000000..46d0483 --- /dev/null +++ b/clang/test/CodeGenCXX/copy-assign-synthesis-1.cpp @@ -0,0 +1,109 @@ +// REQUIRES: x86-registered-target,x86-64-registered-target +// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -S %s -o %t-64.s +// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s +// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -S %s -o %t-32.s +// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s + +extern "C" int printf(...); + +struct B { + B() : B1(3.14), B2(3.15), auB2(3.16) {} + float B1; + float B2; + void pr() { + printf("B1 = %f B2 = %f auB1 = %f\n", B1, B2, auB1); + } + + B& operator=(const B& arg) { B1 = arg.B1; B2 = arg.B2; + auB1 = arg.auB1; return *this; } + union { + float auB1; + float auB2; + }; +}; + +struct M { + M() : M1(10), M2(11) , auM1(12) {} + int M1; + int M2; + void pr() { + printf("M1 = %d M2 = %d auM1 = %d auM2 = %d\n", M1, M2, auM1, auM2); + } + union { + int auM1; + int auM2; + }; +}; + +struct N : B { + N() : N1(20), N2(21) {} + int N1; + int N2; + void pr() { + printf("N1 = %d N2 = %d\n", N1, N2); + for (unsigned i = 0; i < 3; i++) + for (unsigned j = 0; j < 2; j++) + printf("arr_b[%d][%d] = %f\n", i,j,arr_b[i][j].B1); + B::pr(); + } + N& operator=(const N& arg) { + N1 = arg.N1; N2 = arg.N2; + for (unsigned i = 0; i < 3; i++) + for (unsigned j = 0; j < 2; j++) + arr_b[i][j] = arg.arr_b[i][j]; + return *this; + } + B arr_b[3][2]; +}; + +struct Q : B { + Q() : Q1(30), Q2(31) {} + int Q1; + int Q2; + void pr() { + printf("Q1 = %d Q2 = %d\n", Q1, Q2); + } +}; + + +struct X : M , N { + X() : d(0.0), d1(1.1), d2(1.2), d3(1.3) {} + double d; + double d1; + double d2; + double d3; + void pr() { + printf("d = %f d1 = %f d2 = %f d3 = %f\n", d, d1,d2,d3); + M::pr(); N::pr(); + q1.pr(); q2.pr(); + } + + Q q1, q2; +}; + + +X srcX; +X dstX; +X dstY; + +int main() { + dstY = dstX = srcX; + srcX.pr(); + dstX.pr(); + dstY.pr(); +} + +// CHECK-LP64: .globl __ZN1XaSERKS_ +// CHECK-LP64: .weak_definition __ZN1XaSERKS_ +// CHECK-LP64: __ZN1XaSERKS_: +// CHECK-LP64: .globl __ZN1QaSERKS_ +// CHECK-LP64: .weak_definition __ZN1QaSERKS_ +// CHECK-LP64: __ZN1QaSERKS_: + +// CHECK-LP32: .globl __ZN1XaSERKS_ +// CHECK-LP32: .weak_definition __ZN1XaSERKS_ +// CHECK-LP32: __ZN1XaSERKS_: +// CHECK-LP32: .globl __ZN1QaSERKS_ +// CHECK-LP32: .weak_definition __ZN1QaSERKS_ +// CHECK-LP32: __ZN1QaSERKS_: + diff --git a/clang/test/CodeGenCXX/copy-assign-synthesis-2.cpp b/clang/test/CodeGenCXX/copy-assign-synthesis-2.cpp new file mode 100644 index 0000000..c25e046 --- /dev/null +++ b/clang/test/CodeGenCXX/copy-assign-synthesis-2.cpp @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s +struct A {}; +A& (A::*x)(const A&) = &A::operator=; +// CHECK: define linkonce_odr %struct.A* @_ZN1AaSERKS_ diff --git a/clang/test/CodeGenCXX/copy-assign-synthesis-3.cpp b/clang/test/CodeGenCXX/copy-assign-synthesis-3.cpp new file mode 100644 index 0000000..ce4640a --- /dev/null +++ b/clang/test/CodeGenCXX/copy-assign-synthesis-3.cpp @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -emit-llvm-only -verify %s + +struct A { + A& operator=(A&); +}; + +struct B { + void operator=(B); +}; + +struct C { + A a; + B b; + float c; + int (A::*d)(); + _Complex float e; + int f[10]; + A g[2]; + B h[2]; +}; +void a(C& x, C& y) { + x = y; +} + diff --git a/clang/test/CodeGenCXX/copy-assign-synthesis.cpp b/clang/test/CodeGenCXX/copy-assign-synthesis.cpp new file mode 100644 index 0000000..e9fc0c3 --- /dev/null +++ b/clang/test/CodeGenCXX/copy-assign-synthesis.cpp @@ -0,0 +1,79 @@ +// RUN: %clang_cc1 -emit-llvm -o %t %s +// RUN: grep "_ZN1XaSERK1X" %t | count 0 + +extern "C" int printf(...); + +struct B { + B() : B1(3.14), B2(3.15), auB2(3.16) {} + float B1; + float B2; + void pr() { + printf("B1 = %f B2 = %f auB1 = %f\n", B1, B2, auB1); + } + + union { + float auB1; + float auB2; + }; +}; + +struct M { + M() : M1(10), M2(11) , auM1(12) {} + int M1; + int M2; + void pr() { + printf("M1 = %d M2 = %d auM1 = %d auM2 = %d\n", M1, M2, auM1, auM2); + } + union { + int auM1; + int auM2; + }; +}; + +struct N : B { + N() : N1(20), N2(21) {} + int N1; + int N2; + void pr() { + printf("N1 = %d N2 = %d\n", N1, N2); + B::pr(); + } +}; + +struct Q { + Q() : Q1(30), Q2(31) {} + int Q1; + int Q2; + void pr() { + printf("Q1 = %d Q2 = %d\n", Q1, Q2); + } +}; + + +struct X : M , N { + X() : d(0.0), d1(1.1), d2(1.2), d3(1.3) {} + double d; + double d1; + double d2; + double d3; + void pr() { + printf("d = %f d1 = %f d2 = %f d3 = %f\n", d, d1,d2,d3); + M::pr(); N::pr(); + q1.pr(); q2.pr(); + } + + Q q1, q2; +}; + + +X srcX; +X dstX; +X dstY; + +int main() { + dstY = dstX = srcX; + srcX.pr(); + dstX.pr(); + dstY.pr(); +} + diff --git a/clang/test/CodeGenCXX/copy-assign-volatile-synthesis.cpp b/clang/test/CodeGenCXX/copy-assign-volatile-synthesis.cpp new file mode 100644 index 0000000..eb13503 --- /dev/null +++ b/clang/test/CodeGenCXX/copy-assign-volatile-synthesis.cpp @@ -0,0 +1,43 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s +// rdar://9894548 + +typedef unsigned long word_t; +typedef unsigned long u64_t; +typedef unsigned int u32_t; + +class ioapic_redir_t { +public: + union { + struct { + word_t vector : 8; + + word_t delivery_mode : 3; + word_t dest_mode : 1; + + word_t delivery_status : 1; + word_t polarity : 1; + word_t irr : 1; + word_t trigger_mode : 1; + + word_t mask : 1; + word_t _pad0 : 15; + + word_t dest : 8; + }; + volatile u32_t raw[2]; + volatile u64_t raw64; + }; +}; + +struct ioapic_shadow_struct +{ + ioapic_redir_t redirs[24]; +} ioapic_shadow[16]; + +void init_ioapic(unsigned long ioapic_id) +{ + ioapic_redir_t entry; + ioapic_shadow[ioapic_id].redirs[3] = entry; +} + +// CHECK: call void @llvm.memcpy diff --git a/clang/test/CodeGenCXX/copy-constructor-elim-2.cpp b/clang/test/CodeGenCXX/copy-constructor-elim-2.cpp new file mode 100644 index 0000000..9480cbf --- /dev/null +++ b/clang/test/CodeGenCXX/copy-constructor-elim-2.cpp @@ -0,0 +1,77 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s + +struct A { int x; A(int); ~A(); }; +A f() { return A(0); } +// CHECK: define void @_Z1fv +// CHECK: call {{.*}} @_ZN1AC1Ei +// CHECK-NEXT: ret void + +// Verify that we do not elide copies when constructing a base class. +namespace no_elide_base { + struct Base { + Base(const Base&); + ~Base(); + }; + + struct Other { + operator Base() const; + }; + + struct Derived : public virtual Base { + Derived(const Other &O); + }; + + // CHECK: define {{.*}} @_ZN13no_elide_base7DerivedC1ERKNS_5OtherE(%"struct.no_elide_base::Derived"* %this, %"struct.no_elide_base::Other"* %O) unnamed_addr + Derived::Derived(const Other &O) + // CHECK: call {{.*}} @_ZNK13no_elide_base5OthercvNS_4BaseEEv + // CHECK: call {{.*}} @_ZN13no_elide_base4BaseC2ERKS0_ + // CHECK: call {{.*}} @_ZN13no_elide_base4BaseD1Ev + : Base(O) + { + // CHECK: ret + } +} + +// PR8683. + +namespace PR8683 { + +struct A { + A(); + A(const A&); + A& operator=(const A&); +}; + +struct B { + A a; +}; + +void f() { + // Verify that we don't mark the copy constructor in this expression as elidable. + // CHECK: call {{.*}} @_ZN6PR86831AC1ERKS0_ + A a = (B().a); +} + +} + +namespace PR12139 { + struct A { + A() : value(1) { } + A(A const &, int value = 2) : value(value) { } + int value; + + static A makeA() { A a; a.value = 2; return a; } + }; + + // CHECK: define i32 @_ZN7PR121394testEv + int test() { + // CHECK: call void @_ZN7PR121391A5makeAEv + // CHECK-NEXT: call void @_ZN7PR121391AC1ERKS0_i + A a(A::makeA(), 3); + // CHECK-NEXT: getelementptr inbounds + // CHECK-NEXT: load + // CHECK-NEXT: ret i32 + return a.value; + } +} + diff --git a/clang/test/CodeGenCXX/copy-constructor-elim.cpp b/clang/test/CodeGenCXX/copy-constructor-elim.cpp new file mode 100644 index 0000000..c883584 --- /dev/null +++ b/clang/test/CodeGenCXX/copy-constructor-elim.cpp @@ -0,0 +1,42 @@ +// RUN: %clang_cc1 -emit-llvm -o %t %s +// RUN: grep "_ZN1CC1ERK1C" %t | count 0 +// RUN: grep "_ZN1SC1ERK1S" %t | count 0 + +extern "C" int printf(...); + + +struct C { + C() : iC(6) {printf("C()\n"); } + C(const C& c) { printf("C(const C& c)\n"); } + int iC; +}; + +C foo() { + return C(); +}; + +class X { // ... +public: + X(int) {} + X(const X&, int i = 1, int j = 2, C c = foo()) { + printf("X(const X&, %d, %d, %d)\n", i, j, c.iC); + } +}; + + +struct S { + S(); +}; + +S::S() { printf("S()\n"); } + +void Call(S) {}; + +int main() { + X a(1); + X b(a, 2); + X c = b; + X d(a, 5, 6); + S s; + Call(s); +} diff --git a/clang/test/CodeGenCXX/copy-constructor-synthesis-2.cpp b/clang/test/CodeGenCXX/copy-constructor-synthesis-2.cpp new file mode 100644 index 0000000..d028a28 --- /dev/null +++ b/clang/test/CodeGenCXX/copy-constructor-synthesis-2.cpp @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s + +struct A { virtual void a(); }; +A x(A& y) { return y; } + +// CHECK: define linkonce_odr {{.*}} @_ZN1AC1ERKS_(%struct.A* %this, %struct.A*) unnamed_addr +// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1A, i64 0, i64 2) diff --git a/clang/test/CodeGenCXX/copy-constructor-synthesis.cpp b/clang/test/CodeGenCXX/copy-constructor-synthesis.cpp new file mode 100644 index 0000000..68f6805 --- /dev/null +++ b/clang/test/CodeGenCXX/copy-constructor-synthesis.cpp @@ -0,0 +1,156 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o - %s | FileCheck %s + +extern "C" int printf(...); + +int init = 100; + +struct M { + int iM; + M() : iM(init++) {} +}; + +struct N { + int iN; + N() : iN(200) {} + N(N const & arg){this->iN = arg.iN; } +}; + +struct P { + int iP; + P() : iP(init++) {} +}; + + +// CHECK: define linkonce_odr void @_ZN1XC1ERKS_(%struct.X* %this, %struct.X*) unnamed_addr +struct X : M, N, P { // ... + X() : f1(1.0), d1(2.0), i1(3), name("HELLO"), bf1(0xff), bf2(0xabcd), + au_i1(1234), au1_4("MASKED") {} + P p0; + void pr() { + printf("iM = %d iN = %d, m1.iM = %d\n", iM, iN, m1.iM); + printf("im = %d p0.iP = %d, p1.iP = %d\n", iP, p0.iP, p1.iP); + printf("f1 = %f d1 = %f i1 = %d name(%s) \n", f1, d1, i1, name); + printf("bf1 = %x bf2 = %x\n", bf1, bf2); + printf("au_i2 = %d\n", au_i2); + printf("au1_1 = %s\n", au1_1); + } + M m1; + P p1; + float f1; + double d1; + int i1; + const char *name; + unsigned bf1 : 8; + unsigned bf2 : 16; + int arr[2]; + _Complex float complex; + + union { + int au_i1; + int au_i2; + }; + union { + const char * au1_1; + float au1_2; + int au1_3; + const char * au1_4; + }; +}; + +static int ix = 1; +// class with user-defined copy constructor. +struct S { + S() : iS(ix++) { } + S(const S& arg) { *this = arg; } + int iS; +}; + +// class with trivial copy constructor. +struct I { + I() : iI(ix++) { } + int iI; +}; + +struct XM { + XM() { } + double dXM; + S ARR_S[3][4][2]; + void pr() { + for (unsigned i = 0; i < 3; i++) + for (unsigned j = 0; j < 4; j++) + for (unsigned k = 0; k < 2; k++) + printf("ARR_S[%d][%d][%d] = %d\n", i,j,k, ARR_S[i][j][k].iS); + for (unsigned i = 0; i < 3; i++) + for (unsigned k = 0; k < 2; k++) + printf("ARR_I[%d][%d] = %d\n", i,k, ARR_I[i][k].iI); + } + I ARR_I[3][2]; +}; + +int main() { + X a; + X b(a); + b.pr(); + X x; + X c(x); + c.pr(); + + XM m0; + XM m1 = m0; + m1.pr(); +} + +struct A { +}; + +struct B : A { + A &a; +}; + +void f(const B &b1) { + B b2(b1); +} + +// PR6628 +namespace PR6628 { + +struct T { + T(); + ~T(); + + double d; +}; + +struct A { + A(const A &other, const T &t = T(), const T& t2 = T()); +}; + +struct B : A { + A a1; + A a2; + A a[10]; +}; + +// Force the copy constructor to be synthesized. +void f(B b1) { + B b2 = b1; +} + +// CHECK: define linkonce_odr void @_ZN6PR66281BC2ERKS0_(%"struct.PR6628::B"* %this, %"struct.PR6628::B"*) unnamed_addr +// CHECK: call void @_ZN6PR66281TC1Ev +// CHECK: call void @_ZN6PR66281TC1Ev +// CHECK: call void @_ZN6PR66281AC2ERKS0_RKNS_1TES5_ +// CHECK: call void @_ZN6PR66281TD1Ev +// CHECK: call void @_ZN6PR66281TD1Ev +// CHECK: call void @_ZN6PR66281TC1Ev +// CHECK: call void @_ZN6PR66281TC1Ev +// CHECK: call void @_ZN6PR66281AC1ERKS0_RKNS_1TES5_ +// CHECK: call void @_ZN6PR66281TD1Ev +// CHECK: call void @_ZN6PR66281TD1Ev +// CHECK: call void @_ZN6PR66281TC1Ev +// CHECK: call void @_ZN6PR66281TC1Ev +// CHECK: call void @_ZN6PR66281AC1ERKS0_RKNS_1TES5_ +// CHECK: call void @_ZN6PR66281TD1Ev +// CHECK: call void @_ZN6PR66281TD1Ev +} + diff --git a/clang/test/CodeGenCXX/copy-in-cplus-object.cpp b/clang/test/CodeGenCXX/copy-in-cplus-object.cpp new file mode 100644 index 0000000..bdfca5e --- /dev/null +++ b/clang/test/CodeGenCXX/copy-in-cplus-object.cpp @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 %s -fblocks -triple x86_64-apple-darwin -emit-llvm -o - | FileCheck %s + +struct S { + S(const char *); + ~S(); +}; + +struct TestObject +{ + TestObject(const TestObject& inObj, int def = 100, const S &Silly = "silly"); + TestObject(); + ~TestObject(); + TestObject& operator=(const TestObject& inObj); + int version() const; + +}; + +void testRoutine() { + TestObject one; + int (^V)() = ^{ return one.version(); }; +} + +// CHECK: call void @_ZN10TestObjectC1Ev +// CHECK: call void @_ZN1SC1EPKc +// CHECK: call void @_ZN10TestObjectC1ERKS_iRK1S +// CHECK: call void @_ZN1SD1Ev +// CHECK: call void @_ZN10TestObjectD1Ev +// CHECK: call void @_ZN10TestObjectD1Ev diff --git a/clang/test/CodeGenCXX/copy-initialization.cpp b/clang/test/CodeGenCXX/copy-initialization.cpp new file mode 100644 index 0000000..aecd64e --- /dev/null +++ b/clang/test/CodeGenCXX/copy-initialization.cpp @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s + +struct Foo { + Foo(); + Foo(const Foo&); +}; + +struct Bar { + Bar(); + operator const Foo&() const; +}; + +void f(Foo); + +// CHECK: define void @_Z1g3Foo(%struct.Foo* %foo) +void g(Foo foo) { + // CHECK: call void @_ZN3BarC1Ev + // CHECK: @_ZNK3BarcvRK3FooEv + // CHECK: call void @_Z1f3Foo + f(Bar()); + // CHECK: call void @_ZN3FooC1Ev + // CHECK: call void @_Z1f3Foo + f(Foo()); + // CHECK: call void @_ZN3FooC1ERKS_ + // CHECK: call void @_Z1f3Foo + f(foo); + // CHECK: ret +} + diff --git a/clang/test/CodeGenCXX/cxx-apple-kext.cpp b/clang/test/CodeGenCXX/cxx-apple-kext.cpp new file mode 100644 index 0000000..e5ec78b --- /dev/null +++ b/clang/test/CodeGenCXX/cxx-apple-kext.cpp @@ -0,0 +1,36 @@ +// RUN: %clangxx -target x86_64-apple-darwin10 %s -flto -S -o - |\ +// RUN: FileCheck --check-prefix=CHECK-NO-KEXT %s +// RUN: %clangxx -target x86_64-apple-darwin10 %s -fapple-kext -flto -S -o - |\ +// RUN: FileCheck --check-prefix=CHECK-KEXT %s + +// CHECK-NO-KEXT-NOT: _GLOBAL__D_a +// CHECK-NO-KEXT: @is_hosted = global +// CHECK-NO-KEXT: @_ZTI3foo = {{.*}} @_ZTVN10__cxxabiv117 +// CHECK-NO-KEXT: call i32 @__cxa_atexit({{.*}} @_ZN3fooD1Ev +// CHECK-NO-KEXT: declare i32 @__cxa_atexit + +// CHECK-KEXT: @_ZTV3foo = +// CHECK-KEXT-NOT: @_ZTVN10__cxxabiv117 +// CHECK-KEXT-NOT: call i32 @__cxa_atexit({{.*}} @_ZN3fooD1Ev +// CHECK-KEXT-NOT: declare i32 @__cxa_atexit +// CHECK-KEXT: @is_freestanding = global +// CHECK-KEXT: _GLOBAL__D_a +// CHECK-KEXT: call void @_ZN3fooD1Ev(%class.foo* @a) + +class foo { +public: + foo(); + virtual ~foo(); +}; + +foo a; +foo::~foo() {} + +#if !(__STDC_HOSTED__ == 1) +int is_freestanding = 1; +#else +int is_hosted = 1; +#endif + +extern "C" void f1() { +} diff --git a/clang/test/CodeGenCXX/cxx-block-objects.cpp b/clang/test/CodeGenCXX/cxx-block-objects.cpp new file mode 100644 index 0000000..b989065 --- /dev/null +++ b/clang/test/CodeGenCXX/cxx-block-objects.cpp @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 %s -fblocks -triple x86_64-apple-darwin -emit-llvm -o - | FileCheck %s +// rdar://8594790 + +extern "C" { +extern "C" void *_Block_copy(const void *aBlock); +extern "C" void _Block_release(const void *aBlock); +} + +class A { +public: + int x; + A(const A &o); + A(); + virtual ~A(); + void hello() const; +}; + +int +main() +{ + A a; + void (^c)(void) = ((__typeof(^{ a.hello(); }))_Block_copy((const void *)(^{ a.hello(); }))); + c(); + _Block_release((const void *)(c)); + return 0; +} + +// CHECK: define internal void @__copy_helper_block_ +// CHECK: call void @_ZN1AC1ERKS_ + + +// CHECK:define internal void @__destroy_helper_block_ +// CHECK: call void @_ZN1AD1Ev diff --git a/clang/test/CodeGenCXX/cxx0x-defaulted-templates.cpp b/clang/test/CodeGenCXX/cxx0x-defaulted-templates.cpp new file mode 100644 index 0000000..f4d5ccc --- /dev/null +++ b/clang/test/CodeGenCXX/cxx0x-defaulted-templates.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -std=c++11 -emit-llvm -o - %s | FileCheck %s + +template +struct X { + X(); +}; + +// CHECK: define {{.*}} @_ZN1XIbEC1Ev +// CHECK: define {{.*}} @_ZN1XIbEC2Ev +template <> X::X() = default; + +// CHECK: define weak_odr {{.*}} @_ZN1XIiEC1Ev +// CHECK: define weak_odr {{.*}} @_ZN1XIiEC2Ev +template X::X() = default; +template X::X(); + +// CHECK: define linkonce_odr {{.*}} @_ZN1XIcEC1Ev +// CHECK: define linkonce_odr {{.*}} @_ZN1XIcEC2Ev +X x; diff --git a/clang/test/CodeGenCXX/cxx0x-delegating-ctors.cpp b/clang/test/CodeGenCXX/cxx0x-delegating-ctors.cpp new file mode 100644 index 0000000..f5684d9 --- /dev/null +++ b/clang/test/CodeGenCXX/cxx0x-delegating-ctors.cpp @@ -0,0 +1,56 @@ +// RUN: %clang_cc1 -emit-llvm -fexceptions -fcxx-exceptions -std=c++11 -o - %s | FileCheck %s + +struct non_trivial { + non_trivial(); + ~non_trivial() noexcept(false); +}; +non_trivial::non_trivial() {} +non_trivial::~non_trivial() noexcept(false) {} + +// We use a virtual base to ensure that the constructor +// delegation optimization (complete->base) can't be +// performed. +struct delegator { + non_trivial n; + delegator(); + delegator(int); + delegator(char); + delegator(bool); +}; + +delegator::delegator() { + throw 0; +} + + +delegator::delegator(bool) +{} + +// CHECK: define {{.*}} @_ZN9delegatorC1Ec +// CHECK: {{.*}} @_ZN9delegatorC1Eb +// CHECK: void @__cxa_throw +// CHECK: void @_ZSt9terminatev +// CHECK: {{.*}} @_ZN9delegatorD1Ev +// CHECK: define {{.*}} @_ZN9delegatorC2Ec +// CHECK: {{.*}} @_ZN9delegatorC2Eb +// CHECK: void @__cxa_throw +// CHECK: void @_ZSt9terminatev +// CHECK: {{.*}} @_ZN9delegatorD2Ev +delegator::delegator(char) + : delegator(true) { + throw 0; +} + +// CHECK: define {{.*}} @_ZN9delegatorC1Ei +// CHECK: {{.*}} @_ZN9delegatorC1Ev +// CHECK-NOT: void @_ZSt9terminatev +// CHECK: ret +// CHECK-NOT: void @_ZSt9terminatev +// CHECK: define {{.*}} @_ZN9delegatorC2Ei +// CHECK: {{.*}} @_ZN9delegatorC2Ev +// CHECK-NOT: void @_ZSt9terminatev +// CHECK: ret +// CHECK-NOT: void @_ZSt9terminatev +delegator::delegator(int) + : delegator() +{} diff --git a/clang/test/CodeGenCXX/cxx0x-initializer-array.cpp b/clang/test/CodeGenCXX/cxx0x-initializer-array.cpp new file mode 100644 index 0000000..b773178 --- /dev/null +++ b/clang/test/CodeGenCXX/cxx0x-initializer-array.cpp @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -std=c++11 -S -emit-llvm -o - %s | FileCheck %s + +struct A { int a[1]; }; +typedef A x[]; +int f() { + x{{{1}}}; + // CHECK: define i32 @_Z1fv + // CHECK: store i32 1 + // (It's okay if the output changes here, as long as we don't crash.) +} diff --git a/clang/test/CodeGenCXX/cxx0x-initializer-references.cpp b/clang/test/CodeGenCXX/cxx0x-initializer-references.cpp new file mode 100644 index 0000000..4c847b8 --- /dev/null +++ b/clang/test/CodeGenCXX/cxx0x-initializer-references.cpp @@ -0,0 +1,69 @@ +// RUN: %clang_cc1 -std=c++11 -S -emit-llvm -o - %s | FileCheck %s + +namespace reference { + struct A { + int i1, i2; + }; + + void single_init() { + // No superfluous instructions allowed here, they could be + // hiding extra temporaries. + + // CHECK: store i32 1, i32* + // CHECK-NEXT: store i32* %{{.*}}, i32** + const int &cri2a = 1; + + // CHECK-NEXT: store i32 1, i32* + // CHECK-NEXT: store i32* %{{.*}}, i32** + const int &cri1a = {1}; + + // CHECK-NEXT: store i32 1, i32* + int i = 1; + // CHECK-NEXT: store i32* %{{.*}}, i32** + int &ri1a = {i}; + + // CHECK-NEXT: bitcast + // CHECK-NEXT: memcpy + A a{1, 2}; + // CHECK-NEXT: store %{{.*}}* %{{.*}}, %{{.*}}** % + A &ra1a = {a}; + + // CHECK-NEXT: ret + } + + void reference_to_aggregate() { + // CHECK: getelementptr {{.*}}, i32 0, i32 0 + // CHECK-NEXT: store i32 1 + // CHECK-NEXT: getelementptr {{.*}}, i32 0, i32 1 + // CHECK-NEXT: store i32 2 + // CHECK-NEXT: store %{{.*}}* %{{.*}}, %{{.*}}** %{{.*}}, align + const A &ra1{1, 2}; + + // CHECK-NEXT: getelementptr inbounds [3 x i32]* %{{.*}}, i{{32|64}} 0, i{{32|64}} 0 + // CHECK-NEXT: store i32 1 + // CHECK-NEXT: getelementptr inbounds i32* %{{.*}}, i{{32|64}} 1 + // CHECK-NEXT: store i32 2 + // CHECK-NEXT: getelementptr inbounds i32* %{{.*}}, i{{32|64}} 1 + // CHECK-NEXT: store i32 3 + // CHECK-NEXT: store [3 x i32]* %{{.*}}, [3 x i32]** %{{.*}}, align + const int (&arrayRef)[] = {1, 2, 3}; + + // CHECK-NEXT: ret + } + + struct B { + B(); + ~B(); + }; + + void single_init_temp_cleanup() + { + // Ensure lifetime extension. + + // CHECK: call void @_ZN9reference1BC1Ev + // CHECK-NEXT: store %{{.*}}* %{{.*}}, %{{.*}}** % + const B &rb{ B() }; + // CHECK: call void @_ZN9reference1BD1Ev + } + +} diff --git a/clang/test/CodeGenCXX/cxx0x-initializer-scalars.cpp b/clang/test/CodeGenCXX/cxx0x-initializer-scalars.cpp new file mode 100644 index 0000000..10c6966 --- /dev/null +++ b/clang/test/CodeGenCXX/cxx0x-initializer-scalars.cpp @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -std=c++11 -S -emit-llvm -o - %s | FileCheck %s + +void f() +{ + // CHECK: store i32 0 + int i{}; +} diff --git a/clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-pr12086.cpp b/clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-pr12086.cpp new file mode 100644 index 0000000..14d2f77 --- /dev/null +++ b/clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-pr12086.cpp @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -std=c++11 -emit-llvm -o - -verify %s + +namespace std { + typedef decltype(sizeof(int)) size_t; + + // libc++'s implementation + template + class initializer_list + { + const _E* __begin_; + size_t __size_; + + initializer_list(const _E* __b, size_t __s) + : __begin_(__b), + __size_(__s) + {} + + public: + typedef _E value_type; + typedef const _E& reference; + typedef const _E& const_reference; + typedef size_t size_type; + + typedef const _E* iterator; + typedef const _E* const_iterator; + + initializer_list() : __begin_(nullptr), __size_(0) {} + + size_t size() const {return __size_;} + const _E* begin() const {return __begin_;} + const _E* end() const {return __begin_ + __size_;} + }; +} + +std::initializer_list> pleasefail = { + {1, 2}, {3, 4}, {5, 6} // expected-error {{cannot compile}} +}; diff --git a/clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-startend.cpp b/clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-startend.cpp new file mode 100644 index 0000000..c533e45 --- /dev/null +++ b/clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-startend.cpp @@ -0,0 +1,85 @@ +// RUN: %clang_cc1 -std=c++11 -S -emit-llvm -o - %s | FileCheck %s + +namespace std { + typedef decltype(sizeof(int)) size_t; + + // libc++'s implementation with __size_ replaced by __end_ + template + class initializer_list + { + const _E* __begin_; + const _E* __end_; + + initializer_list(const _E* __b, const _E* __e) + : __begin_(__b), + __end_(__e) + {} + + public: + typedef _E value_type; + typedef const _E& reference; + typedef const _E& const_reference; + typedef size_t size_type; + + typedef const _E* iterator; + typedef const _E* const_iterator; + + initializer_list() : __begin_(nullptr), __end_(nullptr) {} + + size_t size() const {return __end_ - __begin_;} + const _E* begin() const {return __begin_;} + const _E* end() const {return __end_;} + }; +} + +// CHECK: @_ZL25globalInitList1__initlist = internal global [3 x i32] [i32 1, i32 2, i32 3] +// CHECK: @globalInitList1 = global {{[^ ]+}} { i32* getelementptr inbounds ([3 x i32]* @_ZL25globalInitList1__initlist, {{[^)]*}}), i32* +std::initializer_list globalInitList1 = {1, 2, 3}; + +void fn1(int i) { + // CHECK: define void @_Z3fn1i + // temporary array + // CHECK: [[array:%[^ ]+]] = alloca [3 x i32] + // CHECK: getelementptr inbounds [3 x i32]* [[array]], i{{32|64}} 0 + // CHECK-NEXT: store i32 1, i32* + // CHECK-NEXT: getelementptr + // CHECK-NEXT: store + // CHECK-NEXT: getelementptr + // CHECK-NEXT: load + // CHECK-NEXT: store + // init the list + // CHECK-NEXT: getelementptr + // CHECK-NEXT: getelementptr inbounds [3 x i32]* + // CHECK-NEXT: store i32* + // CHECK-NEXT: getelementptr + // CHECK-NEXT: getelementptr inbounds [3 x i32]* [[array]], i{{32|64}} 0, i{{32|64}} 3 + // CHECK-NEXT: store i32* + std::initializer_list intlist{1, 2, i}; +} + +struct destroyme1 { + ~destroyme1(); +}; +struct destroyme2 { + ~destroyme2(); +}; + + +void fn2() { + // CHECK: define void @_Z3fn2v + void target(std::initializer_list); + // objects should be destroyed before dm2, after call returns + target({ destroyme1(), destroyme1() }); + // CHECK: call void @_ZN10destroyme1D1Ev + destroyme2 dm2; + // CHECK: call void @_ZN10destroyme2D1Ev +} + +void fn3() { + // CHECK: define void @_Z3fn3v + // objects should be destroyed after dm2 + auto list = { destroyme1(), destroyme1() }; + destroyme2 dm2; + // CHECK: call void @_ZN10destroyme2D1Ev + // CHECK: call void @_ZN10destroyme1D1Ev +} diff --git a/clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp b/clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp new file mode 100644 index 0000000..81ce559 --- /dev/null +++ b/clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp @@ -0,0 +1,252 @@ +// RUN: %clang_cc1 -std=c++11 -S -emit-llvm -o - %s | FileCheck %s + +namespace std { + typedef decltype(sizeof(int)) size_t; + + // libc++'s implementation + template + class initializer_list + { + const _E* __begin_; + size_t __size_; + + initializer_list(const _E* __b, size_t __s) + : __begin_(__b), + __size_(__s) + {} + + public: + typedef _E value_type; + typedef const _E& reference; + typedef const _E& const_reference; + typedef size_t size_type; + + typedef const _E* iterator; + typedef const _E* const_iterator; + + initializer_list() : __begin_(nullptr), __size_(0) {} + + size_t size() const {return __size_;} + const _E* begin() const {return __begin_;} + const _E* end() const {return __begin_ + __size_;} + }; +} + +struct destroyme1 { + ~destroyme1(); +}; +struct destroyme2 { + ~destroyme2(); +}; +struct witharg1 { + witharg1(const destroyme1&); + ~witharg1(); +}; +struct wantslist1 { + wantslist1(std::initializer_list); + ~wantslist1(); +}; + +// CHECK: @_ZL25globalInitList1__initlist = internal global [3 x i32] [i32 1, i32 2, i32 3] +// CHECK: @globalInitList1 = global %{{[^ ]+}} { i32* getelementptr inbounds ([3 x i32]* @_ZL25globalInitList1__initlist, i32 0, i32 0), i{{32|64}} 3 } +std::initializer_list globalInitList1 = {1, 2, 3}; + +// CHECK: @_ZL25globalInitList2__initlist = internal global [2 x %{{[^ ]*}}] zeroinitializer +// CHECK: @globalInitList2 = global %{{[^ ]+}} { %[[WITHARG:[^ *]+]]* getelementptr inbounds ([2 x +// CHECK: appending global +// CHECK: define internal void +// CHECK: call void @_ZN8witharg1C1ERK10destroyme1(%[[WITHARG]]* getelementptr inbounds ([2 x %[[WITHARG]]]* @_ZL25globalInitList2__initlist, i{{32|64}} 0, i{{32|64}} 0 +// CHECK: call void @_ZN8witharg1C1ERK10destroyme1(%[[WITHARG]]* getelementptr inbounds ([2 x %[[WITHARG]]]* @_ZL25globalInitList2__initlist, i{{32|64}} 0, i{{32|64}} 1 +// CHECK: __cxa_atexit +// CHECK: call void @_ZN10destroyme1D1Ev +// CHECK: call void @_ZN10destroyme1D1Ev +std::initializer_list globalInitList2 = { + witharg1(destroyme1()), witharg1(destroyme1()) +}; + +void fn1(int i) { + // CHECK: define void @_Z3fn1i + // temporary array + // CHECK: [[array:%[^ ]+]] = alloca [3 x i32] + // CHECK: getelementptr inbounds [3 x i32]* [[array]], i{{32|64}} 0 + // CHECK-NEXT: store i32 1, i32* + // CHECK-NEXT: getelementptr + // CHECK-NEXT: store + // CHECK-NEXT: getelementptr + // CHECK-NEXT: load + // CHECK-NEXT: store + // init the list + // CHECK-NEXT: getelementptr + // CHECK-NEXT: getelementptr inbounds [3 x i32]* + // CHECK-NEXT: store i32* + // CHECK-NEXT: getelementptr + // CHECK-NEXT: store i{{32|64}} 3 + std::initializer_list intlist{1, 2, i}; +} + +void fn2() { + // CHECK: define void @_Z3fn2v + void target(std::initializer_list); + // objects should be destroyed before dm2, after call returns + // CHECK: call void @_Z6targetSt16initializer_listI10destroyme1E + target({ destroyme1(), destroyme1() }); + // CHECK: call void @_ZN10destroyme1D1Ev + destroyme2 dm2; + // CHECK: call void @_ZN10destroyme2D1Ev +} + +void fn3() { + // CHECK: define void @_Z3fn3v + // objects should be destroyed after dm2 + auto list = { destroyme1(), destroyme1() }; + destroyme2 dm2; + // CHECK: call void @_ZN10destroyme2D1Ev + // CHECK: call void @_ZN10destroyme1D1Ev +} + +void fn4() { + // CHECK: define void @_Z3fn4v + void target(std::initializer_list); + // objects should be destroyed before dm2, after call returns + // CHECK: call void @_ZN8witharg1C1ERK10destroyme1 + // CHECK: call void @_Z6targetSt16initializer_listI8witharg1E + target({ witharg1(destroyme1()), witharg1(destroyme1()) }); + // CHECK: call void @_ZN8witharg1D1Ev + // CHECK: call void @_ZN10destroyme1D1Ev + destroyme2 dm2; + // CHECK: call void @_ZN10destroyme2D1Ev +} + +void fn5() { + // CHECK: define void @_Z3fn5v + // temps should be destroyed before dm2 + // objects should be destroyed after dm2 + // CHECK: call void @_ZN8witharg1C1ERK10destroyme1 + auto list = { witharg1(destroyme1()), witharg1(destroyme1()) }; + // CHECK: call void @_ZN10destroyme1D1Ev + destroyme2 dm2; + // CHECK: call void @_ZN10destroyme2D1Ev + // CHECK: call void @_ZN8witharg1D1Ev +} + +void fn6() { + // CHECK: define void @_Z3fn6v + void target(const wantslist1&); + // objects should be destroyed before dm2, after call returns + // CHECK: call void @_ZN10wantslist1C1ESt16initializer_listI10destroyme1E + // CHECK: call void @_Z6targetRK10wantslist1 + target({ destroyme1(), destroyme1() }); + // CHECK: call void @_ZN10wantslist1D1Ev + // CHECK: call void @_ZN10destroyme1D1Ev + destroyme2 dm2; + // CHECK: call void @_ZN10destroyme2D1Ev +} + +void fn7() { + // CHECK: define void @_Z3fn7v + // temps should be destroyed before dm2 + // object should be destroyed after dm2 + // CHECK: call void @_ZN10wantslist1C1ESt16initializer_listI10destroyme1E + wantslist1 wl = { destroyme1(), destroyme1() }; + // CHECK: call void @_ZN10destroyme1D1Ev + destroyme2 dm2; + // CHECK: call void @_ZN10destroyme2D1Ev + // CHECK: call void @_ZN10wantslist1D1Ev +} + +void fn8() { + // CHECK: define void @_Z3fn8v + void target(std::initializer_list>); + // objects should be destroyed before dm2, after call returns + // CHECK: call void @_Z6targetSt16initializer_listIS_I10destroyme1EE + std::initializer_list inner; + target({ inner, { destroyme1() } }); + // CHECK: call void @_ZN10destroyme1D1Ev + // Only one destroy loop, since only one inner init list is directly inited. + // CHECK-NOT: call void @_ZN10destroyme1D1Ev + destroyme2 dm2; + // CHECK: call void @_ZN10destroyme2D1Ev +} + +void fn9() { + // CHECK: define void @_Z3fn9v + // objects should be destroyed after dm2 + std::initializer_list inner; + std::initializer_list> list = + { inner, { destroyme1() } }; + destroyme2 dm2; + // CHECK: call void @_ZN10destroyme2D1Ev + // CHECK: call void @_ZN10destroyme1D1Ev + // Only one destroy loop, since only one inner init list is directly inited. + // CHECK-NOT: call void @_ZN10destroyme1D1Ev + // CHECK: ret void +} + +struct haslist1 { + std::initializer_list il; + haslist1(); +}; + +// CHECK: define void @_ZN8haslist1C2Ev +haslist1::haslist1() +// CHECK: alloca [3 x i32] +// CHECK: store i32 1 +// CHECK: store i32 2 +// CHECK: store i32 3 +// CHECK: store i{{32|64}} 3 + : il{1, 2, 3} +{ + destroyme2 dm2; +} + +struct haslist2 { + std::initializer_list il; + haslist2(); +}; + +// CHECK: define void @_ZN8haslist2C2Ev +haslist2::haslist2() + : il{destroyme1(), destroyme1()} +{ + destroyme2 dm2; + // CHECK: call void @_ZN10destroyme2D1Ev + // CHECK: call void @_ZN10destroyme1D1Ev +} + +void fn10() { + // CHECK: define void @_Z4fn10v + // CHECK: alloca [3 x i32] + // CHECK: call noalias i8* @_Znw{{[jm]}} + // CHECK: store i32 1 + // CHECK: store i32 2 + // CHECK: store i32 3 + // CHECK: store i32* + // CHECK: store i{{32|64}} 3 + (void) new std::initializer_list {1, 2, 3}; +} + +void fn11() { + // CHECK: define void @_Z4fn11v + (void) new std::initializer_list {destroyme1(), destroyme1()}; + // CHECK: call void @_ZN10destroyme1D1Ev + destroyme2 dm2; + // CHECK: call void @_ZN10destroyme2D1Ev +} + +namespace PR12178 { + struct string { + string(int); + ~string(); + }; + + struct pair { + string a; + int b; + }; + + struct map { + map(std::initializer_list); + }; + + map m{ {1, 2}, {3, 4} }; +} diff --git a/clang/test/CodeGenCXX/cxx11-exception-spec.cpp b/clang/test/CodeGenCXX/cxx11-exception-spec.cpp new file mode 100644 index 0000000..194b80c --- /dev/null +++ b/clang/test/CodeGenCXX/cxx11-exception-spec.cpp @@ -0,0 +1,120 @@ +// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -verify -fexceptions -fcxx-exceptions -triple x86_64-linux-gnu | FileCheck %s + +void h(); + +template void f() noexcept(sizeof(T) == 4) { h(); } +template void g() noexcept(sizeof(T) == 4); + +template struct S { + static void f() noexcept(sizeof(T) == 4) { h(); } + static void g() noexcept(sizeof(T) == 4); +}; + +// CHECK: define {{.*}} @_Z1fIsEvv() { +template<> void f() { h(); } +// CHECK: define {{.*}} @_Z1fIA2_sEvv() nounwind { +template<> void f() noexcept { h(); } + +// CHECK: define {{.*}} @_ZN1SIsE1fEv() +// CHECK-NOT: nounwind +template<> void S::f() { h(); } +// CHECK: define {{.*}} @_ZN1SIA2_sE1fEv() nounwind +template<> void S::f() noexcept { h(); } + +// CHECK: define {{.*}} @_Z1fIDsEvv() { +template void f(); +// CHECK: define {{.*}} @_Z1fIA2_DsEvv() nounwind { +template void f(); + +// CHECK: define {{.*}} @_ZN1SIDsE1fEv() +// CHECK-NOT: nounwind +template void S::f(); +// CHECK: define {{.*}} @_ZN1SIA2_DsE1fEv() nounwind +template void S::f(); + +void h() { + // CHECK: define {{.*}} @_Z1fIiEvv() nounwind { + f(); + // CHECK: define {{.*}} @_Z1fIA2_iEvv() { + f(); + + // CHECK: define {{.*}} @_ZN1SIiE1fEv() nounwind + S::f(); + // CHECK: define {{.*}} @_ZN1SIA2_iE1fEv() + // CHECK-NOT: nounwind + S::f(); + + // CHECK: define {{.*}} @_Z1fIfEvv() nounwind { + void (*f1)() = &f; + // CHECK: define {{.*}} @_Z1fIdEvv() { + void (*f2)() = &f; + + // CHECK: define {{.*}} @_ZN1SIfE1fEv() nounwind + void (*f3)() = &S::f; + // CHECK: define {{.*}} @_ZN1SIdE1fEv() + // CHECK-NOT: nounwind + void (*f4)() = &S::f; + + // CHECK: define {{.*}} @_Z1fIA4_cEvv() nounwind { + (void)&f; + // CHECK: define {{.*}} @_Z1fIcEvv() { + (void)&f; + + // CHECK: define {{.*}} @_ZN1SIA4_cE1fEv() nounwind + (void)&S::f; + // CHECK: define {{.*}} @_ZN1SIcE1fEv() + // CHECK-NOT: nounwind + (void)&S::f; +} + +// CHECK: define {{.*}} @_Z1iv +void i() { + // CHECK: declare {{.*}} @_Z1gIiEvv() nounwind + g(); + // CHECK: declare {{.*}} @_Z1gIA2_iEvv() + // CHECK-NOT: nounwind + g(); + + // CHECK: declare {{.*}} @_ZN1SIiE1gEv() nounwind + S::g(); + // CHECK: declare {{.*}} @_ZN1SIA2_iE1gEv() + // CHECK-NOT: nounwind + S::g(); + + // CHECK: declare {{.*}} @_Z1gIfEvv() nounwind + void (*g1)() = &g; + // CHECK: declare {{.*}} @_Z1gIdEvv() + // CHECK-NOT: nounwind + void (*g2)() = &g; + + // CHECK: declare {{.*}} @_ZN1SIfE1gEv() nounwind + void (*g3)() = &S::g; + // CHECK: declare {{.*}} @_ZN1SIdE1gEv() + // CHECK-NOT: nounwind + void (*g4)() = &S::g; + + // CHECK: declare {{.*}} @_Z1gIA4_cEvv() nounwind + (void)&g; + // CHECK: declare {{.*}} @_Z1gIcEvv() + // CHECK-NOT: nounwind + (void)&g; + + // CHECK: declare {{.*}} @_ZN1SIA4_cE1gEv() nounwind + (void)&S::g; + // CHECK: declare {{.*}} @_ZN1SIcE1gEv() + // CHECK-NOT: nounwind + (void)&S::g; +} + +template struct Nested { + template void f() noexcept(sizeof(T) == sizeof(U)); +}; + +// CHECK: define {{.*}} @_Z1jv +void j() { + // CHECK: declare {{.*}} @_ZN6NestedIiE1fILb1EcEEvv( + // CHECK-NOT: nounwind + Nested().f(); + // CHECK: declare {{.*}} @_ZN6NestedIlE1fILb0ElEEvv({{.*}}) nounwind + Nested().f(); +} diff --git a/clang/test/CodeGenCXX/cxx11-unrestricted-union.cpp b/clang/test/CodeGenCXX/cxx11-unrestricted-union.cpp new file mode 100644 index 0000000..0397775 --- /dev/null +++ b/clang/test/CodeGenCXX/cxx11-unrestricted-union.cpp @@ -0,0 +1,76 @@ +// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - | FileCheck %s + +struct A { + A(); A(const A&); A(A&&); A &operator=(const A&); A &operator=(A&&); ~A(); +}; +struct B { + B(); B(const B&); B(B&&); B &operator=(const B&); B &operator=(B&&); ~B(); +}; + +union U { + U(); + U(const U &); + U(U &&); + U &operator=(const U&); + U &operator=(U&&); + ~U(); + + A a; + int n; +}; + +// CHECK-NOT: _ZN1A +U::U() {} +U::U(const U&) {} +U::U(U&&) {} +U &U::operator=(const U&) { return *this; } +U &U::operator=(U &&) { return *this; } +U::~U() {} + +struct S { + S(); + S(const S &); + S(S &&); + S &operator=(const S&); + S &operator=(S&&); + ~S(); + + union { + A a; + int n; + }; + B b; + int m; +}; + +// CHECK: _ZN1SC2Ev +// CHECK-NOT: _ZN1A +// CHECK: _ZN1BC1Ev +S::S() {} + +// CHECK-NOT: _ZN1A + +// CHECK: _ZN1SC2ERKS_ +// CHECK-NOT: _ZN1A +// CHECK: _ZN1BC1Ev +S::S(const S&) {} + +// CHECK-NOT: _ZN1A + +// CHECK: _ZN1SC2EOS_ +// CHECK-NOT: _ZN1A +// CHECK: _ZN1BC1Ev +S::S(S&&) {} + +// CHECK-NOT: _ZN1A +// CHECK-NOT: _ZN1B +S &S::operator=(const S&) { return *this; } + +S &S::operator=(S &&) { return *this; } + +// CHECK: _ZN1SD2Ev +// CHECK-NOT: _ZN1A +// CHECK: _ZN1BD1Ev +S::~S() {} + +// CHECK-NOT: _ZN1A diff --git a/clang/test/CodeGenCXX/cxx11-user-defined-literal.cpp b/clang/test/CodeGenCXX/cxx11-user-defined-literal.cpp new file mode 100644 index 0000000..347ffe9 --- /dev/null +++ b/clang/test/CodeGenCXX/cxx11-user-defined-literal.cpp @@ -0,0 +1,69 @@ +// RUN: %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s + +struct S { S(); ~S(); S(const S &); void operator()(int); }; +using size_t = decltype(sizeof(int)); +S operator"" _x(const char *, size_t); +S operator"" _y(wchar_t); +S operator"" _z(unsigned long long); +S operator"" _f(long double); +S operator"" _r(const char *); +template S operator"" _t() { return S(); } + +// CHECK: @[[s_foo:.*]] = {{.*}} constant [4 x i8] c"foo\00" +// CHECK: @[[s_bar:.*]] = {{.*}} constant [4 x i8] c"bar\00" +// CHECK: @[[s_123:.*]] = {{.*}} constant [4 x i8] c"123\00" +// CHECK: @[[s_4_9:.*]] = {{.*}} constant [4 x i8] c"4.9\00" +// CHECK: @[[s_0xffffeeee:.*]] = {{.*}} constant [11 x i8] c"0xffffeeee\00" + +void f() { + // CHECK: call void @_Zli2_xPKcm({{.*}}, i8* getelementptr inbounds ([4 x i8]* @[[s_foo]], i32 0, i32 0), i64 3) + // CHECK: call void @_Zli2_xPKcm({{.*}}, i8* getelementptr inbounds ([4 x i8]* @[[s_bar]], i32 0, i32 0), i64 3) + // CHECK: call void @_Zli2_yw({{.*}} 97) + // CHECK: call void @_Zli2_zy({{.*}} 42) + // CHECK: call void @_Zli2_fe({{.*}} x86_fp80 0xK3FFF8000000000000000) + // CHECK: call void @_ZN1SD1Ev({{.*}}) + // CHECK: call void @_ZN1SD1Ev({{.*}}) + // CHECK: call void @_ZN1SD1Ev({{.*}}) + // CHECK: call void @_ZN1SD1Ev({{.*}}) + // CHECK: call void @_ZN1SD1Ev({{.*}}) + "foo"_x, "bar"_x, L'a'_y, 42_z, 1.0_f; + + // CHECK: call void @_Zli2_rPKc({{.*}}, i8* getelementptr inbounds ([4 x i8]* @[[s_123]], i32 0, i32 0)) + // CHECK: call void @_Zli2_rPKc({{.*}}, i8* getelementptr inbounds ([4 x i8]* @[[s_4_9]], i32 0, i32 0)) + // CHECK: call void @_Zli2_rPKc({{.*}}, i8* getelementptr inbounds ([11 x i8]* @[[s_0xffffeeee]], i32 0, i32 0)) + // CHECK: call void @_ZN1SD1Ev({{.*}}) + // CHECK: call void @_ZN1SD1Ev({{.*}}) + // CHECK: call void @_ZN1SD1Ev({{.*}}) + 123_r, 4.9_r, 0xffff\ +eeee_r; + + // FIXME: This mangling is insane. Maybe we should have a special case for + // char parameter packs? + // CHECK: call void @_Zli2_tIJLc48ELc120ELc49ELc50ELc51ELc52ELc53ELc54ELc55ELc56EEE1Sv({{.*}}) + // CHECK: call void @_ZN1SD1Ev({{.*}}) + 0x12345678_t; +} + +// CHECK: define {{.*}} @_Zli2_tIJLc48ELc120ELc49ELc50ELc51ELc52ELc53ELc54ELc55ELc56EEE1Sv( + +template auto g(T t) -> decltype("foo"_x(t)) { return "foo"_x(t); } +template auto i(T t) -> decltype(operator"" _x("foo", 3)(t)) { return operator"" _x("foo", 3)(t); } + +void h() { + g(42); + i(42); +} + +// CHECK: define {{.*}} @_Z1hv() +// CHECK: call void @_Z1gIiEDTclclL_Zli2_xPKcmELA4_S0_ELm3EEfp_EET_(i32 42) +// CHECK: call void @_Z1iIiEDTclclL_Zli2_xPKcmELA4_S0_ELi3EEfp_EET_(i32 42) + +// CHECK: define {{.*}} @_Z1gIiEDTclclL_Zli2_xPKcmELA4_S0_ELm3EEfp_EET_(i32 +// CHECK: call void @_Zli2_xPKcm({{.*}}, i8* getelementptr inbounds ([4 x i8]* @{{.*}}, i32 0, i32 0), i64 3) +// CHECK: call void @_ZN1SclEi +// CHECK: call void @_ZN1SD1Ev + +// CHECK: define {{.*}} @_Z1iIiEDTclclL_Zli2_xPKcmELA4_S0_ELi3EEfp_EET_(i32 +// CHECK: call void @_Zli2_xPKcm({{.*}}, i8* getelementptr inbounds ([4 x i8]* @{{.*}}, i32 0, i32 0), i64 3) +// CHECK: call void @_ZN1SclEi +// CHECK: call void @_ZN1SD1Ev diff --git a/clang/test/CodeGenCXX/debug-info-artificial-arg.cpp b/clang/test/CodeGenCXX/debug-info-artificial-arg.cpp new file mode 100644 index 0000000..92d1b16 --- /dev/null +++ b/clang/test/CodeGenCXX/debug-info-artificial-arg.cpp @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -emit-llvm -g -triple x86_64-apple-darwin %s -o - | FileCheck %s + +template class B { +public: + explicit B(X* p = 0); +}; + +class A +{ +public: + A(int value) : m_a_value(value) {}; + A(int value, A* client_A) : m_a_value (value), m_client_A (client_A) {} + + virtual ~A() {} + +private: + int m_a_value; + B m_client_A; +}; + +int main(int argc, char **argv) { + A reallyA (500); +} + +// FIXME: The numbers are truly awful. +// CHECK: !18 = metadata !{i32 {{.*}}, i32 0, metadata !"", i32 0, i32 0, i64 64, i64 64, i64 0, i32 64, metadata !19} ; [ DW_TAG_pointer_type ] +// CHECK: !19 = metadata !{i32 {{.*}}, null, metadata !"A", metadata !6, i32 8, i64 128, i64 64, i32 0, i32 0, null, metadata !20, i32 0, metadata !19, null} ; [ DW_TAG_class_type ] +// CHECK: metadata !19, metadata !"A", metadata !"A", metadata !"", metadata !6, i32 12, metadata !45, i1 false, i1 false, i32 0, i32 0, null, i32 256, i1 false, null, null, i32 0, metadata !47, i32 12} ; [ DW_TAG_subprogram ] +// CHECK: metadata !"", i32 0, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !46, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] +// CHECK: !46 = metadata !{null, metadata !18, metadata !9, metadata !34} diff --git a/clang/test/CodeGenCXX/debug-info-byval.cpp b/clang/test/CodeGenCXX/debug-info-byval.cpp new file mode 100644 index 0000000..56ffe13 --- /dev/null +++ b/clang/test/CodeGenCXX/debug-info-byval.cpp @@ -0,0 +1,31 @@ +// RUN: %clang -g -S %s -o - | FileCheck %s +// Test to check presence of debug info for byval parameter. +// Radar 8350436. +class DAG { +public: + int i; + int j; +}; + +class EVT { +public: + int a; + int b; + int c; +}; + +class VAL { +public: + int x; + int y; +}; +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" + EVT e = bar(); + if (dl == n) + foo(missing_arg); +} + diff --git a/clang/test/CodeGenCXX/debug-info-char16.cpp b/clang/test/CodeGenCXX/debug-info-char16.cpp new file mode 100644 index 0000000..24216f9 --- /dev/null +++ b/clang/test/CodeGenCXX/debug-info-char16.cpp @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -emit-llvm -std=c++11 -g %s -o -| FileCheck %s + +// 16 is DW_ATE_UTF (0x10) encoding attribute. +char16_t char_a = u'h'; + +// CHECK: !7 = metadata !{i32 {{.*}}, null, metadata !"char16_t", null, i32 0, i64 16, i64 16, i64 0, i32 0, i32 16} ; [ DW_TAG_base_type ] diff --git a/clang/test/CodeGenCXX/debug-info-class.cpp b/clang/test/CodeGenCXX/debug-info-class.cpp new file mode 100644 index 0000000..151c5f9 --- /dev/null +++ b/clang/test/CodeGenCXX/debug-info-class.cpp @@ -0,0 +1,12 @@ +// RUN: %clang -emit-llvm -g -S %s -o - | grep HdrSize +struct A { + int one; + static const int HdrSize = 52; + int two; + A() { + int x = 1; + } +}; +int main() { + A a; +} diff --git a/clang/test/CodeGenCXX/debug-info-context.cpp b/clang/test/CodeGenCXX/debug-info-context.cpp new file mode 100644 index 0000000..d6d44a1 --- /dev/null +++ b/clang/test/CodeGenCXX/debug-info-context.cpp @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -emit-llvm -g -triple x86_64-apple-darwin %s -o - | FileCheck %s +// PR11345 + +class locale { +private: + void _M_add_reference() const throw() { + } +}; +class ios_base { + locale _M_ios_locale; +public: + class Init { + }; +}; +static ios_base::Init __ioinit; + +// CHECK-NOT: _M_ios_locale diff --git a/clang/test/CodeGenCXX/debug-info-ctor.cpp b/clang/test/CodeGenCXX/debug-info-ctor.cpp new file mode 100644 index 0000000..c31eebe --- /dev/null +++ b/clang/test/CodeGenCXX/debug-info-ctor.cpp @@ -0,0 +1,14 @@ +// RUN: %clang -emit-llvm -g -S %s -o - | FileCheck %s + +struct X { + X(int v); + + int value; +}; + +X::X(int v) { + // CHECK_TEMPORARILY_DISABLED: call void @_ZN1XC2Ei(%struct.X* %this1, i32 %tmp), !dbg + // TEMPORARY CHECK: X + value = v; +} + diff --git a/clang/test/CodeGenCXX/debug-info-ctor2.cpp b/clang/test/CodeGenCXX/debug-info-ctor2.cpp new file mode 100644 index 0000000..19bd64b --- /dev/null +++ b/clang/test/CodeGenCXX/debug-info-ctor2.cpp @@ -0,0 +1,15 @@ +// RUN: %clang -fverbose-asm -g -S %s -o - | grep AT_explicit + + +class MyClass +{ +public: + explicit MyClass (int i) : + m_i (i) + {} +private: + int m_i; +}; + +MyClass m(1); + diff --git a/clang/test/CodeGenCXX/debug-info-cxx0x.cpp b/clang/test/CodeGenCXX/debug-info-cxx0x.cpp new file mode 100644 index 0000000..37ccdb0 --- /dev/null +++ b/clang/test/CodeGenCXX/debug-info-cxx0x.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -emit-llvm-only -std=c++11 -g %s + +namespace PR9414 { + int f() { + auto x = 0; + return x; + } +} diff --git a/clang/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp b/clang/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp new file mode 100644 index 0000000..e67987b --- /dev/null +++ b/clang/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -emit-llvm -g -triple x86_64-apple-darwin -fno-limit-debug-info %s -o - | FileCheck %s + +class Test +{ +public: + Test () : reserved (new data()) {} + + unsigned + getID() const + { + return reserved->objectID; + } +protected: + struct data { + unsigned objectID; + }; + data* reserved; +}; + +Test t; + +// CHECK: metadata !"", null, i32 0, i64 64, i64 64, i64 0, i32 0, metadata {{.*}} [ DW_TAG_pointer_type ] +// CHECK: metadata !"data", metadata !6, 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, diff --git a/clang/test/CodeGenCXX/debug-info-enum.cpp b/clang/test/CodeGenCXX/debug-info-enum.cpp new file mode 100644 index 0000000..c08fc35 --- /dev/null +++ b/clang/test/CodeGenCXX/debug-info-enum.cpp @@ -0,0 +1,8 @@ +// RUN: %clang -fverbose-asm -S -g %s -o - | grep DW_TAG_enumeration_type + +int v; +enum index { MAX }; +void foo(void) +{ + v = MAX; +} diff --git a/clang/test/CodeGenCXX/debug-info-fn-template.cpp b/clang/test/CodeGenCXX/debug-info-fn-template.cpp new file mode 100644 index 0000000..bef9fe1 --- /dev/null +++ b/clang/test/CodeGenCXX/debug-info-fn-template.cpp @@ -0,0 +1,15 @@ +// RUN: %clang -emit-llvm -g -S %s -o - | FileCheck %s + +template +struct XF { + T member; +}; + +template +T fx(XF xi) { + return xi.member; +} + +//CHECK: XF +//CHECK: DW_TAG_template_type_parameter +template int fx(XF); diff --git a/clang/test/CodeGenCXX/debug-info-friend.cpp b/clang/test/CodeGenCXX/debug-info-friend.cpp new file mode 100644 index 0000000..c50f281 --- /dev/null +++ b/clang/test/CodeGenCXX/debug-info-friend.cpp @@ -0,0 +1,11 @@ +// RUN: %clang -fverbose-asm -S -g %s -o - | grep DW_TAG_friend + +class MyFriend; + +class SomeClass +{ + friend class MyFriend; +}; + +SomeClass sc; + diff --git a/clang/test/CodeGenCXX/debug-info-fwd-ref.cpp b/clang/test/CodeGenCXX/debug-info-fwd-ref.cpp new file mode 100644 index 0000000..5480c6b --- /dev/null +++ b/clang/test/CodeGenCXX/debug-info-fwd-ref.cpp @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -emit-llvm -g -triple x86_64-apple-darwin %s -o - | FileCheck %s + +struct baz { + int h; + baz(int a) : h(a) {} +}; + +struct bar { + baz b; + baz& b_ref; + bar(int x) : b(x), b_ref(b) {} +}; + +int main(int argc, char** argv) { + bar myBar(1); + return 0; +} + +// Make sure we have two DW_TAG_class_types for baz and bar and no forward +// references. +// FIXME: These should be struct types to match the declaration. +// CHECK: metadata !{i32 {{.*}}, null, metadata !"bar", metadata !6, i32 8, i64 128, i64 64, i32 0, i32 0, null, metadata !20, i32 0, null, null} ; [ DW_TAG_class_type ] +// CHECK: metadata !{i32 {{.*}}, null, metadata !"baz", metadata !6, i32 3, i64 32, i64 32, i32 0, i32 0, null, metadata !23, i32 0, null, null} ; [ DW_TAG_class_type ] +// CHECK-NOT: metadata !{i32 {{.*}}, null, metadata !"bar", metadata !6, i32 9, i64 0, i64 0, i32 0, i32 4, i32 0, null, i32 0, i32 0} ; [ DW_TAG_class_type ] +// CHECK-NOT: metadata !{i32 {{.*}}, null, metadata !"baz", metadata !6, i32 3, i64 0, i64 0, i32 0, i32 4, null, null, i32 0, null, null} ; [ DW_TAG_class_type ] + diff --git a/clang/test/CodeGenCXX/debug-info-large-constant.cpp b/clang/test/CodeGenCXX/debug-info-large-constant.cpp new file mode 100644 index 0000000..2daa189 --- /dev/null +++ b/clang/test/CodeGenCXX/debug-info-large-constant.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -g -triple=x86_64-apple-darwin %s -o /dev/null +// PR 8913 + +typedef __uint128_t word128; +static const word128 m126 = 0xffffffffffffffffULL; +word128 foo() { + return m126; +} diff --git a/clang/test/CodeGenCXX/debug-info-limit-type.cpp b/clang/test/CodeGenCXX/debug-info-limit-type.cpp new file mode 100644 index 0000000..e03024f --- /dev/null +++ b/clang/test/CodeGenCXX/debug-info-limit-type.cpp @@ -0,0 +1,24 @@ +// RUN: %clang -emit-llvm -g -S %s -o - | FileCheck %s +// XFAIL: * + +class B { +public: + int bb; + void fn2() {} +}; + +class A { +public: + int aa; + void fn1(B b) { b.fn2(); } +}; + +void foo(A *aptr) { +} + +void bar() { + A a; +} + +// B should only be emitted as a forward reference (i32 4). +// CHECK: metadata !"B", metadata !6, i32 3, i32 0, i32 0, i32 0, i32 4} ; [ DW_TAG_class_type ] diff --git a/clang/test/CodeGenCXX/debug-info-limit.cpp b/clang/test/CodeGenCXX/debug-info-limit.cpp new file mode 100644 index 0000000..bca887b --- /dev/null +++ b/clang/test/CodeGenCXX/debug-info-limit.cpp @@ -0,0 +1,14 @@ +// RUN: %clang -emit-llvm -g -S %s -o - | FileCheck %s + +// TAG_member is used to encode debug info for class constructor. +// CHECK: TAG_member +class A { +public: + int z; +}; + +A *foo (A* x) { + A *a = new A(*x); + return a; +} + diff --git a/clang/test/CodeGenCXX/debug-info-member.cpp b/clang/test/CodeGenCXX/debug-info-member.cpp new file mode 100644 index 0000000..8c2e3eb --- /dev/null +++ b/clang/test/CodeGenCXX/debug-info-member.cpp @@ -0,0 +1,6 @@ +// RUN: %clang -fverbose-asm -g -S %s -o - | grep DW_ACCESS_public +class A { +public: + int x; +}; +A a; diff --git a/clang/test/CodeGenCXX/debug-info-method-spec.cpp b/clang/test/CodeGenCXX/debug-info-method-spec.cpp new file mode 100644 index 0000000..2068c5c --- /dev/null +++ b/clang/test/CodeGenCXX/debug-info-method-spec.cpp @@ -0,0 +1,10 @@ +// RUN: %clang -fverbose-asm -g -S %s -o - | grep DW_AT_specification +// Radar 9254491 +class A { +public: + void doSomething(int i) { ++i; } +}; + +void foo(A *a) { + a->doSomething(2); +} diff --git a/clang/test/CodeGenCXX/debug-info-method.cpp b/clang/test/CodeGenCXX/debug-info-method.cpp new file mode 100644 index 0000000..cb022bc --- /dev/null +++ b/clang/test/CodeGenCXX/debug-info-method.cpp @@ -0,0 +1,6 @@ +// RUN: %clang -fverbose-asm -g -S %s -o - | grep DW_ACCESS_protected +class A { +protected: + int foo(); +}; +A a; diff --git a/clang/test/CodeGenCXX/debug-info-method2.cpp b/clang/test/CodeGenCXX/debug-info-method2.cpp new file mode 100644 index 0000000..a927c49 --- /dev/null +++ b/clang/test/CodeGenCXX/debug-info-method2.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -flimit-debug-info -x c++ -g -S -emit-llvm < %s | FileCheck %s +// rdar://10336845 +// Preserve type qualifiers in -flimit-debug-info mode. + +// CHECK: DW_TAG_const_type +class A { +public: + int bar(int arg) const; +}; + +int A::bar(int arg) const{ + return arg+2; +} + +int main() { + A a; + int i = a.bar(2); + return i; +} diff --git a/clang/test/CodeGenCXX/debug-info-namespace.cpp b/clang/test/CodeGenCXX/debug-info-namespace.cpp new file mode 100644 index 0000000..27f5eae --- /dev/null +++ b/clang/test/CodeGenCXX/debug-info-namespace.cpp @@ -0,0 +1,12 @@ +// RUN: %clang -g -S -fverbose-asm %s -o - | FileCheck %s + +// CHECK: TAG_namespace +namespace A { + enum numbers { + ZERO, + ONE + }; +} + +using namespace A; +numbers n; diff --git a/clang/test/CodeGenCXX/debug-info-nullptr.cpp b/clang/test/CodeGenCXX/debug-info-nullptr.cpp new file mode 100644 index 0000000..5540a92 --- /dev/null +++ b/clang/test/CodeGenCXX/debug-info-nullptr.cpp @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -emit-llvm -std=c++11 -g %s -o -| FileCheck %s + +void foo() { + decltype(nullptr) t = 0; +} + +// CHECK: !13 = metadata !{i32 {{.*}}, null, metadata !"nullptr_t", null, i32 0, i64 0, i64 0, i64 0, i32 0, i32 0} ; [ DW_TAG_unspecified_type ] diff --git a/clang/test/CodeGenCXX/debug-info-pubtypes.cpp b/clang/test/CodeGenCXX/debug-info-pubtypes.cpp new file mode 100644 index 0000000..a7abade --- /dev/null +++ b/clang/test/CodeGenCXX/debug-info-pubtypes.cpp @@ -0,0 +1,17 @@ +// REQUIRES: x86-64-registered-target +// RUN: %clang -cc1 -triple x86_64-apple-darwin10 -g -fno-limit-debug-info -S %s -o %t +// RUN: FileCheck %s < %t + +// FIXME: This testcase shouldn't rely on assembly emission. +//CHECK: Lpubtypes_begin1: +//CHECK: .asciz "G" +//CHECK-NEXT: .long 0 +//CHECK-NEXT: Lpubtypes_end1: + +class G { +public: + void foo(); +}; + +void G::foo() { +} diff --git a/clang/test/CodeGenCXX/debug-info-static-fns.cpp b/clang/test/CodeGenCXX/debug-info-static-fns.cpp new file mode 100644 index 0000000..485d28a --- /dev/null +++ b/clang/test/CodeGenCXX/debug-info-static-fns.cpp @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -emit-llvm -g -triple x86_64-apple-darwin %s -o - | FileCheck %s + +namespace A { + static int a(int b) { return b + 4; } + + int b(int c) { return c + a(c); } +} + +// Verify that a is present and mangled. +// CHECK: metadata !{i32 786478, i32 0, metadata !6, metadata !"a", metadata !"a", metadata !"_ZN1AL1aEi", metadata !7, i32 4, metadata !8, i1 true, i1 true, i32 0, i32 0, null, i32 256, i1 false, i32 (i32)* @_ZN1AL1aEi, null, null, metadata !14, i32 4} ; [ DW_TAG_subprogram ] diff --git a/clang/test/CodeGenCXX/debug-info-template-limit.cpp b/clang/test/CodeGenCXX/debug-info-template-limit.cpp new file mode 100644 index 0000000..796a80f --- /dev/null +++ b/clang/test/CodeGenCXX/debug-info-template-limit.cpp @@ -0,0 +1,15 @@ +// RUN: %clang -flimit-debug-info -emit-llvm -g -S %s -o - | FileCheck %s + +// Check that this pointer type is TC +// CHECK: !10} ; [ DW_TAG_pointer_type +// CHECK-NEXT: !10 ={{.*}}"TC" + +template +class TC { +public: + TC(const TC &) {} + TC() {} +}; + +TC tci; + diff --git a/clang/test/CodeGenCXX/debug-info-template-member.cpp b/clang/test/CodeGenCXX/debug-info-template-member.cpp new file mode 100644 index 0000000..6208c80 --- /dev/null +++ b/clang/test/CodeGenCXX/debug-info-template-member.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -emit-llvm -g -triple x86_64-apple-darwin %s -o - | FileCheck %s + +class MyClass +{ +public: + int add2(int j) + { + return add<2>(j); + } +private: + template int add(int j) + { + return i + j; + } +}; + +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 {{.*}} diff --git a/clang/test/CodeGenCXX/debug-info-template-recursive.cpp b/clang/test/CodeGenCXX/debug-info-template-recursive.cpp new file mode 100644 index 0000000..ef04d03 --- /dev/null +++ b/clang/test/CodeGenCXX/debug-info-template-recursive.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -emit-llvm -g -triple x86_64-apple-darwin %s -o - | FileCheck %s + +class base { }; + +template class foo : public base { + void operator=(const foo r) { } +}; + +class bar : public foo { }; +bar filters; + +// For now check that it simply doesn't crash. +// CHECK: {{.*}} diff --git a/clang/test/CodeGenCXX/debug-info-template.cpp b/clang/test/CodeGenCXX/debug-info-template.cpp new file mode 100644 index 0000000..9d52159 --- /dev/null +++ b/clang/test/CodeGenCXX/debug-info-template.cpp @@ -0,0 +1,46 @@ +// RUN: %clang -emit-llvm -g -S %s -o - | FileCheck %s + +//CHECK: TC +//CHECK: DW_TAG_template_type_parameter + +template +class TC { +public: + TC(const TC &) {} + TC() {} +}; + +TC tci; + +//CHECK: TU<2> +//CHECK: DW_TAG_template_value_parameter +template +class TU { + int b; +}; + +TU<2> u2; + +// PR9600 +template class vector {}; +class Foo; +typedef vector FooVector[3]; +struct Test { + virtual void foo(FooVector *); +}; +static Test test; + +// PR9608 +template struct TheTemplate { + struct Empty2 {}; + typedef const Empty2 DependentType[i]; + TheTemplate() {} +}; + +class TheTemplateTest : public TheTemplate<42> { + TheTemplateTest(); + void method(const TheTemplate<42>::DependentType *) {} +}; + +TheTemplateTest::TheTemplateTest() : TheTemplate<42>() {} + diff --git a/clang/test/CodeGenCXX/debug-info-this.cpp b/clang/test/CodeGenCXX/debug-info-this.cpp new file mode 100644 index 0000000..a2842d0 --- /dev/null +++ b/clang/test/CodeGenCXX/debug-info-this.cpp @@ -0,0 +1,15 @@ +// RUN: %clang -emit-llvm -g -S %s -o - | FileCheck %s +// Radar 9239104 +class Class +{ +public: +//CHECK: DW_TAG_const_type + int foo (int p) const { + return p+m_int; + } + +protected: + int m_int; +}; + +Class c; diff --git a/clang/test/CodeGenCXX/debug-info-use-after-free.cpp b/clang/test/CodeGenCXX/debug-info-use-after-free.cpp new file mode 100644 index 0000000..9757ca4 --- /dev/null +++ b/clang/test/CodeGenCXX/debug-info-use-after-free.cpp @@ -0,0 +1,312 @@ +// RUN: %clang_cc1 -g -emit-llvm-only %s +// Check that we don't crash. +// PR12305, PR12315 + +# 1 "a.h" 3 +template < typename T1 > struct Types1 +{ + typedef T1 Head; +}; +template < typename > struct Types; +template < template < typename > class Tmpl > struct TemplateSel +{ + template < typename T > struct Bind + { + typedef Tmpl < T > type; + }; +}; +template < typename > struct NoneT; +template < template < typename > class T1, template < typename > class > struct Templates2 +{ + typedef TemplateSel < T1 > Head; +}; +template < template < typename > class, template < typename > class = + NoneT, template < typename > class = NoneT, template < typename > class = + NoneT > struct Templates; +template < template < typename > class T1, + template < typename > class T2 > struct Templates +{ + typedef Templates2 < T1, T2 > type; +}; +template < typename T > struct TypeList +{ + typedef Types1 < T > type; +}; +template < template < typename > class, class TestSel, + typename Types > class TypeParameterizedTest +{ +public:static bool Register () + { + typedef typename Types::Head Type; + typename TestSel::template Bind < Type >::type TestClass; +}}; + +template < template < typename > class Fixture, typename Tests, + typename Types > class TypeParameterizedTestCase +{ +public:static bool Register (char *, char *, int *) + { + typedef typename Tests::Head Head; + TypeParameterizedTest < Fixture, Head, Types >::Register; +}}; + +template < typename > class TypedTestP1 +{ +}; + +namespace gtest_case_TypedTestP1_ +{ + template < typename gtest_TypeParam_ > class A:TypedTestP1 < + gtest_TypeParam_ > + { + }; +template < typename gtest_TypeParam_ > class B:TypedTestP1 < + gtest_TypeParam_ > + { + }; + typedef Templates < A >::type gtest_AllTests_; +} + +template < typename > class TypedTestP2 +{ +}; + +namespace gtest_case_TypedTestP2_ +{ + template < typename gtest_TypeParam_ > class A:TypedTestP2 < + gtest_TypeParam_ > + { + }; + typedef Templates < A >::type gtest_AllTests_; +} + +bool gtest_Int_TypedTestP1 = + TypeParameterizedTestCase < TypedTestP1, + gtest_case_TypedTestP1_::gtest_AllTests_, + TypeList < int >::type >::Register ("Int", "TypedTestP1", 0); +bool gtest_Int_TypedTestP2 = + TypeParameterizedTestCase < TypedTestP2, + gtest_case_TypedTestP2_::gtest_AllTests_, + TypeList < Types < int > >::type >::Register ("Int", "TypedTestP2", 0); + +template < typename _Tp > struct new_allocator +{ + typedef _Tp *pointer; + template < typename > struct rebind { + typedef new_allocator other; + }; +}; +template < typename _Tp > struct allocator:new_allocator < _Tp > { +}; +template < typename _Tp, typename _Alloc > struct _Vector_base { + typedef typename _Alloc::template rebind < _Tp >::other _Tp_alloc_type; + struct _Vector_impl { + typename _Tp_alloc_type::pointer _M_end_of_storage; + }; + _Vector_base () { + foo((int *) this->_M_impl._M_end_of_storage); + } + void foo(int *); + _Vector_impl _M_impl; +}; +template < typename _Tp, typename _Alloc = +allocator < _Tp > >struct vector:_Vector_base < _Tp, _Alloc > { }; + + +template < class T> struct HHH {}; +struct DDD { int x_;}; +struct Data; +struct X1; +struct CCC:DDD { virtual void xxx (HHH < X1 >); }; +template < class SSS > struct EEE:vector < HHH < SSS > > { }; +template < class SSS, class = EEE < SSS > >class FFF { }; +template < class SSS, class GGG = EEE < SSS > >class AAA:FFF { }; +class BBB:virtual CCC { + void xxx (HHH < X1 >); + vector < HHH < X1 > >aaa; +}; +class ZZZ:AAA < Data >, BBB { virtual ZZZ *ppp () ; }; +ZZZ * ZZZ::ppp () { return new ZZZ; } + +namespace std +{ + template < class, class > struct pair; +} +namespace __gnu_cxx { +template < typename > class new_allocator; +} +namespace std { +template < typename _Tp > class allocator:__gnu_cxx::new_allocator < _Tp > { +}; +template < typename, typename > struct _Vector_base { +}; +template < typename _Tp, typename _Alloc = std::allocator < _Tp > >class vector:_Vector_base < _Tp, + _Alloc + > { + }; +} + +namespace +std { + template < + typename, + typename > struct unary_function; + template < + typename, + typename, + typename > struct binary_function; + template < + typename + _Tp > struct equal_to: + binary_function < + _Tp, + _Tp, + bool > { + }; + template < + typename + _Pair > struct _Select1st: + unary_function < + _Pair, + typename + _Pair::first_type > { + }; +} +# 1 "f.h" 3 +using +std::pair; +namespace +__gnu_cxx { + template < + class > struct hash; + template < + class, + class, + class, + class, + class + _EqualKey, + class > + class + hashtable { + public: + typedef _EqualKey + key_equal; + }; + using + std::equal_to; + using + std::allocator; + using + std::_Select1st; + template < class _Key, class _Tp, class _HashFn = + hash < _Key >, class _EqualKey = equal_to < _Key >, class _Alloc = + allocator < _Tp > >class hash_map { + typedef + hashtable < + pair < + _Key, + _Tp >, + _Key, + _HashFn, + _Select1st < + pair < + _Key, + _Tp > >, + _EqualKey, + _Alloc > + _Ht; + public: + typename _Ht::key_type; + typedef typename + _Ht::key_equal + key_equal; + }; +} +using +__gnu_cxx::hash_map; +class +C2; +template < class > class scoped_ptr { +}; +namespace { +class + AAA { + virtual ~ + AAA () { + }}; +} +template < typename > class EEE; +template < typename CCC, typename = +typename CCC::key_equal, typename = +EEE < CCC > >class III { +}; +namespace +util { + class + EEE { + }; +} +namespace { +class + C1: + util::EEE { + public: + class + C3: + AAA { + struct FFF; + typedef + III < + hash_map < + C2, + FFF > > + GGG; + GGG + aaa; + friend + C1; + }; + void + HHH (C3::GGG &); + }; +} +namespace +n1 { + class + Test { + }; + template < + typename > + class + C7 { + }; + class + C4: + n1::Test { + vector < + C1::C3 * > + a1; + }; + enum C5 { }; + class + C6: + C4, + n1::C7 < + C5 > { + }; + class + C8: + C6 { + }; + class + C9: + C8 { + void + TestBody (); + }; + void + C9::TestBody () { + scoped_ptr < C1::C3 > context; + } +} diff --git a/clang/test/CodeGenCXX/debug-info-wchar.cpp b/clang/test/CodeGenCXX/debug-info-wchar.cpp new file mode 100644 index 0000000..6f53849 --- /dev/null +++ b/clang/test/CodeGenCXX/debug-info-wchar.cpp @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -emit-llvm -g %s -o -| FileCheck %s +void foo() { +// CHECK: metadata !"wchar_t", + const wchar_t w = L'x'; +} diff --git a/clang/test/CodeGenCXX/debug-info.cpp b/clang/test/CodeGenCXX/debug-info.cpp new file mode 100644 index 0000000..33b5278 --- /dev/null +++ b/clang/test/CodeGenCXX/debug-info.cpp @@ -0,0 +1,69 @@ +// RUN: %clang_cc1 -emit-llvm-only -g %s +template struct Identity { + typedef T Type; +}; + +void f(Identity::Type a) {} +void f(Identity a) {} +void f(int& a) { } + +template struct A { + A *next; +}; +void f(A) { } + +struct B { }; + +void f() { + int B::*a = 0; + void (B::*b)() = 0; +} + +namespace EmptyNameCrash { + struct A { A(); }; + typedef struct { A x; } B; + B x; +} + +// PR4890 +namespace PR4890 { + struct X { + ~X(); + }; + + X::~X() { } +} + +namespace VirtualDtor { + struct Y { + virtual ~Y(); + }; + + Y::~Y() { } +} + +namespace VirtualBase { + struct A { }; + struct B : virtual A { }; + + void f() { + B b; + } +} + +void foo() { + const wchar_t c = L'x'; + wchar_t d = c; +} + +namespace b5249287 { +template class A { + struct B; +}; + +class Cls { + template friend class A::B; +}; + +Cls obj; +} diff --git a/clang/test/CodeGenCXX/debug-lambda-expressions.cpp b/clang/test/CodeGenCXX/debug-lambda-expressions.cpp new file mode 100644 index 0000000..859a71b --- /dev/null +++ b/clang/test/CodeGenCXX/debug-lambda-expressions.cpp @@ -0,0 +1,71 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -emit-llvm -o - %s -fexceptions -std=c++11 -g | FileCheck %s + +auto var = [](int i) { return i+1; }; + +extern "C" auto cvar = []{}; + +int a() { return []{ return 1; }(); } + +int b(int x) { return [x]{return x;}(); } + +int c(int x) { return [&x]{return x;}(); } + +struct D { D(); D(const D&); int x; }; +int d(int x) { D y[10]; [x,y] { return y[x].x; }(); } + + +// A: 5 +// 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 ] + +// Randomness for file. -- 6 +// CHECK: [[FILE]] = metadata !{i32 {{.*}}, metadata !{{.*}}debug-lambda-expressions.cpp{{.*}}; [ DW_TAG_file_type ] + +// B: 12 +// 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 ] + +// 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 ] + +// D: 20 +// 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 ] + +// Back to D. -- 120 +// 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_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 14, 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 14, 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 ] + + +// Back to C. -- 159 +// 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_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 ] + + +// Back to B. -- 179 +// 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_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 ] + +// Back to A. -- 204 +// 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_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 ] + +// 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} ; [ 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: [[VAR_ARGS]] = metadata !{metadata !{{.*}}, metadata !{{.*}}, metadata !{{.*}}} + +// 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} ; [ 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: [[CVAR_ARGS]] = metadata !{metadata !{{.*}}, metadata !{{.*}}, metadata !{{.*}}} diff --git a/clang/test/CodeGenCXX/decl-ref-init.cpp b/clang/test/CodeGenCXX/decl-ref-init.cpp new file mode 100644 index 0000000..a066fbb --- /dev/null +++ b/clang/test/CodeGenCXX/decl-ref-init.cpp @@ -0,0 +1,31 @@ +// REQUIRES: x86-registered-target,x86-64-registered-target +// RUN: %clang_cc1 -triple x86_64-apple-darwin -S %s -o %t-64.s +// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s +// RUN: %clang_cc1 -triple i386-apple-darwin -S %s -o %t-32.s +// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s + +struct A {}; + +struct B +{ + operator A&(); +}; + + +struct D : public B { + operator A(); +}; + +extern B f(); +extern D d(); + +int main() { + const A& rca = f(); + const A& rca2 = d(); +} + +// CHECK-LP64: callq __ZN1BcvR1AEv +// CHECK-LP64: callq __ZN1BcvR1AEv + +// CHECK-LP32: calll L__ZN1BcvR1AEv +// CHECK-LP32: calll L__ZN1BcvR1AEv diff --git a/clang/test/CodeGenCXX/default-arg-temps.cpp b/clang/test/CodeGenCXX/default-arg-temps.cpp new file mode 100644 index 0000000..3d741d5 --- /dev/null +++ b/clang/test/CodeGenCXX/default-arg-temps.cpp @@ -0,0 +1,73 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 | FileCheck %s + +struct T { + T(); + ~T(); +}; + +void f(const T& t = T()); + +class X { // ... +public: + X(); + X(const X&, const T& t = T()); +}; + +// CHECK: define void @_Z1gv() +void g() { + // CHECK: call void @_ZN1TC1Ev([[T:%.*]]* [[AGG1:%.*]]) + // CHECK-NEXT: call void @_Z1fRK1T([[T]]* [[AGG1]]) + // CHECK-NEXT: call void @_ZN1TD1Ev([[T]]* [[AGG1]]) + f(); + + // CHECK-NEXT: call void @_ZN1TC1Ev([[T:%.*]]* [[AGG2:%.*]]) + // CHECK-NEXT: call void @_Z1fRK1T([[T]]* [[AGG2]]) + // CHECK-NEXT: call void @_ZN1TD1Ev([[T]]* [[AGG2]]) + f(); + + // CHECK-NEXT: call void @_ZN1XC1Ev( + X a; + + // CHECK-NEXT: call void @_ZN1TC1Ev( + // CHECK-NEXT: call void @_ZN1XC1ERKS_RK1T( + // CHECK-NEXT: call void @_ZN1TD1Ev( + X b(a); + + // CHECK-NEXT: call void @_ZN1TC1Ev( + // CHECK-NEXT: call void @_ZN1XC1ERKS_RK1T( + // CHECK-NEXT: call void @_ZN1TD1Ev( + X c = a; +} + + +class obj{ int a; float b; double d; }; +// CHECK: define void @_Z1hv() +void h() { + // CHECK: call void @llvm.memset.p0i8.i64( + obj o = obj(); +} + +// PR7028 - mostly this shouldn't crash +namespace test1 { + struct A { A(); }; + struct B { B(); ~B(); }; + + struct C { + C(const B &file = B()); + }; + C::C(const B &file) {} + + struct D { + C c; + A a; + + // CHECK: define linkonce_odr void @_ZN5test11DC2Ev(%"struct.test1::D"* %this) unnamed_addr + // CHECK: call void @_ZN5test11BC1Ev( + // CHECK-NEXT: call void @_ZN5test11CC1ERKNS_1BE( + // CHECK-NEXT: call void @_ZN5test11BD1Ev( + // CHECK: call void @_ZN5test11AC1Ev( + D() : c(), a() {} + }; + + D d; +} diff --git a/clang/test/CodeGenCXX/default-arguments.cpp b/clang/test/CodeGenCXX/default-arguments.cpp new file mode 100644 index 0000000..206d4d6 --- /dev/null +++ b/clang/test/CodeGenCXX/default-arguments.cpp @@ -0,0 +1,76 @@ +// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s + +// PR5484 +namespace PR5484 { +struct A { }; +extern A a; + +void f(const A & = a); + +void g() { + f(); +} +} + +struct A1 { + A1(); + ~A1(); +}; + +struct A2 { + A2(); + ~A2(); +}; + +struct B { + B(const A1& = A1(), const A2& = A2()); +}; + +// CHECK: define void @_Z2f1v() +void f1() { + + // CHECK: call void @_ZN2A1C1Ev( + // CHECK: call void @_ZN2A2C1Ev( + // CHECK: call void @_ZN1BC1ERK2A1RK2A2( + // CHECK: call void @_ZN2A2D1Ev + // CHECK: call void @_ZN2A1D1Ev + B bs[2]; +} + +struct C { + B bs[2]; + C(); +}; + +// CHECK: define void @_ZN1CC1Ev(%struct.C* %this) unnamed_addr +// CHECK: call void @_ZN1CC2Ev( + +// CHECK: define void @_ZN1CC2Ev(%struct.C* %this) unnamed_addr +// CHECK: call void @_ZN2A1C1Ev( +// CHECK: call void @_ZN2A2C1Ev( +// CHECK: call void @_ZN1BC1ERK2A1RK2A2( +// CHECK: call void @_ZN2A2D1Ev +// CHECK: call void @_ZN2A1D1Ev +C::C() { } + +// CHECK: define void @_Z2f3v() +void f3() { + // CHECK: call void @_ZN2A1C1Ev( + // CHECK: call void @_ZN2A2C1Ev( + // CHECK: call void @_ZN1BC1ERK2A1RK2A2( + // CHECK: call void @_ZN2A2D1Ev + // CHECK: call void @_ZN2A1D1Ev + B *bs = new B[2]; + delete bs; +} + +void f4() { + void g4(int a, int b = 7); + { + void g4(int a, int b = 5); + } + void g4(int a = 5, int b); + + // CHECK: call void @_Z2g4ii(i32 5, i32 7) + g4(); +} diff --git a/clang/test/CodeGenCXX/default-constructor-default-argument.cpp b/clang/test/CodeGenCXX/default-constructor-default-argument.cpp new file mode 100644 index 0000000..374a967 --- /dev/null +++ b/clang/test/CodeGenCXX/default-constructor-default-argument.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s + +// Check that call to constructor for struct A is generated correctly. +struct A { A(int x = 2); }; +struct B : public A {}; +B x; + +// CHECK: call {{.*}} @_ZN1AC2Ei diff --git a/clang/test/CodeGenCXX/default-constructor-for-members.cpp b/clang/test/CodeGenCXX/default-constructor-for-members.cpp new file mode 100644 index 0000000..714811f --- /dev/null +++ b/clang/test/CodeGenCXX/default-constructor-for-members.cpp @@ -0,0 +1,24 @@ +// REQUIRES: x86-registered-target,x86-64-registered-target +// RUN: %clang_cc1 -triple x86_64-apple-darwin -S %s -o %t-64.s +// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s +// RUN: %clang_cc1 -triple i386-apple-darwin -S %s -o %t-32.s +// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s + +extern "C" int printf(...); + +struct S { + S() { printf("S::S()\n"); } + int iS; +}; + +struct M { + S ARR_S; +}; + +int main() { + M m1; +} + +// CHECK-LP64: callq __ZN1SC1Ev + +// CHECK-LP32: calll L__ZN1SC1Ev diff --git a/clang/test/CodeGenCXX/default-constructor-template-member.cpp b/clang/test/CodeGenCXX/default-constructor-template-member.cpp new file mode 100644 index 0000000..0dd64df --- /dev/null +++ b/clang/test/CodeGenCXX/default-constructor-template-member.cpp @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s + +template struct A { A(); }; +struct B { A x; }; +void a() { + B b; +} +// CHECK: call {{.*}} @_ZN1BC1Ev +// CHECK: define linkonce_odr {{.*}} @_ZN1BC1Ev(%struct.B* %this) unnamed_addr +// CHECK: call {{.*}} @_ZN1AIiEC1Ev diff --git a/clang/test/CodeGenCXX/default-destructor-nested.cpp b/clang/test/CodeGenCXX/default-destructor-nested.cpp new file mode 100644 index 0000000..565a727 --- /dev/null +++ b/clang/test/CodeGenCXX/default-destructor-nested.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 %s -emit-llvm-only +// PR6294 + +class A { +public: virtual ~A(); +}; +class B { + class C; +}; +class B::C : public A { + C(); +}; +B::C::C() {} diff --git a/clang/test/CodeGenCXX/default-destructor-synthesis.cpp b/clang/test/CodeGenCXX/default-destructor-synthesis.cpp new file mode 100644 index 0000000..fac5cc0 --- /dev/null +++ b/clang/test/CodeGenCXX/default-destructor-synthesis.cpp @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -O2 -o - | FileCheck %s +static int count = 0; + +struct S { + S() { count++; } + ~S() { count--; } +}; + +struct P { + P() { count++; } + ~P() { count--; } +}; + +struct Q { + Q() { count++; } + ~Q() { count--; } +}; + +struct M : Q, P { + S s; + Q q; + P p; + P p_arr[3]; + Q q_arr[2][3]; +}; + +// CHECK: define i32 @_Z1fv() nounwind +int f() { + { + count = 1; + M a; + } + + // CHECK: ret i32 1 + return count; +} diff --git a/clang/test/CodeGenCXX/deferred-global-init.cpp b/clang/test/CodeGenCXX/deferred-global-init.cpp new file mode 100644 index 0000000..24c8c67 --- /dev/null +++ b/clang/test/CodeGenCXX/deferred-global-init.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s +// PR5967 + +extern void* foo; +static void* const a = foo; +void* bar() { return a; } + +// CHECK: @_ZL1a = internal global i8* null + +// CHECK: define internal void @__cxx_global_var_init +// CHECK: load i8** @foo +// CHECK: ret void + +// CHECK: define internal void @_GLOBAL__I_a +// CHECK: call void @__cxx_global_var_init() +// CHECK: ret void diff --git a/clang/test/CodeGenCXX/delete-two-arg.cpp b/clang/test/CodeGenCXX/delete-two-arg.cpp new file mode 100644 index 0000000..b82e9ba --- /dev/null +++ b/clang/test/CodeGenCXX/delete-two-arg.cpp @@ -0,0 +1,70 @@ +// RUN: %clang_cc1 -triple i686-pc-linux-gnu %s -o - -emit-llvm -verify | FileCheck %s + +typedef __typeof(sizeof(int)) size_t; + +namespace test1 { + struct A { void operator delete(void*,size_t); int x; }; + + // CHECK: define void @_ZN5test11aEPNS_1AE( + void a(A *x) { + // CHECK: load + // CHECK-NEXT: icmp eq {{.*}}, null + // CHECK-NEXT: br i1 + // CHECK: call void @_ZN5test11AdlEPvj(i8* %{{.*}}, i32 4) + delete x; + } +} + +// Check that we make cookies for the two-arg delete even when using +// the global allocator and deallocator. +namespace test2 { + struct A { + int x; + void *operator new[](size_t); + void operator delete[](void *, size_t); + }; + + // CHECK: define [[A:%.*]]* @_ZN5test24testEv() + A *test() { + // CHECK: [[NEW:%.*]] = call noalias i8* @_Znaj(i32 44) + // CHECK-NEXT: [[T0:%.*]] = bitcast i8* [[NEW]] to i32* + // CHECK-NEXT: store i32 10, i32* [[T0]] + // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8* [[NEW]], i64 4 + // CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to [[A]]* + // CHECK-NEXT: ret [[A]]* [[T2]] + return ::new A[10]; + } + + // CHECK: define void @_ZN5test24testEPNS_1AE( + void test(A *p) { + // CHECK: [[P:%.*]] = alloca [[A]]*, align 4 + // CHECK-NEXT: store [[A]]* {{%.*}}, [[A]]** [[P]], align 4 + // CHECK-NEXT: [[T0:%.*]] = load [[A]]** [[P]], align 4 + // CHECK-NEXT: [[T1:%.*]] = icmp eq [[A]]* [[T0]], null + // CHECK-NEXT: br i1 [[T1]], + // CHECK: [[T2:%.*]] = bitcast [[A]]* [[T0]] to i8* + // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8* [[T2]], i64 -4 + // CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to i32* + // CHECK-NEXT: [[T5:%.*]] = load i32* [[T4]] + // CHECK-NEXT: call void @_ZdaPv(i8* [[T3]]) + // CHECK-NEXT: br label + ::delete[] p; + } +} + +// rdar://problem/8913519 +namespace test3 { + struct A { + int x; + void operator delete[](void *, size_t); + }; + struct B : A {}; + + // CHECK: define void @_ZN5test34testEv() + void test() { + // CHECK: call noalias i8* @_Znaj(i32 24) + // CHECK-NEXT: bitcast + // CHECK-NEXT: store i32 5 + (void) new B[5]; + } +} diff --git a/clang/test/CodeGenCXX/delete.cpp b/clang/test/CodeGenCXX/delete.cpp new file mode 100644 index 0000000..5a88f9f --- /dev/null +++ b/clang/test/CodeGenCXX/delete.cpp @@ -0,0 +1,135 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -emit-llvm -o - | FileCheck %s + +void t1(int *a) { + delete a; +} + +struct S { + int a; +}; + +// POD types. +void t3(S *s) { + delete s; +} + +// Non-POD +struct T { + ~T(); + int a; +}; + +// CHECK: define void @_Z2t4P1T +void t4(T *t) { + // CHECK: call void @_ZN1TD1Ev + // CHECK-NEXT: bitcast + // CHECK-NEXT: call void @_ZdlPv + delete t; +} + +// PR5102 +template +class A { + public: operator T *() const; +}; + +void f() { + A a; + + delete a; +} + +namespace test0 { + struct A { + void *operator new(__SIZE_TYPE__ sz); + void operator delete(void *p) { ::operator delete(p); } + ~A() {} + }; + + // CHECK: define void @_ZN5test04testEPNS_1AE( + void test(A *a) { + // CHECK: call void @_ZN5test01AD1Ev + // CHECK-NEXT: bitcast + // CHECK-NEXT: call void @_ZN5test01AdlEPv + delete a; + } + + // CHECK: define linkonce_odr void @_ZN5test01AD1Ev(%"struct.test0::A"* %this) unnamed_addr + // CHECK: define linkonce_odr void @_ZN5test01AdlEPv +} + +namespace test1 { + struct A { + int x; + ~A(); + }; + + // CHECK: define void @_ZN5test14testEPA10_A20_NS_1AE( + void test(A (*arr)[10][20]) { + delete [] arr; + // CHECK: icmp eq [10 x [20 x [[A:%.*]]]]* [[PTR:%.*]], null + // CHECK-NEXT: br i1 + + // CHECK: [[BEGIN:%.*]] = getelementptr inbounds [10 x [20 x [[A]]]]* [[PTR]], i32 0, i32 0, i32 0 + // CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]* [[BEGIN]] to i8* + // CHECK-NEXT: [[ALLOC:%.*]] = getelementptr inbounds i8* [[T0]], i64 -8 + // CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[ALLOC]] to i64* + // CHECK-NEXT: [[COUNT:%.*]] = load i64* [[T1]] + // CHECK: [[END:%.*]] = getelementptr inbounds [[A]]* [[BEGIN]], i64 [[COUNT]] + // CHECK-NEXT: [[ISEMPTY:%.*]] = icmp eq [[A]]* [[BEGIN]], [[END]] + // CHECK-NEXT: br i1 [[ISEMPTY]], + // CHECK: [[PAST:%.*]] = phi [[A]]* [ [[END]], {{%.*}} ], [ [[CUR:%.*]], {{%.*}} ] + // CHECK-NEXT: [[CUR:%.*]] = getelementptr inbounds [[A]]* [[PAST]], i64 -1 + // CHECK-NEXT: call void @_ZN5test11AD1Ev([[A]]* [[CUR]]) + // CHECK-NEXT: [[ISDONE:%.*]] = icmp eq [[A]]* [[CUR]], [[BEGIN]] + // CHECK-NEXT: br i1 [[ISDONE]] + // CHECK: call void @_ZdaPv(i8* [[ALLOC]]) + } +} + +namespace test2 { + // CHECK: define void @_ZN5test21fEPb + void f(bool *b) { + // CHECK: call void @_ZdlPv(i8* + delete b; + // CHECK: call void @_ZdaPv(i8* + delete [] b; + } +} + +namespace test3 { + void f(int a[10][20]) { + // CHECK: call void @_ZdaPv(i8* + delete a; + } +} + +namespace test4 { + // PR10341: ::delete with a virtual destructor + struct X { + virtual ~X(); + void operator delete (void *); + }; + + // CHECK: define void @_ZN5test421global_delete_virtualEPNS_1XE + void global_delete_virtual(X *xp) { + // CHECK: [[VTABLE:%.*]] = load void ([[X:%.*]])*** + // CHECK-NEXT: [[VFN:%.*]] = getelementptr inbounds void ([[X]])** [[VTABLE]], i64 0 + // CHECK-NEXT: [[VFNPTR:%.*]] = load void ([[X]])** [[VFN]] + // CHECK-NEXT: call void [[VFNPTR]]([[X]] [[OBJ:%.*]]) + // CHECK-NEXT: [[OBJVOID:%.*]] = bitcast [[X]] [[OBJ]] to i8* + // CHECK-NEXT: call void @_ZdlPv(i8* [[OBJVOID]]) nounwind + ::delete xp; + } +} + +namespace test5 { + struct Incomplete; + // CHECK: define void @_ZN5test523array_delete_incompleteEPNS_10IncompleteES1_ + void array_delete_incomplete(Incomplete *p1, Incomplete *p2) { + // CHECK: call void @_ZdlPv + delete p1; + // CHECK: call void @_ZdaPv + delete [] p2; + } +} diff --git a/clang/test/CodeGenCXX/dependent-type-member-pointer.cpp b/clang/test/CodeGenCXX/dependent-type-member-pointer.cpp new file mode 100644 index 0000000..41bb5e2 --- /dev/null +++ b/clang/test/CodeGenCXX/dependent-type-member-pointer.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -emit-llvm-only -verify %s +// PR7736 + +template int InitMember(scriptmemberptr); + +template +struct contentmap +{ + static void InitDataMap() + { InitMember(&contentmap::SizeHolder); } + int SizeHolder; +}; + +void ReadFrom( ) +{ + contentmap::InitDataMap(); +} + diff --git a/clang/test/CodeGenCXX/derived-to-base-conv.cpp b/clang/test/CodeGenCXX/derived-to-base-conv.cpp new file mode 100644 index 0000000..8c51809 --- /dev/null +++ b/clang/test/CodeGenCXX/derived-to-base-conv.cpp @@ -0,0 +1,85 @@ +// REQUIRES: x86-registered-target,x86-64-registered-target +// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -S %s -o %t-64.s +// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s +// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -S %s -o %t-32.s +// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s + +extern "C" int printf(...); +extern "C" void exit(int); + +struct A { + A (const A&) { printf("A::A(const A&)\n"); } + A() {}; + ~A() { printf("A::~A()\n"); } +}; + +struct B : public A { + B() {}; + B(const B& Other) : A(Other) { printf("B::B(const B&)\n"); } + ~B() { printf("B::~B()\n"); } +}; + +struct C : public B { + C() {}; + C(const C& Other) : B(Other) { printf("C::C(const C&)\n"); } + ~C() { printf("C::~C()\n"); } +}; + +struct X { + operator B&() {printf("X::operator B&()\n"); return b; } + operator C&() {printf("X::operator C&()\n"); return c; } + X (const X&) { printf("X::X(const X&)\n"); } + X () { printf("X::X()\n"); } + ~X () { printf("X::~X()\n"); } + B b; + C c; +}; + +void f(A) { + printf("f(A)\n"); +} + + +void func(X x) +{ + f (x); +} + +int main() +{ + X x; + func(x); +} + +struct Base; + +struct Root { + operator Base&() { exit(1); } +}; + +struct Derived; + +struct Base : Root { + Base(const Base&) { printf("Base::(const Base&)\n"); } + Base() { printf("Base::Base()\n"); } + operator Derived&() { exit(1); } +}; + +struct Derived : Base { +}; + +void foo(Base) {} + +void test(Derived bb) +{ + // CHECK-LP64-NOT: callq __ZN4BasecvR7DerivedEv + // CHECK-LP32-NOT: callq L__ZN4BasecvR7DerivedEv + foo(bb); +} +// CHECK-LP64: callq __ZN1XcvR1BEv +// CHECK-LP64: callq __ZN1AC1ERKS_ + +// CHECK-LP32: calll L__ZN1XcvR1BEv +// CHECK-LP32: calll L__ZN1AC1ERKS_ + + diff --git a/clang/test/CodeGenCXX/derived-to-base.cpp b/clang/test/CodeGenCXX/derived-to-base.cpp new file mode 100644 index 0000000..76b79fc --- /dev/null +++ b/clang/test/CodeGenCXX/derived-to-base.cpp @@ -0,0 +1,47 @@ +// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s +struct A { + void f(); + + int a; +}; + +struct B : A { + double b; +}; + +void f() { + B b; + + b.f(); +} + +// CHECK: define %struct.B* @_Z1fP1A(%struct.A* %a) nounwind +B *f(A *a) { + // CHECK-NOT: br label + // CHECK: ret %struct.B* + return static_cast(a); +} + +// PR5965 +namespace PR5965 { + +// CHECK: define %struct.A* @_ZN6PR59651fEP1B(%struct.B* %b) nounwind +A *f(B* b) { + // CHECK-NOT: br label + // CHECK: ret %struct.A* + return b; +} + +} + +// Don't crash on a derived-to-base conversion of an r-value +// aggregate. +namespace test3 { + struct A {}; + struct B : A {}; + + void foo(A a); + void test() { + foo(B()); + } +} diff --git a/clang/test/CodeGenCXX/derived-to-virtual-base-class-calls-final.cpp b/clang/test/CodeGenCXX/derived-to-virtual-base-class-calls-final.cpp new file mode 100644 index 0000000..0e15302 --- /dev/null +++ b/clang/test/CodeGenCXX/derived-to-virtual-base-class-calls-final.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s + +struct A { int i; }; +struct B { char j; }; +struct C : A, B { int k; }; + +struct D final : virtual C { + D(); + virtual void f(); +}; + +// CHECK: define %struct.B* @_Z1fR1D +B &f(D &d) { + // CHECK-NOT: load i8** + return d; +} diff --git a/clang/test/CodeGenCXX/destructor-calls.cpp b/clang/test/CodeGenCXX/destructor-calls.cpp new file mode 100644 index 0000000..4da46a4 --- /dev/null +++ b/clang/test/CodeGenCXX/destructor-calls.cpp @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 %s -emit-llvm -o %t + +extern "C" int printf(...); + +static int val; + +struct B { + B() : iB(++val) { printf("B()\n"); } + int iB; + ~B() { printf("~B(%d)\n", iB); --val; } +}; + +struct M : B { + M() : iM(++val) { printf("M()\n"); } + int iM; + ~M() { printf("~M(%d)\n", iM); --val; } +}; + +struct P { + P() : iP(++val) { printf("P()\n"); } + int iP; + ~P() { printf("~P(%d)\n", iP); --val; } +}; + +struct N : M, P { + N() { printf("N()\n"); iN = ++val; } + ~N() { printf("~N(%d) val = %d\n", iN, --val); } + int iN; + M m; + P p; +}; + +struct O : B { + ~O() { return; } +}; + +int main() { + N n1; + N n2; + O o; +} diff --git a/clang/test/CodeGenCXX/destructor-debug-info.cpp b/clang/test/CodeGenCXX/destructor-debug-info.cpp new file mode 100644 index 0000000..9e32275 --- /dev/null +++ b/clang/test/CodeGenCXX/destructor-debug-info.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -g -S -emit-llvm -o %t %s +// RUN: grep "i32 20, i32 3, metadata" %t | count 1 +// Check there is a line number entry for line 20 where b1 is destructed. +class A { int a; }; +class B { +public: + B() { a = new A; } + ~B() { delete a; } +private: + A *a; +}; + +void fn(B b); + +int i; +void foo() { + if (i) { + B b1; + fn (b1); + } +} diff --git a/clang/test/CodeGenCXX/destructors.cpp b/clang/test/CodeGenCXX/destructors.cpp new file mode 100644 index 0000000..d9962e6 --- /dev/null +++ b/clang/test/CodeGenCXX/destructors.cpp @@ -0,0 +1,403 @@ +// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o - -mconstructor-aliases -fcxx-exceptions -fexceptions | FileCheck %s + +// CHECK: @_ZN5test01AD1Ev = alias {{.*}} @_ZN5test01AD2Ev +// CHECK: @_ZN5test11MD2Ev = alias {{.*}} @_ZN5test11AD2Ev +// CHECK: @_ZN5test11ND2Ev = alias {{.*}} @_ZN5test11AD2Ev +// CHECK: @_ZN5test11OD2Ev = alias {{.*}} @_ZN5test11AD2Ev +// CHECK: @_ZN5test11SD2Ev = alias bitcast {{.*}} @_ZN5test11AD2Ev + +// CHECK: @_ZN5test312_GLOBAL__N_11DD1Ev = alias internal {{.*}} @_ZN5test312_GLOBAL__N_11DD2Ev +// CHECK: @_ZN5test312_GLOBAL__N_11DD2Ev = alias internal bitcast {{.*}} @_ZN5test312_GLOBAL__N_11CD2Ev +// CHECK: @_ZN5test312_GLOBAL__N_11CD1Ev = alias internal {{.*}} @_ZN5test312_GLOBAL__N_11CD2Ev + +struct A { + int a; + + ~A(); +}; + +// Base with non-trivial destructor +struct B : A { + ~B(); +}; + +B::~B() { } + +// Field with non-trivial destructor +struct C { + A a; + + ~C(); +}; + +C::~C() { } + +namespace PR7526 { + extern void foo(); + struct allocator { + ~allocator() throw(); + }; + + struct allocator_derived : allocator { }; + + // CHECK: define void @_ZN6PR75269allocatorD2Ev(%"struct.PR7526::allocator"* %this) unnamed_addr + // CHECK: call void @__cxa_call_unexpected + allocator::~allocator() throw() { foo(); } + + // CHECK: define linkonce_odr void @_ZN6PR752617allocator_derivedD1Ev(%"struct.PR7526::allocator_derived"* %this) unnamed_addr + // CHECK-NOT: call void @__cxa_call_unexpected + // CHECK: } + void foo() { + allocator_derived ad; + } +} + +// PR5084 +template +class A1 { + ~A1(); +}; + +template<> A1::~A1(); + +// PR5529 +namespace PR5529 { + struct A { + ~A(); + }; + + A::~A() { } + struct B : A { + virtual ~B(); + }; + + B::~B() {} +} + +// FIXME: there's a known problem in the codegen here where, if one +// destructor throws, the remaining destructors aren't run. Fix it, +// then make this code check for it. +namespace test0 { + void foo(); + struct VBase { ~VBase(); }; + struct Base { ~Base(); }; + struct Member { ~Member(); }; + + struct A : Base { + Member M; + ~A(); + }; + + // The function-try-block won't suppress -mconstructor-aliases here. + A::~A() try { } catch (int i) {} + +// complete destructor alias tested above + +// CHECK: define void @_ZN5test01AD2Ev(%"struct.test0::A"* %this) unnamed_addr +// CHECK: invoke void @_ZN5test06MemberD1Ev +// CHECK: unwind label [[MEM_UNWIND:%[a-zA-Z0-9.]+]] +// CHECK: invoke void @_ZN5test04BaseD2Ev +// CHECK: unwind label [[BASE_UNWIND:%[a-zA-Z0-9.]+]] + + struct B : Base, virtual VBase { + Member M; + ~B(); + }; + B::~B() try { } catch (int i) {} + // It will suppress the delegation optimization here, though. + +// CHECK: define void @_ZN5test01BD1Ev(%"struct.test0::B"* %this) unnamed_addr +// CHECK: invoke void @_ZN5test06MemberD1Ev +// CHECK: unwind label [[MEM_UNWIND:%[a-zA-Z0-9.]+]] +// CHECK: invoke void @_ZN5test04BaseD2Ev +// CHECK: unwind label [[BASE_UNWIND:%[a-zA-Z0-9.]+]] +// CHECK: invoke void @_ZN5test05VBaseD2Ev +// CHECK: unwind label [[VBASE_UNWIND:%[a-zA-Z0-9.]+]] + +// CHECK: define void @_ZN5test01BD2Ev(%"struct.test0::B"* %this, i8** %vtt) unnamed_addr +// CHECK: invoke void @_ZN5test06MemberD1Ev +// CHECK: unwind label [[MEM_UNWIND:%[a-zA-Z0-9.]+]] +// CHECK: invoke void @_ZN5test04BaseD2Ev +// CHECK: unwind label [[BASE_UNWIND:%[a-zA-Z0-9.]+]] +} + +// Test base-class aliasing. +namespace test1 { + struct A { ~A(); char ***m; }; // non-trivial destructor + struct B { ~B(); }; // non-trivial destructor + struct Empty { }; // trivial destructor, empty + struct NonEmpty { int x; }; // trivial destructor, non-empty + + // There must be a definition in this translation unit for the alias + // optimization to apply. + A::~A() { delete m; } + + struct M : A { ~M(); }; + M::~M() {} // alias tested above + + struct N : A, Empty { ~N(); }; + N::~N() {} // alias tested above + + struct O : Empty, A { ~O(); }; + O::~O() {} // alias tested above + + struct P : NonEmpty, A { ~P(); }; + P::~P() {} // CHECK: define void @_ZN5test11PD2Ev(%"struct.test1::P"* %this) unnamed_addr + + struct Q : A, B { ~Q(); }; + Q::~Q() {} // CHECK: define void @_ZN5test11QD2Ev(%"struct.test1::Q"* %this) unnamed_addr + + struct R : A { ~R(); }; + R::~R() { A a; } // CHECK: define void @_ZN5test11RD2Ev(%"struct.test1::R"* %this) unnamed_addr + + struct S : A { ~S(); int x; }; + S::~S() {} // alias tested above + + struct T : A { ~T(); B x; }; + T::~T() {} // CHECK: define void @_ZN5test11TD2Ev(%"struct.test1::T"* %this) unnamed_addr + + // The VTT parameter prevents this. We could still make this work + // for calling conventions that are safe against extra parameters. + struct U : A, virtual B { ~U(); }; + U::~U() {} // CHECK: define void @_ZN5test11UD2Ev(%"struct.test1::U"* %this, i8** %vtt) unnamed_addr +} + +// PR6471 +namespace test2 { + struct A { ~A(); char ***m; }; + struct B : A { ~B(); }; + + B::~B() {} + // CHECK: define void @_ZN5test21BD2Ev(%"struct.test2::B"* %this) unnamed_addr + // CHECK: call void @_ZN5test21AD2Ev +} + +// PR7142 +namespace test3 { + struct A { virtual ~A(); }; + struct B { virtual ~B(); }; + namespace { // internal linkage => deferred + struct C : A, B {}; // ~B() in D requires a this-adjustment thunk + struct D : C {}; // D::~D() is an alias to C::~C() + } + + void test() { + new D; // Force emission of D's vtable + } + + // Checked at top of file: + // @_ZN5test312_GLOBAL__N_11CD1Ev = alias internal {{.*}} @_ZN5test312_GLOBAL__N_11CD2Ev + + // More checks at end of file. + +} + +namespace test4 { + struct A { ~A(); }; + + // CHECK: define void @_ZN5test43fooEv() + // CHECK: call void @_ZN5test41AD1Ev + // CHECK: ret void + void foo() { + { + A a; + goto failure; + } + + failure: + return; + } + + // CHECK: define void @_ZN5test43barEi( + // CHECK: [[X:%.*]] = alloca i32 + // CHECK-NEXT: [[A:%.*]] = alloca + // CHECK: br label + // CHECK: [[TMP:%.*]] = load i32* [[X]] + // CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP]], 0 + // CHECK-NEXT: br i1 + // CHECK: call void @_ZN5test41AD1Ev( + // CHECK: br label + // CHECK: [[TMP:%.*]] = load i32* [[X]] + // CHECK: [[TMP2:%.*]] = add nsw i32 [[TMP]], -1 + // CHECK: store i32 [[TMP2]], i32* [[X]] + // CHECK: br label + // CHECK: ret void + void bar(int x) { + for (A a; x; ) { + x--; + } + } +} + +// PR7575 +namespace test5 { + struct A { ~A(); }; + + // CHECK: define void @_ZN5test53fooEv() + // CHECK: [[ELEMS:%.*]] = alloca [5 x [[A:%.*]]], align + // CHECK-NEXT: [[EXN:%.*]] = alloca i8* + // CHECK-NEXT: [[SEL:%.*]] = alloca i32 + // CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [5 x [[A]]]* [[ELEMS]], i32 0, i32 0 + // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]]* [[BEGIN]], i64 5 + // CHECK-NEXT: br label + // CHECK: [[POST:%.*]] = phi [[A]]* [ [[END]], {{%.*}} ], [ [[ELT:%.*]], {{%.*}} ] + // CHECK-NEXT: [[ELT]] = getelementptr inbounds [[A]]* [[POST]], i64 -1 + // CHECK-NEXT: invoke void @_ZN5test51AD1Ev([[A]]* [[ELT]]) + // CHECK: [[T0:%.*]] = icmp eq [[A]]* [[ELT]], [[BEGIN]] + // CHECK-NEXT: br i1 [[T0]], + // CHECK: ret void + // lpad + // CHECK: [[EMPTY:%.*]] = icmp eq [[A]]* [[BEGIN]], [[ELT]] + // CHECK-NEXT: br i1 [[EMPTY]] + // CHECK: [[AFTER:%.*]] = phi [[A]]* [ [[ELT]], {{%.*}} ], [ [[CUR:%.*]], {{%.*}} ] + // CHECK-NEXT: [[CUR:%.*]] = getelementptr inbounds [[A]]* [[AFTER]], i64 -1 + // CHECK-NEXT: invoke void @_ZN5test51AD1Ev([[A]]* [[CUR]]) + // CHECK: [[DONE:%.*]] = icmp eq [[A]]* [[CUR]], [[BEGIN]] + // CHECK-NEXT: br i1 [[DONE]], + void foo() { + A elems[5]; + } +} + +namespace test6 { + void opaque(); + + struct A { ~A(); }; + template struct B { B(); ~B(); int _; }; + struct C : B<0>, B<1>, virtual B<2>, virtual B<3> { + A x, y, z; + + C(); + ~C(); + }; + + C::C() { opaque(); } + // CHECK: define void @_ZN5test61CC1Ev(%"struct.test6::C"* %this) unnamed_addr + // CHECK: call void @_ZN5test61BILj2EEC2Ev + // CHECK: invoke void @_ZN5test61BILj3EEC2Ev + // CHECK: invoke void @_ZN5test61BILj0EEC2Ev + // CHECK: invoke void @_ZN5test61BILj1EEC2Ev + // CHECK: invoke void @_ZN5test66opaqueEv + // CHECK: ret void + // FIXME: way too much EH cleanup code follows + + C::~C() { opaque(); } + // CHECK: define void @_ZN5test61CD1Ev(%"struct.test6::C"* %this) unnamed_addr + // CHECK: invoke void @_ZN5test61CD2Ev + // CHECK: invoke void @_ZN5test61BILj3EED2Ev + // CHECK: call void @_ZN5test61BILj2EED2Ev + // CHECK: ret void + // CHECK: invoke void @_ZN5test61BILj3EED2Ev + // CHECK: invoke void @_ZN5test61BILj2EED2Ev + + // CHECK: define void @_ZN5test61CD2Ev(%"struct.test6::C"* %this, i8** %vtt) unnamed_addr + // CHECK: invoke void @_ZN5test66opaqueEv + // CHECK: invoke void @_ZN5test61AD1Ev + // CHECK: invoke void @_ZN5test61AD1Ev + // CHECK: invoke void @_ZN5test61AD1Ev + // CHECK: invoke void @_ZN5test61BILj1EED2Ev + // CHECK: call void @_ZN5test61BILj0EED2Ev + // CHECK: ret void + // CHECK: invoke void @_ZN5test61AD1Ev + // CHECK: invoke void @_ZN5test61AD1Ev + // CHECK: invoke void @_ZN5test61AD1Ev + // CHECK: invoke void @_ZN5test61BILj1EED2Ev + // CHECK: invoke void @_ZN5test61BILj0EED2Ev +} + +// PR 9197 +namespace test7 { + struct D { ~D(); }; + + struct A { ~A(); }; + A::~A() { } + + struct B : public A { + ~B(); + D arr[1]; + }; + + // Verify that this doesn't get emitted as an alias + // CHECK: define void @_ZN5test71BD2Ev( + // CHECK: invoke void @_ZN5test71DD1Ev( + // CHECK: call void @_ZN5test71AD2Ev( + B::~B() {} +} + +// PR10467 +namespace test8 { + struct A { A(); ~A(); }; + + void die() __attribute__((noreturn)); + void test() { + A x; + while (1) { + A y; + goto l; + } + l: die(); + } + + // CHECK: define void @_ZN5test84testEv() + // CHECK: [[X:%.*]] = alloca [[A:%.*]], align 1 + // CHECK-NEXT: [[Y:%.*]] = alloca [[A:%.*]], align 1 + // CHECK: call void @_ZN5test81AC1Ev([[A]]* [[X]]) + // CHECK-NEXT: br label + // CHECK: invoke void @_ZN5test81AC1Ev([[A]]* [[Y]]) + // CHECK: invoke void @_ZN5test81AD1Ev([[A]]* [[Y]]) + // CHECK-NOT: switch + // CHECK: invoke void @_ZN5test83dieEv() + // CHECK: unreachable +} + +// Checks from test3: + + // CHECK: define internal void @_ZN5test312_GLOBAL__N_11DD0Ev(%"struct.test3::::D"* %this) unnamed_addr + // CHECK: invoke void @_ZN5test312_GLOBAL__N_11DD1Ev( + // CHECK: call void @_ZdlPv({{.*}}) nounwind + // CHECK: ret void + // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + // CHECK-NEXT: cleanup + // CHECK: call void @_ZdlPv({{.*}}) nounwind + // CHECK: resume { i8*, i32 } + + // Checked at top of file: + // @_ZN5test312_GLOBAL__N_11DD1Ev = alias internal {{.*}} @_ZN5test312_GLOBAL__N_11DD2Ev + // @_ZN5test312_GLOBAL__N_11DD2Ev = alias internal bitcast {{.*}} @_ZN5test312_GLOBAL__N_11CD2Ev + + // CHECK: define internal void @_ZThn8_N5test312_GLOBAL__N_11DD1Ev( + // CHECK: getelementptr inbounds i8* {{.*}}, i64 -8 + // CHECK: call void @_ZN5test312_GLOBAL__N_11DD1Ev( + // CHECK: ret void + + // CHECK: define internal void @_ZThn8_N5test312_GLOBAL__N_11DD0Ev( + // CHECK: getelementptr inbounds i8* {{.*}}, i64 -8 + // CHECK: call void @_ZN5test312_GLOBAL__N_11DD0Ev( + // CHECK: ret void + + // CHECK: define internal void @_ZN5test312_GLOBAL__N_11CD2Ev(%"struct.test3::::C"* %this) unnamed_addr + // CHECK: invoke void @_ZN5test31BD2Ev( + // CHECK: call void @_ZN5test31AD2Ev( + // CHECK: ret void + + // CHECK: declare void @_ZN5test31BD2Ev( + // CHECK: declare void @_ZN5test31AD2Ev( + + // CHECK: define internal void @_ZN5test312_GLOBAL__N_11CD0Ev(%"struct.test3::::C"* %this) unnamed_addr + // CHECK: invoke void @_ZN5test312_GLOBAL__N_11CD1Ev( + // CHECK: call void @_ZdlPv({{.*}}) nounwind + // CHECK: ret void + // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + // CHECK-NEXT: cleanup + // CHECK: call void @_ZdlPv({{.*}}) nounwind + // CHECK: resume { i8*, i32 } + + // CHECK: define internal void @_ZThn8_N5test312_GLOBAL__N_11CD1Ev( + // CHECK: getelementptr inbounds i8* {{.*}}, i64 -8 + // CHECK: call void @_ZN5test312_GLOBAL__N_11CD1Ev( + // CHECK: ret void + + // CHECK: define internal void @_ZThn8_N5test312_GLOBAL__N_11CD0Ev( + // CHECK: getelementptr inbounds i8* {{.*}}, i64 -8 + // CHECK: call void @_ZN5test312_GLOBAL__N_11CD0Ev( + // CHECK: ret void diff --git a/clang/test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp b/clang/test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp new file mode 100644 index 0000000..3de75ed --- /dev/null +++ b/clang/test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp @@ -0,0 +1,51 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s + +namespace Test1 { + struct A { + virtual int f() final; + }; + + // CHECK: define i32 @_ZN5Test11fEPNS_1AE + int f(A *a) { + // CHECK: call i32 @_ZN5Test11A1fEv + return a->f(); + } +} + +namespace Test2 { + struct A final { + virtual int f(); + }; + + // CHECK: define i32 @_ZN5Test21fEPNS_1AE + int f(A *a) { + // CHECK: call i32 @_ZN5Test21A1fEv + return a->f(); + } +} + +namespace Test3 { + struct A { + virtual int f(); + }; + + struct B final : A { }; + + // CHECK: define i32 @_ZN5Test31fEPNS_1BE + int f(B *b) { + // CHECK: call i32 @_ZN5Test31A1fEv + return b->f(); + } + + // CHECK: define i32 @_ZN5Test31fERNS_1BE + int f(B &b) { + // CHECK: call i32 @_ZN5Test31A1fEv + return b.f(); + } + + // CHECK: define i32 @_ZN5Test31fEPv + int f(void *v) { + // CHECK: call i32 @_ZN5Test31A1fEv + return static_cast(v)->f(); + } +} diff --git a/clang/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp b/clang/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp new file mode 100644 index 0000000..5eede66 --- /dev/null +++ b/clang/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp @@ -0,0 +1,55 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s + +struct A { + virtual void f(); + virtual void f_const() const; + + A h(); +}; + +A g(); + +void f(A a, A *ap, A& ar) { + // This should not be a virtual function call. + + // CHECK: call void @_ZN1A1fEv(%struct.A* %a) + a.f(); + + // CHECK: call void % + ap->f(); + + // CHECK: call void % + ar.f(); + + // CHECK: call void @_ZN1A1fEv + A().f(); + + // CHECK: call void @_ZN1A1fEv + g().f(); + + // CHECK: call void @_ZN1A1fEv + a.h().f(); + + // CHECK: call void @_ZNK1A7f_constEv + a.f_const(); + + // CHECK: call void @_ZN1A1fEv + (a).f(); +} + +struct B { + virtual void f(); + ~B(); + + B h(); +}; + + +void f() { + // CHECK: call void @_ZN1B1fEv + B().f(); + + // CHECK: call void @_ZN1B1fEv + B().h().f(); +} + diff --git a/clang/test/CodeGenCXX/dynamic-cast-always-null.cpp b/clang/test/CodeGenCXX/dynamic-cast-always-null.cpp new file mode 100644 index 0000000..2c3ea13 --- /dev/null +++ b/clang/test/CodeGenCXX/dynamic-cast-always-null.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -I%S %s -triple x86_64-apple-darwin10 -emit-llvm -fcxx-exceptions -fexceptions -std=c++11 -o - | FileCheck %s +struct A { virtual ~A(); }; +struct B final : A { }; +struct C { virtual ~C(); int c; }; + +// CHECK: @_Z1fP1B +C *f(B* b) { + // CHECK-NOT: call i8* @__dynamic_cast + // CHECK: ret %struct.C* null + return dynamic_cast(b); +} + +// CHECK: @_Z1fR1B +C &f(B& b) { + // CHECK-NOT: call i8* @__dynamic_cast + // CHECK: call void @__cxa_bad_cast() noreturn + // CHECK: ret %struct.C* undef + return dynamic_cast(b); +} diff --git a/clang/test/CodeGenCXX/dynamic-cast.cpp b/clang/test/CodeGenCXX/dynamic-cast.cpp new file mode 100644 index 0000000..813e36e --- /dev/null +++ b/clang/test/CodeGenCXX/dynamic-cast.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -I%S %s -triple x86_64-apple-darwin10 -emit-llvm -fcxx-exceptions -fexceptions -o - | FileCheck %s +struct A { virtual void f(); }; +struct B : A { }; + +// CHECK: {{define.*@_Z1fP1A}} +B fail; +const B& f(A *a) { + try { + // CHECK: call i8* @__dynamic_cast + // CHECK: br i1 + // CHECK: invoke void @__cxa_bad_cast() noreturn + dynamic_cast(*a); + } catch (...) { + // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + // CHECK-NEXT: catch i8* null + } + return fail; +} diff --git a/clang/test/CodeGenCXX/eh.cpp b/clang/test/CodeGenCXX/eh.cpp new file mode 100644 index 0000000..584af40 --- /dev/null +++ b/clang/test/CodeGenCXX/eh.cpp @@ -0,0 +1,446 @@ +// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -triple x86_64-apple-darwin -std=c++11 -emit-llvm %s -o %t.ll +// RUN: FileCheck --input-file=%t.ll %s + +struct test1_D { + double d; +} d1; + +void test1() { + throw d1; +} + +// CHECK: define void @_Z5test1v() +// CHECK: [[EXNOBJ:%.*]] = call i8* @__cxa_allocate_exception(i64 8) +// CHECK-NEXT: [[EXN:%.*]] = bitcast i8* [[EXNOBJ]] to [[DSTAR:%[^*]*\*]] +// CHECK-NEXT: [[EXN2:%.*]] = bitcast [[DSTAR]] [[EXN]] to i8* +// CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[EXN2]], i8* bitcast ([[DSTAR]] @d1 to i8*), i64 8, i32 8, i1 false) +// CHECK-NEXT: call void @__cxa_throw(i8* [[EXNOBJ]], i8* bitcast ({ i8*, i8* }* @_ZTI7test1_D to i8*), i8* null) noreturn +// CHECK-NEXT: unreachable + + +struct test2_D { + test2_D(const test2_D&o); + test2_D(); + virtual void bar() { } + int i; int j; +} d2; + +void test2() { + throw d2; +} + +// CHECK: define void @_Z5test2v() +// CHECK: [[EXNVAR:%.*]] = alloca i8* +// CHECK-NEXT: [[SELECTORVAR:%.*]] = alloca i32 +// CHECK-NEXT: [[EXNOBJ:%.*]] = call i8* @__cxa_allocate_exception(i64 16) +// CHECK-NEXT: [[EXN:%.*]] = bitcast i8* [[EXNOBJ]] to [[DSTAR:%[^*]*\*]] +// CHECK-NEXT: invoke void @_ZN7test2_DC1ERKS_([[DSTAR]] [[EXN]], [[DSTAR]] @d2) +// CHECK-NEXT: to label %[[CONT:.*]] unwind label %{{.*}} +// : [[CONT]]: (can't check this in Release-Asserts builds) +// CHECK: call void @__cxa_throw(i8* [[EXNOBJ]], i8* bitcast ({{.*}}* @_ZTI7test2_D to i8*), i8* null) noreturn +// CHECK-NEXT: unreachable + + +struct test3_D { + test3_D() { } + test3_D(volatile test3_D&o); + virtual void bar(); +}; + +void test3() { + throw (volatile test3_D *)0; +} + +// CHECK: define void @_Z5test3v() +// CHECK: [[EXNOBJ:%.*]] = call i8* @__cxa_allocate_exception(i64 8) +// CHECK-NEXT: [[EXN:%.*]] = bitcast i8* [[EXNOBJ]] to [[D:%[^*]+]]** +// CHECK-NEXT: store [[D]]* null, [[D]]** [[EXN]] +// CHECK-NEXT: call void @__cxa_throw(i8* [[EXNOBJ]], i8* bitcast ({ i8*, i8*, i32, i8* }* @_ZTIPV7test3_D to i8*), i8* null) noreturn +// CHECK-NEXT: unreachable + + +void test4() { + throw; +} + +// CHECK: define void @_Z5test4v() +// CHECK: call void @__cxa_rethrow() noreturn +// CHECK-NEXT: unreachable + + +// rdar://problem/7696549 +namespace test5 { + struct A { + A(); + A(const A&); + ~A(); + }; + + void test() { + try { throw A(); } catch (A &x) {} + } +// CHECK: define void @_ZN5test54testEv() +// CHECK: [[EXNOBJ:%.*]] = call i8* @__cxa_allocate_exception(i64 1) +// CHECK: [[EXNCAST:%.*]] = bitcast i8* [[EXNOBJ]] to [[A:%[^*]*]]* +// CHECK-NEXT: invoke void @_ZN5test51AC1Ev([[A]]* [[EXNCAST]]) +// CHECK: invoke void @__cxa_throw(i8* [[EXNOBJ]], i8* bitcast ({{.*}}* @_ZTIN5test51AE to i8*), i8* bitcast (void ([[A]]*)* @_ZN5test51AD1Ev to i8*)) noreturn +// CHECK-NEXT: to label {{%.*}} unwind label %[[HANDLER:[^ ]*]] +// : [[HANDLER]]: (can't check this in Release-Asserts builds) +// CHECK: {{%.*}} = call i32 @llvm.eh.typeid.for(i8* bitcast ({{.*}}* @_ZTIN5test51AE to i8*)) +} + +namespace test6 { + template struct allocator { + ~allocator() throw() { } + }; + + void foo() { + allocator a; + } +} + +// PR7127 +namespace test7 { +// CHECK: define i32 @_ZN5test73fooEv() + int foo() { +// CHECK: [[CAUGHTEXNVAR:%.*]] = alloca i8* +// CHECK-NEXT: [[SELECTORVAR:%.*]] = alloca i32 +// CHECK-NEXT: [[INTCATCHVAR:%.*]] = alloca i32 + try { + try { +// CHECK-NEXT: [[EXNALLOC:%.*]] = call i8* @__cxa_allocate_exception +// CHECK-NEXT: bitcast i8* [[EXNALLOC]] to i32* +// CHECK-NEXT: store i32 1, i32* +// CHECK-NEXT: invoke void @__cxa_throw(i8* [[EXNALLOC]], i8* bitcast (i8** @_ZTIi to i8*), i8* null + throw 1; + } + +// CHECK: [[CAUGHTVAL:%.*]] = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) +// CHECK-NEXT: catch i8* bitcast (i8** @_ZTIi to i8*) +// CHECK-NEXT: catch i8* null +// CHECK-NEXT: [[CAUGHTEXN:%.*]] = extractvalue { i8*, i32 } [[CAUGHTVAL]], 0 +// CHECK-NEXT: store i8* [[CAUGHTEXN]], i8** [[CAUGHTEXNVAR]] +// CHECK-NEXT: [[SELECTOR:%.*]] = extractvalue { i8*, i32 } [[CAUGHTVAL]], 1 +// CHECK-NEXT: store i32 [[SELECTOR]], i32* [[SELECTORVAR]] +// CHECK-NEXT: br label +// CHECK: [[SELECTOR:%.*]] = load i32* [[SELECTORVAR]] +// CHECK-NEXT: [[T0:%.*]] = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*)) +// CHECK-NEXT: icmp eq i32 [[SELECTOR]], [[T0]] +// CHECK-NEXT: br i1 +// CHECK: [[T0:%.*]] = load i8** [[CAUGHTEXNVAR]] +// CHECK-NEXT: [[T1:%.*]] = call i8* @__cxa_begin_catch(i8* [[T0]]) +// CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to i32* +// CHECK-NEXT: [[T3:%.*]] = load i32* [[T2]] +// CHECK-NEXT: store i32 [[T3]], i32* {{%.*}}, align 4 +// CHECK-NEXT: invoke void @__cxa_rethrow + catch (int) { + throw; + } + } +// CHECK: [[CAUGHTVAL:%.*]] = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) +// CHECK-NEXT: catch i8* null +// CHECK-NEXT: [[CAUGHTEXN:%.*]] = extractvalue { i8*, i32 } [[CAUGHTVAL]], 0 +// CHECK-NEXT: store i8* [[CAUGHTEXN]], i8** [[CAUGHTEXNVAR]] +// CHECK-NEXT: [[SELECTOR:%.*]] = extractvalue { i8*, i32 } [[CAUGHTVAL]], 1 +// CHECK-NEXT: store i32 [[SELECTOR]], i32* [[SELECTORVAR]] +// CHECK-NEXT: call void @__cxa_end_catch() +// CHECK-NEXT: br label +// CHECK: load i8** [[CAUGHTEXNVAR]] +// CHECK-NEXT: call i8* @__cxa_begin_catch +// CHECK-NEXT: call void @__cxa_end_catch + catch (...) { + } +// CHECK: ret i32 0 + return 0; + } +} + +// Ordering of destructors in a catch handler. +namespace test8 { + struct A { A(const A&); ~A(); }; + void bar(); + + // CHECK: define void @_ZN5test83fooEv() + void foo() { + try { + // CHECK: invoke void @_ZN5test83barEv() + bar(); + } catch (A a) { + // CHECK: call i8* @__cxa_get_exception_ptr + // CHECK-NEXT: bitcast + // CHECK-NEXT: invoke void @_ZN5test81AC1ERKS0_( + // CHECK: call i8* @__cxa_begin_catch + // CHECK-NEXT: call void @_ZN5test81AD1Ev( + // CHECK: call void @__cxa_end_catch() + // CHECK: ret void + } + } +} + +// Constructor function-try-block must rethrow on fallthrough. +// rdar://problem/7696603 +namespace test9 { + void opaque(); + + struct A { A(); }; + + // CHECK: define void @_ZN5test91AC1Ev(%"struct.test9::A"* %this) unnamed_addr + // CHECK: call void @_ZN5test91AC2Ev + // CHECK-NEXT: ret void + + // CHECK: define void @_ZN5test91AC2Ev(%"struct.test9::A"* %this) unnamed_addr + A::A() try { + // CHECK: invoke void @_ZN5test96opaqueEv() + opaque(); + } catch (int x) { + // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + // CHECK-NEXT: catch i8* bitcast (i8** @_ZTIi to i8*) + + // CHECK: call i8* @__cxa_begin_catch + // CHECK: invoke void @_ZN5test96opaqueEv() + // CHECK: invoke void @__cxa_rethrow() + opaque(); + } +} + +// __cxa_end_catch can throw for some kinds of caught exceptions. +namespace test10 { + void opaque(); + + struct A { ~A(); }; + struct B { int x; }; + + // CHECK: define void @_ZN6test103fooEv() + void foo() { + A a; // force a cleanup context + + try { + // CHECK: invoke void @_ZN6test106opaqueEv() + opaque(); + } catch (int i) { + // CHECK: call i8* @__cxa_begin_catch + // CHECK-NEXT: bitcast + // CHECK-NEXT: load i32* + // CHECK-NEXT: store i32 + // CHECK-NEXT: call void @__cxa_end_catch() nounwind + } catch (B a) { + // CHECK: call i8* @__cxa_begin_catch + // CHECK-NEXT: bitcast + // CHECK-NEXT: bitcast + // CHECK-NEXT: bitcast + // CHECK-NEXT: call void @llvm.memcpy + // CHECK-NEXT: invoke void @__cxa_end_catch() + } catch (...) { + // CHECK: call i8* @__cxa_begin_catch + // CHECK-NEXT: invoke void @__cxa_end_catch() + } + + // CHECK: call void @_ZN6test101AD1Ev( + } +} + +// __cxa_begin_catch returns pointers by value, even when catching by reference +// +namespace test11 { + void opaque(); + + // CHECK: define void @_ZN6test113fooEv() + void foo() { + try { + // CHECK: invoke void @_ZN6test116opaqueEv() + opaque(); + } catch (int**&p) { + // CHECK: [[EXN:%.*]] = load i8** + // CHECK-NEXT: call i8* @__cxa_begin_catch(i8* [[EXN]]) nounwind + // CHECK-NEXT: [[ADJ1:%.*]] = getelementptr i8* [[EXN]], i32 32 + // CHECK-NEXT: [[ADJ2:%.*]] = bitcast i8* [[ADJ1]] to i32*** + // CHECK-NEXT: store i32*** [[ADJ2]], i32**** [[P:%.*]] + // CHECK-NEXT: call void @__cxa_end_catch() nounwind + } + } + + struct A {}; + + // CHECK: define void @_ZN6test113barEv() + void bar() { + try { + // CHECK: [[EXNSLOT:%.*]] = alloca i8* + // CHECK-NEXT: [[SELECTORSLOT:%.*]] = alloca i32 + // CHECK-NEXT: [[P:%.*]] = alloca [[A:%.*]]**, + // CHECK-NEXT: [[TMP:%.*]] = alloca [[A]]* + // CHECK-NEXT: invoke void @_ZN6test116opaqueEv() + opaque(); + } catch (A*&p) { + // CHECK: [[EXN:%.*]] = load i8** [[EXNSLOT]] + // CHECK-NEXT: [[ADJ1:%.*]] = call i8* @__cxa_begin_catch(i8* [[EXN]]) nounwind + // CHECK-NEXT: [[ADJ2:%.*]] = bitcast i8* [[ADJ1]] to [[A]]* + // CHECK-NEXT: store [[A]]* [[ADJ2]], [[A]]** [[TMP]] + // CHECK-NEXT: store [[A]]** [[TMP]], [[A]]*** [[P]] + // CHECK-NEXT: call void @__cxa_end_catch() nounwind + } + } +} + +// PR7686 +namespace test12 { + struct A { ~A() noexcept(false); }; + bool opaque(const A&); + + // CHECK: define void @_ZN6test124testEv() + void test() { + // CHECK: [[X:%.*]] = alloca [[A:%.*]], + // CHECK: [[EHCLEANUPDEST:%.*]] = alloca i32 + // CHECK: [[Y:%.*]] = alloca [[A]] + // CHECK: [[Z:%.*]] = alloca [[A]] + // CHECK: [[CLEANUPDEST:%.*]] = alloca i32 + + A x; + // CHECK: invoke zeroext i1 @_ZN6test126opaqueERKNS_1AE( + if (opaque(x)) { + A y; + A z; + + // CHECK: invoke void @_ZN6test121AD1Ev([[A]]* [[Z]]) + // CHECK: invoke void @_ZN6test121AD1Ev([[A]]* [[Y]]) + // CHECK-NOT: switch + goto success; + } + + success: + bool _ = true; + + // CHECK: call void @_ZN6test121AD1Ev([[A]]* [[X]]) + // CHECK-NEXT: ret void + } +} + +// Reduced from some TableGen code that was causing a self-host crash. +namespace test13 { + struct A { ~A(); }; + + void test0(int x) { + try { + switch (x) { + case 0: + break; + case 1:{ + A a; + break; + } + default: + return; + } + return; + } catch (int x) { + } + return; + } + + void test1(int x) { + A y; + try { + switch (x) { + default: break; + } + } catch (int x) {} + } +} + +// rdar://problem/8231514 +namespace test14 { + struct A { ~A(); }; + struct B { ~B(); }; + + B b(); + void opaque(); + + void foo() { + A a; + try { + B str = b(); + opaque(); + } catch (int x) { + } + } +} + +// rdar://problem/8231514 +// JumpDests shouldn't get confused by scopes that aren't normal cleanups. +namespace test15 { + struct A { ~A(); }; + + bool opaque(int); + + // CHECK: define void @_ZN6test153fooEv() + void foo() { + A a; + + try { + // CHECK: [[X:%.*]] = alloca i32 + // CHECK: store i32 10, i32* [[X]] + // CHECK-NEXT: br label + // -> while.cond + int x = 10; + + while (true) { + // CHECK: load i32* [[X]] + // CHECK-NEXT: [[COND:%.*]] = invoke zeroext i1 @_ZN6test156opaqueEi + // CHECK: br i1 [[COND]] + if (opaque(x)) + // CHECK: br label + break; + + // CHECK: br label + } + // CHECK: br label + } catch (int x) { } + + // CHECK: call void @_ZN6test151AD1Ev + } +} + +namespace test16 { + struct A { A(); ~A() noexcept(false); }; + struct B { int x; B(const A &); ~B() noexcept(false); }; + void foo(); + bool cond(); + + // CHECK: define void @_ZN6test163barEv() + void bar() { + // CHECK: [[EXN_SAVE:%.*]] = alloca i8* + // CHECK-NEXT: [[EXN_ACTIVE:%.*]] = alloca i1 + // CHECK-NEXT: [[TEMP:%.*]] = alloca [[A:%.*]], + // CHECK-NEXT: [[EXNSLOT:%.*]] = alloca i8* + // CHECK-NEXT: [[SELECTORSLOT:%.*]] = alloca i32 + // CHECK-NEXT: [[TEMP_ACTIVE:%.*]] = alloca i1 + + cond() ? throw B(A()) : foo(); + + // CHECK-NEXT: [[COND:%.*]] = call zeroext i1 @_ZN6test164condEv() + // CHECK-NEXT: store i1 false, i1* [[EXN_ACTIVE]] + // CHECK-NEXT: store i1 false, i1* [[TEMP_ACTIVE]] + // CHECK-NEXT: br i1 [[COND]], + + // CHECK: [[EXN:%.*]] = call i8* @__cxa_allocate_exception(i64 4) + // CHECK-NEXT: store i8* [[EXN]], i8** [[EXN_SAVE]] + // CHECK-NEXT: store i1 true, i1* [[EXN_ACTIVE]] + // CHECK-NEXT: [[T0:%.*]] = bitcast i8* [[EXN]] to [[B:%.*]]* + // CHECK-NEXT: invoke void @_ZN6test161AC1Ev([[A]]* [[TEMP]]) + // CHECK: store i1 true, i1* [[TEMP_ACTIVE]] + // CHECK-NEXT: invoke void @_ZN6test161BC1ERKNS_1AE([[B]]* [[T0]], [[A]]* [[TEMP]]) + // CHECK: store i1 false, i1* [[EXN_ACTIVE]] + // CHECK-NEXT: invoke void @__cxa_throw(i8* [[EXN]], + + // CHECK: invoke void @_ZN6test163fooEv() + // CHECK: br label + + // CHECK: invoke void @_ZN6test161AD1Ev([[A]]* [[TEMP]]) + // CHECK: ret void + + // CHECK: [[T0:%.*]] = load i1* [[EXN_ACTIVE]] + // CHECK-NEXT: br i1 [[T0]] + // CHECK: [[T1:%.*]] = load i8** [[EXN_SAVE]] + // CHECK-NEXT: call void @__cxa_free_exception(i8* [[T1]]) + // CHECK-NEXT: br label + } +} diff --git a/clang/test/CodeGenCXX/elide-call-reference.cpp b/clang/test/CodeGenCXX/elide-call-reference.cpp new file mode 100644 index 0000000..55d30e2 --- /dev/null +++ b/clang/test/CodeGenCXX/elide-call-reference.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s +// PR5695 + +struct A { A(const A&); ~A(); }; +A& a(); +void b() { + A x = a(); +} + +// CHECK: call {{.*}} @_ZN1AC1ERKS_ +// CHECK: call {{.*}} @_ZN1AD1Ev diff --git a/clang/test/CodeGenCXX/empty-classes.cpp b/clang/test/CodeGenCXX/empty-classes.cpp new file mode 100644 index 0000000..1ce1dad --- /dev/null +++ b/clang/test/CodeGenCXX/empty-classes.cpp @@ -0,0 +1,82 @@ +// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -emit-llvm -O3 -o - | FileCheck %s + +struct Empty { }; + +struct A { + explicit A(unsigned a = 0xffffffff) : a(a) { } + + unsigned a; +}; + +struct B : A, Empty { + B() : A(), Empty() { } +}; + +struct C : A, Empty { + C() : A(), Empty() { } + C(const C& other) : A(0x12345678), Empty(other) { } +}; + +struct D : A, Empty { + D& operator=(const D& other) { + a = 0x87654321; + Empty::operator=(other); + + return *this; + } +}; + +#define CHECK(x) if (!(x)) return __LINE__ + +// PR7012 +// CHECK: define i32 @_Z1fv() +int f() { + B b1; + + // Check that A::a is not overwritten by the Empty default constructor. + CHECK(b1.a == 0xffffffff); + + C c1; + C c2(c1); + + // Check that A::a has the value set in the C::C copy constructor. + CHECK(c2.a == 0x12345678); + + D d1, d2; + d2 = d1; + + // Check that A::as has the value set in the D copy assignment operator. + CHECK(d2.a == 0x87654321); + + // Success! + // CHECK: ret i32 0 + return 0; +} + +namespace PR8796 { + struct FreeCell { + }; + union ThingOrCell { + FreeCell t; + FreeCell cell; + }; + struct Things { + ThingOrCell things; + }; + Things x; +} + +#ifdef HARNESS +extern "C" void printf(const char *, ...); + +int main() { + int result = f(); + + if (result == 0) + printf("success!\n"); + else + printf("test on line %d failed!\n", result); + + return result; +} +#endif diff --git a/clang/test/CodeGenCXX/empty-union.cpp b/clang/test/CodeGenCXX/empty-union.cpp new file mode 100644 index 0000000..7f3e6cc --- /dev/null +++ b/clang/test/CodeGenCXX/empty-union.cpp @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s + +union sigval { }; +union sigval Test1; + +union NonPODUnion { ~NonPODUnion(); }; +union NonPODUnion Test2; diff --git a/clang/test/CodeGenCXX/enum.cpp b/clang/test/CodeGenCXX/enum.cpp new file mode 100644 index 0000000..cfcd264 --- /dev/null +++ b/clang/test/CodeGenCXX/enum.cpp @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 -emit-llvm-only -verify %s + +enum A { a } __attribute((packed)); +int func(A x) { return x==a; } diff --git a/clang/test/CodeGenCXX/eval-recursive-constant.cpp b/clang/test/CodeGenCXX/eval-recursive-constant.cpp new file mode 100644 index 0000000..608c95d --- /dev/null +++ b/clang/test/CodeGenCXX/eval-recursive-constant.cpp @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 %s -emit-llvm-only + +extern const int a,b; +const int a=b,b=a; +int c() { if (a) return 1; return 0; } diff --git a/clang/test/CodeGenCXX/exceptions-no-rtti.cpp b/clang/test/CodeGenCXX/exceptions-no-rtti.cpp new file mode 100644 index 0000000..902d6ac --- /dev/null +++ b/clang/test/CodeGenCXX/exceptions-no-rtti.cpp @@ -0,0 +1,51 @@ +// RUN: %clang_cc1 -fno-rtti -fcxx-exceptions -fexceptions %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s + +// CHECK: @_ZTIN5test11AE = linkonce_odr unnamed_addr constant +// CHECK: @_ZTIN5test11BE = linkonce_odr unnamed_addr constant +// CHECK: @_ZTIN5test11CE = linkonce_odr unnamed_addr constant +// CHECK: @_ZTIN5test11DE = linkonce_odr unnamed_addr constant +// CHECK: @_ZTIPN5test11DE = linkonce_odr unnamed_addr constant {{.*}} @_ZTIN5test11DE + +// PR6974: this shouldn't crash +namespace test0 { + class err {}; + + void f(void) { + try { + } catch (err &) { + } + } +} + +namespace test1 { + // These classes have key functions defined out-of-line. Under + // normal circumstances, we wouldn't generate RTTI for them; under + // -fno-rtti, we generate RTTI only when required by EH. But + // everything gets hidden visibility because we assume that all + // users are also compiled under -fno-rtti and therefore will be + // emitting RTTI regardless of key function. + class A { virtual void foo(); }; + class B { virtual void foo(); }; + class C { virtual void foo(); }; + class D { virtual void foo(); }; + + void opaque(); + + void test0() { + throw A(); + } + + void test1() throw(B) { + opaque(); + } + + void test2() { + try { + opaque(); + } catch (C&) {} + } + + void test3(D *ptr) { + throw ptr; + }; +} diff --git a/clang/test/CodeGenCXX/exceptions.cpp b/clang/test/CodeGenCXX/exceptions.cpp new file mode 100644 index 0000000..079c1e5 --- /dev/null +++ b/clang/test/CodeGenCXX/exceptions.cpp @@ -0,0 +1,416 @@ +// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - -fcxx-exceptions -fexceptions | FileCheck %s + +typedef typeof(sizeof(0)) size_t; + +// This just shouldn't crash. +namespace test0 { + struct allocator { + allocator(); + allocator(const allocator&); + ~allocator(); + }; + + void f(); + void g(bool b, bool c) { + if (b) { + if (!c) + throw allocator(); + + return; + } + f(); + } +} + +namespace test1 { + struct A { A(int); A(int, int); ~A(); void *p; }; + + A *a() { + // CHECK: define [[A:%.*]]* @_ZN5test11aEv() + // CHECK: [[NEW:%.*]] = call noalias i8* @_Znwm(i64 8) + // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]* + // CHECK-NEXT: invoke void @_ZN5test11AC1Ei([[A]]* [[CAST]], i32 5) + // CHECK: ret [[A]]* [[CAST]] + // CHECK: call void @_ZdlPv(i8* [[NEW]]) + return new A(5); + } + + A *b() { + // CHECK: define [[A:%.*]]* @_ZN5test11bEv() + // CHECK: [[NEW:%.*]] = call noalias i8* @_Znwm(i64 8) + // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]* + // CHECK-NEXT: [[FOO:%.*]] = invoke i32 @_ZN5test13fooEv() + // CHECK: invoke void @_ZN5test11AC1Ei([[A]]* [[CAST]], i32 [[FOO]]) + // CHECK: ret [[A]]* [[CAST]] + // CHECK: call void @_ZdlPv(i8* [[NEW]]) + extern int foo(); + return new A(foo()); + } + + struct B { B(); ~B(); operator int(); int x; }; + B makeB(); + + A *c() { + // CHECK: define [[A:%.*]]* @_ZN5test11cEv() + // CHECK: [[ACTIVE:%.*]] = alloca i1 + // CHECK-NEXT: [[NEW:%.*]] = call noalias i8* @_Znwm(i64 8) + // CHECK-NEXT: store i1 true, i1* [[ACTIVE]] + // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]* + // CHECK-NEXT: invoke void @_ZN5test11BC1Ev([[B:%.*]]* [[T0:%.*]]) + // CHECK: [[T1:%.*]] = getelementptr inbounds [[B]]* [[T0]], i32 0, i32 0 + // CHECK-NEXT: [[T2:%.*]] = load i32* [[T1]], align 4 + // CHECK-NEXT: invoke void @_ZN5test11AC1Ei([[A]]* [[CAST]], i32 [[T2]]) + // CHECK: store i1 false, i1* [[ACTIVE]] + // CHECK-NEXT: invoke void @_ZN5test11BD1Ev([[B]]* [[T0]]) + // CHECK: ret [[A]]* [[CAST]] + // CHECK: [[ISACTIVE:%.*]] = load i1* [[ACTIVE]] + // CHECK-NEXT: br i1 [[ISACTIVE]] + // CHECK: call void @_ZdlPv(i8* [[NEW]]) + return new A(B().x); + } + + A *d() { + // CHECK: define [[A:%.*]]* @_ZN5test11dEv() + // CHECK: [[ACTIVE:%.*]] = alloca i1 + // CHECK-NEXT: [[NEW:%.*]] = call noalias i8* @_Znwm(i64 8) + // CHECK-NEXT: store i1 true, i1* [[ACTIVE]] + // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]* + // CHECK-NEXT: invoke void @_ZN5test11BC1Ev([[B:%.*]]* [[T0:%.*]]) + // CHECK: [[T1:%.*]] = invoke i32 @_ZN5test11BcviEv([[B]]* [[T0]]) + // CHECK: invoke void @_ZN5test11AC1Ei([[A]]* [[CAST]], i32 [[T1]]) + // CHECK: store i1 false, i1* [[ACTIVE]] + // CHECK-NEXT: invoke void @_ZN5test11BD1Ev([[B]]* [[T0]]) + // CHECK: ret [[A]]* [[CAST]] + // CHECK: [[ISACTIVE:%.*]] = load i1* [[ACTIVE]] + // CHECK-NEXT: br i1 [[ISACTIVE]] + // CHECK: call void @_ZdlPv(i8* [[NEW]]) + return new A(B()); + } + + A *e() { + // CHECK: define [[A:%.*]]* @_ZN5test11eEv() + // CHECK: [[ACTIVE:%.*]] = alloca i1 + // CHECK-NEXT: [[NEW:%.*]] = call noalias i8* @_Znwm(i64 8) + // CHECK-NEXT: store i1 true, i1* [[ACTIVE]] + // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]* + // CHECK-NEXT: invoke void @_ZN5test11BC1Ev([[B:%.*]]* [[T0:%.*]]) + // CHECK: [[T1:%.*]] = invoke i32 @_ZN5test11BcviEv([[B]]* [[T0]]) + // CHECK: invoke void @_ZN5test11BC1Ev([[B]]* [[T2:%.*]]) + // CHECK: [[T3:%.*]] = invoke i32 @_ZN5test11BcviEv([[B]]* [[T2]]) + // CHECK: invoke void @_ZN5test11AC1Eii([[A]]* [[CAST]], i32 [[T1]], i32 [[T3]]) + // CHECK: store i1 false, i1* [[ACTIVE]] + // CHECK-NEXT: invoke void @_ZN5test11BD1Ev([[B]]* [[T2]]) + // CHECK: invoke void @_ZN5test11BD1Ev([[B]]* [[T0]]) + // CHECK: ret [[A]]* [[CAST]] + // CHECK: [[ISACTIVE:%.*]] = load i1* [[ACTIVE]] + // CHECK-NEXT: br i1 [[ISACTIVE]] + // CHECK: call void @_ZdlPv(i8* [[NEW]]) + return new A(B(), B()); + } + A *f() { + return new A(makeB().x); + } + A *g() { + return new A(makeB()); + } + A *h() { + return new A(makeB(), makeB()); + } + + A *i() { + // CHECK: define [[A:%.*]]* @_ZN5test11iEv() + // CHECK: [[X:%.*]] = alloca [[A]]*, align 8 + // CHECK: [[ACTIVE:%.*]] = alloca i1 + // CHECK: [[NEW:%.*]] = call noalias i8* @_Znwm(i64 8) + // CHECK-NEXT: store i1 true, i1* [[ACTIVE]] + // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]* + // CHECK-NEXT: invoke void @_ZN5test15makeBEv([[B:%.*]]* sret [[T0:%.*]]) + // CHECK: [[T1:%.*]] = invoke i32 @_ZN5test11BcviEv([[B]]* [[T0]]) + // CHECK: invoke void @_ZN5test11AC1Ei([[A]]* [[CAST]], i32 [[T1]]) + // CHECK: store i1 false, i1* [[ACTIVE]] + // CHECK-NEXT: store [[A]]* [[CAST]], [[A]]** [[X]], align 8 + // CHECK: invoke void @_ZN5test15makeBEv([[B:%.*]]* sret [[T2:%.*]]) + // CHECK: [[RET:%.*]] = load [[A]]** [[X]], align 8 + // CHECK: invoke void @_ZN5test11BD1Ev([[B]]* [[T2]]) + // CHECK: invoke void @_ZN5test11BD1Ev([[B]]* [[T0]]) + // CHECK: ret [[A]]* [[RET]] + // CHECK: [[ISACTIVE:%.*]] = load i1* [[ACTIVE]] + // CHECK-NEXT: br i1 [[ISACTIVE]] + // CHECK: call void @_ZdlPv(i8* [[NEW]]) + A *x; + return (x = new A(makeB()), makeB(), x); + } +} + +namespace test2 { + struct A { + A(int); A(int, int); ~A(); + void *p; + void *operator new(size_t); + void operator delete(void*, size_t); + }; + + A *a() { + // CHECK: define [[A:%.*]]* @_ZN5test21aEv() + // CHECK: [[NEW:%.*]] = call i8* @_ZN5test21AnwEm(i64 8) + // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]* + // CHECK-NEXT: invoke void @_ZN5test21AC1Ei([[A]]* [[CAST]], i32 5) + // CHECK: ret [[A]]* [[CAST]] + // CHECK: invoke void @_ZN5test21AdlEPvm(i8* [[NEW]], i64 8) + // CHECK: call void @_ZSt9terminatev() + return new A(5); + } +} + +namespace test3 { + struct A { + A(int); A(int, int); A(const A&); ~A(); + void *p; + void *operator new(size_t, void*, double); + void operator delete(void*, void*, double); + }; + + void *foo(); + double bar(); + A makeA(), *makeAPtr(); + + A *a() { + // CHECK: define [[A:%.*]]* @_ZN5test31aEv() + // CHECK: [[FOO:%.*]] = call i8* @_ZN5test33fooEv() + // CHECK: [[BAR:%.*]] = call double @_ZN5test33barEv() + // CHECK: [[NEW:%.*]] = call i8* @_ZN5test31AnwEmPvd(i64 8, i8* [[FOO]], double [[BAR]]) + // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]* + // CHECK-NEXT: invoke void @_ZN5test31AC1Ei([[A]]* [[CAST]], i32 5) + // CHECK: ret [[A]]* [[CAST]] + // CHECK: invoke void @_ZN5test31AdlEPvS1_d(i8* [[NEW]], i8* [[FOO]], double [[BAR]]) + // CHECK: call void @_ZSt9terminatev() + return new(foo(),bar()) A(5); + } + + // rdar://problem/8439196 + A *b(bool cond) { + + // CHECK: define [[A:%.*]]* @_ZN5test31bEb(i1 zeroext + // CHECK: [[SAVED0:%.*]] = alloca i8* + // CHECK-NEXT: [[SAVED1:%.*]] = alloca i8* + // CHECK-NEXT: [[CLEANUPACTIVE:%.*]] = alloca i1 + + // CHECK: [[COND:%.*]] = trunc i8 {{.*}} to i1 + // CHECK-NEXT: store i1 false, i1* [[CLEANUPACTIVE]] + // CHECK-NEXT: br i1 [[COND]] + return (cond ? + + // CHECK: [[FOO:%.*]] = call i8* @_ZN5test33fooEv() + // CHECK-NEXT: [[NEW:%.*]] = call i8* @_ZN5test31AnwEmPvd(i64 8, i8* [[FOO]], double [[CONST:.*]]) + // CHECK-NEXT: store i8* [[NEW]], i8** [[SAVED0]] + // CHECK-NEXT: store i8* [[FOO]], i8** [[SAVED1]] + // CHECK-NEXT: store i1 true, i1* [[CLEANUPACTIVE]] + // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]* + // CHECK-NEXT: invoke void @_ZN5test35makeAEv([[A]]* sret [[CAST]]) + // CHECK: br label + // -> cond.end + new(foo(),10.0) A(makeA()) : + + // CHECK: [[MAKE:%.*]] = call [[A]]* @_ZN5test38makeAPtrEv() + // CHECK: br label + // -> cond.end + makeAPtr()); + + // cond.end: + // CHECK: [[RESULT:%.*]] = phi [[A]]* {{.*}}[[CAST]]{{.*}}[[MAKE]] + // CHECK: ret [[A]]* [[RESULT]] + + // in the EH path: + // CHECK: [[ISACTIVE:%.*]] = load i1* [[CLEANUPACTIVE]] + // CHECK-NEXT: br i1 [[ISACTIVE]] + // CHECK: [[V0:%.*]] = load i8** [[SAVED0]] + // CHECK-NEXT: [[V1:%.*]] = load i8** [[SAVED1]] + // CHECK-NEXT: invoke void @_ZN5test31AdlEPvS1_d(i8* [[V0]], i8* [[V1]], double [[CONST]]) + } +} + +namespace test4 { + struct A { + A(int); A(int, int); ~A(); + void *p; + void *operator new(size_t, void*, void*); + void operator delete(void*, size_t, void*, void*); // not a match + }; + + A *a() { + // CHECK: define [[A:%.*]]* @_ZN5test41aEv() + // CHECK: [[FOO:%.*]] = call i8* @_ZN5test43fooEv() + // CHECK-NEXT: [[BAR:%.*]] = call i8* @_ZN5test43barEv() + // CHECK-NEXT: [[NEW:%.*]] = call i8* @_ZN5test41AnwEmPvS1_(i64 8, i8* [[FOO]], i8* [[BAR]]) + // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]* + // CHECK-NEXT: call void @_ZN5test41AC1Ei([[A]]* [[CAST]], i32 5) + // CHECK-NEXT: ret [[A]]* [[CAST]] + extern void *foo(), *bar(); + + return new(foo(),bar()) A(5); + } +} + +// PR7908 +namespace test5 { + struct T { T(); ~T(); }; + + struct A { + A(const A &x, const T &t = T()); + ~A(); + }; + + void foo(); + + // CHECK: define void @_ZN5test54testEv() + // CHECK: [[EXNSLOT:%.*]] = alloca i8* + // CHECK-NEXT: [[SELECTORSLOT:%.*]] = alloca i32 + // CHECK-NEXT: [[A:%.*]] = alloca [[A_T:%.*]], align 1 + // CHECK-NEXT: [[T:%.*]] = alloca [[T_T:%.*]], align 1 + // CHECK-NEXT: invoke void @_ZN5test53fooEv() + // CHECK: [[EXN:%.*]] = load i8** [[EXNSLOT]] + // CHECK-NEXT: [[ADJ:%.*]] = call i8* @__cxa_get_exception_ptr(i8* [[EXN]]) + // CHECK-NEXT: [[SRC:%.*]] = bitcast i8* [[ADJ]] to [[A_T]]* + // CHECK-NEXT: invoke void @_ZN5test51TC1Ev([[T_T]]* [[T]]) + // CHECK: invoke void @_ZN5test51AC1ERKS0_RKNS_1TE([[A_T]]* [[A]], [[A_T]]* [[SRC]], [[T_T]]* [[T]]) + // CHECK: invoke void @_ZN5test51TD1Ev([[T_T]]* [[T]]) + // CHECK: call i8* @__cxa_begin_catch(i8* [[EXN]]) nounwind + // CHECK-NEXT: invoke void @_ZN5test51AD1Ev([[A_T]]* [[A]]) + // CHECK: call void @__cxa_end_catch() + void test() { + try { + foo(); + } catch (A a) { + } + } +} + +// PR9303: invalid assert on this +namespace test6 { + bool cond(); + void test() { + try { + lbl: + if (cond()) goto lbl; + } catch (...) { + } + } +} + +// PR9298 +namespace test7 { + struct A { A(); ~A(); }; + struct B { + // The throw() operator means that a bad allocation is signalled + // with a null return, which means that the initializer is + // evaluated conditionally. + static void *operator new(size_t size) throw(); + B(const A&, B*); + ~B(); + }; + + B *test() { + // CHECK: define [[B:%.*]]* @_ZN5test74testEv() + // CHECK: [[OUTER_NEW:%.*]] = alloca i1 + // CHECK-NEXT: alloca [[A:%.*]], + // CHECK-NEXT: alloca i8* + // CHECK-NEXT: alloca i32 + // CHECK-NEXT: [[OUTER_A:%.*]] = alloca i1 + // CHECK-NEXT: alloca i8* + // CHECK-NEXT: [[INNER_NEW:%.*]] = alloca i1 + // CHECK-NEXT: alloca [[A]] + // CHECK-NEXT: [[INNER_A:%.*]] = alloca i1 + + // Allocate the outer object. + // CHECK-NEXT: [[NEW:%.*]] = call i8* @_ZN5test71BnwEm( + // CHECK-NEXT: icmp eq i8* [[NEW]], null + + // These stores, emitted before the outermost conditional branch, + // deactivate the temporary cleanups. + // CHECK-NEXT: store i1 false, i1* [[OUTER_NEW]] + // CHECK-NEXT: store i1 false, i1* [[OUTER_A]] + // CHECK-NEXT: store i1 false, i1* [[INNER_NEW]] + // CHECK-NEXT: store i1 false, i1* [[INNER_A]] + // CHECK-NEXT: br i1 + + // We passed the first null check; activate that cleanup and continue. + // CHECK: store i1 true, i1* [[OUTER_NEW]] + // CHECK-NEXT: bitcast + + // Create the first A temporary and activate that cleanup. + // CHECK-NEXT: invoke void @_ZN5test71AC1Ev( + // CHECK: store i1 true, i1* [[OUTER_A]] + + // Allocate the inner object. + // CHECK-NEXT: [[NEW:%.*]] = call i8* @_ZN5test71BnwEm( + // CHECK-NEXT: icmp eq i8* [[NEW]], null + // CHECK-NEXT: br i1 + + // We passed the second null check; save that pointer, activate + // that cleanup, and continue. + // CHECK: store i8* [[NEW]] + // CHECK-NEXT: store i1 true, i1* [[INNER_NEW]] + // CHECK-NEXT: bitcast + + // Build the second A temporary and activate that cleanup. + // CHECK-NEXT: invoke void @_ZN5test71AC1Ev( + // CHECK: store i1 true, i1* [[INNER_A]] + + // Build the inner B object and deactivate the inner delete cleanup. + // CHECK-NEXT: invoke void @_ZN5test71BC1ERKNS_1AEPS0_( + // CHECK: store i1 false, i1* [[INNER_NEW]] + // CHECK: phi + + // Build the outer B object and deactivate the outer delete cleanup. + // CHECK-NEXT: invoke void @_ZN5test71BC1ERKNS_1AEPS0_( + // CHECK: store i1 false, i1* [[OUTER_NEW]] + // CHECK: phi + + // Destroy the inner A object. + // CHECK-NEXT: load i1* [[INNER_A]] + // CHECK-NEXT: br i1 + // CHECK: invoke void @_ZN5test71AD1Ev( + + // Destroy the outer A object. + // CHECK: load i1* [[OUTER_A]] + // CHECK-NEXT: br i1 + // CHECK: invoke void @_ZN5test71AD1Ev( + + return new B(A(), new B(A(), 0)); + } +} + +// Just don't crash. +namespace test8 { + struct A { + // Having both of these is required to trigger the assert we're + // trying to avoid. + A(const A&); + A&operator=(const A&); + + ~A(); + }; + + A makeA(); + void test() { + throw makeA(); + } + // CHECK: define void @_ZN5test84testEv +} + +// Make sure we generate the correct code for the delete[] call which +// happens if A::A() throws. (We were previously calling delete[] on +// a pointer to the first array element, not the pointer returned by new[].) +// PR10870 +namespace test9 { + struct A { + A(); + ~A(); + }; + A* test() { + return new A[10]; + } + // CHECK: define {{%.*}}* @_ZN5test94testEv + // CHECK: [[TEST9_NEW:%.*]] = call noalias i8* @_Znam + // CHECK: call void @_ZdaPv(i8* [[TEST9_NEW]]) +} diff --git a/clang/test/CodeGenCXX/explicit-instantiation.cpp b/clang/test/CodeGenCXX/explicit-instantiation.cpp new file mode 100644 index 0000000..8daf3c6 --- /dev/null +++ b/clang/test/CodeGenCXX/explicit-instantiation.cpp @@ -0,0 +1,45 @@ +// RUN: %clang_cc1 -emit-llvm -triple i686-pc-linux-gnu -o - %s | FileCheck %s + +// This check logically is attached to 'template int S::i;' below. +// CHECK: @_ZN1SIiE1iE = weak_odr global i32 + +template +struct plus { + Result operator()(const T& t, const U& u) const; +}; + +template +Result plus::operator()(const T& t, const U& u) const { + return t + u; +} + +// CHECK: define weak_odr i32 @_ZNK4plusIillEclERKiRKl +template struct plus; + +// Check that we emit definitions from explicit instantiations even when they +// occur prior to the definition itself. +template struct S { + void f(); + static void g(); + static int i; + struct S2 { + void h(); + }; +}; + +// CHECK: define weak_odr void @_ZN1SIiE1fEv +template void S::f(); + +// CHECK: define weak_odr void @_ZN1SIiE1gEv +template void S::g(); + +// See the check line at the top of the file. +template int S::i; + +// CHECK: define weak_odr void @_ZN1SIiE2S21hEv +template void S::S2::h(); + +template void S::f() {} +template void S::g() {} +template int S::i; +template void S::S2::h() {} diff --git a/clang/test/CodeGenCXX/expr.cpp b/clang/test/CodeGenCXX/expr.cpp new file mode 100644 index 0000000..33e8e63 --- /dev/null +++ b/clang/test/CodeGenCXX/expr.cpp @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -emit-llvm -x c++ < %s + +void test0(int x) { + if (x != 0) return; +} + + +// PR5211 +void test1() { + char *xpto; + while ( true && xpto[0] ); +} + +// PR5514 +int a; +void test2() { ++a+=10; } + +// PR7892 +int test3(const char*); +int test3g = test3(__PRETTY_FUNCTION__); + + +// PR7889 +struct test4A { + int j : 2; +}; +int test4() { + test4A a; + (a.j = 2) = 3; +} + +// Incomplete type in conditional operator. +// Check operations on incomplete types. +struct s5; +struct s5 &f5_0(bool cond, struct s5 &a, struct s5 &b) { + return cond ? a : b; +} diff --git a/clang/test/CodeGenCXX/extern-c.cpp b/clang/test/CodeGenCXX/extern-c.cpp new file mode 100644 index 0000000..ca5cd73 --- /dev/null +++ b/clang/test/CodeGenCXX/extern-c.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -emit-llvm %s -o %t +namespace foo { + +// RUN: not grep "@a = global i32" %t +extern "C" int a; + +// RUN: not grep "@_ZN3foo1bE = global i32" %t +extern int b; + +// RUN: grep "@_ZN3foo1cE = global i32" %t | count 1 +int c = 5; + +// RUN: not grep "@_ZN3foo1dE" %t +extern "C" struct d; + +} diff --git a/clang/test/CodeGenCXX/field-access-debug-info.cpp b/clang/test/CodeGenCXX/field-access-debug-info.cpp new file mode 100644 index 0000000..fd899ed --- /dev/null +++ b/clang/test/CodeGenCXX/field-access-debug-info.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -g -S -masm-verbose -o - %s | FileCheck %s + +// CHECK: abbrev_begin: +// CHECK: DW_AT_accessibility +// CHECK-NEXT: DW_FORM_data1 + +class A { +public: + int p; +private: + int pr; +}; + +A a; diff --git a/clang/test/CodeGenCXX/for-range-temporaries.cpp b/clang/test/CodeGenCXX/for-range-temporaries.cpp new file mode 100644 index 0000000..a03bb0a --- /dev/null +++ b/clang/test/CodeGenCXX/for-range-temporaries.cpp @@ -0,0 +1,146 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -std=c++11 -emit-llvm -o - -UDESUGAR %s | opt -instnamer -S | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -std=c++11 -emit-llvm -o - -DDESUGAR %s | opt -instnamer -S | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -std=c++11 -emit-llvm -o - -UDESUGAR -DTEMPLATE %s | opt -instnamer -S | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -std=c++11 -emit-llvm -o - -DDESUGAR -DTEMPLATE %s | opt -instnamer -S | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -std=c++11 -emit-llvm -o - -UDESUGAR -DTEMPLATE -DDEPENDENT %s | opt -instnamer -S | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -std=c++11 -emit-llvm -o - -DDESUGAR -DTEMPLATE -DDEPENDENT %s | opt -instnamer -S | FileCheck %s + +struct A { + A(); + A(const A &); + ~A(); +}; + +struct B { + B(); + B(const B &); + ~B(); +}; + +struct C { + C(const B &); + C(const C &); + ~C(); +}; + +struct E; +struct D { + D(const C &); + D(const D &); + ~D(); +}; +E begin(D); +E end(D); + +struct F; +struct G; +struct H; +struct E { + E(const E &); + ~E(); + F operator*(); + G operator++(); + H operator!=(const E &o); +}; + +struct I; +struct F { + F(const F &); + ~F(); + operator I(); +}; + +struct G { + G(const G &); + ~G(); + operator bool(); +}; + +struct H { + H(const H &); + ~H(); + operator bool(); +}; + +struct I { + I(const I &); + ~I(); +}; + +void body(const I &); + +#ifdef TEMPLATE +#ifdef DEPENDENT +template +#else +template +#endif +#endif +void for_temps() { + A a; +#ifdef DESUGAR + { + auto && __range = D(B()); + for (auto __begin = begin(__range), __end = end(__range); + __begin != __end; ++__begin) { + I i = *__begin; + body(i); + } + } +#else + for (I i : D(B())) { + body(i); + } +#endif +} + +#ifdef TEMPLATE +template void for_temps(); +#endif + +// CHECK: define {{.*}}for_temps +// CHECK: call void @_ZN1AC1Ev( +// CHECK: call void @_ZN1BC1Ev( +// CHECK: call void @_ZN1CC1ERK1B( +// CHECK: call void @_ZN1DC1ERK1C( +// CHECK: call void @_ZN1CD1Ev( +// CHECK: call void @_ZN1BD1Ev( +// CHECK: call void @_ZN1DC1ERKS_( +// CHECK: call void @_Z5begin1D( +// CHECK: call void @_ZN1DD1Ev( +// CHECK: call void @_ZN1DC1ERKS_( +// CHECK: call void @_Z3end1D( +// CHECK: call void @_ZN1DD1Ev( +// CHECK: br label %[[COND:.*]] + +// CHECK: [[COND]]: +// CHECK: call void @_ZN1EneERKS_( +// CHECK: %[[CMP:.*]] = call zeroext i1 @_ZN1HcvbEv( +// CHECK: call void @_ZN1HD1Ev( +// CHECK: br i1 %[[CMP]], label %[[BODY:.*]], label %[[CLEANUP:.*]] + +// CHECK: [[CLEANUP]]: +// CHECK: call void @_ZN1ED1Ev( +// CHECK: call void @_ZN1ED1Ev( +// In for-range: +// call void @_ZN1DD1Ev( +// CHECK: br label %[[END:.*]] + +// CHECK: [[BODY]]: +// CHECK: call void @_ZN1EdeEv( +// CHECK: call void @_ZN1Fcv1IEv( +// CHECK: call void @_ZN1FD1Ev( +// CHECK: call void @_Z4bodyRK1I( +// CHECK: call void @_ZN1ID1Ev( +// CHECK: br label %[[INC:.*]] + +// CHECK: [[INC]]: +// CHECK: call void @_ZN1EppEv( +// CHECK: call void @_ZN1GD1Ev( +// CHECK: br label %[[COND]] + +// CHECK: [[END]]: +// In desugared version: +// call void @_ZN1DD1Ev( +// CHECK: call void @_ZN1AD1Ev( +// CHECK: ret void diff --git a/clang/test/CodeGenCXX/for-range.cpp b/clang/test/CodeGenCXX/for-range.cpp new file mode 100644 index 0000000..0f35dda7 --- /dev/null +++ b/clang/test/CodeGenCXX/for-range.cpp @@ -0,0 +1,128 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -std=c++11 -emit-llvm -o - %s | opt -instnamer -S | FileCheck %s + +struct A { + A(); + A(const A&); + ~A(); +}; + +struct B { + B(); + B(const B&); + ~B(); +}; + +struct C { + C(); + C(const C&); + ~C(); +}; + +struct D { + D(); + D(const D&); + ~D(); + + B *begin(); + B *end(); +}; + +namespace std { + B *begin(C&); + B *end(C&); +} + +extern B array[5]; + +// CHECK: define void @_Z9for_arrayv( +void for_array() { + // CHECK: call void @_ZN1AC1Ev(%struct.A* [[A:.*]]) + A a; + for (B b : array) { + // CHECK-NOT: 5begin + // CHECK-NOT: 3end + // CHECK: getelementptr {{.*}}, i32 0 + // CHECK: getelementptr {{.*}}, i64 5 + // CHECK: br label %[[COND:.*]] + + // CHECK: [[COND]]: + // CHECK: %[[CMP:.*]] = icmp ne + // CHECK: br i1 %[[CMP]], label %[[BODY:.*]], label %[[END:.*]] + + // CHECK: [[BODY]]: + // CHECK: call void @_ZN1BC1ERKS_( + // CHECK: call void @_ZN1BD1Ev( + // CHECK: br label %[[INC:.*]] + + // CHECK: [[INC]]: + // CHECK: getelementptr {{.*}} i32 1 + // CHECK: br label %[[COND]] + } + // CHECK: [[END]]: + // CHECK: call void @_ZN1AD1Ev(%struct.A* [[A]]) + // CHECK: ret void +} + +// CHECK: define void @_Z9for_rangev( +void for_range() { + // CHECK: call void @_ZN1AC1Ev(%struct.A* [[A:.*]]) + A a; + for (B b : C()) { + // CHECK: call void @_ZN1CC1Ev( + // CHECK: = call %struct.B* @_ZSt5beginR1C( + // CHECK: = call %struct.B* @_ZSt3endR1C( + // CHECK: br label %[[COND:.*]] + + // CHECK: [[COND]]: + // CHECK: %[[CMP:.*]] = icmp ne + // CHECK: br i1 %[[CMP]], label %[[BODY:.*]], label %[[CLEANUP:.*]] + + // CHECK: [[CLEANUP]]: + // CHECK: call void @_ZN1CD1Ev( + // CHECK: br label %[[END:.*]] + + // CHECK: [[BODY]]: + // CHECK: call void @_ZN1BC1ERKS_( + // CHECK: call void @_ZN1BD1Ev( + // CHECK: br label %[[INC:.*]] + + // CHECK: [[INC]]: + // CHECK: getelementptr {{.*}} i32 1 + // CHECK: br label %[[COND]] + } + // CHECK: [[END]]: + // CHECK: call void @_ZN1AD1Ev(%struct.A* [[A]]) + // CHECK: ret void +} + +// CHECK: define void @_Z16for_member_rangev( +void for_member_range() { + // CHECK: call void @_ZN1AC1Ev(%struct.A* [[A:.*]]) + A a; + for (B b : D()) { + // CHECK: call void @_ZN1DC1Ev( + // CHECK: = call %struct.B* @_ZN1D5beginEv( + // CHECK: = call %struct.B* @_ZN1D3endEv( + // CHECK: br label %[[COND:.*]] + + // CHECK: [[COND]]: + // CHECK: %[[CMP:.*]] = icmp ne + // CHECK: br i1 %[[CMP]], label %[[BODY:.*]], label %[[CLEANUP:.*]] + + // CHECK: [[CLEANUP]]: + // CHECK: call void @_ZN1DD1Ev( + // CHECK: br label %[[END:.*]] + + // CHECK: [[BODY]]: + // CHECK: call void @_ZN1BC1ERKS_( + // CHECK: call void @_ZN1BD1Ev( + // CHECK: br label %[[INC:.*]] + + // CHECK: [[INC]]: + // CHECK: getelementptr {{.*}} i32 1 + // CHECK: br label %[[COND]] + } + // CHECK: [[END]]: + // CHECK: call void @_ZN1AD1Ev(%struct.A* [[A]]) + // CHECK: ret void +} diff --git a/clang/test/CodeGenCXX/forward-enum.cpp b/clang/test/CodeGenCXX/forward-enum.cpp new file mode 100644 index 0000000..c1169e0 --- /dev/null +++ b/clang/test/CodeGenCXX/forward-enum.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin11.0.0 -emit-llvm -o - %s | FileCheck %s + +enum MyEnum : char; +void bar(MyEnum value) { } + +// CHECK: define void @_Z3foo6MyEnum +void foo(MyEnum value) +{ + // CHECK: call void @_Z3bar6MyEnum(i8 signext + bar(value); +} diff --git a/clang/test/CodeGenCXX/fp16-mangle.cpp b/clang/test/CodeGenCXX/fp16-mangle.cpp new file mode 100644 index 0000000..4a056d6 --- /dev/null +++ b/clang/test/CodeGenCXX/fp16-mangle.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -emit-llvm -o - -triple arm-none-linux-gnueabi %s | FileCheck %s + +// CHECK: @_ZN1SIDhDhE1iE = global i32 3 +template struct S { static int i; }; +template <> int S<__fp16, __fp16>::i = 3; + +// CHECK: define void @_Z1fPDh(i16* %x) +void f (__fp16 *x) { } + +// CHECK: define void @_Z1gPDhS_(i16* %x, i16* %y) +void g (__fp16 *x, __fp16 *y) { } + diff --git a/clang/test/CodeGenCXX/fp16-overload.cpp b/clang/test/CodeGenCXX/fp16-overload.cpp new file mode 100644 index 0000000..7562210 --- /dev/null +++ b/clang/test/CodeGenCXX/fp16-overload.cpp @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -emit-llvm -o - -triple arm-none-linux-gnueabi %s | FileCheck %s + +extern int foo(float x); +extern int foo(double x); + +__fp16 a; + +// CHECK: call i32 @_Z3foof +// CHECK-NOT: call i32 @_Z3food +int bar (void) { return foo(a); } diff --git a/clang/test/CodeGenCXX/friend-redecl.cpp b/clang/test/CodeGenCXX/friend-redecl.cpp new file mode 100644 index 0000000..18292cd --- /dev/null +++ b/clang/test/CodeGenCXX/friend-redecl.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -triple i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s +// PR8864 + +struct Foo { + friend bool TryFoo(Foo *f2) { return TryFoo(0, f2); } + +// CHECK: define{{.*}}Z6TryFooP3Foo +// CHECK-NOT: ret +// CHECK: call{{.*}}Z6TryFooiP3Foo +// CHECK: ret + + friend bool TryFoo(int, Foo *f3); +}; +bool TryFoo(Foo *f5); +int main(void) { + Foo f; + TryFoo(&f); +} diff --git a/clang/test/CodeGenCXX/function-template-explicit-specialization.cpp b/clang/test/CodeGenCXX/function-template-explicit-specialization.cpp new file mode 100644 index 0000000..21f0127 --- /dev/null +++ b/clang/test/CodeGenCXX/function-template-explicit-specialization.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s + +template void a(T); +template<> void a(int) {} + +// CHECK: define void @_Z1aIiEvT_ + +namespace X { +template void b(T); +template<> void b(int) {} +} + +// CHECK: define void @_ZN1X1bIiEEvT_ diff --git a/clang/test/CodeGenCXX/function-template-specialization.cpp b/clang/test/CodeGenCXX/function-template-specialization.cpp new file mode 100644 index 0000000..4a79fb1 --- /dev/null +++ b/clang/test/CodeGenCXX/function-template-specialization.cpp @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s +template +T* next(T* ptr, const U& diff); + +template +T* next(T* ptr, const U& diff) { + return ptr + diff; +} + +void test(int *iptr, float *fptr, int diff) { + // CHECK: _Z4nextIiiEPT_S1_RKT0_ + iptr = next(iptr, diff); + + // CHECK: _Z4nextIfiEPT_S1_RKT0_ + fptr = next(fptr, diff); +} + +template +T* next(T* ptr, const U& diff); + +void test2(int *iptr, double *dptr, int diff) { + iptr = next(iptr, diff); + + // CHECK: _Z4nextIdiEPT_S1_RKT0_ + dptr = next(dptr, diff); +} diff --git a/clang/test/CodeGenCXX/global-array-destruction.cpp b/clang/test/CodeGenCXX/global-array-destruction.cpp new file mode 100644 index 0000000..5b5dfac --- /dev/null +++ b/clang/test/CodeGenCXX/global-array-destruction.cpp @@ -0,0 +1,34 @@ +// REQUIRES: x86-64-registered-target +// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -S %s -o %t-64.s +// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s + +extern "C" int printf(...); + +int count; + +struct S { + S() : iS(++count) { printf("S::S(%d)\n", iS); } + ~S() { printf("S::~S(%d)\n", iS); } + int iS; +}; + + +S arr[2][1]; +S s1; +S arr1[3]; +static S sarr[4]; + +int main () {} +S arr2[2]; +static S sarr1[4]; +S s2; +S arr3[3]; + +// CHECK-LP64: callq ___cxa_atexit +// CHECK-LP64: callq ___cxa_atexit +// CHECK-LP64: callq ___cxa_atexit +// CHECK-LP64: callq ___cxa_atexit +// CHECK-LP64: callq ___cxa_atexit +// CHECK-LP64: callq ___cxa_atexit +// CHECK-LP64: callq ___cxa_atexit +// CHECK-LP64: callq ___cxa_atexit diff --git a/clang/test/CodeGenCXX/global-dtor-no-atexit.cpp b/clang/test/CodeGenCXX/global-dtor-no-atexit.cpp new file mode 100644 index 0000000..def97b2 --- /dev/null +++ b/clang/test/CodeGenCXX/global-dtor-no-atexit.cpp @@ -0,0 +1,44 @@ +// RUN: %clang_cc1 -triple x86_64 %s -fno-use-cxa-atexit -emit-llvm -o - | FileCheck %s + +// PR7097 +// RUN: %clang_cc1 -triple x86_64 %s -fno-use-cxa-atexit -mconstructor-aliases -emit-llvm -o - | FileCheck %s + +// CHECK: call void @_ZN1AC1Ev([[A:%.*]]* @a) +// CHECK-NEXT: call i32 @atexit(void ()* @__dtor_a) +// CHECK: define internal void @__dtor_a() nounwind +// CHECK: call void @_ZN1AD1Ev([[A]]* @a) + +// CHECK: call void @_ZN1AC1Ev([[A]]* @b) +// CHECK-NEXT: call i32 @atexit(void ()* @__dtor_b) +// CHECK: define internal void @__dtor_b() nounwind +// CHECK: call void @_ZN1AD1Ev([[A]]* @b) + +class A { +public: + A(); + ~A(); +}; + +A a, b; + +// PR9593 +// CHECK: define void @_Z4funcv() +// CHECK: call i32 @__cxa_guard_acquire(i64* @_ZGVZ4funcvE2a1) +// CHECK: call void @_ZN1AC1Ev([[A]]* @_ZZ4funcvE2a1) +// CHECK-NEXT: call i32 @atexit(void ()* @__dtor__ZZ4funcvE2a1) +// CHECK-NEXT: call void @__cxa_guard_release(i64* @_ZGVZ4funcvE2a1) + +// CHECK: call i32 @__cxa_guard_acquire(i64* @_ZGVZ4funcvE2a2) +// CHECK: call void @_ZN1AC1Ev([[A]]* @_ZZ4funcvE2a2) +// CHECK-NEXT: call i32 @atexit(void ()* @__dtor__ZZ4funcvE2a2) +// CHECK-NEXT: call void @__cxa_guard_release(i64* @_ZGVZ4funcvE2a2) + +// CHECK: define internal void @__dtor__ZZ4funcvE2a1() nounwind +// CHECK: call void @_ZN1AD1Ev([[A]]* @_ZZ4funcvE2a1) + +// CHECK: define internal void @__dtor__ZZ4funcvE2a2() nounwind +// CHECK: call void @_ZN1AD1Ev([[A]]* @_ZZ4funcvE2a2) + +void func() { + static A a1, a2; +} diff --git a/clang/test/CodeGenCXX/global-init-darwin.cpp b/clang/test/CodeGenCXX/global-init-darwin.cpp new file mode 100644 index 0000000..20c13c6 --- /dev/null +++ b/clang/test/CodeGenCXX/global-init-darwin.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -triple=x86_64-apple-darwin10 -emit-llvm %s -o - |FileCheck %s + +struct A { + A(); + ~A(); +}; + +A a; +A as[2]; + +struct B { + B(); + ~B(); + int f(); +}; + +int i = B().f(); + +// CHECK: "__TEXT,__StaticInit,regular,pure_instructions" { +// CHECK: "__TEXT,__StaticInit,regular,pure_instructions" { +// CHECK: "__TEXT,__StaticInit,regular,pure_instructions" { +// CHECK: "__TEXT,__StaticInit,regular,pure_instructions" { +// CHECK: "__TEXT,__StaticInit,regular,pure_instructions" { diff --git a/clang/test/CodeGenCXX/global-init.cpp b/clang/test/CodeGenCXX/global-init.cpp new file mode 100644 index 0000000..8e6ef77 --- /dev/null +++ b/clang/test/CodeGenCXX/global-init.cpp @@ -0,0 +1,122 @@ +// RUN: %clang_cc1 -triple=x86_64-apple-darwin10 -emit-llvm -fexceptions %s -o - |FileCheck %s +// RUN: %clang_cc1 -triple=x86_64-apple-darwin10 -emit-llvm %s -o - |FileCheck -check-prefix NOEXC %s + +struct A { + A(); + ~A(); +}; + +struct B { B(); ~B(); }; + +struct C { void *field; }; + +struct D { ~D(); }; + +// CHECK: @__dso_handle = external unnamed_addr global i8 +// CHECK: @c = global %struct.C zeroinitializer, align 8 + +// It's okay if we ever implement the IR-generation optimization to remove this. +// CHECK: @_ZN5test3L3varE = internal constant i8* getelementptr inbounds ([7 x i8]* + +// PR6205: The casts should not require global initializers +// CHECK: @_ZN6PR59741cE = external global %"struct.PR5974::C" +// CHECK: @_ZN6PR59741aE = global %"struct.PR5974::A"* getelementptr inbounds (%"struct.PR5974::C"* @_ZN6PR59741cE, i32 0, i32 0) +// CHECK: @_ZN6PR59741bE = global %"struct.PR5974::B"* bitcast (i8* getelementptr (i8* bitcast (%"struct.PR5974::C"* @_ZN6PR59741cE to i8*), i64 4) to %"struct.PR5974::B"*), align 8 + +// CHECK: call void @_ZN1AC1Ev(%struct.A* @a) +// CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.A*)* @_ZN1AD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.A* @a, i32 0, i32 0), i8* @__dso_handle) +A a; + +// CHECK: call void @_ZN1BC1Ev(%struct.B* @b) +// CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.B*)* @_ZN1BD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.B* @b, i32 0, i32 0), i8* @__dso_handle) +B b; + +// PR6205: this should not require a global initializer +// CHECK-NOT: call void @_ZN1CC1Ev(%struct.C* @c) +C c; + +// CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.D*)* @_ZN1DD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.D* @d, i32 0, i32 0), i8* @__dso_handle) +D d; + +// +namespace test1 { + int f(); + const int x = f(); // This has side-effects and gets emitted immediately. + const int y = x - 1; // This gets deferred. + const int z = ~y; // This also gets deferred, but gets "undeferred" before y. + int test() { return z; } +// CHECK: define i32 @_ZN5test14testEv() + + // All of these initializers end up delayed, so we check them later. +} + +// +namespace test2 { + struct allocator { allocator(); ~allocator(); }; + struct A { A(const allocator &a = allocator()); ~A(); }; + + A a; +// CHECK: call void @_ZN5test29allocatorC1Ev( +// CHECK: invoke void @_ZN5test21AC1ERKNS_9allocatorE( +// CHECK: call void @_ZN5test29allocatorD1Ev( +// CHECK: call i32 @__cxa_atexit({{.*}} @_ZN5test21AD1Ev {{.*}} @_ZN5test21aE +} + +namespace test3 { + // Tested at the beginning of the file. + const char * const var = "string"; + extern const char * const var; + + const char *test() { return var; } +} + +namespace test6 { + struct A { + A(); + }; + extern int foo(); + + // This needs an initialization function and guard variables. + // CHECK: load i8* bitcast (i64* @_ZGVN5test61xE + // CHECK: [[CALL:%.*]] = call i32 @_ZN5test63fooEv + // CHECK-NEXT: store i32 [[CALL]], i32* @_ZN5test61xE + // CHECK-NEXT: store i64 1, i64* @_ZGVN5test61xE + __attribute__((weak)) int x = foo(); +} + +namespace PR5974 { + struct A { int a; }; + struct B { int b; }; + struct C : A, B { int c; }; + + extern C c; + + // These should not require global initializers. + A* a = &c; + B* b = &c; +} +// CHECK: define internal void [[TEST1_Z_INIT:@.*]]() +// CHECK: load i32* @_ZN5test1L1yE +// CHECK-NEXT: xor +// CHECK-NEXT: store i32 {{.*}}, i32* @_ZN5test1L1zE +// CHECK: define internal void [[TEST1_Y_INIT:@.*]]() +// CHECK: load i32* @_ZN5test1L1xE +// CHECK-NEXT: sub +// CHECK-NEXT: store i32 {{.*}}, i32* @_ZN5test1L1yE + +// PR9570: the indirect field shouldn't crash IR gen. +namespace test5 { + static union { + unsigned bar[4096] __attribute__((aligned(128))); + }; +} + + +// At the end of the file, we check that y is initialized before z. + +// CHECK: define internal void @_GLOBAL__I_a() section "__TEXT,__StaticInit,regular,pure_instructions" { +// CHECK: call void [[TEST1_Y_INIT]] +// CHECK: call void [[TEST1_Z_INIT]] + +// rdar://problem/8090834: this should be nounwind +// CHECK-NOEXC: define internal void @_GLOBAL__I_a() nounwind section "__TEXT,__StaticInit,regular,pure_instructions" { diff --git a/clang/test/CodeGenCXX/global-llvm-constant.cpp b/clang/test/CodeGenCXX/global-llvm-constant.cpp new file mode 100644 index 0000000..2bd43b9 --- /dev/null +++ b/clang/test/CodeGenCXX/global-llvm-constant.cpp @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s + +struct A { + A() { x = 10; } + int x; +}; + +const A x; + +// CHECK: @_ZL1x = internal global + +struct X { + int (*fp)(int, int); +}; + +int add(int x, int y) { return x + y; } + +// CHECK: @x2 = constant +extern const X x2; +const X x2 = { &add }; + +struct X1 { + mutable int i; +}; + +struct X2 { + X1 array[3]; +}; + +// CHECK: @x2b = global +extern const X2 x2b; +const X2 x2b = { { { 1 }, { 2 }, { 3 } } }; diff --git a/clang/test/CodeGenCXX/goto.cpp b/clang/test/CodeGenCXX/goto.cpp new file mode 100644 index 0000000..77b6166 --- /dev/null +++ b/clang/test/CodeGenCXX/goto.cpp @@ -0,0 +1,43 @@ +// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -fcxx-exceptions -fexceptions -emit-llvm -o - | FileCheck %s + +// Reduced from a crash on boost::interprocess's node_allocator_test.cpp. +namespace test0 { + struct A { A(); ~A(); }; + struct V { V(const A &a = A()); ~V(); }; + + // CHECK: define linkonce_odr i32 @_ZN5test04testILi0EEEii + template int test(int x) { + // CHECK: [[RET:%.*]] = alloca i32 + // CHECK-NEXT: [[X:%.*]] = alloca i32 + // CHECK-NEXT: [[Y:%.*]] = alloca [[A:%.*]], + // CHECK-NEXT: [[Z:%.*]] = alloca [[A]] + // CHECK-NEXT: [[EXN:%.*]] = alloca i8* + // CHECK-NEXT: [[SEL:%.*]] = alloca i32 + // CHECK-NEXT: [[V:%.*]] = alloca [[V:%.*]]*, + // CHECK-NEXT: [[TMP:%.*]] = alloca [[A]] + // CHECK-NEXT: [[CLEANUPACTIVE:%.*]] = alloca i1 + // CHECK: call void @_ZN5test01AC1Ev([[A]]* [[Y]]) + // CHECK-NEXT: invoke void @_ZN5test01AC1Ev([[A]]* [[Z]]) + // CHECK: [[NEW:%.*]] = invoke noalias i8* @_Znwm(i64 1) + // CHECK: store i1 true, i1* [[CLEANUPACTIVE]] + // CHECK: [[NEWCAST:%.*]] = bitcast i8* [[NEW]] to [[V]]* + // CHECK-NEXT: invoke void @_ZN5test01AC1Ev([[A]]* [[TMP]]) + // CHECK: invoke void @_ZN5test01VC1ERKNS_1AE([[V]]* [[NEWCAST]], [[A]]* [[TMP]]) + // CHECK: store i1 false, i1* [[CLEANUPACTIVE]] + // CHECK-NEXT: invoke void @_ZN5test01AD1Ev([[A]]* [[TMP]]) + A y; + try { + A z; + V *v = new V(); + + if (x) return 1; + } catch (int ex) { + return 1; + } + return 0; + } + + int test() { + return test<0>(5); + } +} diff --git a/clang/test/CodeGenCXX/implicit-copy-assign-operator.cpp b/clang/test/CodeGenCXX/implicit-copy-assign-operator.cpp new file mode 100644 index 0000000..0ec89fc --- /dev/null +++ b/clang/test/CodeGenCXX/implicit-copy-assign-operator.cpp @@ -0,0 +1,56 @@ +// RUN: %clang_cc1 -emit-llvm -triple x86_64-apple-darwin10.0.0 -o - %s | FileCheck %s +struct A { + A &operator=(const A&); + A &operator=(A&); +}; + +struct B { + B &operator=(B&); +}; + +struct C { + virtual C& operator=(const C&); +}; + +struct POD { + int array[3][4]; +}; + +struct CopyByValue { + CopyByValue(const CopyByValue&); + CopyByValue &operator=(CopyByValue); +}; + +struct D : A, B, virtual C { + int scalar; + int scalar_array[2][3]; + B class_member; + C class_member_array[2][3]; + POD pod_array[2][3]; + + union { + int x; + float f[3]; + }; + + CopyByValue by_value; +}; + +void test_D(D d1, D d2) { + d1 = d2; +} + +// CHECK: define linkonce_odr %struct.D* @_ZN1DaSERS_ +// CHECK: {{call.*_ZN1AaSERS_}} +// CHECK: {{call.*_ZN1BaSERS_}} +// CHECK: {{call.*_ZN1CaSERKS_}} +// CHECK: {{call void @llvm.memcpy.p0i8.p0i8.i64.*i64 24}} +// CHECK: {{call.*_ZN1BaSERS_}} +// CHECK: br +// CHECK: {{call.*_ZN1CaSERKS_}} +// CHECK: {{call void @llvm.memcpy.p0i8.p0i8.i64.*i64 288}} +// CHECK: {{call void @llvm.memcpy.p0i8.p0i8.i64.*i64 12}} +// CHECK: call void @_ZN11CopyByValueC1ERKS_ +// CHECK: {{call.*_ZN11CopyByValueaSES_}} +// CHECK: ret + diff --git a/clang/test/CodeGenCXX/implicit-copy-constructor.cpp b/clang/test/CodeGenCXX/implicit-copy-constructor.cpp new file mode 100644 index 0000000..8bc84a5 --- /dev/null +++ b/clang/test/CodeGenCXX/implicit-copy-constructor.cpp @@ -0,0 +1,82 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s + +struct A { + A(); + A(const A&); + A(A&); + ~A(); +}; + +struct B { + B(); + B(B&); +}; + +struct C { + C() {} + C(C& other, A a = A()); + int i, j; +}; + +struct POD { + int array[3][4]; +}; + +struct D : A, B, virtual C { + D(); + int scalar; + int scalar_array[2][3]; + B class_member; + C class_member_array[2][3]; + POD pod_array[2][3]; + + union { + int x; + float f[3]; + }; +}; + +void f(D d) { + D d2(d); +} + +// CHECK: define linkonce_odr void @_ZN1DC1ERS_(%struct.D* %this, %struct.D*) unnamed_addr +// CHECK: call void @_ZN1AC1Ev +// CHECK: call void @_ZN1CC2ERS_1A +// CHECK: call void @_ZN1AD1Ev +// CHECK: call void @_ZN1AC2ERS_ +// CHECK: call void @_ZN1BC2ERS_ +// CHECK: {{call void @llvm.memcpy.p0i8.p0i8.i64.*i64 24}} +// CHECK: call void @_ZN1BC1ERS_ +// CHECK: br +// CHECK: {{icmp ult.*, 2}} +// CHECK: {{icmp ult.*, 3}} +// CHECK: call void @_ZN1AC1Ev +// CHECK: call void @_ZN1CC1ERS_1A +// CHECK: call void @_ZN1AD1Ev +// CHECK: {{call void @llvm.memcpy.p0i8.p0i8.i64.*i64 288}} +// CHECK: {{call void @llvm.memcpy.p0i8.p0i8.i64.*i64 12}} +// CHECK: ret void + + +template struct X0 { void f0(T * ) { } }; +template struct X1 { X1( X1& , int = 0 ) { } }; +struct X2 { X1 result; }; +void test_X2() +{ + typedef X2 impl; + typedef X0 pimpl; + impl* i; + pimpl pdata; + pdata.f0( new impl(*i)); +} + +// rdar://problem/9598341 +namespace test3 { + struct A { A(const A&); A&operator=(const A&); }; + struct B { A a; unsigned : 0; }; + void test(const B &x) { + B y = x; + y = x; + } +} diff --git a/clang/test/CodeGenCXX/implicit-instantiation-1.cpp b/clang/test/CodeGenCXX/implicit-instantiation-1.cpp new file mode 100644 index 0000000..0c826e4 --- /dev/null +++ b/clang/test/CodeGenCXX/implicit-instantiation-1.cpp @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -emit-llvm %s -o %t + +template +struct X { + void f(T) { } + void f(char) { } + + void g(T) { } + + void h(T) { } +}; + +void foo(X &xi, X *xfp, int i, float f) { + // RUN: grep "linkonce_odr.*_ZN1XIiE1fEi" %t | count 1 + xi.f(i); + + // RUN: grep "linkonce_odr.*_ZN1XIiE1gEi" %t | count 1 + xi.g(f); + + // RUN: grep "linkonce_odr.*_ZN1XIfE1fEf" %t | count 1 + xfp->f(f); + + // RUN: grep "linkonce_odr.*_ZN1XIfE1hEf" %t | count 0 + +} + + + diff --git a/clang/test/CodeGenCXX/incomplete-member-function-pointer.cpp b/clang/test/CodeGenCXX/incomplete-member-function-pointer.cpp new file mode 100644 index 0000000..b97e44c --- /dev/null +++ b/clang/test/CodeGenCXX/incomplete-member-function-pointer.cpp @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 %s -emit-llvm-only +// PR7040 +struct fake_tuple; +struct connection { + void bar(fake_tuple); +}; +void (connection::*a)(fake_tuple) = &connection::bar; +void f() { + void (connection::*b)(fake_tuple) = &connection::bar; +} diff --git a/clang/test/CodeGenCXX/incomplete-types.cpp b/clang/test/CodeGenCXX/incomplete-types.cpp new file mode 100644 index 0000000..1d4f430 --- /dev/null +++ b/clang/test/CodeGenCXX/incomplete-types.cpp @@ -0,0 +1,43 @@ +// RUN: %clang_cc1 %s -emit-llvm-only -verify +// PR5489 + +template +struct Bar { + int x_; +}; + +static struct Bar bar[1] = { + { 0 } +}; + + + +namespace incomplete_type_refs { + struct A; + extern A g[]; + void foo(A*); + void f(void) { + foo(g); // Reference to array with unknown element type. + } + + struct A { // define the element type. + int a,b,c; + }; + + A *f2() { + return &g[1]; + } + +} + +namespace PR10395 { + struct T; + extern T x[]; + T* f() { return x; } +} + +namespace PR10384 { + struct X; + extern X x[1]; + X* f() { return x; } +} diff --git a/clang/test/CodeGenCXX/inheriting-constructor.cpp b/clang/test/CodeGenCXX/inheriting-constructor.cpp new file mode 100644 index 0000000..a998402 --- /dev/null +++ b/clang/test/CodeGenCXX/inheriting-constructor.cpp @@ -0,0 +1,11 @@ +// 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() {} +// CHECK: define void @_ZN1BD0Ev +// CHECK: define void @_ZN1BD1Ev +// CHECK: define void @_ZN1BD2Ev diff --git a/clang/test/CodeGenCXX/init-invariant.cpp b/clang/test/CodeGenCXX/init-invariant.cpp new file mode 100644 index 0000000..9eb1989 --- /dev/null +++ b/clang/test/CodeGenCXX/init-invariant.cpp @@ -0,0 +1,60 @@ +// RUN: %clang_cc1 -triple i686-linux-gnu -emit-llvm %s -O0 -o - | FileCheck %s --check-prefix=CHECK-O0 +// RUN: %clang_cc1 -triple i686-linux-gnu -emit-llvm %s -O1 -o - | FileCheck %s + +// Check that we add an llvm.invariant.start to mark when a global becomes +// read-only. If globalopt can fold the initializer, it will then mark the +// variable as constant. + +// Do not produce markers at -O0. +// CHECK-O0-NOT: llvm.invariant.start + +struct A { + A(); + int n; +}; + +// CHECK: @a = global {{.*}} zeroinitializer +extern const A a = A(); + +struct B { + B(); + mutable int n; +}; + +// CHECK: @b = global {{.*}} zeroinitializer +extern const B b = B(); + +struct C { + C(); + ~C(); + int n; +}; + +// CHECK: @c = global {{.*}} zeroinitializer +extern const C c = C(); + +int f(); +// CHECK: @d = global i32 0 +extern const int d = f(); + +void e() { + static const A a = A(); +} + +// CHECK: call void @_ZN1AC1Ev({{.*}}* @a) +// CHECK: call {{.*}}@llvm.invariant.start(i64 4, i8* bitcast ({{.*}} @a to i8*)) + +// CHECK: call void @_ZN1BC1Ev({{.*}}* @b) +// CHECK-NOT: call {{.*}}@llvm.invariant.start(i64 4, i8* bitcast ({{.*}} @b to i8*)) + +// CHECK: call void @_ZN1CC1Ev({{.*}}* @c) +// CHECK-NOT: call {{.*}}@llvm.invariant.start(i64 4, i8* bitcast ({{.*}} @c to i8*)) + +// CHECK: call i32 @_Z1fv( +// CHECK: store {{.*}}, i32* @d +// CHECK: call {{.*}}@llvm.invariant.start(i64 4, i8* bitcast ({{.*}} @d to i8*)) + +// CHECK: define void @_Z1ev( +// CHECK: call void @_ZN1AC1Ev(%struct.A* @_ZZ1evE1a) +// CHECK: call {{.*}}@llvm.invariant.start(i64 4, i8* bitcast ({{.*}} @_ZZ1evE1a to i8*)) +// CHECK-NOT: llvm.invariant.end diff --git a/clang/test/CodeGenCXX/inline-functions.cpp b/clang/test/CodeGenCXX/inline-functions.cpp new file mode 100644 index 0000000..69dfe0d --- /dev/null +++ b/clang/test/CodeGenCXX/inline-functions.cpp @@ -0,0 +1,55 @@ +// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s +// CHECK: ; ModuleID + +struct A { + inline void f(); +}; + +// CHECK-NOT: define void @_ZN1A1fEv +void A::f() { } + +template struct B { }; + +template<> struct B { + inline void f(); +}; + +// CHECK-NOT: _ZN1BIcE1fEv +void B::f() { } + +// We need a final CHECK line here. + +// CHECK: define void @_Z1fv +void f() { } + +// +inline void f1(int); + +// CHECK: define linkonce_odr void @_Z2f1i +void f1(int) { } + +void test_f1() { f1(17); } + +// PR8789 +namespace test1 { + template class ClassTemplate { + private: + friend void T::func(); + void g() {} + }; + + // CHECK: define linkonce_odr void @_ZN5test11C4funcEv( + + class C { + public: + void func() { + ClassTemplate ct; + ct.g(); + } + }; + + void f() { + C c; + c.func(); + } +} diff --git a/clang/test/CodeGenCXX/instantiate-blocks.cpp b/clang/test/CodeGenCXX/instantiate-blocks.cpp new file mode 100644 index 0000000..e206582 --- /dev/null +++ b/clang/test/CodeGenCXX/instantiate-blocks.cpp @@ -0,0 +1,59 @@ +// RUN: %clang_cc1 -fblocks -emit-llvm -o - %s +// rdar : // 6182276 + +template T foo(T t) +{ + void (^block)(int); + return 1; +} + +int test1(void) +{ + int i = 1; + int b = 2; + i = foo(b); + return 0; +} + +template void foo(T t, T1 r) +{ + T block_arg; + __block T1 byref_block_arg; + + T1 (^block)(char, T, T1, double) = + ^ T1 (char ch, T arg, T1 arg2, double d1) { byref_block_arg = arg2; + return byref_block_arg + block_arg + arg; }; + + void (^block2)() = ^{}; +} + +void test2(void) +{ + foo(100, 'a'); +} + +namespace rdar6182276 { +extern "C" { +int printf(const char *, ...); +} + +template T foo(T t) +{ + void (^testing)(int) = ^(int bar) { printf("bar is %d\n", bar); }; + printf("bar is\n"); + return 1; +} + +template void gorf(T t) +{ + foo(t); +} + + +void test(void) +{ + gorf(2); +} +} + + diff --git a/clang/test/CodeGenCXX/instantiate-init-list.cpp b/clang/test/CodeGenCXX/instantiate-init-list.cpp new file mode 100644 index 0000000..49c6f51 --- /dev/null +++ b/clang/test/CodeGenCXX/instantiate-init-list.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 %s -emit-llvm-only -verify + +struct F { + void (*x)(); +}; +void G(); +template class A { +public: A(); +}; +template A::A() { + static F f = { G }; +} +A a; diff --git a/clang/test/CodeGenCXX/instantiate-temporaries.cpp b/clang/test/CodeGenCXX/instantiate-temporaries.cpp new file mode 100644 index 0000000..29cfc07 --- /dev/null +++ b/clang/test/CodeGenCXX/instantiate-temporaries.cpp @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -triple x86_64-apple-macosx10.7.0 -emit-llvm -o - %s | FileCheck %s + +struct X { + X(); + ~X(); +}; + +struct Y { + X get(); +}; + +struct X2 { + X x; +}; + +template +void call() { + Y().get(); +} + +// CHECK: define weak_odr void @_Z4callIiEvv +// CHECK: call void @_ZN1Y3getEv +// CHECK-NEXT: call void @_ZN1XD1Ev +// CHECK-NEXT: ret void +template void call(); + +template +void compound_literal() { + (X2){}; +} + +// CHECK: define weak_odr void @_Z16compound_literalIiEvv +// CHECK: call void @_ZN1XC1Ev +// CHECK-NEXT: call void @_ZN2X2D1Ev +// CHECK-NEXT: ret void +template void compound_literal(); + diff --git a/clang/test/CodeGenCXX/instrument-functions.cpp b/clang/test/CodeGenCXX/instrument-functions.cpp new file mode 100644 index 0000000..253e096 --- /dev/null +++ b/clang/test/CodeGenCXX/instrument-functions.cpp @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -S -emit-llvm -o - %s -finstrument-functions | FileCheck %s + +// CHECK: @_Z5test1i +int test1(int x) { +// CHECK: __cyg_profile_func_enter +// CHECK: __cyg_profile_func_exit +// CHECK: ret + return x; +} + +// CHECK: @_Z5test2i +int test2(int) __attribute__((no_instrument_function)); +int test2(int x) { +// CHECK-NOT: __cyg_profile_func_enter +// CHECK-NOT: __cyg_profile_func_exit +// CHECK: ret + return x; +} + +// This test case previously crashed code generation. It exists solely +// to test -finstrument-function does not crash codegen for this trivial +// case. +namespace rdar9445102 { + class Rdar9445102 { + public: + Rdar9445102(); + }; +} +static rdar9445102::Rdar9445102 s_rdar9445102Initializer; + diff --git a/clang/test/CodeGenCXX/internal-linkage.cpp b/clang/test/CodeGenCXX/internal-linkage.cpp new file mode 100644 index 0000000..56cb810 --- /dev/null +++ b/clang/test/CodeGenCXX/internal-linkage.cpp @@ -0,0 +1,64 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s + +struct Global { Global(); }; +template struct X { X() {} }; + + +namespace { + struct Anon { Anon() {} }; + + // CHECK: @_ZN12_GLOBAL__N_15anon0E = internal global + Global anon0; +} + +// CHECK: @anon1 = internal global +Anon anon1; + +// CHECK: @anon2 = internal global +X anon2; + +// rdar: // 8071804 +char const * const xyzzy = "Hello, world!"; +extern char const * const xyzzy; + +char const * const *test1() +{ + // CHECK: @_ZL5xyzzy = internal constant + return &xyzzy; +} + +static char const * const static_xyzzy = "Hello, world!"; +extern char const * const static_xyzzy; + +char const * const *test2() +{ + // CHECK: @_ZL12static_xyzzy = internal constant + return &static_xyzzy; +} + +static char const * static_nonconst_xyzzy = "Hello, world!"; +extern char const * static_nonconst_xyzzy; + +char const * *test3() +{ + // CHECK: @_ZL21static_nonconst_xyzzy = internal global + return &static_nonconst_xyzzy; +} + + +char const * extern_nonconst_xyzzy = "Hello, world!"; +extern char const * extern_nonconst_xyzzy; + +char const * *test4() +{ + // CHECK: @extern_nonconst_xyzzy = global + return &extern_nonconst_xyzzy; +} + +// PR10120 +template class klass { + virtual void f(); +}; +namespace { struct S; } +void foo () { klass x; } +// CHECK: @_ZTV5klassIN12_GLOBAL__N_11SEE = internal unnamed_addr constant diff --git a/clang/test/CodeGenCXX/key-function-vtable.cpp b/clang/test/CodeGenCXX/key-function-vtable.cpp new file mode 100644 index 0000000..8e474bd --- /dev/null +++ b/clang/test/CodeGenCXX/key-function-vtable.cpp @@ -0,0 +1,52 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s + +// Simple key function test +struct testa { virtual void a(); }; +void testa::a() {} + +// Simple key function test +struct testb { virtual void a() {} }; +testb *testbvar = new testb; + +// Key function with out-of-line inline definition +struct testc { virtual void a(); }; +inline void testc::a() {} + +// Functions with inline specifier are not key functions (PR5705) +struct testd { inline virtual void a(); }; +void testd::a() {} + +// Functions with inline specifier are not key functions (PR5705) +struct teste { inline virtual void a(); }; +teste *testevar = new teste; + +// Key functions with namespace (PR5711) +namespace { + struct testf { virtual void a(); }; +} +void testf::a() {} + +// Key functions with namespace (PR5711) +namespace { + struct testg { virtual void a(); }; +} +void testg::a() {} +testg *testgvar = new testg; + +struct X0 { virtual ~X0(); }; +struct X1 : X0 { + virtual void f(); +}; + +inline void X1::f() { } + +void use_X1(X1 *x1) { x1->f(); } + +// FIXME: The checks are extremely difficult to get right when the globals +// aren't alphabetized +// CHECK: @_ZTV2X1 = linkonce_odr unnamed_addr constant +// CHECK: @_ZTV5testa = unnamed_addr constant [3 x i8*] [i8* null +// CHECK: @_ZTV5testc = linkonce_odr unnamed_addr constant [3 x i8*] [i8* null +// CHECK: @_ZTVN12_GLOBAL__N_15testgE = internal unnamed_addr constant [3 x i8*] [i8* null +// CHECK: @_ZTV5teste = linkonce_odr unnamed_addr constant [3 x i8*] [i8* null +// CHECK: @_ZTV5testb = linkonce_odr unnamed_addr constant [3 x i8*] [i8* null diff --git a/clang/test/CodeGenCXX/lambda-expressions.cpp b/clang/test/CodeGenCXX/lambda-expressions.cpp new file mode 100644 index 0000000..797cbf4 --- /dev/null +++ b/clang/test/CodeGenCXX/lambda-expressions.cpp @@ -0,0 +1,78 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -emit-llvm -o - %s -fexceptions -std=c++11 | FileCheck %s + +// CHECK: @var = internal global +auto var = [](int i) { return i+1; }; + +// CHECK: @cvar = global +extern "C" auto cvar = []{}; + +int a() { return []{ return 1; }(); } +// CHECK: define i32 @_Z1av +// CHECK: call i32 @"_ZZ1avENK3$_0clEv" +// CHECK: define internal i32 @"_ZZ1avENK3$_0clEv" +// CHECK: ret i32 1 + +int b(int x) { return [x]{return x;}(); } +// CHECK: define i32 @_Z1bi +// CHECK: store i32 +// CHECK: load i32* +// CHECK: store i32 +// CHECK: call i32 @"_ZZ1biENK3$_1clEv" +// CHECK: define internal i32 @"_ZZ1biENK3$_1clEv" +// CHECK: load i32* +// CHECK: ret i32 + +int c(int x) { return [&x]{return x;}(); } +// CHECK: define i32 @_Z1ci +// CHECK: store i32 +// CHECK: store i32* +// CHECK: call i32 @"_ZZ1ciENK3$_2clEv" +// CHECK: define internal i32 @"_ZZ1ciENK3$_2clEv" +// CHECK: load i32** +// CHECK: load i32* +// CHECK: ret i32 + +struct D { D(); D(const D&); int x; }; +int d(int x) { D y[10]; [x,y] { return y[x].x; }(); } + +// CHECK: define i32 @_Z1di +// CHECK: call void @_ZN1DC1Ev +// CHECK: icmp ult i64 %{{.*}}, 10 +// CHECK: call void @_ZN1DC1ERKS_ +// CHECK: call i32 @"_ZZ1diENK3$_3clEv" +// CHECK: define internal i32 @"_ZZ1diENK3$_3clEv" +// CHECK: load i32* +// CHECK: load i32* +// CHECK: ret i32 + +struct E { E(); E(const E&); ~E(); int x; }; +int e(E a, E b, bool cond) { [a,b,cond](){ return (cond ? a : b).x; }(); } +// CHECK: define i32 @_Z1e1ES_b +// CHECK: call void @_ZN1EC1ERKS_ +// CHECK: invoke void @_ZN1EC1ERKS_ +// CHECK: invoke i32 @"_ZZ1e1ES_bENK3$_4clEv" +// CHECK: call void @"_ZZ1e1ES_bEN3$_4D1Ev" +// CHECK: call void @"_ZZ1e1ES_bEN3$_4D1Ev" + +// CHECK: define internal i32 @"_ZZ1e1ES_bENK3$_4clEv" +// CHECK: trunc i8 +// CHECK: load i32* +// CHECK: ret i32 + +void f() { + // CHECK: define void @_Z1fv() + // CHECK: @"_ZZ1fvENK3$_5cvPFiiiEEv" + // CHECK-NEXT: store i32 (i32, i32)* + // CHECK-NEXT: ret void + int (*fp)(int, int) = [](int x, int y){ return x + y; }; +} + +// CHECK: define internal i32 @"_ZZ1fvEN3$_58__invokeEii" +// CHECK: store i32 +// CHECK-NEXT: store i32 +// CHECK-NEXT: load i32* +// CHECK-NEXT: load i32* +// CHECK-NEXT: call i32 @"_ZZ1fvENK3$_5clEii" +// CHECK-NEXT: ret i32 + +// CHECK: define internal void @"_ZZ1e1ES_bEN3$_4D2Ev" diff --git a/clang/test/CodeGenCXX/lvalue-bitcasts.cpp b/clang/test/CodeGenCXX/lvalue-bitcasts.cpp new file mode 100644 index 0000000..8c5fa4a --- /dev/null +++ b/clang/test/CodeGenCXX/lvalue-bitcasts.cpp @@ -0,0 +1,163 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -emit-llvm -o - %s | FileCheck %s + +struct X { int i; float f; }; +struct Y { X x; }; + +// CHECK: define void @_Z21reinterpret_cast_testRiRfR1X +void reinterpret_cast_test(int &ir, float &fr, X &xr) { + // CHECK: load float** + // CHECK: bitcast float* + // CHECK: load i32* + ir = reinterpret_cast(fr); + // CHECK: load + // CHECK: {{bitcast.*to i32\*}} + // CHECK: load i32* + ir = reinterpret_cast(xr); + // CHECK: load i32 + // CHECK: {{bitcast.*to float\*}} + // CHECK: load float* + fr = reinterpret_cast(ir); + // CHECK: load + // CHECK: {{bitcast.*to float\*}} + // CHECK: load float* + fr = reinterpret_cast(xr); + // CHECK: load i32** + // CHECK: bitcast i32* + // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64 + xr = reinterpret_cast(ir); + // CHECK: load float** + // CHECK: bitcast float* + // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64 + xr = reinterpret_cast(fr); + _Complex float cf; + _Complex float &cfr = cf; + // CHECK: load i32** + // CHECK: bitcast i32* + // CHECK: load float* + // CHECK: load float* + cfr = reinterpret_cast<_Complex float&>(ir); + // CHECK: load float** + // CHECK: bitcast float* + // CHECK: load float* + // CHECK: load float* + cfr = reinterpret_cast<_Complex float&>(fr); + // CHECK: bitcast + // CHECK: load float* + // CHECK: load float* + cfr = reinterpret_cast<_Complex float&>(xr); + // CHECK: ret void +} + +// CHECK: define void @_Z6c_castRiRfR1X +void c_cast(int &ir, float &fr, X &xr) { + // CHECK: load float** + // CHECK: bitcast float* + // CHECK: load i32* + ir = (int&)fr; + // CHECK: load + // CHECK: {{bitcast.*to i32\*}} + // CHECK: load i32* + ir = (int&)xr; + // CHECK: load i32 + // CHECK: {{bitcast.*to float\*}} + // CHECK: load float* + fr = (float&)ir; + // CHECK: load + // CHECK: {{bitcast.*to float\*}} + // CHECK: load float* + fr = (float&)xr; + // CHECK: load i32** + // CHECK: bitcast i32* + // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64 + xr = (X&)ir; + // CHECK: load float** + // CHECK: bitcast float* + // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64 + xr = (X&)fr; + _Complex float cf; + _Complex float &cfr = cf; + // CHECK: load i32** + // CHECK: bitcast i32* + // CHECK: load float* + // CHECK: load float* + cfr = (_Complex float&)ir; + // CHECK: load float** + // CHECK: bitcast float* + // CHECK: load float* + // CHECK: load float* + cfr = (_Complex float&)fr; + // CHECK: bitcast + // CHECK: load float* + // CHECK: load float* + cfr = (_Complex float&)xr; + // CHECK: ret void +} + +// CHECK: define void @_Z15functional_castRiRfR1X +void functional_cast(int &ir, float &fr, X &xr) { + typedef int &intref; + typedef float &floatref; + typedef X &Xref; + // CHECK: load float** + // CHECK: bitcast float* + // CHECK: load i32* + ir = intref(fr); + // CHECK: load + // CHECK: {{bitcast.*to i32\*}} + // CHECK: load i32* + ir = intref(xr); + // CHECK: load i32 + // CHECK: {{bitcast.*to float\*}} + // CHECK: load float* + fr = floatref(ir); + // CHECK: load + // CHECK: {{bitcast.*to float\*}} + // CHECK: load float* + fr = floatref(xr); + // CHECK: load i32** + // CHECK: bitcast i32* + // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64 + xr = Xref(ir); + // CHECK: load float** + // CHECK: bitcast float* + // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64 + xr = Xref(fr); + typedef _Complex float &complex_float_ref; + _Complex float cf; + _Complex float &cfr = cf; + // CHECK: load i32** + // CHECK: bitcast i32* + // CHECK: load float* + // CHECK: load float* + cfr = complex_float_ref(ir); + // CHECK: load float** + // CHECK: bitcast float* + // CHECK: load float* + // CHECK: load float* + cfr = complex_float_ref(fr); + // CHECK: bitcast + // CHECK: load float* + // CHECK: load float* + cfr = complex_float_ref(xr); + // CHECK: ret void +} + +namespace PR6437 { + struct in_addr {}; + void copy( const struct in_addr &new_addr ) { + int addr = (int&)new_addr; + } +} + +namespace PR7593 { + void foo(double &X, char *A) { + X = reinterpret_cast(A[4]); + } +} + +namespace PR7344 { + void serialize_annotatable_id( void*& id ) + { + unsigned long l_id = (unsigned long&)id; + } +} diff --git a/clang/test/CodeGenCXX/m64-ptr.cpp b/clang/test/CodeGenCXX/m64-ptr.cpp new file mode 100644 index 0000000..29916bf --- /dev/null +++ b/clang/test/CodeGenCXX/m64-ptr.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 %s -emit-llvm -triple x86_64-apple-darwin -o - | FileCheck %s + +// Make sure pointers are passed as pointers, not converted to int. +// The first load should be of type i8** in either 32 or 64 bit mode. +// This formerly happened on x86-64, 7375899. + +class StringRef { +public: + const char *Data; + long Len; +}; +void foo(StringRef X); +void bar(StringRef &A) { +// CHECK: @_Z3barR9StringRef +// CHECK: load i8** + foo(A); +// CHECK: ret void +} diff --git a/clang/test/CodeGenCXX/mangle-98.cpp b/clang/test/CodeGenCXX/mangle-98.cpp new file mode 100644 index 0000000..a9ab6ca --- /dev/null +++ b/clang/test/CodeGenCXX/mangle-98.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -std=c++98 | FileCheck %s + +template struct S3 {}; + +// CHECK: define void @_Z1f2S3ILb1EE +void f(S3) {} + +// CHECK: define void @_Z1f2S3ILb0EE +void f(S3) {} + +// CHECK: define void @_Z2f22S3ILb1EE +void f2(S3<100>) {} diff --git a/clang/test/CodeGenCXX/mangle-abi-examples.cpp b/clang/test/CodeGenCXX/mangle-abi-examples.cpp new file mode 100644 index 0000000..7124078 --- /dev/null +++ b/clang/test/CodeGenCXX/mangle-abi-examples.cpp @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s + +// CHECK: @_ZTVZ3foovEN1C1DE = +// CHECK: @_ZTVZN1A3fooEiE1B = +// CHECK: define {{.*}} @_ZZZ3foovEN1C3barEvEN1E3bazEv( + +// Itanium C++ ABI examples. +struct A { + void foo (int) { + struct B { virtual ~B() {} }; + B(); + } +}; +void foo () { + struct C { + struct D { virtual ~D() {} }; + void bar () { + struct E { + void baz() { } + }; + E().baz(); + } + }; + A().foo(0); + C::D(); + C().bar(); +} diff --git a/clang/test/CodeGenCXX/mangle-address-space.cpp b/clang/test/CodeGenCXX/mangle-address-space.cpp new file mode 100644 index 0000000..ff23c20 --- /dev/null +++ b/clang/test/CodeGenCXX/mangle-address-space.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s + +// CHECK: define void @_Z2f0Pc +void f0(char *p) { } +// CHECK: define void @_Z2f0PU3AS1c +void f0(char __attribute__((address_space(1))) *p) { } + +struct OpaqueType; +typedef OpaqueType __attribute__((address_space(100))) * OpaqueTypePtr; + +// CHECK: define void @_Z2f0PU5AS10010OpaqueType +void f0(OpaqueTypePtr) { } diff --git a/clang/test/CodeGenCXX/mangle-alias-template.cpp b/clang/test/CodeGenCXX/mangle-alias-template.cpp new file mode 100644 index 0000000..5ace0b0 --- /dev/null +++ b/clang/test/CodeGenCXX/mangle-alias-template.cpp @@ -0,0 +1,48 @@ +// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s + +template struct alloc {}; +template using Alloc = alloc; +template> struct vector {}; + +template using Vec = vector; + +template void f(Vec v); +template void g(T); + +template class F> void h(F); + +template struct S {}; +template using U = S; +template void h(U, Ts...); + +// CHECK: define void @_Z1zv( +void z() { + vector VI; + f(VI); + // CHECK: call void @_Z1fIiEv6vectorIT_5allocIS1_EE( + + Vec VD; + g(VD); + // CHECK: call void @_Z1gI6vectorId5allocIdEEEvT_( + + h(VI); + // CHECK: call void @_Z1hI3VecEvT_IiE( + + Alloc AC; + h(AC); + // CHECK: call void @_Z1hI5allocEvT_IiE( + + h(AC); + // CHECK: call void @_Z1hI5AllocEvT_IiE( + + Vec VC; + g>(VC); + // CHECK: call void @_Z1gI6vectorIc5allocIcEEEvT_( + + Vec> VVI; + g(VVI); + // CHECK: call void @_Z1gI6vectorIS0_Ii5allocIiEES1_IS3_EEEvT_( + + // CHECK: call void @_Z1hIJidEEv1UIDpT_ES2_ + h({}, 0, 0.0); +} diff --git a/clang/test/CodeGenCXX/mangle-exprs.cpp b/clang/test/CodeGenCXX/mangle-exprs.cpp new file mode 100644 index 0000000..30da4fb --- /dev/null +++ b/clang/test/CodeGenCXX/mangle-exprs.cpp @@ -0,0 +1,193 @@ +// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 | FileCheck %s + +namespace std { + typedef decltype(sizeof(int)) size_t; + + // libc++'s implementation + template + class initializer_list + { + const _E* __begin_; + size_t __size_; + + initializer_list(const _E* __b, size_t __s) + : __begin_(__b), + __size_(__s) + {} + + public: + typedef _E value_type; + typedef const _E& reference; + typedef const _E& const_reference; + typedef size_t size_type; + + typedef const _E* iterator; + typedef const _E* const_iterator; + + initializer_list() : __begin_(nullptr), __size_(0) {} + + size_t size() const {return __size_;} + const _E* begin() const {return __begin_;} + const _E* end() const {return __begin_ + __size_;} + }; +} + +template < bool condition, typename T = void > +struct enable_if { typedef T type; }; + +template< typename T > +struct enable_if< false, T > {}; + +// PR5876 +namespace Casts { + template< unsigned O > + void implicit(typename enable_if< O <= 4 >::type* = 0) { + } + + template< unsigned O > + void cstyle(typename enable_if< O <= (unsigned)4 >::type* = 0) { + } + + template< unsigned O > + void functional(typename enable_if< O <= unsigned(4) >::type* = 0) { + } + + template< unsigned O > + void static_(typename enable_if< O <= static_cast(4) >::type* = 0) { + } + + template< typename T > + void auto_(decltype(new auto(T()))) { + } + + template< typename T > + void scalar_(decltype(T(), int())) { + } + + // FIXME: Test const_cast, reinterpret_cast, dynamic_cast, which are + // a bit harder to use in template arguments. + template struct T {}; + + template T f() { return T(); } + + // CHECK: define weak_odr void @_ZN5Casts8implicitILj4EEEvPN9enable_ifIXleT_Li4EEvE4typeE + template void implicit<4>(void*); + // CHECK: define weak_odr void @_ZN5Casts6cstyleILj4EEEvPN9enable_ifIXleT_cvjLi4EEvE4typeE + template void cstyle<4>(void*); + // CHECK: define weak_odr void @_ZN5Casts10functionalILj4EEEvPN9enable_ifIXleT_cvjLi4EEvE4typeE + template void functional<4>(void*); + // CHECK: define weak_odr void @_ZN5Casts7static_ILj4EEEvPN9enable_ifIXleT_cvjLi4EEvE4typeE + template void static_<4>(void*); + + // CHECK: define weak_odr void @_ZN5Casts1fILi6EEENS_1TIXT_EEEv + template T<6> f<6>(); + + // CHECK: define weak_odr void @_ZN5Casts5auto_IiEEvDTnw_DapicvT__EEE( + template void auto_(int*); + + // CHECK: define weak_odr void @_ZN5Casts7scalar_IiEEvDTcmcvT__Ecvi_EE( + template void scalar_(int); +} + +namespace test1 { + short foo(short); + int foo(int); + + // CHECK: define linkonce_odr signext i16 @_ZN5test11aIsEEDTcl3foocvT__EEES1_( + template auto a(T t) -> decltype(foo(T())) { return foo(t); } + + // CHECK: define linkonce_odr signext i16 @_ZN5test11bIsEEDTcp3foocvT__EEES1_( + template auto b(T t) -> decltype((foo)(T())) { return (foo)(t); } + + void test(short s) { + a(s); + b(s); + } +} + +namespace test2 { + template void a(T x, decltype(x()) y) {} + template auto b(T x) -> decltype(x()) { return x(); } + template void c(T x, void (*p)(decltype(x()))) {} + template void d(T x, auto (*p)() -> decltype(x())) {} + template void e(auto (*p)(T y) -> decltype(y())) {} + template void f(void (*p)(T x, decltype(x()) y)) {} + template void g(T x, decltype(x()) y) { + static decltype(x()) variable; + variable = 0; + } + template void h(T x, decltype((decltype(x())(*)()) 0) y) {} + template void i(decltype((auto (*)(T x) -> decltype(x())) 0) y) {} + + float foo(); + void bar(float); + float baz(float(*)()); + void fred(float(*)(), float); + + // CHECK: define void @_ZN5test211instantiateEv + void instantiate() { + // CHECK: call void @_ZN5test21aIPFfvEEEvT_DTclfL0p_EE( + a(foo, 0.0f); + // CHECK: call float @_ZN5test21bIPFfvEEEDTclfp_EET_( + (void) b(foo); + // CHECK: call void @_ZN5test21cIPFfvEEEvT_PFvDTclfL1p_EEE( + c(foo, bar); + // CHECK: call void @_ZN5test21dIPFfvEEEvT_PFDTclfL0p_EEvE( + d(foo, foo); + // CHECK: call void @_ZN5test21eIPFfvEEEvPFDTclfp_EET_E( + e(baz); + // CHECK: call void @_ZN5test21fIPFfvEEEvPFvT_DTclfL0p_EEE( + f(fred); + // CHECK: call void @_ZN5test21gIPFfvEEEvT_DTclfL0p_EE( + g(foo, 0.0f); + // CHECK: call void @_ZN5test21hIPFfvEEEvT_DTcvPFDTclfL0p_EEvELi0EE( + h(foo, foo); + // CHECK: call void @_ZN5test21iIPFfvEEEvDTcvPFDTclfp_EET_ELi0EE( + i(baz); + } + + // CHECK: store float {{.*}}, float* @_ZZN5test21gIPFfvEEEvT_DTclfL0p_EEE8variable, +} + +namespace test3 { + template void a(T x, U y, decltype(x.*y) z) {} + + struct X { + int *member; + }; + + // CHECK: define void @_ZN5test311instantiateEv + void instantiate() { + X x; + int *ip; + // CHECK: call void @_ZN5test31aINS_1XEMS1_PiEEvT_T0_DTdsfL0p_fL0p0_E + a(x, &X::member, ip); + } +} + +namespace test4 { + struct X { + X(int); + }; + + template + void tf1(decltype(new T(1)) p) + {} + + template + void tf2(decltype(new T({1})) p) + {} + + template + void tf3(decltype(new T{1}) p) + {} + + // CHECK: void @_ZN5test43tf1INS_1XEEEvDTnw_T_piLi1EEE + template void tf1(X*); + + // CHECK: void @_ZN5test43tf2INS_1XEEEvDTnw_T_piilLi1EEEE + template void tf2(X*); + + // CHECK: void @_ZN5test43tf3INS_1XEEEvDTnw_T_ilLi1EEE + template void tf3(X*); +} diff --git a/clang/test/CodeGenCXX/mangle-extern-local.cpp b/clang/test/CodeGenCXX/mangle-extern-local.cpp new file mode 100644 index 0000000..ed91da4 --- /dev/null +++ b/clang/test/CodeGenCXX/mangle-extern-local.cpp @@ -0,0 +1,45 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s + +// CHECK: @var1 = external global i32 +// CHECK: @_ZN1N4var2E = external global i32 +// CHECK: @var5 = external global i32 +// CHECK: @_ZN1N4var3E = external global i32 +// CHECK: @_ZN1N4var4E = external global i32 + +// CHECK: declare i32 @_Z5func1v() +// CHECK: declare i32 @_ZN1N5func2Ev() +// CHECK: declare i32 @func4() +// CHECK: declare i32 @_ZN1N5func3Ev() + +int f1() { + extern int var1, func1(); + return var1 + func1(); +} + +namespace N { + +int f2() { + extern int var2, func2(); + return var2 + func2(); +} + +struct S { + static int f3() { + extern int var3, func3(); + struct LC { int localfunc() { extern int var4; return var4; } }; + LC localobj; + return var3 + func3() + localobj.localfunc(); + } +}; + +int anchorf3() { return S::f3(); } + +extern "C" { +int f4() { + extern int var5, func4(); + return var5 + func4(); +} +} + +} + diff --git a/clang/test/CodeGenCXX/mangle-extreme.cpp b/clang/test/CodeGenCXX/mangle-extreme.cpp new file mode 100644 index 0000000..ef2d466 --- /dev/null +++ b/clang/test/CodeGenCXX/mangle-extreme.cpp @@ -0,0 +1,47 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 | FileCheck %s + +struct X { }; + +// CHECK: define void @_Z1fPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP1XS13_S12_S11_S10_SZ_SY_SX_SW_SV_SU_ST_SS_SR_SQ_SP_SO_SN_SM_SL_SK_SJ_SI_SH_SG_SF_SE_SD_SC_SB_SA_S9_S8_S7_S6_S5_S4_S3_S2_S1_S0_S_( +void f(X****************************************, + X****************************************, + X***************************************, + X**************************************, + X*************************************, + X************************************, + X***********************************, + X**********************************, + X*********************************, + X********************************, + X*******************************, + X******************************, + X*****************************, + X****************************, + X***************************, + X**************************, + X*************************, + X************************, + X***********************, + X**********************, + X*********************, + X********************, + X*******************, + X******************, + X*****************, + X****************, + X***************, + X**************, + X*************, + X************, + X***********, + X**********, + X*********, + X********, + X*******, + X******, + X*****, + X****, + X***, + X**, + X*, + X) { } diff --git a/clang/test/CodeGenCXX/mangle-lambdas.cpp b/clang/test/CodeGenCXX/mangle-lambdas.cpp new file mode 100644 index 0000000..cc53b01 --- /dev/null +++ b/clang/test/CodeGenCXX/mangle-lambdas.cpp @@ -0,0 +1,202 @@ +// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-macosx10.7.0 -emit-llvm -o - %s | FileCheck %s + +// CHECK: define linkonce_odr void @_Z11inline_funci +inline void inline_func(int n) { + // CHECK: call i32 @_ZZ11inline_funciENKUlvE_clEv + int i = []{ return 1; }(); + + // CHECK: call i32 @_ZZ11inline_funciENKUlvE0_clEv + int j = [=] { return n + i; }(); + + // CHECK: call double @_ZZ11inline_funciENKUlvE1_clEv + int k = [=] () -> double { return n + i; }(); + + // CHECK: call i32 @_ZZ11inline_funciENKUliE_clEi + int l = [=] (int x) -> int { return x + i; }(n); + + int inner(int i = []{ return 17; }()); + // CHECK: call i32 @_ZZ11inline_funciENKUlvE2_clEv + // CHECK-NEXT: call i32 @_Z5inneri + inner(); + + // CHECK-NEXT: ret void +} + +void call_inline_func() { + inline_func(17); +} + +struct S { + void f(int = []{return 1;}() + + []{return 2;}(), + int = []{return 3;}()); + void g(int, int); +}; + +void S::g(int i = []{return 1;}(), + int j = []{return 2; }()) {} + +// CHECK: define void @_Z6test_S1S +void test_S(S s) { + // CHECK: call i32 @_ZZN1S1fEiiEd0_NKUlvE_clEv + // CHECK-NEXT: call i32 @_ZZN1S1fEiiEd0_NKUlvE0_clEv + // CHECK-NEXT: add nsw i32 + // CHECK-NEXT: call i32 @_ZZN1S1fEiiEd_NKUlvE_clEv + // CHECK-NEXT: call void @_ZN1S1fEii + s.f(); + + // NOTE: These manglings don't actually matter that much, because + // the lambdas in the default arguments of g() won't be seen by + // multiple translation units. We check them mainly to ensure that they don't + // get the special mangling for lambdas in in-class default arguments. + // CHECK: call i32 @"_ZNK1S3$_0clEv" + // CHECK-NEXT: call i32 @"_ZNK1S3$_1clEv" + // CHECK-NEXT: call void @_ZN1S1gEi + s.g(); + + // CHECK-NEXT: ret void +} + +// Check the linkage of the lambda call operators used in test_S. +// CHECK: define linkonce_odr i32 @_ZZN1S1fEiiEd0_NKUlvE_clEv +// CHECK: ret i32 1 +// CHECK: define linkonce_odr i32 @_ZZN1S1fEiiEd0_NKUlvE0_clEv +// CHECK: ret i32 2 +// CHECK: define linkonce_odr i32 @_ZZN1S1fEiiEd_NKUlvE_clEv +// CHECK: ret i32 3 +// CHECK: define internal i32 @"_ZNK1S3$_0clEv" +// CHECK: ret i32 1 +// CHECK: define internal i32 @"_ZNK1S3$_1clEv" +// CHECK: ret i32 2 + +template +struct ST { + void f(T = []{return T() + 1;}() + + []{return T() + 2;}(), + T = []{return T(3);}()); +}; + +// CHECK: define void @_Z7test_ST2STIdE +void test_ST(ST st) { + // CHECK: call double @_ZZN2ST1fET_S0_Ed0_NKUlvE_clEv + // CHECK-NEXT: call double @_ZZN2ST1fET_S0_Ed0_NKUlvE0_clEv + // CHECK-NEXT: fadd double + // CHECK-NEXT: call double @_ZZN2ST1fET_S0_Ed_NKUlvE_clEv + // CHECK-NEXT: call void @_ZN2STIdE1fEdd + st.f(); + + // CHECK-NEXT: ret void +} + +// Check the linkage of the lambda call operators used in test_ST. +// CHECK: define linkonce_odr double @_ZZN2ST1fET_S0_Ed0_NKUlvE_clEv +// CHECK: ret double 1 +// CHECK: define linkonce_odr double @_ZZN2ST1fET_S0_Ed0_NKUlvE0_clEv +// CHECK: ret double 2 +// CHECK: define linkonce_odr double @_ZZN2ST1fET_S0_Ed_NKUlvE_clEv +// CHECK: ret double 3 + +template +struct StaticMembers { + static T x; + static T y; + static T z; +}; + +template int accept_lambda(T); + +template +T StaticMembers::x = []{return 1;}() + []{return 2;}(); + +template +T StaticMembers::y = []{return 3;}(); + +template +T StaticMembers::z = accept_lambda([]{return 4;}); + +// CHECK: define internal void @__cxx_global_var_init() +// CHECK: call i32 @_ZNK13StaticMembersIfE1xMUlvE_clEv +// CHECK-NEXT: call i32 @_ZNK13StaticMembersIfE1xMUlvE0_clEv +// CHECK-NEXT: add nsw +// CHECK: define linkonce_odr i32 @_ZNK13StaticMembersIfE1xMUlvE_clEv +// CHECK: ret i32 1 +// CHECK: define linkonce_odr i32 @_ZNK13StaticMembersIfE1xMUlvE0_clEv +// CHECK: ret i32 2 +template float StaticMembers::x; + +// CHECK: define internal void @__cxx_global_var_init1() +// CHECK: call i32 @_ZNK13StaticMembersIfE1yMUlvE_clEv +// CHECK: define linkonce_odr i32 @_ZNK13StaticMembersIfE1yMUlvE_clEv +// CHECK: ret i32 3 +template float StaticMembers::y; + +// CHECK: define internal void @__cxx_global_var_init2() +// CHECK: call i32 @_Z13accept_lambdaIN13StaticMembersIfE1zMUlvE_EEiT_ +// CHECK: declare i32 @_Z13accept_lambdaIN13StaticMembersIfE1zMUlvE_EEiT_() +template float StaticMembers::z; + +// CHECK: define internal void @__cxx_global_var_init3 +// CHECK: call i32 @"_ZNK13StaticMembersIdE3$_2clEv" +// CHECK: define internal i32 @"_ZNK13StaticMembersIdE3$_2clEv" +// CHECK: ret i32 42 +template<> double StaticMembers::z = []{return 42; }(); + +template +void func_template(T = []{ return T(); }()); + +// CHECK: define void @_Z17use_func_templatev() +void use_func_template() { + // CHECK: call i32 @"_ZZ13func_templateIiEvT_ENKS_IiE3$_3clEv" + func_template(); +} + +// CHECK: define linkonce_odr void @_Z1fIZZNK23TestNestedInstantiationclEvENKUlvE_clEvEUlvE_EvT_ + +struct Members { + int x = [] { return 1; }() + [] { return 2; }(); + int y = [] { return 3; }(); +}; + +void test_Members() { + // CHECK: define linkonce_odr void @_ZN7MembersC2Ev + // CHECK: call i32 @_ZNK7Members1xMUlvE_clEv + // CHECK-NEXT: call i32 @_ZNK7Members1xMUlvE0_clE + // CHECK-NEXT: add nsw i32 + // CHECK: call i32 @_ZNK7Members1yMUlvE_clEv + Members members; + // CHECK: ret void +} + +template void f(P) { } + +struct TestNestedInstantiation { + void operator()() const { + []() -> void { + return f([]{}); + }(); + } +}; + +void test_NestedInstantiation() { + TestNestedInstantiation()(); +} + +// Check the linkage of the lambdas used in test_Members. +// CHECK: define linkonce_odr i32 @_ZNK7Members1xMUlvE_clEv +// CHECK: ret i32 1 +// CHECK: define linkonce_odr i32 @_ZNK7Members1xMUlvE0_clEv +// CHECK: ret i32 2 +// CHECK: define linkonce_odr i32 @_ZNK7Members1yMUlvE_clEv +// CHECK: ret i32 3 + +// Check linkage of the various lambdas. +// CHECK: define linkonce_odr i32 @_ZZ11inline_funciENKUlvE_clEv +// CHECK: ret i32 1 +// CHECK: define linkonce_odr i32 @_ZZ11inline_funciENKUlvE0_clEv +// CHECK: ret i32 +// CHECK: define linkonce_odr double @_ZZ11inline_funciENKUlvE1_clEv +// CHECK: ret double +// CHECK: define linkonce_odr i32 @_ZZ11inline_funciENKUliE_clEi +// CHECK: ret i32 +// CHECK: define linkonce_odr i32 @_ZZ11inline_funciENKUlvE2_clEv +// CHECK: ret i32 17 diff --git a/clang/test/CodeGenCXX/mangle-local-class-names.cpp b/clang/test/CodeGenCXX/mangle-local-class-names.cpp new file mode 100644 index 0000000..3321460 --- /dev/null +++ b/clang/test/CodeGenCXX/mangle-local-class-names.cpp @@ -0,0 +1,57 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s + +// CHECK: @_ZZ4FUNCvEN4SSSSC1ERKf +// CHECK: @_ZZ4FUNCvEN4SSSSC2E_0RKf +// CHECK: @_ZZ4GORFfEN4SSSSC1ERKf +// CHECK: @_ZZ4GORFfEN4SSSSC2E_0RKf + +void FUNC () +{ + { + float IVAR1 ; + + struct SSSS + { + float bv; + SSSS( const float& from): bv(from) { } + }; + + SSSS VAR1(IVAR1); + } + + { + float IVAR2 ; + + struct SSSS + { + SSSS( const float& from) {} + }; + + SSSS VAR2(IVAR2); + } +} + +void GORF (float IVAR1) +{ + { + struct SSSS + { + float bv; + SSSS( const float& from): bv(from) { } + }; + + SSSS VAR1(IVAR1); + } + + { + float IVAR2 ; + + struct SSSS + { + SSSS( const float& from) {} + }; + + SSSS VAR2(IVAR2); + } +} + diff --git a/clang/test/CodeGenCXX/mangle-local-class-vtables.cpp b/clang/test/CodeGenCXX/mangle-local-class-vtables.cpp new file mode 100644 index 0000000..d9d3afe --- /dev/null +++ b/clang/test/CodeGenCXX/mangle-local-class-vtables.cpp @@ -0,0 +1,61 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s + +// CHECK: @_ZTVZN1J1KEvE1C = {{.*}} @_ZTIZN1J1KEvE1C {{.*}} @_ZZN1J1KEvENK1C1FEv +// CHECK: @_ZTIZN1J1KEvE1C = {{.*}} @_ZTSZN1J1KEvE1C +// CHECK: @_ZTVZ1GvE1C_1 = {{.*}} @_ZTIZ1GvE1C_1 {{.*}} @_ZZ1GvENK1C1FE_1v +// CHECK: @_ZTIZ1GvE1C_1 = {{.*}} @_ZTSZ1GvE1C_1 +// CHECK: @_ZTVZ1GvE1C_0 = {{.*}} @_ZTIZ1GvE1C_0 {{.*}} @_ZZ1GvENK1C1FE_0v +// CHECK: @_ZTIZ1GvE1C_0 = {{.*}} @_ZTSZ1GvE1C_0 +// CHECK: @_ZTVZ1GvE1C = {{.*}} @_ZTIZ1GvE1C {{.*}} @_ZZ1GvENK1C1FEv +// CHECK: @_ZTIZ1GvE1C = {{.*}} @_ZTSZ1GvE1C + +// CHECK: define {{.*}} @_ZZN1J1KEvEN1CC2Ev( +// CHECK: define {{.*}} @_ZZN1J1KEvENK1C1FEv( +// CHECK: define {{.*}} @_ZZ1GvEN1CC2E_1v( +// CHECK: define {{.*}} @_ZZ1GvENK1C1FE_1v( +// CHECK: define {{.*}} @_ZZ1GvENK1C1HE_1v( +// CHECK: define {{.*}} @_ZZ1GvEN1CC2E_0v( +// CHECK: define {{.*}} @_ZZ1GvENK1C1FE_0v( +// CHECK: define {{.*}} @_ZZ1GvENK1C1GE_0v( +// CHECK: define {{.*}} @_ZZ1GvEN1CC2Ev( +// CHECK: define {{.*}} @_ZZ1GvENK1C1FEv( + +struct I { + virtual void F() const = 0; +}; + +void Go(const I &i); + +void G() { + { + struct C : I { + void F() const {} + }; + Go(C()); + } + { + struct C : I { + void F() const { G(); } + void G() const {} + }; + Go(C()); + } + { + struct C : I { + void F() const { H(); } + void H() const {} + }; + Go(C()); + } +} + +struct J { + void K(); +}; + +void J::K() { + struct C : I { + void F() const {} + }; + Go(C()); +} diff --git a/clang/test/CodeGenCXX/mangle-local-classes-nested.cpp b/clang/test/CodeGenCXX/mangle-local-classes-nested.cpp new file mode 100644 index 0000000..fafa5d4 --- /dev/null +++ b/clang/test/CodeGenCXX/mangle-local-classes-nested.cpp @@ -0,0 +1,81 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s + +// CHECK: @_ZTVZZ1HvEN1S1IEvE1S = + +// CHECK: define {{.*}} @_Z2L1v( +// CHECK: define {{.*}} @_ZZ2L1vEN1S2L2Ev( +// CHECK: define {{.*}} @_ZZ2L1vEN1S2L2E_0v( +// CHECK: define {{.*}} @_ZZ1FvEN1S1T1S1T1GEv( +// CHECK: define {{.*}} @_ZZZ2L1vEN1S2L2E_0vEN1S3L3cEv( +// CHECK: define {{.*}} @_ZZZ2L1vEN1S2L2E_0vEN1S3L3dE_0v( +// CHECK: define {{.*}} @_ZZZ2L1vEN1S2L2EvEN1S3L3aEv( +// CHECK: define {{.*}} @_ZZZ2L1vEN1S2L2EvEN1S3L3bE_0v( + +void L1() { + { + struct S { + void L2() { + { + struct S { + void L3a() {} + }; + S().L3a(); + } + { + struct S { + void L3b() {} + }; + S().L3b(); + } + } + }; + S().L2(); + } + { + struct S { + void L2() { + { + struct S { + void L3c() {} + }; + S().L3c(); + } + { + struct S { + void L3d() {} + }; + S().L3d(); + } + } + }; + S().L2(); + } +} + +void F() { + struct S { + struct T { + struct S { + struct T { + void G() {} + }; + }; + }; + }; + S::T::S::T().G(); +} + +struct B { virtual void Foo() = 0; }; +void G(const B &); + +void H() { + struct S { + void I() { + struct S : B { + virtual void Foo() {} + }; + G(S()); + } + }; + S().I(); +} diff --git a/clang/test/CodeGenCXX/mangle-ms.cpp b/clang/test/CodeGenCXX/mangle-ms.cpp new file mode 100644 index 0000000..fe5fde1 --- /dev/null +++ b/clang/test/CodeGenCXX/mangle-ms.cpp @@ -0,0 +1,105 @@ +// RUN: %clang_cc1 -fms-extensions -fblocks -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s + +// CHECK: @"\01?a@@3HA" +// CHECK: @"\01?b@N@@3HA" +// CHECK: @c +// CHECK: @"\01?d@foo@@0FB" +// CHECK: @"\01?e@foo@@1JC" +// CHECK: @"\01?f@foo@@2DD" +// CHECK: @"\01?g@bar@@2HA" +// CHECK: @"\01?h@@3QAHA" +// CHECK: @"\01?i@@3PAY0BE@HA" +// CHECK: @"\01?j@@3P6GHCE@ZA" +// CHECK: @"\01?k@@3PTfoo@@DA" +// CHECK: @"\01?l@@3P8foo@@AEHH@ZA" + +int a; + +namespace N { int b; } + +static int c; +int _c(void) {return c;} +// CHECK: @"\01?_c@@YAHXZ" + +class foo { + static const short d; +protected: + static volatile long e; +public: + static const volatile char f; + int operator+(int a); + foo(){} +//CHECK: @"\01??0foo@@QAE@XZ" + + ~foo(){} +//CHECK: @"\01??1foo@@QAE@XZ" + + foo(int i){} +//CHECK: @"\01??0foo@@QAE@H@Z" + + foo(char *q){} +//CHECK: @"\01??0foo@@QAE@PAD@Z" +}f,s1(1),s2((char*)0); + +struct bar { + static int g; +}; + +union baz { + int a; + char b; + double c; +}; + +enum quux { + qone, + qtwo, + qthree +}; + +int foo::operator+(int a) {return a;} +// CHECK: @"\01??Hfoo@@QAEHH@Z" + +const short foo::d = 0; +volatile long foo::e; +const volatile char foo::f = 'C'; + +int bar::g; + +extern int * const h = &a; + +int i[10][20]; + +int (__stdcall *j)(signed char, unsigned char); + +const volatile char foo::*k; + +int (foo::*l)(int); + +// Static functions are mangled, too. +// Also make sure calling conventions, arglists, and throw specs work. +static void __stdcall alpha(float a, double b) throw() {} +bool __fastcall beta(long long a, wchar_t b) throw(signed char, unsigned char) { +// CHECK: @"\01?beta@@YI_N_J_W@Z" + alpha(0.f, 0.0); + return false; +} + +// CHECK: @"\01?alpha@@YGXMN@Z" + +// Make sure tag-type mangling works. +void gamma(class foo, struct bar, union baz, enum quux) {} +// CHECK: @"\01?gamma@@YAXVfoo@@Ubar@@Tbaz@@W4quux@@@Z" + +// Make sure pointer/reference-type mangling works. +void delta(int * const a, const long &) {} +// CHECK: @"\01?delta@@YAXQAHABJ@Z" + +// Array mangling. +void epsilon(int a[][10][20]) {} +// CHECK: @"\01?epsilon@@YAXQAY19BE@H@Z" + +// Blocks mangling (Clang extension). +void zeta(int (^)(int, int)) {} +// CHECK: @"\01?zeta@@YAXP_EAHHH@Z@Z" + diff --git a/clang/test/CodeGenCXX/mangle-neon-vectors.cpp b/clang/test/CodeGenCXX/mangle-neon-vectors.cpp new file mode 100644 index 0000000..3723deb --- /dev/null +++ b/clang/test/CodeGenCXX/mangle-neon-vectors.cpp @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s + +typedef float float32_t; +typedef signed char poly8_t; +typedef short poly16_t; +typedef unsigned long long uint64_t; + +typedef __attribute__((neon_vector_type(2))) int int32x2_t; +typedef __attribute__((neon_vector_type(4))) int int32x4_t; +typedef __attribute__((neon_vector_type(1))) uint64_t uint64x1_t; +typedef __attribute__((neon_vector_type(2))) uint64_t uint64x2_t; +typedef __attribute__((neon_vector_type(2))) float32_t float32x2_t; +typedef __attribute__((neon_vector_type(4))) float32_t float32x4_t; +typedef __attribute__((neon_polyvector_type(16))) poly8_t poly8x16_t; +typedef __attribute__((neon_polyvector_type(8))) poly16_t poly16x8_t; + +// CHECK: 16__simd64_int32_t +void f1(int32x2_t v) { } +// CHECK: 17__simd128_int32_t +void f2(int32x4_t v) { } +// CHECK: 17__simd64_uint64_t +void f3(uint64x1_t v) { } +// CHECK: 18__simd128_uint64_t +void f4(uint64x2_t v) { } +// CHECK: 18__simd64_float32_t +void f5(float32x2_t v) { } +// CHECK: 19__simd128_float32_t +void f6(float32x4_t v) { } +// CHECK: 17__simd128_poly8_t +void f7(poly8x16_t v) { } +// CHECK: 18__simd128_poly16_t +void f8(poly16x8_t v) { } diff --git a/clang/test/CodeGenCXX/mangle-nullptr-arg.cpp b/clang/test/CodeGenCXX/mangle-nullptr-arg.cpp new file mode 100644 index 0000000..393de0b --- /dev/null +++ b/clang/test/CodeGenCXX/mangle-nullptr-arg.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -std=c++11 -emit-llvm -o - %s | FileCheck %s + +template struct IP {}; + +// CHECK: define void @_Z5test12IPILPi0EE +void test1(IP) {} + +struct X{ }; +template struct PM {}; + +// CHECK: define void @_Z5test22PMILM1Xi0EE +void test2(PM) { } + diff --git a/clang/test/CodeGenCXX/mangle-ref-qualifiers.cpp b/clang/test/CodeGenCXX/mangle-ref-qualifiers.cpp new file mode 100644 index 0000000..568cf9f --- /dev/null +++ b/clang/test/CodeGenCXX/mangle-ref-qualifiers.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s +struct X { + int f() &; + int g() &&; + int h() const &&; +}; + +// CHECK: define i32 @_ZNR1X1fEv +int X::f() & { return 0; } +// CHECK: define i32 @_ZNO1X1gEv +int X::g() && { return 0; } +// CHECK: define i32 @_ZNKO1X1hEv +int X::h() const && { return 0; } + +// CHECK: define void @_Z1fM1XRFivEMS_OFivEMS_KOFivE +void f(int (X::*)() &, int (X::*)() &&, int (X::*)() const&&) { } diff --git a/clang/test/CodeGenCXX/mangle-std-externc.cpp b/clang/test/CodeGenCXX/mangle-std-externc.cpp new file mode 100644 index 0000000..a478dee --- /dev/null +++ b/clang/test/CodeGenCXX/mangle-std-externc.cpp @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 %s -DNS=std -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-STD +// RUN: %clang_cc1 %s -DNS=n -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-N + +// _ZNSt1DISt1CE1iE = std::D::i +// CHECK-STD: @_ZNSt1DISt1CE1iE = + +// _ZN1n1DINS_1CEE1iE == n::D::i +// CHECK-N: @_ZN1n1DINS_1CEE1iE = + +namespace NS { + extern "C" { + class C { + }; + } + + template + class D { + public: + static int i; + }; + +} + + +int f() { + return NS::D::i; +} diff --git a/clang/test/CodeGenCXX/mangle-subst-std.cpp b/clang/test/CodeGenCXX/mangle-subst-std.cpp new file mode 100644 index 0000000..04e3e84 --- /dev/null +++ b/clang/test/CodeGenCXX/mangle-subst-std.cpp @@ -0,0 +1,112 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 | FileCheck %s + +// Check mangling of Vtables, VTTs, and construction vtables that +// involve standard substitutions. + +// CHECK: @_ZTVSd = linkonce_odr unnamed_addr constant +// CHECK: @_ZTTSd = linkonce_odr unnamed_addr constant +// CHECK: @_ZTCSd0_Si = linkonce_odr unnamed_addr constant +// CHECK: @_ZTCSd16_So = linkonce_odr unnamed_addr constant +// CHECK: @_ZTVSo = linkonce_odr unnamed_addr constant +// CHECK: @_ZTTSo = linkonce_odr unnamed_addr constant +// CHECK: @_ZTVSi = linkonce_odr unnamed_addr constant +// CHECK: @_ZTTSi = linkonce_odr unnamed_addr constant + +namespace std { + struct A { A(); }; + + // CHECK: define void @_ZNSt1AC1Ev(%"struct.std::A"* %this) unnamed_addr + // CHECK: define void @_ZNSt1AC2Ev(%"struct.std::A"* %this) unnamed_addr + A::A() { } +}; + +namespace std { + template struct allocator { }; +} + +// CHECK: define void @_Z1fSaIcESaIiE +void f(std::allocator, std::allocator) { } + +namespace std { + template struct basic_string { }; +} + +// CHECK: define void @_Z1fSbIcciE +void f(std::basic_string) { } + +namespace std { + template struct char_traits { }; + + typedef std::basic_string, std::allocator > string; +} + +// CHECK: _Z1fSs +void f(std::string) { } + +namespace std { + template struct basic_ios { + basic_ios(int); + virtual ~basic_ios(); + }; + template > + struct basic_istream : virtual public basic_ios { + basic_istream(int x) : basic_ios(x), stored(x) { } + + int stored; + }; + template > + struct basic_ostream : virtual public basic_ios { + basic_ostream(int x) : basic_ios(x), stored(x) { } + + float stored; + }; + + template > + struct basic_iostream : public basic_istream, + public basic_ostream { + basic_iostream(int x) : basic_istream(x), + basic_ostream(x), + basic_ios(x) { } + }; +} + +// CHECK: _Z1fSi +void f(std::basic_istream >) { } + +// CHECK: _Z1fSo +void f(std::basic_ostream >) { } + +// CHECK: _Z1fSd +void f(std::basic_iostream >) { } + +extern "C++" { +namespace std +{ + typedef void (*terminate_handler) (); + + // CHECK: _ZSt13set_terminatePFvvE + terminate_handler set_terminate(terminate_handler) { return 0; } +} +} + +// Make sure we don't treat the following like std::string +// CHECK: define void @_Z1f12basic_stringIcSt11char_traitsIcESaIcEE +template struct basic_string { }; +typedef basic_string, std::allocator > not_string; +void f(not_string) { } + +// Manglings for instantiations caused by this function are at the +// top of the test. +void create_streams() { + std::basic_iostream bio(17); +} + +// Make sure we don't mangle 'std' as 'St' here. +namespace N { + namespace std { + struct A { void f(); }; + + // CHECK: define void @_ZN1N3std1A1fEv + void A::f() { } + } +} diff --git a/clang/test/CodeGenCXX/mangle-subst.cpp b/clang/test/CodeGenCXX/mangle-subst.cpp new file mode 100644 index 0000000..d83a081 --- /dev/null +++ b/clang/test/CodeGenCXX/mangle-subst.cpp @@ -0,0 +1,82 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 | FileCheck %s + +struct X {}; + +// CHECK: define void @_Z1f1XS_( +void f(X, X) { } + +// CHECK: define void @_Z1fR1XS0_( +void f(X&, X&) { } + +// CHECK: define void @_Z1fRK1XS1_( +void f(const X&, const X&) { } + +typedef void T(); +struct S {}; + +// CHECK: define void @_Z1fPFvvEM1SFvvE( +void f(T*, T (S::*)) {} + +namespace A { + struct A { }; + struct B { }; +}; + +// CHECK: define void @_Z1fN1A1AENS_1BE( +void f(A::A a, A::B b) { } + +struct C { + struct D { }; +}; + +// CHECK: define void @_Z1fN1C1DERS_PS_S1_( +void f(C::D, C&, C*, C&) { } + +template +struct V { + typedef int U; +}; + +template void f1(typename V::U, V) { } + +// CHECK: @_Z2f1IiEvN1VIT_E1UES2_ +template void f1(int, V); + +template void f2(V, typename V::U) { } + +// CHECK: @_Z2f2IiEv1VIT_ENS2_1UE +template void f2(V, int); + +namespace NS { +template struct S1 {}; +template void ft3(S1, S1) { } + +// CHECK: @_ZN2NS3ft3IiEEvNS_2S1IT_EENS1_IcEE +template void ft3(S1, S1); +} + +// PR5196 +// CHECK: @_Z1fPKcS0_ +void f(const char*, const char*) {} + +namespace NS { + class C; +} + +namespace NS { + // CHECK: @_ZN2NS1fERNS_1CE + void f(C&) { } +} + +namespace Test1 { + +struct A { }; +struct B { }; + +// CHECK: @_ZN5Test11fEMNS_1BEFvvENS_1AES3_ +void f(void (B::*)(), A, A) { } + +// CHECK: @_ZN5Test11fEMNS_1BEFvvENS_1AES3_MS0_FvS3_EMS3_FvvE +void f(void (B::*)(), A, A, void (B::*)(A), void (A::*)()) { } + +} diff --git a/clang/test/CodeGenCXX/mangle-system-header.cpp b/clang/test/CodeGenCXX/mangle-system-header.cpp new file mode 100644 index 0000000..6716b58 --- /dev/null +++ b/clang/test/CodeGenCXX/mangle-system-header.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 | FileCheck %s + +// PR5420 + +# 1 "fake_system_header.h" 1 3 4 +// CHECK: define void @_ZdlPvS_( +void operator delete (void*, void*) {} + +// PR6217 +// CHECK: define void @_Z3barv() +void bar() { } diff --git a/clang/test/CodeGenCXX/mangle-template.cpp b/clang/test/CodeGenCXX/mangle-template.cpp new file mode 100644 index 0000000..05c3a58 --- /dev/null +++ b/clang/test/CodeGenCXX/mangle-template.cpp @@ -0,0 +1,172 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s +namespace test1 { +int x; +template class T { }; +// CHECK: void @_ZN5test12f0ENS_1TILZNS_1xEEEE( +void f0(T a0) {} +} + +namespace test1 { +// CHECK: void @_ZN5test12f0Ef +void f0(float) {} +template struct t1 {}; +// CHECK: void @_ZN5test12f1ENS_2t1ILZNS_2f0EfEEE( +void f1(t1 a0) {} +} + +namespace test2 { +// CHECK: void @_ZN5test22f0Ef +void f0(float) {} +template struct t1 {}; +// FIXME: Fails because we don't treat as an expression. +// CHECK-FIXME: void @_ZN5test22f1ENS_2t1IXadL_ZNS_2f0EfEEEE( +void f1(t1 a0) {} +} + +namespace test3 { +// CHECK: void @test3_f0 +extern "C" void test3_f0(float) {} +template struct t1 {}; +// FIXME: Fails because we tack on a namespace. +// CHECK-FIXME: void @_ZN5test32f1ENS_2t1ILZ8test3_f0EEE( +void f1(t1 a0) {} +} + +namespace test4 { +// CHECK: void @test4_f0 +extern "C" void test4_f0(float) {} +template struct t1 {}; +// FIXME: Fails because we don't treat as an expression. +// CHECK-FIXME: void @_ZN5test42f1ENS_2t1IXadL_Z8test4_f0EEEE( +void f1(t1 a0) {} +} + +// CHECK: void @test5_f0 +extern "C" void test5_f0(float) {} +int main(int) {} + +namespace test5 { +template struct t1 {}; +// CHECK: void @_ZN5test52f1ENS_2t1ILZ8test5_f0EEE( +void f1(t1 a0) {} + +template struct t2 {}; +// CHECK: void @_ZN5test52f2ENS_2t2ILZ4mainEEE +void f2(t2
a0) {} +} + +// FIXME: This fails. +namespace test6 { +struct A { void im0(float); }; +// CHECK: void @_ZN5test61A3im0Ef +void A::im0(float) {} +template class T { }; +// FIXME: Fails because we don't treat as an expression. +// CHECK-FAIL: void @_ZN5test62f0ENS_1TIXadL_ZNS_1A3im0EfEEEE( +void f0(T<&A::im0> a0) {} +} + +namespace test7 { + template + struct meta { + static const unsigned value = sizeof(T); + }; + + template struct int_c { + typedef float type; + }; + + template + struct X { + template + X(U*, typename int_c<(meta::value + meta::value)>::type *) { } + }; + + // CHECK: define weak_odr {{.*}} @_ZN5test71XIiEC1IdEEPT_PNS_5int_cIXplL_ZNS_4metaIiE5valueEEsr4metaIS3_EE5valueEE4typeE(%"struct.test7::X"* %this, double*, float*) unnamed_addr + template X::X(double*, float*); +} + +namespace test8 { + template + struct meta { + struct type { + static const unsigned value = sizeof(T); + }; + }; + + template struct int_c { + typedef float type; + }; + + template + void f(int_c::type::value>) { } + + // CHECK: define weak_odr void @_ZN5test81fIiEEvNS_5int_cIXsr4metaIT_E4typeE5valueEEE + template void f(int_c); +} + +namespace test9 { + template + struct supermeta { + template + struct apply { + typedef T U::*type; + }; + }; + + struct X { }; + + template + typename supermeta::template apply::type f(); + + void test_f() { + // CHECK: @_ZN5test91fIiNS_1XEEENS_9supermetaIT_E5applyIT0_E4typeEv() + // Note: GCC incorrectly mangles this as + // _ZN5test91fIiNS_1XEEENS_9supermetaIT_E5apply4typeEv, while EDG + // gets it right. + f(); + } +} + +namespace test10 { + template + struct X { + template + struct definition { + }; + }; + + // CHECK: _ZN6test101fIidEENS_1XIT_E10definitionIT0_EES2_S5_ + template + typename X::template definition f(T, U) { } + + void g(int i, double d) { + f(i, d); + } +} + +// Report from Jason Merrill on cxx-abi-dev, 2012.01.04. +namespace test11 { + int cmp(char a, char b); + template struct A {}; + template void f(A &) {} + template void f(A &); + // CHECK: @_ZN6test111fIcEEvRNS_1AIT_L_ZNS_3cmpEccEEE( +} + +namespace test12 { + // Make sure we can mangle non-type template args with internal linkage. + static int f(); + const int n = 10; + template void test() {} + void use() { + // CHECK: define internal void @_ZN6test124testIFivEXadL_ZNS_L1fEvEEEEvv( + test(); + // CHECK: define internal void @_ZN6test124testIRFivEXadL_ZNS_L1fEvEEEEvv( + test(); + // CHECK: define internal void @_ZN6test124testIPKiXadL_ZNS_L1nEEEEEvv( + test(); + // CHECK: define internal void @_ZN6test124testIRKiXadL_ZNS_L1nEEEEEvv( + test(); + } +} diff --git a/clang/test/CodeGenCXX/mangle-this-cxx11.cpp b/clang/test/CodeGenCXX/mangle-this-cxx11.cpp new file mode 100644 index 0000000..f9e9479 --- /dev/null +++ b/clang/test/CodeGenCXX/mangle-this-cxx11.cpp @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 | FileCheck %s + +struct B { + template U f(); +}; + +struct A { + B b; + // implicitly rewritten to (*this).b.f() + template auto f() -> decltype (b.f()); + template auto g() -> decltype (this->b.f()); +}; + +int main() { + A a; + // CHECK: call i32 @_ZN1A1fIiEEDTcldtdtdefpT1b1fIT_EEEv + a.f(); + // CHECK: call i32 @_ZN1A1gIiEEDTcldtptfpT1b1fIT_EEEv + a.g(); +} diff --git a/clang/test/CodeGenCXX/mangle-unnameable-conversions.cpp b/clang/test/CodeGenCXX/mangle-unnameable-conversions.cpp new file mode 100644 index 0000000..2ecded0 --- /dev/null +++ b/clang/test/CodeGenCXX/mangle-unnameable-conversions.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s + +template using id = T; +struct S { + template + operator id&(); + template + operator id() const; +}; + +void f() { + int (&a)[42] = S(); // CHECK: @_ZN1ScvRAT0__T_IiLi42EEEv( + char (S::*fp)() = S(); // CHECK: @_ZNK1ScvMT0_FT_vEIcS_EEv( +}; diff --git a/clang/test/CodeGenCXX/mangle-unnamed.cpp b/clang/test/CodeGenCXX/mangle-unnamed.cpp new file mode 100644 index 0000000..53f381c --- /dev/null +++ b/clang/test/CodeGenCXX/mangle-unnamed.cpp @@ -0,0 +1,92 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin10 | FileCheck %s + +struct S { + virtual ~S() { } +}; + +// PR5706 +// Make sure this doesn't crash; the mangling doesn't matter because the name +// doesn't have linkage. +static struct : S { } obj8; + +void f() { + // Make sure this doesn't crash; the mangling doesn't matter because the + // generated vtable/etc. aren't modifiable (although it would be nice for + // codesize to make it consistent inside inline functions). + static struct : S { } obj8; +} + +inline int f2() { + // FIXME: We don't mangle the names of a or x correctly! + static struct { int a() { static int x; return ++x; } } obj; + return obj.a(); +} + +int f3() { return f2(); } + +struct A { + typedef struct { int x; } *ptr; + ptr m; + int a() { + static struct x { + // FIXME: We don't mangle the names of a or x correctly! + int a(ptr A::*memp) { static int x; return ++x; } + } a; + return a.a(&A::m); + } +}; + +int f4() { return A().a(); } + +int f5() { + static union { + int a; + }; + + // CHECK: _ZZ2f5vE1a + return a; +} + +int f6() { + static union { + union { + int : 1; + }; + int b; + }; + + // CHECK: _ZZ2f6vE1b + return b; +} + +int f7() { + static union { + union { + int b; + } a; + }; + + // CHECK: _ZZ2f7vE1a + return a.b; +} + +// This used to cause an assert because the typedef-for-anonymous-tag +// code was trying to claim the enum for the template. +enum { T8 }; +template struct Test8 { + typedef T type; + Test8(type t) {} // tested later +}; +template void make_test8(T value) { Test8 t(value); } +void test8() { make_test8(T8); } + +// CHECK: define internal void @"_ZNV3$_35test9Ev"( +typedef volatile struct { + void test9() volatile {} +} Test9; +void test9() { + Test9 a; + a.test9(); +} + +// CHECK: define internal void @"_ZN5Test8I3$_2EC1ES0_"( diff --git a/clang/test/CodeGenCXX/mangle-variadic-templates.cpp b/clang/test/CodeGenCXX/mangle-variadic-templates.cpp new file mode 100644 index 0000000..b5bdae2 --- /dev/null +++ b/clang/test/CodeGenCXX/mangle-variadic-templates.cpp @@ -0,0 +1,67 @@ +// RUN: %clang_cc1 -std=c++11 -emit-llvm -triple=x86_64-apple-darwin9 -o - %s | FileCheck %s + +template +struct X { }; + +template struct identity { }; +template struct add_reference; +template struct tuple { }; +template struct int_tuple { }; +template class ...Templates> struct template_tuple { }; + +// CHECK: define weak_odr void @_Z2f0IJEEv1XIXsZT_EJDpRT_EE +template +void f0(X) { } + +template void f0(X<0>); + +// CHECK: define weak_odr void @_Z2f0IJifdEEv1XIXsZT_EJDpRT_EE +template void f0(X<3, int&, float&, double&>); + +// Mangling for template argument packs +template void f1() {} +// CHECK: define weak_odr void @_Z2f1IJEEvv +template void f1<>(); +// CHECK: define weak_odr void @_Z2f1IJiEEvv +template void f1(); +// CHECK: define weak_odr void @_Z2f1IJifEEvv +template void f1(); + +// Mangling function parameter packs +template void f2(Types...) {} +// CHECK: define weak_odr void @_Z2f2IJEEvDpT_ +template void f2<>(); +// CHECK: define weak_odr void @_Z2f2IJiEEvDpT_ +template void f2(int); +// CHECK: define weak_odr void @_Z2f2IJifEEvDpT_ +template void f2(int, float); + +// Mangling non-trivial function parameter packs +template void f3(const Types *...) {} +// CHECK: define weak_odr void @_Z2f3IJEEvDpPKT_ +template void f3<>(); +// CHECK: define weak_odr void @_Z2f3IJiEEvDpPKT_ +template void f3(const int*); +// CHECK: define weak_odr void @_Z2f3IJifEEvDpPKT_ +template void f3(const int*, const float*); + +// Mangling of type pack expansions in a template argument +template tuple f4() {} +// CHECK: define weak_odr void @_Z2f4IJifdEE5tupleIJDpT_EEv +template tuple f4(); + +// Mangling of type pack expansions in a function type +template identity f5() {} +// CHECK: define weak_odr void @_Z2f5IiJifdEE8identityIFT_DpT0_EEv +template identity f5(); + +// Mangling of non-type template argument expansions +template int_tuple f6() {} +// CHECK: define weak_odr void @_Z2f6IJLi1ELi2ELi3EEE9int_tupleIJXspT_EEEv +template int_tuple<1, 2, 3> f6(); + +// Mangling of template template argument expansions +template class ...Templates> +template_tuple f7() {} +// CHECK: define weak_odr void @_Z2f7IJ8identity13add_referenceEE14template_tupleIJDpT_EEv +template template_tuple f7(); diff --git a/clang/test/CodeGenCXX/mangle.cpp b/clang/test/CodeGenCXX/mangle.cpp new file mode 100644 index 0000000..ba1b3bf --- /dev/null +++ b/clang/test/CodeGenCXX/mangle.cpp @@ -0,0 +1,854 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -fblocks -std=c++11 | FileCheck %s +struct X { }; +struct Y { }; + +// CHECK: @unmangled_variable = global +// CHECK: @_ZN1N1iE = global +// CHECK: @_ZZN1N1fEiiE1b = internal global +// CHECK: @_ZZN1N1gEvE1a = internal global +// CHECK: @_ZGVZN1N1gEvE1a = internal global + +//CHECK: @pr5966_i = external global +//CHECK: @_ZL8pr5966_i = internal global + +// CHECK: define zeroext i1 @_ZplRK1YRA100_P1X +bool operator+(const Y&, X* (&xs)[100]) { return false; } + +// CHECK: define void @_Z1f1s +typedef struct { int a; } s; +void f(s) { } + +// CHECK: define void @_Z1f1e +typedef enum { foo } e; +void f(e) { } + +// CHECK: define void @_Z1f1u +typedef union { int a; } u; +void f(u) { } + +// CHECK: define void @_Z1f1x +typedef struct { int a; } x,y; +void f(y) { } + +// CHECK: define void @_Z1fv +void f() { } + +// CHECK: define void @_ZN1N1fEv +namespace N { void f() { } } + +// CHECK: define void @_ZN1N1N1fEv +namespace N { namespace N { void f() { } } } + +// CHECK: define void @unmangled_function +extern "C" { namespace N { void unmangled_function() { } } } + +extern "C" { namespace N { int unmangled_variable = 10; } } + +namespace N { int i; } + +namespace N { int f(int, int) { static int b; return b; } } + +namespace N { int h(); void g() { static int a = h(); } } + +// CHECK: define void @_Z1fno +void f(__int128_t, __uint128_t) { } + +template struct S1 {}; + +// CHECK: define void @_Z1f2S1IiE +void f(S1) {} + +// CHECK: define void @_Z1f2S1IdE +void f(S1) {} + +template struct S2 {}; +// CHECK: define void @_Z1f2S2ILi100EE +void f(S2<100>) {} + +// CHECK: define void @_Z1f2S2ILin100EE +void f(S2<-100>) {} + +template struct S3 {}; + +// CHECK: define void @_Z1f2S3ILb1EE +void f(S3) {} + +// CHECK: define void @_Z1f2S3ILb0EE +void f(S3) {} + +struct S; + +// CHECK: define void @_Z1fM1SKFvvE +void f(void (S::*)() const) {} + +// CHECK: define void @_Z1fM1SFvvE +void f(void (S::*)()) {} + +// CHECK: define void @_Z1fi +void f(const int) { } + +template void ft1(U u, T t) { } + +template void ft2(T t, void (*)(T), void (*)(T)) { } + +template > struct S4 { }; +template void ft3(S4*) { } + +namespace NS { + template void ft1(T) { } +} + +void g1() { + // CHECK: @_Z3ft1IidEvT0_T_ + ft1(1, 0); + + // CHECK: @_Z3ft2IcEvT_PFvS0_ES2_ + ft2(1, 0, 0); + + // CHECK: @_Z3ft3IiEvP2S4IT_2S1IS1_EE + ft3(0); + + // CHECK: @_ZN2NS3ft1IiEEvT_ + NS::ft1(1); +} + +// Expressions +template struct S5 { }; + +template void ft4(S5) { } +void g2() { + // CHECK: @_Z3ft4ILi10EEv2S5IXT_EE + ft4(S5<10>()); + + // CHECK: @_Z3ft4ILi20EEv2S5IXT_EE + ft4(S5<20>()); +} + +extern "C++" { + // CHECK: @_Z1hv + void h() { } +} + +// PR5019 +extern "C" { struct a { int b; }; } + +// CHECK: @_Z1fP1a +int f(struct a *x) { + return x->b; +} + +// PR5017 +extern "C" { +struct Debug { + const Debug& operator<< (unsigned a) const { return *this; } +}; +Debug dbg; +// CHECK: @_ZNK5DebuglsEj +int main(void) { dbg << 32 ;} +} + +template struct S6 { + typedef int B; +}; + +template void ft5(typename S6::B) { } +// CHECK: @_Z3ft5IiEvN2S6IT_E1BE +template void ft5(int); + +template class A {}; + +namespace NS { +template bool operator==(const A&, const A&) { return true; } +} + +// CHECK: @_ZN2NSeqIcEEbRK1AIT_ES5_ +template bool NS::operator==(const ::A&, const ::A&); + +namespace std { +template bool operator==(const A&, const A&) { return true; } +} + +// CHECK: @_ZSteqIcEbRK1AIT_ES4_ +template bool std::operator==(const ::A&, const ::A&); + +struct S { + typedef int U; +}; + +template typename T::U ft6(const T&) { return 0; } + +// CHECK: @_Z3ft6I1SENT_1UERKS1_ +template int ft6(const S&); + +template struct __is_scalar_type { + enum { __value = 1 }; +}; + +template struct __enable_if { }; + +template struct __enable_if { + typedef T __type; +}; + +// PR5063 +template typename __enable_if<__is_scalar_type::__value, void>::__type ft7() { } + +// CHECK: @_Z3ft7IiEN11__enable_ifIXsr16__is_scalar_typeIT_EE7__valueEvE6__typeEv +template void ft7(); +// CHECK: @_Z3ft7IPvEN11__enable_ifIXsr16__is_scalar_typeIT_EE7__valueEvE6__typeEv +template void ft7(); + +// PR5144 +extern "C" { +void extern_f(void); +}; + +// CHECK: @extern_f +void extern_f(void) { } + +struct S7 { + S7(); + + struct S { S(); }; + struct { + S s; + } a; +}; + +// PR5139 +// CHECK: @_ZN2S7C1Ev +// CHECK: @_ZN2S7C2Ev +// CHECK: @"_ZN2S73$_0C1Ev" +S7::S7() {} + +// PR5063 +template typename __enable_if<(__is_scalar_type::__value), void>::__type ft8() { } +// CHECK: @_Z3ft8IiEN11__enable_ifIXsr16__is_scalar_typeIT_EE7__valueEvE6__typeEv +template void ft8(); +// CHECK: @_Z3ft8IPvEN11__enable_ifIXsr16__is_scalar_typeIT_EE7__valueEvE6__typeEv +template void ft8(); + +// PR5796 +namespace PR5796 { +template struct __is_scalar_type { + enum { __value = 0 }; +}; + +template struct __enable_if {}; +template struct __enable_if { typedef T __type; }; +template + +// CHECK: define linkonce_odr void @_ZN6PR57968__fill_aIiEENS_11__enable_ifIXntsr16__is_scalar_typeIT_EE7__valueEvE6__typeEv +typename __enable_if::__value, void>::__type __fill_a() { }; + +void f() { __fill_a(); } +} + +namespace Expressions { +// Unary operators. + +// CHECK: define weak_odr void @_ZN11Expressions2f1ILi1EEEvPAplngT_Li2E_i +template void f1(int (*)[(-i) + 2]) { }; +template void f1<1>(int (*)[1]); + +// CHECK: define weak_odr void @_ZN11Expressions2f2ILi1EEEvPApsT__i +template void f2(int (*)[+i]) { }; +template void f2<1>(int (*)[1]); + +// Binary operators. + +// CHECK: define weak_odr void @_ZN11Expressions2f3ILi1EEEvPAplT_T__i +template void f3(int (*)[i+i]) { }; +template void f3<1>(int (*)[2]); + +// CHECK: define weak_odr void @_ZN11Expressions2f4ILi1EEEvPAplplLi2ET_T__i +template void f4(int (*)[2 + i+i]) { }; +template void f4<1>(int (*)[4]); + +// The ternary operator. +// CHECK: define weak_odr void @_ZN11Expressions2f4ILb1EEEvPAquT_Li1ELi2E_i +template void f4(int (*)[b ? 1 : 2]) { }; +template void f4(int (*)[1]); +} + +struct Ops { + Ops& operator+(const Ops&); + Ops& operator-(const Ops&); + Ops& operator&(const Ops&); + Ops& operator*(const Ops&); + + void *v; +}; + +// CHECK: define %struct.Ops* @_ZN3OpsplERKS_ +Ops& Ops::operator+(const Ops&) { return *this; } +// CHECK: define %struct.Ops* @_ZN3OpsmiERKS_ +Ops& Ops::operator-(const Ops&) { return *this; } +// CHECK: define %struct.Ops* @_ZN3OpsanERKS_ +Ops& Ops::operator&(const Ops&) { return *this; } +// CHECK: define %struct.Ops* @_ZN3OpsmlERKS_ +Ops& Ops::operator*(const Ops&) { return *this; } + +// PR5861 +namespace PR5861 { +template class P; +template<> class P {}; + +template