From 3dd5a298bfff48c0939448c9b4bc987cf6bb5385 Mon Sep 17 00:00:00 2001 From: Roman Lebedev Date: Wed, 26 Feb 2020 01:37:17 +0300 Subject: [PATCH] [clang] Annotating C++'s `operator new` with more attributes Summary: Right now we annotate C++'s `operator new` with `noalias` attribute, which very much is healthy for optimizations. However as per [[ http://eel.is/c++draft/basic.stc.dynamic.allocation | `[basic.stc.dynamic.allocation]` ]], there are more promises on global `operator new`, namely: * non-`std::nothrow_t` `operator new` *never* returns `nullptr` * If `std::align_val_t align` parameter is taken, the pointer will also be `align`-aligned * ~~global `operator new`-returned pointer is `__STDCPP_DEFAULT_NEW_ALIGNMENT__`-aligned ~~ It's more caveated than that. Supplying this information may not cause immediate landslide effects on any specific benchmarks, but it for sure will be healthy for optimizer in the sense that the IR will better reflect the guarantees provided in the source code. The caveat is `-fno-assume-sane-operator-new`, which currently prevents emitting `noalias` attribute, and is automatically passed by Sanitizers ([[ https://bugs.llvm.org/show_bug.cgi?id=16386 | PR16386 ]]) - should it also cover these attributes? The problem is that the flag is back-end-specific, as seen in `test/Modules/explicit-build-flags.cpp`. But while it is okay to add `noalias` metadata in backend, we really should be adding at least the alignment metadata to the AST, since that allows us to perform sema checks on it. Reviewers: erichkeane, rjmccall, jdoerfert, eugenis, rsmith Reviewed By: rsmith Subscribers: xbolva00, jrtc27, atanasyan, nlopes, cfe-commits Tags: #llvm, #clang Differential Revision: https://reviews.llvm.org/D73380 --- clang/include/clang/AST/Decl.h | 9 ++- clang/include/clang/Sema/Sema.h | 2 + clang/lib/AST/Decl.cpp | 12 ++- clang/lib/CodeGen/CGCall.cpp | 7 ++ clang/lib/CodeGen/CodeGenModule.cpp | 9 --- clang/lib/Sema/SemaDecl.cpp | 73 ++++++++++++++++++ clang/lib/Sema/SemaExprCXX.cpp | 6 +- clang/test/AST/ast-dump-stmt-json.cpp | 90 ++++++++++++++++++++++ clang/test/Analysis/new-ctor-malloc.cpp | 1 + clang/test/Analysis/new-ctor-null-throw.cpp | 2 + clang/test/Analysis/new-ctor-null.cpp | 2 + .../test/CodeGenCXX/align-avx-complete-objects.cpp | 4 +- clang/test/CodeGenCXX/arm.cpp | 18 ++--- clang/test/CodeGenCXX/builtin-calling-conv.cpp | 12 +-- .../CodeGenCXX/builtin-is-constant-evaluated.cpp | 4 +- .../CodeGenCXX/builtin-operator-new-delete.cpp | 11 ++- .../cxx0x-initializer-stdinitializerlist.cpp | 3 +- .../CodeGenCXX/cxx11-initializer-array-new.cpp | 7 +- clang/test/CodeGenCXX/cxx1z-aligned-allocation.cpp | 22 +++--- clang/test/CodeGenCXX/delete-two-arg.cpp | 8 +- clang/test/CodeGenCXX/dllexport.cpp | 4 +- clang/test/CodeGenCXX/dllimport.cpp | 4 +- clang/test/CodeGenCXX/exceptions.cpp | 22 +++--- clang/test/CodeGenCXX/goto.cpp | 2 +- .../CodeGenCXX/microsoft-abi-array-cookies.cpp | 6 +- clang/test/CodeGenCXX/mips-size_t-ptrdiff_t.cpp | 12 +-- clang/test/CodeGenCXX/multi-dim-operator-new.cpp | 7 +- clang/test/CodeGenCXX/new-alias.cpp | 2 +- clang/test/CodeGenCXX/new-array-init.cpp | 14 ++-- clang/test/CodeGenCXX/new-overflow.cpp | 18 ++--- clang/test/CodeGenCXX/new.cpp | 62 +++++++-------- clang/test/CodeGenCXX/operator-new.cpp | 24 +++--- clang/test/CodeGenCXX/runtime-dllstorage.cpp | 7 +- clang/test/CodeGenCXX/static-init.cpp | 2 +- clang/test/CodeGenCoroutines/coro-alloc.cpp | 10 +-- clang/test/CodeGenCoroutines/coro-cleanup.cpp | 2 +- clang/test/CodeGenCoroutines/coro-gro-nrvo.cpp | 4 +- clang/test/CodeGenCoroutines/coro-gro.cpp | 2 +- clang/test/CodeGenCoroutines/coro-return.cpp | 4 +- clang/test/CodeGenObjCXX/arc-new-delete.mm | 16 ++-- clang/test/CodeGenObjCXX/copy.mm | 2 +- clang/test/SemaCXX/builtin-operator-new-delete.cpp | 2 +- clang/test/SemaCXX/new-delete.cpp | 12 +-- 43 files changed, 359 insertions(+), 183 deletions(-) diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index 43c6c7b8..b31cbab 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -2306,8 +2306,13 @@ public: /// allocation function. [...] /// /// If this function is an aligned allocation/deallocation function, return - /// true through IsAligned. - bool isReplaceableGlobalAllocationFunction(bool *IsAligned = nullptr) const; + /// the parameter number of the requested alignment through AlignmentParam. + /// + /// If this function is an allocation/deallocation function that takes + /// the `std::nothrow_t` tag, return true through IsNothrow, + bool isReplaceableGlobalAllocationFunction( + Optional *AlignmentParam = nullptr, + bool *IsNothrow = nullptr) const; /// Determine if this function provides an inline implementation of a builtin. bool isInlineBuiltinDeclaration() const; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index f100b576..2d7676e 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -3796,6 +3796,8 @@ public: SourceLocation Loc); NamedDecl *ImplicitlyDefineFunction(SourceLocation Loc, IdentifierInfo &II, Scope *S); + void AddKnownFunctionAttributesForReplaceableGlobalAllocationFunction( + FunctionDecl *FD); void AddKnownFunctionAttributes(FunctionDecl *FD); // More parsing and symbol table subroutines. diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 216137b..7625acd 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -2952,7 +2952,8 @@ bool FunctionDecl::isReservedGlobalPlacementOperator() const { return (proto->getParamType(1).getCanonicalType() == Context.VoidPtrTy); } -bool FunctionDecl::isReplaceableGlobalAllocationFunction(bool *IsAligned) const { +bool FunctionDecl::isReplaceableGlobalAllocationFunction( + Optional *AlignmentParam, bool *IsNothrow) const { if (getDeclName().getNameKind() != DeclarationName::CXXOperatorName) return false; if (getDeclName().getCXXOverloadedOperator() != OO_New && @@ -2999,9 +3000,9 @@ bool FunctionDecl::isReplaceableGlobalAllocationFunction(bool *IsAligned) const // In C++17, the next parameter can be a 'std::align_val_t' for aligned // new/delete. if (Ctx.getLangOpts().AlignedAllocation && !Ty.isNull() && Ty->isAlignValT()) { - if (IsAligned) - *IsAligned = true; Consume(); + if (AlignmentParam) + *AlignmentParam = Params; } // Finally, if this is not a sized delete, the final parameter can @@ -3010,8 +3011,11 @@ bool FunctionDecl::isReplaceableGlobalAllocationFunction(bool *IsAligned) const Ty = Ty->getPointeeType(); if (Ty.getCVRQualifiers() != Qualifiers::Const) return false; - if (Ty->isNothrowT()) + if (Ty->isNothrowT()) { + if (IsNothrow) + *IsNothrow = true; Consume(); + } } return Params == FPT->getNumParams(); diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 98365db..42d5467 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -1906,6 +1906,13 @@ void CodeGenModule::ConstructAttributeList( if (const FunctionDecl *Fn = dyn_cast(TargetDecl)) { AddAttributesFromFunctionProtoType( getContext(), FuncAttrs, Fn->getType()->getAs()); + if (AttrOnCallSite && Fn->isReplaceableGlobalAllocationFunction()) { + // A sane operator new returns a non-aliasing pointer. + auto Kind = Fn->getDeclName().getCXXOverloadedOperator(); + if (getCodeGenOpts().AssumeSaneOperatorNew && + (Kind == OO_New || Kind == OO_Array_New)) + RetAttrs.addAttribute(llvm::Attribute::NoAlias); + } const CXXMethodDecl *MD = dyn_cast(Fn); const bool IsVirtualCall = MD && MD->isVirtual(); // Don't use [[noreturn]], _Noreturn or [[no_builtin]] for a call to a diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index d4ed486..652efd8 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -1875,15 +1875,6 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD, llvm::Function *F, // default, only if it is invoked by a new-expression or delete-expression. F->addAttribute(llvm::AttributeList::FunctionIndex, llvm::Attribute::NoBuiltin); - - // A sane operator new returns a non-aliasing pointer. - // FIXME: Also add NonNull attribute to the return value - // for the non-nothrow forms? - auto Kind = FD->getDeclName().getCXXOverloadedOperator(); - if (getCodeGenOpts().AssumeSaneOperatorNew && - (Kind == OO_New || Kind == OO_Array_New)) - F->addAttribute(llvm::AttributeList::ReturnIndex, - llvm::Attribute::NoAlias); } if (isa(FD) || isa(FD)) diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 4c088aa..7fe3213 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -14475,6 +14475,77 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc, return FD; } +/// If this function is a C++ replaceable global allocation function +/// (C++2a [basic.stc.dynamic.allocation], C++2a [new.delete]), +/// adds any function attributes that we know a priori based on the standard. +/// +/// We need to check for duplicate attributes both here and where user-written +/// attributes are applied to declarations. +void Sema::AddKnownFunctionAttributesForReplaceableGlobalAllocationFunction( + FunctionDecl *FD) { + if (FD->isInvalidDecl()) + return; + + if (FD->getDeclName().getCXXOverloadedOperator() != OO_New && + FD->getDeclName().getCXXOverloadedOperator() != OO_Array_New) + return; + + Optional AlignmentParam; + bool IsNothrow = false; + if (!FD->isReplaceableGlobalAllocationFunction(&AlignmentParam, &IsNothrow)) + return; + + // C++2a [basic.stc.dynamic.allocation]p4: + // An allocation function that has a non-throwing exception specification + // indicates failure by returning a null pointer value. Any other allocation + // function never returns a null pointer value and indicates failure only by + // throwing an exception [...] + if (!IsNothrow && !FD->hasAttr()) + FD->addAttr(ReturnsNonNullAttr::CreateImplicit(Context, FD->getLocation())); + + // C++2a [basic.stc.dynamic.allocation]p2: + // An allocation function attempts to allocate the requested amount of + // storage. [...] If the request succeeds, the value returned by a + // replaceable allocation function is a [...] pointer value p0 different + // from any previously returned value p1 [...] + // + // However, this particular information is being added in codegen, + // because there is an opt-out switch for it (-fno-assume-sane-operator-new) + + // C++2a [basic.stc.dynamic.allocation]p2: + // An allocation function attempts to allocate the requested amount of + // storage. If it is successful, it returns the address of the start of a + // block of storage whose length in bytes is at least as large as the + // requested size. + if (!FD->hasAttr()) { + FD->addAttr(AllocSizeAttr::CreateImplicit( + Context, /*ElemSizeParam=*/ParamIdx(1, FD), + /*NumElemsParam=*/ParamIdx(), FD->getLocation())); + } + + // C++2a [basic.stc.dynamic.allocation]p3: + // For an allocation function [...], the pointer returned on a successful + // call shall represent the address of storage that is aligned as follows: + // (3.1) If the allocation function takes an argument of type + // std​::​align_­val_­t, the storage will have the alignment + // specified by the value of this argument. + if (AlignmentParam.hasValue() && !FD->hasAttr()) { + FD->addAttr(AllocAlignAttr::CreateImplicit( + Context, ParamIdx(AlignmentParam.getValue(), FD), FD->getLocation())); + } + + // FIXME: + // C++2a [basic.stc.dynamic.allocation]p3: + // For an allocation function [...], the pointer returned on a successful + // call shall represent the address of storage that is aligned as follows: + // (3.2) Otherwise, if the allocation function is named operator new[], + // the storage is aligned for any object that does not have + // new-extended alignment ([basic.align]) and is no larger than the + // requested size. + // (3.3) Otherwise, the storage is aligned for any object that does not + // have new-extended alignment and is of the requested size. +} + /// Adds any function attributes that we know a priori based on /// the declaration of this function. /// @@ -14575,6 +14646,8 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) { } } + AddKnownFunctionAttributesForReplaceableGlobalAllocationFunction(FD); + // If C++ exceptions are enabled but we are told extern "C" functions cannot // throw, add an implicit nothrow attribute to any extern "C" function we come // across. diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 9e5c735..44fd699 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -1788,8 +1788,9 @@ Sema::isUnavailableAlignedAllocationFunction(const FunctionDecl &FD) const { return false; if (FD.isDefined()) return false; - bool IsAligned = false; - if (FD.isReplaceableGlobalAllocationFunction(&IsAligned) && IsAligned) + Optional AlignmentParam; + if (FD.isReplaceableGlobalAllocationFunction(&AlignmentParam) && + AlignmentParam.hasValue()) return true; return false; } @@ -2943,6 +2944,7 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name, Alloc->setParams(ParamDecls); if (ExtraAttr) Alloc->addAttr(ExtraAttr); + AddKnownFunctionAttributesForReplaceableGlobalAllocationFunction(Alloc); Context.getTranslationUnitDecl()->addDecl(Alloc); IdResolver.tryAddTopLevelDecl(Alloc, Name); }; diff --git a/clang/test/AST/ast-dump-stmt-json.cpp b/clang/test/AST/ast-dump-stmt-json.cpp index 85a3a66..f7f3a2c 100644 --- a/clang/test/AST/ast-dump-stmt-json.cpp +++ b/clang/test/AST/ast-dump-stmt-json.cpp @@ -1461,6 +1461,24 @@ void TestDependentGenericSelectionExpr(Ty T) { // CHECK-NEXT: "end": {} // CHECK-NEXT: }, // CHECK-NEXT: "implicit": true +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "ReturnsNonNullAttr", +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": {}, +// CHECK-NEXT: "end": {} +// CHECK-NEXT: }, +// CHECK-NEXT: "implicit": true +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "AllocSizeAttr", +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": {}, +// CHECK-NEXT: "end": {} +// CHECK-NEXT: }, +// CHECK-NEXT: "implicit": true // CHECK-NEXT: } // CHECK-NEXT: ] // CHECK-NEXT: } @@ -1513,6 +1531,33 @@ void TestDependentGenericSelectionExpr(Ty T) { // CHECK-NEXT: "end": {} // CHECK-NEXT: }, // CHECK-NEXT: "implicit": true +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "ReturnsNonNullAttr", +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": {}, +// CHECK-NEXT: "end": {} +// CHECK-NEXT: }, +// CHECK-NEXT: "implicit": true +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "AllocSizeAttr", +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": {}, +// CHECK-NEXT: "end": {} +// CHECK-NEXT: }, +// CHECK-NEXT: "implicit": true +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "AllocAlignAttr", +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": {}, +// CHECK-NEXT: "end": {} +// CHECK-NEXT: }, +// CHECK-NEXT: "implicit": true // CHECK-NEXT: } // CHECK-NEXT: ] // CHECK-NEXT: } @@ -1553,6 +1598,24 @@ void TestDependentGenericSelectionExpr(Ty T) { // CHECK-NEXT: "end": {} // CHECK-NEXT: }, // CHECK-NEXT: "implicit": true +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "ReturnsNonNullAttr", +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": {}, +// CHECK-NEXT: "end": {} +// CHECK-NEXT: }, +// CHECK-NEXT: "implicit": true +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "AllocSizeAttr", +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": {}, +// CHECK-NEXT: "end": {} +// CHECK-NEXT: }, +// CHECK-NEXT: "implicit": true // CHECK-NEXT: } // CHECK-NEXT: ] // CHECK-NEXT: } @@ -1605,6 +1668,33 @@ void TestDependentGenericSelectionExpr(Ty T) { // CHECK-NEXT: "end": {} // CHECK-NEXT: }, // CHECK-NEXT: "implicit": true +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "ReturnsNonNullAttr", +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": {}, +// CHECK-NEXT: "end": {} +// CHECK-NEXT: }, +// CHECK-NEXT: "implicit": true +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "AllocSizeAttr", +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": {}, +// CHECK-NEXT: "end": {} +// CHECK-NEXT: }, +// CHECK-NEXT: "implicit": true +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "AllocAlignAttr", +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": {}, +// CHECK-NEXT: "end": {} +// CHECK-NEXT: }, +// CHECK-NEXT: "implicit": true // CHECK-NEXT: } // CHECK-NEXT: ] // CHECK-NEXT: } diff --git a/clang/test/Analysis/new-ctor-malloc.cpp b/clang/test/Analysis/new-ctor-malloc.cpp index 74b1e21..e38433e 100644 --- a/clang/test/Analysis/new-ctor-malloc.cpp +++ b/clang/test/Analysis/new-ctor-malloc.cpp @@ -11,6 +11,7 @@ void *operator new(size_t size) throw() { if (!x) // expected-note {{Assuming 'x' is non-null}} // expected-note@-1 {{Taking false branch}} return nullptr; + // expected-warning@-1 {{null returned from function that requires a non-null return value}} return x; } diff --git a/clang/test/Analysis/new-ctor-null-throw.cpp b/clang/test/Analysis/new-ctor-null-throw.cpp index 28922c0..6c17ceb 100644 --- a/clang/test/Analysis/new-ctor-null-throw.cpp +++ b/clang/test/Analysis/new-ctor-null-throw.cpp @@ -15,10 +15,12 @@ typedef __typeof__(sizeof(int)) size_t; void *operator new(size_t size) { return nullptr; // expected-warning@-1 {{'operator new' should not return a null pointer unless it is declared 'throw()' or 'noexcept'}} + // expected-warning@-2 {{null returned from function that requires a non-null return value}} } void *operator new[](size_t size) { return nullptr; // expected-warning@-1 {{'operator new[]' should not return a null pointer unless it is declared 'throw()' or 'noexcept'}} + // expected-warning@-2 {{null returned from function that requires a non-null return value}} } struct S { diff --git a/clang/test/Analysis/new-ctor-null.cpp b/clang/test/Analysis/new-ctor-null.cpp index f3c07e2..7b4d67a 100644 --- a/clang/test/Analysis/new-ctor-null.cpp +++ b/clang/test/Analysis/new-ctor-null.cpp @@ -9,9 +9,11 @@ typedef __typeof__(sizeof(int)) size_t; void *operator new(size_t size) throw() { return nullptr; + // expected-warning@-1 {{null returned from function that requires a non-null return value}} } void *operator new[](size_t size) throw() { return nullptr; + // expected-warning@-1 {{null returned from function that requires a non-null return value}} } struct S { diff --git a/clang/test/CodeGenCXX/align-avx-complete-objects.cpp b/clang/test/CodeGenCXX/align-avx-complete-objects.cpp index ad4a914..6477da5 100644 --- a/clang/test/CodeGenCXX/align-avx-complete-objects.cpp +++ b/clang/test/CodeGenCXX/align-avx-complete-objects.cpp @@ -13,7 +13,7 @@ volatile float TestAlign(void) } // CHECK: [[R:%.*]] = alloca <8 x float>, align 32 -// CHECK-NEXT: [[CALL:%.*]] = call i8* @_Znwm(i64 32) +// CHECK-NEXT: [[CALL:%.*]] = call noalias nonnull i8* @_Znwm(i64 32) // CHECK-NEXT: [[ZERO:%.*]] = bitcast i8* [[CALL]] to <8 x float>* // CHECK-NEXT: store <8 x float>* [[ZERO]], <8 x float>** [[P:%.*]], align 8 // CHECK-NEXT: [[ONE:%.*]] = load <8 x float>*, <8 x float>** [[P]], align 8 @@ -42,7 +42,7 @@ volatile float TestAlign2(void) } // CHECK: [[R:%.*]] = alloca <8 x float>, align 32 -// CHECK-NEXT: [[CALL:%.*]] = call i8* @_Znwm(i64 32) +// CHECK-NEXT: [[CALL:%.*]] = call noalias nonnull i8* @_Znwm(i64 32) // CHECK-NEXT: [[ZERO:%.*]] = bitcast i8* [[CALL]] to <8 x float>* // CHECK-NEXT: store <8 x float>* [[ZERO]], <8 x float>** [[P:%.*]], align 8 // CHECK-NEXT: [[ONE:%.*]] = load <8 x float>*, <8 x float>** [[P]], align 8 diff --git a/clang/test/CodeGenCXX/arm.cpp b/clang/test/CodeGenCXX/arm.cpp index 7eba017..663c6a0 100644 --- a/clang/test/CodeGenCXX/arm.cpp +++ b/clang/test/CodeGenCXX/arm.cpp @@ -110,7 +110,7 @@ namespace test3 { void a() { // CHECK-LABEL: define void @_ZN5test31aEv() - // CHECK: call i8* @_Znam(i32 48) + // CHECK: call noalias nonnull i8* @_Znam(i32 48) // CHECK: store i32 4 // CHECK: store i32 10 A *x = new A[10]; @@ -123,7 +123,7 @@ namespace test3 { // CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8) // CHECK: [[OR:%.*]] = or i1 // CHECK: [[SZ:%.*]] = select i1 [[OR]] - // CHECK: call i8* @_Znam(i32 [[SZ]]) + // CHECK: call noalias nonnull i8* @_Znam(i32 [[SZ]]) // CHECK: store i32 4 // CHECK: store i32 [[N]] A *x = new A[n]; @@ -131,7 +131,7 @@ namespace test3 { void c() { // CHECK-LABEL: define void @_ZN5test31cEv() - // CHECK: call i8* @_Znam(i32 808) + // CHECK: call noalias nonnull i8* @_Znam(i32 808) // CHECK: store i32 4 // CHECK: store i32 200 A (*x)[20] = new A[10][20]; @@ -144,7 +144,7 @@ namespace test3 { // CHECK: [[NE:%.*]] = mul i32 [[N]], 20 // CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8) // CHECK: [[SZ:%.*]] = select - // CHECK: call i8* @_Znam(i32 [[SZ]]) + // CHECK: call noalias nonnull i8* @_Znam(i32 [[SZ]]) // CHECK: store i32 4 // CHECK: store i32 [[NE]] A (*x)[20] = new A[n][20]; @@ -185,7 +185,7 @@ namespace test4 { void a() { // CHECK-LABEL: define void @_ZN5test41aEv() - // CHECK: call i8* @_Znam(i32 48) + // CHECK: call noalias nonnull i8* @_Znam(i32 48) // CHECK: store i32 4 // CHECK: store i32 10 A *x = new A[10]; @@ -197,7 +197,7 @@ namespace test4 { // CHECK: @llvm.umul.with.overflow.i32(i32 [[N]], i32 4) // CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8) // CHECK: [[SZ:%.*]] = select - // CHECK: call i8* @_Znam(i32 [[SZ]]) + // CHECK: call noalias nonnull i8* @_Znam(i32 [[SZ]]) // CHECK: store i32 4 // CHECK: store i32 [[N]] A *x = new A[n]; @@ -205,7 +205,7 @@ namespace test4 { void c() { // CHECK-LABEL: define void @_ZN5test41cEv() - // CHECK: call i8* @_Znam(i32 808) + // CHECK: call noalias nonnull i8* @_Znam(i32 808) // CHECK: store i32 4 // CHECK: store i32 200 A (*x)[20] = new A[10][20]; @@ -218,7 +218,7 @@ namespace test4 { // CHECK: [[NE:%.*]] = mul i32 [[N]], 20 // CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8) // CHECK: [[SZ:%.*]] = select - // CHECK: call i8* @_Znam(i32 [[SZ]]) + // CHECK: call noalias nonnull i8* @_Znam(i32 [[SZ]]) // CHECK: store i32 4 // CHECK: store i32 [[NE]] A (*x)[20] = new A[n][20]; @@ -386,7 +386,7 @@ namespace test9 { // CHECK-NEXT: [[OVERFLOW:%.*]] = or i1 [[O0]], [[O1]] // CHECK-NEXT: [[T3:%.*]] = extractvalue { i32, i1 } [[T2]], 0 // CHECK-NEXT: [[T4:%.*]] = select i1 [[OVERFLOW]], i32 -1, i32 [[T3]] -// CHECK-NEXT: [[ALLOC:%.*]] = call i8* @_Znam(i32 [[T4]]) +// CHECK-NEXT: [[ALLOC:%.*]] = call noalias nonnull i8* @_Znam(i32 [[T4]]) // CHECK-NEXT: [[T0:%.*]] = bitcast i8* [[ALLOC]] to i32* // CHECK-NEXT: store i32 16, i32* [[T0]] // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i32, i32* [[T0]], i32 1 diff --git a/clang/test/CodeGenCXX/builtin-calling-conv.cpp b/clang/test/CodeGenCXX/builtin-calling-conv.cpp index f7759e3..11e8114 100644 --- a/clang/test/CodeGenCXX/builtin-calling-conv.cpp +++ b/clang/test/CodeGenCXX/builtin-calling-conv.cpp @@ -27,27 +27,27 @@ void user() { } // LINUX: define void @_Z4userv() -// LINUX: call i8* @_Znwm +// LINUX: call noalias nonnull i8* @_Znwm // LINUX: call float @atan2f // LINUX: call void @_Z3foov -// LINUX: declare noalias i8* @_Znwm(i64) +// LINUX: declare nonnull i8* @_Znwm(i64) // LINUX: declare float @atan2f(float, float) // LINUX: declare void @_Z3foov() // SPIR: define spir_func void @_Z4userv() -// SPIR: call spir_func i8* @_Znwj +// SPIR: call spir_func noalias nonnull i8* @_Znwj // SPIR: call spir_func float @atan2f // SPIR: call spir_func void @_Z3foov -// SPIR: declare spir_func noalias i8* @_Znwj(i32) +// SPIR: declare spir_func nonnull i8* @_Znwj(i32) // SPIR: declare spir_func float @atan2f(float, float) // SPIR: declare spir_func void @_Z3foov() // Note: Windows /G options should not change the platform default calling // convention of builtins. // WIN32: define dso_local x86_stdcallcc void @"?user@@YGXXZ"() -// WIN32: call i8* @"??2@YAPAXI@Z" +// WIN32: call noalias nonnull i8* @"??2@YAPAXI@Z" // WIN32: call float @atan2f // WIN32: call x86_stdcallcc void @"?foo@@YGXXZ" -// WIN32: declare dso_local noalias i8* @"??2@YAPAXI@Z"( +// WIN32: declare dso_local nonnull i8* @"??2@YAPAXI@Z"( // WIN32: declare dso_local float @atan2f(float, float) // WIN32: declare dso_local x86_stdcallcc void @"?foo@@YGXXZ"() diff --git a/clang/test/CodeGenCXX/builtin-is-constant-evaluated.cpp b/clang/test/CodeGenCXX/builtin-is-constant-evaluated.cpp index 74f414d..cc4e375 100644 --- a/clang/test/CodeGenCXX/builtin-is-constant-evaluated.cpp +++ b/clang/test/CodeGenCXX/builtin-is-constant-evaluated.cpp @@ -84,7 +84,7 @@ void test_arr_expr() { // CHECK-ARR-LABEL: define void @_Z17test_new_arr_exprv void test_new_arr_expr() { - // CHECK-ARR: call i8* @_Znam(i64 17) + // CHECK-ARR: call noalias nonnull i8* @_Znam(i64 17) new char[std::is_constant_evaluated() || __builtin_is_constant_evaluated() ? 1 : 17]; } @@ -130,4 +130,4 @@ void test_ref_to_static_var() { static int i_non_constant = 101; // CHECK-FOLD: store i32* @_ZZ22test_ref_to_static_varvE10i_constant, i32** %r, int &r = __builtin_is_constant_evaluated() ? i_constant : i_non_constant; -} \ No newline at end of file +} diff --git a/clang/test/CodeGenCXX/builtin-operator-new-delete.cpp b/clang/test/CodeGenCXX/builtin-operator-new-delete.cpp index 712805a..fe220fe 100644 --- a/clang/test/CodeGenCXX/builtin-operator-new-delete.cpp +++ b/clang/test/CodeGenCXX/builtin-operator-new-delete.cpp @@ -37,27 +37,26 @@ void *operator new[](size_t, void*, bool) throw(); // CHECK-LABEL: define void @test_basic( extern "C" void test_basic() { - // CHECK: call i8* @_Znwm(i64 4) [[ATTR_BUILTIN_NEW:#[^ ]*]] + // CHECK: call noalias nonnull i8* @_Znwm(i64 4) [[ATTR_BUILTIN_NEW:#[^ ]*]] // CHECK: call void @_ZdlPv({{.*}}) [[ATTR_BUILTIN_DELETE:#[^ ]*]] // CHECK: ret void __builtin_operator_delete(__builtin_operator_new(4)); } -// CHECK: declare noalias i8* @_Znwm(i64) [[ATTR_NOBUILTIN:#[^ ]*]] +// CHECK: declare nonnull i8* @_Znwm(i64) [[ATTR_NOBUILTIN:#[^ ]*]] // CHECK: declare void @_ZdlPv(i8*) [[ATTR_NOBUILTIN_NOUNWIND:#[^ ]*]] // CHECK-LABEL: define void @test_aligned_alloc( extern "C" void test_aligned_alloc() { - // CHECK: call i8* @_ZnwmSt11align_val_t(i64 4, i64 4) [[ATTR_BUILTIN_NEW:#[^ ]*]] + // CHECK: call noalias nonnull align 4 i8* @_ZnwmSt11align_val_t(i64 4, i64 4) [[ATTR_BUILTIN_NEW:#[^ ]*]] // CHECK: call void @_ZdlPvSt11align_val_t({{.*}}, i64 4) [[ATTR_BUILTIN_DELETE:#[^ ]*]] __builtin_operator_delete(__builtin_operator_new(4, std::align_val_t(4)), std::align_val_t(4)); } -// CHECK: declare noalias i8* @_ZnwmSt11align_val_t(i64, i64) [[ATTR_NOBUILTIN:#[^ ]*]] +// CHECK: declare nonnull i8* @_ZnwmSt11align_val_t(i64, i64) [[ATTR_NOBUILTIN:#[^ ]*]] // CHECK: declare void @_ZdlPvSt11align_val_t(i8*, i64) [[ATTR_NOBUILTIN_NOUNWIND:#[^ ]*]] - // CHECK-LABEL: define void @test_sized_delete( extern "C" void test_sized_delete() { - // CHECK: call i8* @_Znwm(i64 4) [[ATTR_BUILTIN_NEW:#[^ ]*]] + // CHECK: call noalias nonnull i8* @_Znwm(i64 4) [[ATTR_BUILTIN_NEW:#[^ ]*]] // CHECK: call void @_ZdlPvm({{.*}}, i64 4) [[ATTR_BUILTIN_DELETE:#[^ ]*]] __builtin_operator_delete(__builtin_operator_new(4), 4); } diff --git a/clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp b/clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp index e3c7e26..13b6c63 100644 --- a/clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp +++ b/clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp @@ -239,7 +239,8 @@ void fn9() { void fn10(int i) { // CHECK-LABEL: define void @_Z4fn10i // CHECK: alloca [3 x i32] - // CHECK: call i8* @_Znw{{[jm]}} + // CHECK-X86: call noalias nonnull align 16 i8* @_Znw{{[jm]}} + // CHECK-AMDGPU: call noalias nonnull align 8 i8* @_Znw{{[jm]}} // CHECK: store i32 % // CHECK: store i32 2 // CHECK: store i32 3 diff --git a/clang/test/CodeGenCXX/cxx11-initializer-array-new.cpp b/clang/test/CodeGenCXX/cxx11-initializer-array-new.cpp index 6e24212..f8e3441 100644 --- a/clang/test/CodeGenCXX/cxx11-initializer-array-new.cpp +++ b/clang/test/CodeGenCXX/cxx11-initializer-array-new.cpp @@ -7,7 +7,7 @@ struct S { S(); S(int); ~S(); int n; }; void *p = new S[2][3]{ { 1, 2, 3 }, { 4, 5, 6 } }; // CHECK-LABEL: define -// CHECK: %[[ALLOC:.*]] = call i8* @_Znam(i64 32) +// CHECK: %[[ALLOC:.*]] = call noalias nonnull i8* @_Znam(i64 32) // CHECK: %[[COOKIE:.*]] = bitcast i8* %[[ALLOC]] to i64* // CHECK: store i64 6, i64* %[[COOKIE]] // CHECK: %[[START_AS_i8:.*]] = getelementptr inbounds i8, i8* %[[ALLOC]], i64 8 @@ -50,7 +50,7 @@ void *q = new S[n][3]{ { 1, 2, 3 }, { 4, 5, 6 } }; // CHECK: call {{.*}} @llvm.umul.with.overflow.i64(i64 %[[N:.*]], i64 12) // CHECK: %[[ELTS:.*]] = mul i64 %[[N]], 3 // CHECK: call {{.*}} @llvm.uadd.with.overflow.i64(i64 %{{.*}}, i64 8) -// CHECK: %[[ALLOC:.*]] = call i8* @_Znam(i64 %{{.*}}) +// CHECK: %[[ALLOC:.*]] = call noalias nonnull i8* @_Znam(i64 %{{.*}}) // // CHECK: %[[COOKIE:.*]] = bitcast i8* %[[ALLOC]] to i64* // CHECK: store i64 %[[ELTS]], i64* %[[COOKIE]] @@ -113,7 +113,7 @@ void *r = new T[n][3]{ { 1, 2, 3 }, { 4, 5, 6 } }; // No cookie. // CHECK-NOT: @llvm.uadd.with.overflow // -// CHECK: %[[ALLOC:.*]] = call i8* @_Znam(i64 %{{.*}}) +// CHECK: %[[ALLOC:.*]] = call noalias nonnull i8* @_Znam(i64 %{{.*}}) // // CHECK: %[[START_AS_T:.*]] = bitcast i8* %[[ALLOC]] to %[[T:.*]]* // @@ -157,4 +157,3 @@ void *r = new T[n][3]{ { 1, 2, 3 }, { 4, 5, 6 } }; // CHECK: call void @llvm.memset.p0i8.i64(i8* align 4 %[[REST]], i8 0, i64 %[[SIZE]], i1 false) // // CHECK: } - diff --git a/clang/test/CodeGenCXX/cxx1z-aligned-allocation.cpp b/clang/test/CodeGenCXX/cxx1z-aligned-allocation.cpp index 2e2bfc5..d2b5b64 100644 --- a/clang/test/CodeGenCXX/cxx1z-aligned-allocation.cpp +++ b/clang/test/CodeGenCXX/cxx1z-aligned-allocation.cpp @@ -27,10 +27,10 @@ namespace std { enum class align_val_t : size_t {}; } struct OVERALIGNED A { A(); int n[128]; }; // CHECK-LABEL: define {{.*}} @_Z2a0v() -// CHECK: %[[ALLOC:.*]] = call i8* @_ZnwmSt11align_val_t(i64 512, i64 32) +// CHECK: %[[ALLOC:.*]] = call noalias nonnull align 32 i8* @_ZnwmSt11align_val_t(i64 512, i64 32) // CHECK: call void @_ZdlPvSt11align_val_t(i8* %[[ALLOC]], i64 32) // CHECK-MS-LABEL: define {{.*}} @"?a0@@YAPEAXXZ"() -// CHECK-MS: %[[ALLOC:.*]] = call i8* @"??2@YAPEAX_KW4align_val_t@std@@@Z"(i64 512, i64 32) +// CHECK-MS: %[[ALLOC:.*]] = call noalias nonnull align 32 i8* @"??2@YAPEAX_KW4align_val_t@std@@@Z"(i64 512, i64 32) // CHECK-MS: cleanuppad // CHECK-MS: call void @"??3@YAXPEAXW4align_val_t@std@@@Z"(i8* %[[ALLOC]], i64 32) void *a0() { return new A; } @@ -39,13 +39,13 @@ void *a0() { return new A; } // The size is known. // // CHECK-LABEL: define {{.*}} @_Z2a1l( -// CHECK: %[[ALLOC:.*]] = call i8* @_ZnamSt11align_val_t(i64 %{{.*}}, i64 32) +// CHECK: %[[ALLOC:.*]] = call noalias nonnull align 32 i8* @_ZnamSt11align_val_t(i64 %{{.*}}, i64 32) // No array cookie. // CHECK-NOT: store // CHECK: invoke void @_ZN1AC1Ev( // CHECK: call void @_ZdaPvSt11align_val_t(i8* %[[ALLOC]], i64 32) // CHECK-MS-LABEL: define {{.*}} @"?a1@@YAPEAXJ@Z"( -// CHECK-MS: %[[ALLOC:.*]] = call i8* @"??_U@YAPEAX_KW4align_val_t@std@@@Z"(i64 %{{.*}}, i64 32) +// CHECK-MS: %[[ALLOC:.*]] = call noalias nonnull align 32 i8* @"??_U@YAPEAX_KW4align_val_t@std@@@Z"(i64 %{{.*}}, i64 32) // No array cookie. // CHECK-MS-NOT: store // CHECK-MS: invoke %struct.A* @"??0A@@QEAA@XZ"( @@ -84,7 +84,7 @@ struct OVERALIGNED B { void *b0() { return new B; } // CHECK-LABEL: define {{.*}} @_Z2b1l( -// CHECK: %[[ALLOC:.*]] = call i8* @_ZnamSt11align_val_t(i64 %{{.*}}, i64 32) +// CHECK: %[[ALLOC:.*]] = call noalias nonnull align 32 i8* @_ZnamSt11align_val_t(i64 %{{.*}}, i64 32) // No array cookie. // CHECK-NOT: store // CHECK: invoke void @_ZN1BC1Ev( @@ -169,14 +169,14 @@ void *d0() { return new (q) D; } #ifndef UNALIGNED // CHECK-LABEL: define {{.*}} @_Z2e0v( -// CHECK: %[[ALLOC:.*]] = call i8* @_ZnwmSt11align_val_t(i64 512, i64 5) -// CHECK: call void @_ZdlPvSt11align_val_t(i8* %[[ALLOC]], i64 5) -void *e0() { return new (std::align_val_t(5)) A; } +// CHECK: %[[ALLOC:.*]] = call noalias nonnull align 4 i8* @_ZnwmSt11align_val_t(i64 512, i64 4) +// CHECK: call void @_ZdlPvSt11align_val_t(i8* %[[ALLOC]], i64 4) +void *e0() { return new (std::align_val_t(4)) A; } // CHECK-LABEL: define {{.*}} @_Z2e1v( -// CHECK: %[[ALLOC:.*]] = call i8* @_ZN1BnwEmSt11align_val_t(i64 512, i64 5) -// CHECK: call void @_ZN1BdlEPvSt11align_val_t(i8* %[[ALLOC]], i64 5) -void *e1() { return new (std::align_val_t(5)) B; } +// CHECK: %[[ALLOC:.*]] = call i8* @_ZN1BnwEmSt11align_val_t(i64 512, i64 4) +// CHECK: call void @_ZN1BdlEPvSt11align_val_t(i8* %[[ALLOC]], i64 4) +void *e1() { return new (std::align_val_t(4)) B; } #endif // Variadic placement/non-placement allocation functions. diff --git a/clang/test/CodeGenCXX/delete-two-arg.cpp b/clang/test/CodeGenCXX/delete-two-arg.cpp index 68a6fa6..3000ece 100644 --- a/clang/test/CodeGenCXX/delete-two-arg.cpp +++ b/clang/test/CodeGenCXX/delete-two-arg.cpp @@ -27,7 +27,7 @@ namespace test2 { // CHECK: define [[A:%.*]]* @_ZN5test24testEv() A *test() { - // CHECK: [[NEW:%.*]] = call i8* @_Znaj(i32 44) + // CHECK: [[NEW:%.*]] = call noalias nonnull 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, i8* [[NEW]], i32 4 @@ -58,13 +58,13 @@ namespace test3 { struct A { int x; void operator delete[](void *, size_t); - }; + }; struct B : A {}; // CHECK-LABEL: define void @_ZN5test34testEv() void test() { - // CHECK: call i8* @_Znaj(i32 24) - // CHECK-NEXT: bitcast + // CHECK: [[CALL:%.*]] = call noalias nonnull i8* @_Znaj(i32 24) + // CHECK-NEXT: bitcast i8* [[CALL]] to i32* // CHECK-NEXT: store i32 5 (void) new B[5]; } diff --git a/clang/test/CodeGenCXX/dllexport.cpp b/clang/test/CodeGenCXX/dllexport.cpp index 045cb45..fcbd937 100644 --- a/clang/test/CodeGenCXX/dllexport.cpp +++ b/clang/test/CodeGenCXX/dllexport.cpp @@ -305,8 +305,8 @@ struct __declspec(dllexport) Befriended { void Befriended::func() {} // Implicit declarations can be redeclared with dllexport. -// MSC-DAG: define dso_local dllexport noalias i8* @"??2@{{YAPAXI|YAPEAX_K}}@Z"( -// GNU-DAG: define dso_local dllexport noalias i8* @_Znw{{[yj]}}( +// MSC-DAG: define dso_local dllexport nonnull i8* @"??2@{{YAPAXI|YAPEAX_K}}@Z"( +// GNU-DAG: define dso_local dllexport nonnull i8* @_Znw{{[yj]}}( void* alloc(__SIZE_TYPE__ n); __declspec(dllexport) void* operator new(__SIZE_TYPE__ n) { return alloc(n); } diff --git a/clang/test/CodeGenCXX/dllimport.cpp b/clang/test/CodeGenCXX/dllimport.cpp index 2f4a1b9..530ddd31 100644 --- a/clang/test/CodeGenCXX/dllimport.cpp +++ b/clang/test/CodeGenCXX/dllimport.cpp @@ -308,8 +308,8 @@ USE(friend4) USE(friend5) // Implicit declarations can be redeclared with dllimport. -// MSC-DAG: declare dllimport noalias i8* @"??2@{{YAPAXI|YAPEAX_K}}@Z"( -// GNU-DAG: declare dllimport noalias i8* @_Znw{{[yj]}}( +// MSC-DAG: declare dllimport nonnull i8* @"??2@{{YAPAXI|YAPEAX_K}}@Z"( +// GNU-DAG: declare dllimport nonnull i8* @_Znw{{[yj]}}( __declspec(dllimport) void* operator new(__SIZE_TYPE__ n); void UNIQ(use)() { ::operator new(42); } diff --git a/clang/test/CodeGenCXX/exceptions.cpp b/clang/test/CodeGenCXX/exceptions.cpp index 302488a..90db402 100644 --- a/clang/test/CodeGenCXX/exceptions.cpp +++ b/clang/test/CodeGenCXX/exceptions.cpp @@ -31,7 +31,7 @@ namespace test1 { A *a() { // CHECK: define [[A:%.*]]* @_ZN5test11aEv() - // CHECK: [[NEW:%.*]] = call i8* @_Znwm(i64 8) + // CHECK: [[NEW:%.*]] = call noalias nonnull 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]] @@ -41,7 +41,7 @@ namespace test1 { A *b() { // CHECK: define [[A:%.*]]* @_ZN5test11bEv() - // CHECK: [[NEW:%.*]] = call i8* @_Znwm(i64 8) + // CHECK: [[NEW:%.*]] = call noalias nonnull 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]]) @@ -57,8 +57,8 @@ namespace test1 { A *c() { // CHECK: define [[A:%.*]]* @_ZN5test11cEv() // CHECK: [[ACTIVE:%.*]] = alloca i1 - // CHECK-NEXT: [[NEW:%.*]] = call i8* @_Znwm(i64 8) - // CHECK-NEXT: store i1 true, i1* [[ACTIVE]] + // CHECK-NEXT: [[NEW:%.*]] = call noalias nonnull 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]], [[B]]* [[T0]], i32 0, i32 0 @@ -86,8 +86,8 @@ namespace test1 { A *d() { // CHECK: define [[A:%.*]]* @_ZN5test11dEv() // CHECK: [[ACTIVE:%.*]] = alloca i1 - // CHECK-NEXT: [[NEW:%.*]] = call i8* @_Znwm(i64 8) - // CHECK-NEXT: store i1 true, i1* [[ACTIVE]] + // CHECK-NEXT: [[NEW:%.*]] = call noalias nonnull 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]]) @@ -107,8 +107,8 @@ namespace test1 { A *e() { // CHECK: define [[A:%.*]]* @_ZN5test11eEv() // CHECK: [[ACTIVE:%.*]] = alloca i1 - // CHECK-NEXT: [[NEW:%.*]] = call i8* @_Znwm(i64 8) - // CHECK-NEXT: store i1 true, i1* [[ACTIVE]] + // CHECK-NEXT: [[NEW:%.*]] = call noalias nonnull 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]]) @@ -143,8 +143,8 @@ namespace test1 { // CHECK: define [[A:%.*]]* @_ZN5test11iEv() // CHECK: [[X:%.*]] = alloca [[A]]*, align 8 // CHECK: [[ACTIVE:%.*]] = alloca i1 - // CHECK: [[NEW:%.*]] = call i8* @_Znwm(i64 8) - // CHECK-NEXT: store i1 true, i1* [[ACTIVE]] + // CHECK: [[NEW:%.*]] = call noalias nonnull 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]]) @@ -455,7 +455,7 @@ namespace test9 { return new A[10]; } // CHECK: define {{%.*}}* @_ZN5test94testEv - // CHECK: [[TEST9_NEW:%.*]] = call i8* @_Znam + // CHECK: [[TEST9_NEW:%.*]] = call noalias nonnull i8* @_Znam // CHECK: call void @_ZdaPv(i8* [[TEST9_NEW]]) } diff --git a/clang/test/CodeGenCXX/goto.cpp b/clang/test/CodeGenCXX/goto.cpp index 2f5b719..d0107ff 100644 --- a/clang/test/CodeGenCXX/goto.cpp +++ b/clang/test/CodeGenCXX/goto.cpp @@ -19,7 +19,7 @@ namespace test0 { // CHECK-NEXT: [[CLEANUPACTIVE:%.*]] = alloca i1 // CHECK: call void @_ZN5test01AC1Ev([[A]]* [[Y]]) // CHECK-NEXT: invoke void @_ZN5test01AC1Ev([[A]]* [[Z]]) - // CHECK: [[NEW:%.*]] = invoke i8* @_Znwm(i64 1) + // CHECK: [[NEW:%.*]] = invoke noalias nonnull i8* @_Znwm(i64 1) // CHECK: store i1 true, i1* [[CLEANUPACTIVE]] // CHECK: [[NEWCAST:%.*]] = bitcast i8* [[NEW]] to [[V]]* // CHECK-NEXT: invoke void @_ZN5test01AC1Ev([[A]]* [[TMP]]) diff --git a/clang/test/CodeGenCXX/microsoft-abi-array-cookies.cpp b/clang/test/CodeGenCXX/microsoft-abi-array-cookies.cpp index 2814045..52207b3 100644 --- a/clang/test/CodeGenCXX/microsoft-abi-array-cookies.cpp +++ b/clang/test/CodeGenCXX/microsoft-abi-array-cookies.cpp @@ -7,7 +7,7 @@ struct ClassWithoutDtor { void check_array_no_cookies() { // CHECK: define dso_local void @"?check_array_no_cookies@@YAXXZ"() [[NUW:#[0-9]+]] -// CHECK: call i8* @"??_U@YAPAXI@Z"(i32 42) +// CHECK: call noalias nonnull i8* @"??_U@YAPAXI@Z"(i32 42) ClassWithoutDtor *array = new ClassWithoutDtor[42]; // CHECK: call void @"??_V@YAXPAX@Z"( @@ -24,7 +24,7 @@ void check_array_cookies_simple() { // CHECK: define {{.*}} @"?check_array_cookies_simple@@YAXXZ"() ClassWithDtor *array = new ClassWithDtor[42]; -// CHECK: [[ALLOCATED:%.*]] = call i8* @"??_U@YAPAXI@Z"(i32 46) +// CHECK: [[ALLOCATED:%.*]] = call noalias nonnull i8* @"??_U@YAPAXI@Z"(i32 46) // 46 = 42 + size of cookie (4) // CHECK: [[COOKIE:%.*]] = bitcast i8* [[ALLOCATED]] to i32* // CHECK: store i32 42, i32* [[COOKIE]] @@ -46,7 +46,7 @@ struct __attribute__((aligned(8))) ClassWithAlignment { void check_array_cookies_aligned() { // CHECK: define {{.*}} @"?check_array_cookies_aligned@@YAXXZ"() ClassWithAlignment *array = new ClassWithAlignment[42]; -// CHECK: [[ALLOCATED:%.*]] = call i8* @"??_U@YAPAXI@Z"(i32 344) +// CHECK: [[ALLOCATED:%.*]] = call noalias nonnull i8* @"??_U@YAPAXI@Z"(i32 344) // 344 = 42*8 + size of cookie (8, due to alignment) // CHECK: [[COOKIE:%.*]] = bitcast i8* [[ALLOCATED]] to i32* // CHECK: store i32 42, i32* [[COOKIE]] diff --git a/clang/test/CodeGenCXX/mips-size_t-ptrdiff_t.cpp b/clang/test/CodeGenCXX/mips-size_t-ptrdiff_t.cpp index 5b245a4..ff55735 100644 --- a/clang/test/CodeGenCXX/mips-size_t-ptrdiff_t.cpp +++ b/clang/test/CodeGenCXX/mips-size_t-ptrdiff_t.cpp @@ -10,13 +10,13 @@ long *alloc_long() { return rv; } // O32-LABEL: define i32* @_Z10alloc_longv() -// O32: call i8* @_Znwj(i32 signext 4) +// O32: call noalias nonnull i8* @_Znwj(i32 signext 4) // N32-LABEL: define i32* @_Z10alloc_longv() -// N32: call i8* @_Znwj(i32 signext 4) +// N32: call noalias nonnull i8* @_Znwj(i32 signext 4) // N64-LABEL: define i64* @_Z10alloc_longv() -// N64: call i8* @_Znwm(i64 zeroext 8) +// N64: call noalias nonnull i8* @_Znwm(i64 zeroext 8) long *alloc_long_array() { long *rv = new long[2]; @@ -24,13 +24,13 @@ long *alloc_long_array() { } // O32-LABEL: define i32* @_Z16alloc_long_arrayv() -// O32: call i8* @_Znaj(i32 signext 8) +// O32: call noalias nonnull i8* @_Znaj(i32 signext 8) // N32-LABEL: define i32* @_Z16alloc_long_arrayv() -// N32: call i8* @_Znaj(i32 signext 8) +// N32: call noalias nonnull i8* @_Znaj(i32 signext 8) // N64-LABEL: define i64* @_Z16alloc_long_arrayv() -// N64: call i8* @_Znam(i64 zeroext 16) +// N64: call noalias nonnull i8* @_Znam(i64 zeroext 16) #include diff --git a/clang/test/CodeGenCXX/multi-dim-operator-new.cpp b/clang/test/CodeGenCXX/multi-dim-operator-new.cpp index 0dfcffb..5cd7383 100644 --- a/clang/test/CodeGenCXX/multi-dim-operator-new.cpp +++ b/clang/test/CodeGenCXX/multi-dim-operator-new.cpp @@ -43,7 +43,6 @@ int main() { return 0; } -// CHECK: call i8* @_Znam -// CHECK: call i8* @_Znam -// CHECK: call i8* @_Znam - +// CHECK: call noalias nonnull i8* @_Znam +// CHECK: call noalias nonnull i8* @_Znam +// CHECK: call noalias nonnull i8* @_Znam diff --git a/clang/test/CodeGenCXX/new-alias.cpp b/clang/test/CodeGenCXX/new-alias.cpp index b21638a..d7669ce 100644 --- a/clang/test/CodeGenCXX/new-alias.cpp +++ b/clang/test/CodeGenCXX/new-alias.cpp @@ -9,5 +9,5 @@ extern "C" char *something(long long x) { void *operator new(size_t) __attribute__((alias("something"))); // PR16715: don't assert here. -// CHECK: call i8* @_Znwm(i64 4){{$}} +// CHECK: call noalias nonnull i8* @_Znwm(i64 4) #3{{$}} int *pr16715 = new int; diff --git a/clang/test/CodeGenCXX/new-array-init.cpp b/clang/test/CodeGenCXX/new-array-init.cpp index b504d5e..97977ba 100644 --- a/clang/test/CodeGenCXX/new-array-init.cpp +++ b/clang/test/CodeGenCXX/new-array-init.cpp @@ -34,7 +34,7 @@ void check_array_value_init() { struct S; new (int S::*[3][4][5]) (); - // CHECK: call i8* @_Zna{{.}}(i{{32 240|64 480}}) + // CHECK: call noalias nonnull i8* @_Zna{{.}}(i{{32 240|64 480}}) // CHECK: getelementptr inbounds i{{32|64}}, i{{32|64}}* {{.*}}, i{{32|64}} 60 // CHECK: phi @@ -49,7 +49,7 @@ void string_nonconst(int n) { // CHECK: icmp slt i{{32|64}} %{{[^ ]+}}, 4 // FIXME: Conditionally throw an exception rather than passing -1 to alloc function // CHECK: select - // CHECK: %[[PTR:.*]] = call i8* @_Zna{{.}}(i{{32|64}} + // CHECK: %[[PTR:.*]] = call noalias nonnull i8* @_Zna{{.}}(i{{32|64}} // CHECK: call void @llvm.memcpy{{.*}}(i8* align {{[0-9]+}} %[[PTR]], i8* align {{[0-9]+}} getelementptr inbounds ([4 x i8], [4 x i8]* @[[ABC4]], i32 0, i32 0), i32 4, // CHECK: %[[REST:.*]] = getelementptr inbounds i8, i8* %[[PTR]], i32 4 // CHECK: %[[RESTSIZE:.*]] = sub {{.*}}, 4 @@ -60,7 +60,7 @@ void string_nonconst(int n) { // CHECK-LABEL: define void @_Z12string_exactv void string_exact() { // CHECK-NOT: icmp - // CHECK: %[[PTR:.*]] = call i8* @_Zna{{.}}(i{{32|64}} 4) + // CHECK: %[[PTR:.*]] = call noalias nonnull i8* @_Zna{{.}}(i{{32|64}} 4) // CHECK: call void @llvm.memcpy{{.*}}(i8* align {{[0-9]+}} %[[PTR]], i8* align {{[0-9]+}} getelementptr inbounds ([4 x i8], [4 x i8]* @[[ABC4]], i32 0, i32 0), i32 4, // CHECK-NOT: memset new char[4] { "abc" }; @@ -69,7 +69,7 @@ void string_exact() { // CHECK-LABEL: define void @_Z17string_sufficientv void string_sufficient() { // CHECK-NOT: icmp - // CHECK: %[[PTR:.*]] = call i8* @_Zna{{.}}(i{{32|64}} 15) + // CHECK: %[[PTR:.*]] = call noalias nonnull i8* @_Zna{{.}}(i{{32|64}} 15) // FIXME: For very large arrays, it would be preferable to emit a small copy and a memset. // CHECK: call void @llvm.memcpy{{.*}}(i8* align {{[0-9]+}} %[[PTR]], i8* align {{[0-9]+}} getelementptr inbounds ([15 x i8], [15 x i8]* @[[ABC15]], i32 0, i32 0), i32 15, // CHECK-NOT: memset @@ -79,7 +79,7 @@ void string_sufficient() { // CHECK-LABEL: define void @_Z10aggr_exactv void aggr_exact() { // CHECK-NOT: icmp - // CHECK: %[[MEM:.*]] = call i8* @_Zna{{.}}(i{{32|64}} 16) + // CHECK: %[[MEM:.*]] = call noalias nonnull i8* @_Zna{{.}}(i{{32|64}} 16) // CHECK: %[[PTR0:.*]] = bitcast i8* %[[MEM]] to %[[AGGR:.*]]* // CHECK: %[[FIELD:.*]] = getelementptr inbounds %[[AGGR]], %[[AGGR]]* %[[PTR0]], i32 0, i32 0{{$}} // CHECK: store i32 1, i32* %[[FIELD]] @@ -99,7 +99,7 @@ void aggr_exact() { // CHECK-LABEL: define void @_Z15aggr_sufficienti void aggr_sufficient(int n) { // CHECK: icmp ult i32 %{{.*}}, 2 - // CHECK: %[[MEM:.*]] = call i8* @_Zna{{.}}( + // CHECK: %[[MEM:.*]] = call noalias nonnull i8* @_Zna{{.}}( // CHECK: %[[PTR0:.*]] = bitcast i8* %[[MEM]] to %[[AGGR:.*]]* // CHECK: %[[FIELD:.*]] = getelementptr inbounds %[[AGGR]], %[[AGGR]]* %[[PTR0]], i32 0, i32 0{{$}} // CHECK: store i32 1, i32* %[[FIELD]] @@ -120,7 +120,7 @@ void aggr_sufficient(int n) { // SIO-LABEL: define void @_Z14constexpr_testv void constexpr_test() { - // SIO: call i8* @_Zna{{.}}(i32 4) + // SIO: call noalias nonnull i8* @_Zna{{.}}(i32 4) new int[0+1]{0}; } diff --git a/clang/test/CodeGenCXX/new-overflow.cpp b/clang/test/CodeGenCXX/new-overflow.cpp index a2269bf..e596afb 100644 --- a/clang/test/CodeGenCXX/new-overflow.cpp +++ b/clang/test/CodeGenCXX/new-overflow.cpp @@ -17,7 +17,7 @@ namespace test0 { // CHECK-NEXT: [[T1:%.*]] = extractvalue { i32, i1 } [[T0]], 1 // CHECK-NEXT: [[T2:%.*]] = extractvalue { i32, i1 } [[T0]], 0 // CHECK-NEXT: [[T3:%.*]] = select i1 [[T1]], i32 -1, i32 [[T2]] - // CHECK-NEXT: call i8* @_Znaj(i32 [[T3]]) + // CHECK-NEXT: call noalias nonnull i8* @_Znaj(i32 [[T3]]) // CHECK: getelementptr inbounds {{.*}}, i32 [[N]] elt *test(short s) { return new elt[s]; @@ -40,7 +40,7 @@ namespace test1 { // CHECK-NEXT: [[T2:%.*]] = extractvalue { i32, i1 } [[T0]], 0 // CHECK-NEXT: [[T3:%.*]] = mul i32 [[N]], 100 // CHECK-NEXT: [[T4:%.*]] = select i1 [[T1]], i32 -1, i32 [[T2]] - // CHECK-NEXT: call i8* @_Znaj(i32 [[T4]]) + // CHECK-NEXT: call noalias nonnull i8* @_Znaj(i32 [[T4]]) // CHECK: getelementptr inbounds {{.*}}, i32 [[T3]] elt *test(short s) { return new elt[s]; @@ -68,7 +68,7 @@ namespace test2 { // CHECK-NEXT: [[T6:%.*]] = or i1 [[T1]], [[T5]] // CHECK-NEXT: [[T7:%.*]] = extractvalue { i32, i1 } [[T4]], 0 // CHECK-NEXT: [[T8:%.*]] = select i1 [[T6]], i32 -1, i32 [[T7]] - // CHECK-NEXT: call i8* @_Znaj(i32 [[T8]]) + // CHECK-NEXT: call noalias nonnull i8* @_Znaj(i32 [[T8]]) // CHECK: getelementptr inbounds {{.*}}, i32 [[T3]] elt *test(short s) { return new elt[s]; @@ -85,7 +85,7 @@ namespace test4 { // CHECK: define [[A:%.*]]* @_ZN5test44testEs(i16 signext // CHECK: [[N:%.*]] = sext i16 {{%.*}} to i32 - // CHECK-NEXT: call i8* @_Znaj(i32 [[N]]) + // CHECK-NEXT: call noalias nonnull i8* @_Znaj(i32 [[N]]) // CHECK: getelementptr inbounds {{.*}}, i32 [[N]] elt *test(short s) { return new elt[s]; @@ -102,7 +102,7 @@ namespace test5 { // CHECK: define [[A:%.*]]* @_ZN5test54testEi(i32 // CHECK: [[N:%.*]] = load i32, i32* - // CHECK-NEXT: call i8* @_Znaj(i32 [[N]]) + // CHECK-NEXT: call noalias nonnull i8* @_Znaj(i32 [[N]]) // CHECK: getelementptr inbounds {{.*}}, i32 [[N]] elt *test(int s) { return new elt[s]; @@ -124,7 +124,7 @@ namespace test6 { // CHECK-NEXT: [[T1:%.*]] = extractvalue { i32, i1 } [[T0]], 1 // CHECK-NEXT: [[T2:%.*]] = extractvalue { i32, i1 } [[T0]], 0 // CHECK-NEXT: [[T3:%.*]] = select i1 [[T1]], i32 -1, i32 [[T2]] - // CHECK-NEXT: call i8* @_Znaj(i32 [[T3]]) + // CHECK-NEXT: call noalias nonnull i8* @_Znaj(i32 [[T3]]) // CHECK: getelementptr inbounds {{.*}}, i32 [[N]] elt *test(unsigned short s) { return new elt[s]; @@ -147,7 +147,7 @@ namespace test7 { // CHECK-NEXT: [[T2:%.*]] = extractvalue { i32, i1 } [[T0]], 0 // CHECK-NEXT: [[T3:%.*]] = mul i32 [[N]], 100 // CHECK-NEXT: [[T4:%.*]] = select i1 [[T1]], i32 -1, i32 [[T2]] - // CHECK-NEXT: call i8* @_Znaj(i32 [[T4]]) + // CHECK-NEXT: call noalias nonnull i8* @_Znaj(i32 [[T4]]) // CHECK: getelementptr inbounds {{.*}}, i32 [[T3]] elt *test(unsigned short s) { return new elt[s]; @@ -170,7 +170,7 @@ namespace test8 { // CHECK-NEXT: [[T3:%.*]] = extractvalue { i32, i1 } [[T2]], 1 // CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T2]], 0 // CHECK-NEXT: [[T6:%.*]] = select i1 [[T3]], i32 -1, i32 [[T5]] - // CHECK-NEXT: call i8* @_Znaj(i32 [[T6]]) + // CHECK-NEXT: call noalias nonnull i8* @_Znaj(i32 [[T6]]) // CHECK: getelementptr inbounds {{.*}}, i32 [[T1]] elt *test(long long s) { return new elt[s]; @@ -193,7 +193,7 @@ namespace test9 { // CHECK-NEXT: [[T3:%.*]] = extractvalue { i32, i1 } [[T2]], 1 // CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T2]], 0 // CHECK-NEXT: [[T6:%.*]] = select i1 [[T3]], i32 -1, i32 [[T5]] - // CHECK-NEXT: call i8* @_Znaj(i32 [[T6]]) + // CHECK-NEXT: call noalias nonnull i8* @_Znaj(i32 [[T6]]) // CHECK: getelementptr inbounds {{.*}}, i32 [[T1]] elt *test(unsigned long long s) { return new elt[s]; diff --git a/clang/test/CodeGenCXX/new.cpp b/clang/test/CodeGenCXX/new.cpp index 1f5288d..d8ad4c5 100644 --- a/clang/test/CodeGenCXX/new.cpp +++ b/clang/test/CodeGenCXX/new.cpp @@ -14,9 +14,9 @@ void t1() { delete [] new int [3]; } -// CHECK: declare noalias i8* @_Znwm(i64) [[ATTR_NOBUILTIN:#[^ ]*]] +// CHECK: declare nonnull i8* @_Znwm(i64) [[ATTR_NOBUILTIN:#[^ ]*]] // CHECK: declare void @_ZdlPv(i8*) [[ATTR_NOBUILTIN_NOUNWIND:#[^ ]*]] -// CHECK: declare noalias i8* @_Znam(i64) [[ATTR_NOBUILTIN]] +// CHECK: declare nonnull i8* @_Znam(i64) [[ATTR_NOBUILTIN]] // CHECK: declare void @_ZdaPv(i8*) [[ATTR_NOBUILTIN_NOUNWIND]] namespace std { @@ -52,7 +52,7 @@ struct S { void t3() { int *a = new int(10); _Complex int* b = new _Complex int(10i); - + S s; s.a = 10; S *sp = new S(s); @@ -74,7 +74,7 @@ struct T2 { T2(int, int); }; -void t5() { +void t5() { // CHECK: call void @_ZN2T2C1Eii T2 *t2 = new T2(10, 10); } @@ -91,15 +91,15 @@ void t7() { struct U { ~U(); }; - + void t8(int n) { new int[10]; new int[n]; - + // Non-POD new T[10]; new T[n]; - + // Cookie required new U[10]; new U[n]; @@ -108,7 +108,7 @@ void t8(int n) { void t9() { bool b; - new bool(true); + new bool(true); new (&b) bool(true); } @@ -127,19 +127,19 @@ struct B { int a; }; struct Bmemptr { int Bmemptr::* memptr; int a; }; void t11(int n) { - // CHECK: call i8* @_Znwm + // CHECK: call noalias nonnull i8* @_Znwm // CHECK: call void @llvm.memset.p0i8.i64( B* b = new B(); - // CHECK: call i8* @_Znam + // CHECK: call noalias nonnull i8* @_Znam // CHECK: {{call void.*llvm.memset.p0i8.i64.*i8 0, i64 %}} B *b2 = new B[n](); - // CHECK: call i8* @_Znam + // CHECK: call noalias nonnull i8* @_Znam // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64 // CHECK: br Bmemptr *b_memptr = new Bmemptr[n](); - + // CHECK: ret void } @@ -148,11 +148,11 @@ struct Empty { }; // We don't need to initialize an empty class. // CHECK-LABEL: define void @_Z3t12v void t12() { - // CHECK: call i8* @_Znam + // CHECK: call noalias nonnull i8* @_Znam // CHECK-NOT: br (void)new Empty[10]; - // CHECK: call i8* @_Znam + // CHECK: call noalias nonnull i8* @_Znam // CHECK-NOT: br (void)new Empty[10](); @@ -162,11 +162,11 @@ void t12() { // Zero-initialization // CHECK-LABEL: define void @_Z3t13i void t13(int n) { - // CHECK: call i8* @_Znwm + // CHECK: call noalias nonnull i8* @_Znwm // CHECK: store i32 0, i32* (void)new int(); - // CHECK: call i8* @_Znam + // CHECK: call noalias nonnull i8* @_Znam // CHECK: {{call void.*llvm.memset.p0i8.i64.*i8 0, i64 %}} (void)new int[n](); @@ -186,7 +186,7 @@ void f() { // CHECK: call void @_ZN5AllocD1Ev( // CHECK: call void @_ZN5AllocdaEPv(i8* delete[] new Alloc[10][20]; - // CHECK: call i8* @_Znwm + // CHECK: call noalias nonnull i8* @_Znwm // CHECK: call void @_ZdlPv(i8* delete new bool; // CHECK: ret void @@ -272,8 +272,8 @@ namespace PR10197 { // CHECK-LABEL: define weak_odr void @_ZN7PR101971fIiEEvv() template void f() { - // CHECK: [[CALL:%.*]] = call i8* @_Znwm - // CHECK-NEXT: [[CASTED:%.*]] = bitcast i8* [[CALL]] to + // CHECK: [[CALL:%.*]] = call noalias nonnull i8* @_Znwm + // CHECK-NEXT: [[CASTED:%.*]] = bitcast i8* [[CALL]] to new T; // CHECK-NEXT: ret void } @@ -294,7 +294,7 @@ namespace PR11757 { struct X { X(); X(const X&); }; X* a(X* x) { return new X(X()); } // CHECK: define {{.*}} @_ZN7PR117571aEPNS_1XE - // CHECK: [[CALL:%.*]] = call i8* @_Znwm + // CHECK: [[CALL:%.*]] = call noalias nonnull i8* @_Znwm // CHECK-NEXT: [[CASTED:%.*]] = bitcast i8* [[CALL]] to // CHECK-NEXT: call void @_ZN7PR117571XC1Ev({{.*}}* [[CASTED]]) // CHECK-NEXT: ret {{.*}} [[CASTED]] @@ -304,7 +304,7 @@ namespace PR13380 { struct A { A() {} }; struct B : public A { int x; }; // CHECK-LABEL: define i8* @_ZN7PR133801fEv - // CHECK: call i8* @_Znam( + // CHECK: call noalias nonnull i8* @_Znam( // CHECK: call void @llvm.memset.p0i8 // CHECK-NEXT: call void @_ZN7PR133801BC1Ev void* f() { return new B[2](); } @@ -318,40 +318,40 @@ namespace N3664 { // CHECK-LABEL: define void @_ZN5N36641fEv void f() { - // CHECK: call i8* @_Znwm(i64 4) [[ATTR_BUILTIN_NEW:#[^ ]*]] + // CHECK: call noalias nonnull i8* @_Znwm(i64 4) [[ATTR_BUILTIN_NEW:#[^ ]*]] int *p = new int; // expected-note {{allocated with 'new' here}} // CHECK: call void @_ZdlPv({{.*}}) [[ATTR_BUILTIN_DELETE:#[^ ]*]] delete p; - // CHECK: call i8* @_Znam(i64 12) [[ATTR_BUILTIN_NEW]] + // CHECK: call noalias nonnull i8* @_Znam(i64 12) [[ATTR_BUILTIN_NEW]] int *q = new int[3]; // CHECK: call void @_ZdaPv({{.*}}) [[ATTR_BUILTIN_DELETE]] delete[] p; // expected-warning {{'delete[]' applied to a pointer that was allocated with 'new'; did you mean 'delete'?}} - // CHECK: call i8* @_ZnamRKSt9nothrow_t(i64 3, {{.*}}) [[ATTR_BUILTIN_NOTHROW_NEW:#[^ ]*]] + // CHECK: call noalias i8* @_ZnamRKSt9nothrow_t(i64 3, {{.*}}) [[ATTR_BUILTIN_NOTHROW_NEW:#[^ ]*]] (void) new (nothrow) S[3]; // CHECK: call i8* @_Znwm15MyPlacementType(i64 4){{$}} (void) new (mpt) int; } - // CHECK: declare noalias i8* @_ZnamRKSt9nothrow_t(i64, {{.*}}) [[ATTR_NOBUILTIN_NOUNWIND]] + // CHECK: declare i8* @_ZnamRKSt9nothrow_t(i64, {{.*}}) [[ATTR_NOBUILTIN_NOUNWIND_ALLOCSIZE:#[^ ]*]] // CHECK-LABEL: define void @_ZN5N36641gEv void g() { // It's OK for there to be attributes here, so long as we don't have a // 'builtin' attribute. - // CHECK: call i8* @_Znwm(i64 4){{$}} + // CHECK: call noalias nonnull i8* @_Znwm(i64 4) {{#[^ ]*}}{{$}} int *p = (int*)operator new(4); // CHECK: call void @_ZdlPv({{.*}}) [[ATTR_NOUNWIND:#[^ ]*]] operator delete(p); - // CHECK: call i8* @_Znam(i64 12){{$}} + // CHECK: call noalias nonnull i8* @_Znam(i64 12) {{#[^ ]*}}{{$}} int *q = (int*)operator new[](12); // CHECK: call void @_ZdaPv({{.*}}) [[ATTR_NOUNWIND]] operator delete [](p); - // CHECK: call i8* @_ZnamRKSt9nothrow_t(i64 3, {{.*}}) [[ATTR_NOUNWIND]] + // CHECK: call noalias i8* @_ZnamRKSt9nothrow_t(i64 3, {{.*}}) [[ATTR_NOUNWIND_ALLOCSIZE:#[^ ]*]] (void) operator new[](3, nothrow); } } @@ -359,14 +359,15 @@ namespace N3664 { namespace builtins { // CHECK-LABEL: define void @_ZN8builtins1fEv void f() { - // CHECK: call i8* @_Znwm(i64 4) [[ATTR_BUILTIN_NEW]] + // CHECK: call noalias nonnull i8* @_Znwm(i64 4) [[ATTR_BUILTIN_NEW]] // CHECK: call void @_ZdlPv({{.*}}) [[ATTR_BUILTIN_DELETE]] __builtin_operator_delete(__builtin_operator_new(4)); } } -// CHECK-DAG: attributes [[ATTR_NOBUILTIN]] = {{[{].*}} nobuiltin {{.*[}]}} +// CHECK-DAG: attributes [[ATTR_NOBUILTIN]] = {{[{].*}} nobuiltin allocsize(0) {{.*[}]}} // CHECK-DAG: attributes [[ATTR_NOBUILTIN_NOUNWIND]] = {{[{].*}} nobuiltin nounwind {{.*[}]}} +// CHECK-DAG: attributes [[ATTR_NOBUILTIN_NOUNWIND_ALLOCSIZE]] = {{[{].*}} nobuiltin nounwind allocsize(0) {{.*[}]}} // CHECK-DAG: attributes [[ATTR_BUILTIN_NEW]] = {{[{].*}} builtin {{.*[}]}} // CHECK-DAG: attributes [[ATTR_BUILTIN_DELETE]] = {{[{].*}} builtin {{.*[}]}} @@ -374,3 +375,4 @@ namespace builtins { // The ([^b}|...) monstrosity is matching a character that's not the start of 'builtin'. // Add more letters if this matches some other attribute. // CHECK-DAG: attributes [[ATTR_NOUNWIND]] = {{([^b]|b[^u]|bu[^i]|bui[^l])*}} nounwind {{([^b]|b[^u]|bu[^i]|bui[^l])*$}} +// CHECK-DAG: attributes [[ATTR_NOUNWIND_ALLOCSIZE]] = {{([^b]|b[^u]|bu[^i]|bui[^l])*}} nounwind allocsize(0) {{([^b]|b[^u]|bu[^i]|bui[^l])*$}} diff --git a/clang/test/CodeGenCXX/operator-new.cpp b/clang/test/CodeGenCXX/operator-new.cpp index dc1c36d..d3679be 100644 --- a/clang/test/CodeGenCXX/operator-new.cpp +++ b/clang/test/CodeGenCXX/operator-new.cpp @@ -1,8 +1,7 @@ // RUN: %clang_cc1 -triple i686-pc-linux-gnu -emit-llvm -o %t-1.ll %s -// RUN: FileCheck -check-prefix SANE --input-file=%t-1.ll %s +// RUN: FileCheck --check-prefix=ALL -check-prefix SANE --input-file=%t-1.ll %s // RUN: %clang_cc1 -triple i686-pc-linux-gnu -emit-llvm -fno-assume-sane-operator-new -o %t-2.ll %s -// RUN: FileCheck -check-prefix SANENOT --input-file=%t-2.ll %s - +// RUN: FileCheck --check-prefix=ALL -check-prefix SANENOT --input-file=%t-2.ll %s class teste { int A; @@ -11,21 +10,20 @@ public: }; void f1() { - // SANE: declare noalias i8* @_Znwj( - // SANENOT: declare i8* @_Znwj( + // ALL: declare nonnull i8* @_Znwj( new teste(); } // rdar://5739832 - operator new should check for overflow in multiply. void *f2(long N) { return new int[N]; - -// SANE: [[UWO:%.*]] = call {{.*}} @llvm.umul.with.overflow -// SANE-NEXT: [[OVER:%.*]] = extractvalue {{.*}} [[UWO]], 1 -// SANE-NEXT: [[SUM:%.*]] = extractvalue {{.*}} [[UWO]], 0 -// SANE-NEXT: [[RESULT:%.*]] = select i1 [[OVER]], i32 -1, i32 [[SUM]] -// SANE-NEXT: call i8* @_Znaj(i32 [[RESULT]]) + + // ALL: [[UWO:%.*]] = call {{.*}} @llvm.umul.with.overflow + // ALL-NEXT: [[OVER:%.*]] = extractvalue {{.*}} [[UWO]], 1 + // ALL-NEXT: [[SUM:%.*]] = extractvalue {{.*}} [[UWO]], 0 + // ALL-NEXT: [[RESULT:%.*]] = select i1 [[OVER]], i32 -1, i32 [[SUM]] + // SANE-NEXT: call noalias nonnull i8* @_Znaj(i32 [[RESULT]]) + // SANENOT-NEXT: call nonnull i8* @_Znaj(i32 [[RESULT]]) } -// SANE: declare noalias i8* @_Znaj( -// SANENOT: declare i8* @_Znaj( +// ALL: declare nonnull i8* @_Znaj( diff --git a/clang/test/CodeGenCXX/runtime-dllstorage.cpp b/clang/test/CodeGenCXX/runtime-dllstorage.cpp index 694a9b4..4f63c93 100644 --- a/clang/test/CodeGenCXX/runtime-dllstorage.cpp +++ b/clang/test/CodeGenCXX/runtime-dllstorage.cpp @@ -110,7 +110,7 @@ void l() { // CHECK-MS-DAG: declare dso_local i32 @atexit(void ()*) // CHECK-MS-DYNAMIC-DAG: declare {{.*}} void @_CxxThrowException // CHECK-MS-STATIC-DAG: declare {{.*}} void @_CxxThrowException -// CHECK-MS-DAG: declare dso_local noalias i8* @"??2@YAPAXI@Z" +// CHECK-MS-DAG: declare dso_local nonnull i8* @"??2@YAPAXI@Z" // CHECK-MS-DAG: declare dso_local void @_Init_thread_header(i32*) // CHECK-MS-DAG: declare dso_local void @_Init_thread_footer(i32*) @@ -129,7 +129,7 @@ void l() { // CHECK-DYNAMIC-NODECL-IA-DAG: declare dllimport i32 @__cxa_guard_acquire(i64*) // CHECK-DYNAMIC-IMPORT-IA-DAG: declare dllimport i32 @__cxa_guard_acquire(i64*) // CHECK-DYNAMIC-EXPORT-IA-DAG: declare dllexport i32 @__cxa_guard_acquire(i64*) -// CHECK-IA-DAG: declare dso_local noalias i8* @_Znwj(i32) +// CHECK-IA-DAG: declare dso_local nonnull i8* @_Znwj(i32) // CHECK-DYNAMIC-DECL-IA-DAG: declare dllimport void @__cxa_guard_release(i64*) // CHECK-DYNAMIC-NODECL-IA-DAG: declare dllimport void @__cxa_guard_release(i64*) // CHECK-DYNAMIC-IMPORT-IA-DAG: declare dllimport void @__cxa_guard_release(i64*) @@ -147,7 +147,7 @@ void l() { // CHECK-STATIC-NODECL-IA-DAG: declare dso_local i32 @__cxa_guard_acquire(i64*) // CHECK-STATIC-IMPORT-IA-DAG: declare dso_local i32 @__cxa_guard_acquire(i64*) // CHECK-STATIC-EXPORT-IA-DAG: declare dso_local i32 @__cxa_guard_acquire(i64*) -// CHECK-IA-DAG: declare dso_local noalias i8* @_Znwj(i32) +// CHECK-IA-DAG: declare dso_local nonnull i8* @_Znwj(i32) // CHECK-STATIC-DECL-IA-DAG: declare dso_local void @__cxa_guard_release(i64*) // CHECK-STATIC-NODECL-IA-DAG: declare dso_local void @__cxa_guard_release(i64*) // CHECK-STATIC-IMPORT-IA-DAG: declare dso_local void @__cxa_guard_release(i64*) @@ -156,4 +156,3 @@ void l() { // CHECK-STATIC-NODECL-IA-DAG: declare dso_local void @_ZSt9terminatev() // CHECK-STATIC-IMPORT-IA-DAG: declare dso_local void @_ZSt9terminatev() // CHECK-STATIC-EXPORT-IA-DAG: declare dso_local dllexport void @_ZSt9terminatev() - diff --git a/clang/test/CodeGenCXX/static-init.cpp b/clang/test/CodeGenCXX/static-init.cpp index 925ddec..a420e13 100644 --- a/clang/test/CodeGenCXX/static-init.cpp +++ b/clang/test/CodeGenCXX/static-init.cpp @@ -28,7 +28,7 @@ void f() { } void g() { - // CHECK: call i8* @_Znwm(i64 1) + // CHECK: call noalias nonnull i8* @_Znwm(i64 1) // CHECK: call void @_ZN1AC1Ev( static A& a = *new A; } diff --git a/clang/test/CodeGenCoroutines/coro-alloc.cpp b/clang/test/CodeGenCoroutines/coro-alloc.cpp index 20b00d4..2e7a65a 100644 --- a/clang/test/CodeGenCoroutines/coro-alloc.cpp +++ b/clang/test/CodeGenCoroutines/coro-alloc.cpp @@ -61,7 +61,7 @@ extern "C" void f0(global_new_delete_tag) { // CHECK: [[AllocBB]]: // CHECK: %[[SIZE:.+]] = call i64 @llvm.coro.size.i64() - // CHECK: %[[MEM:.+]] = call i8* @_Znwm(i64 %[[SIZE]]) + // CHECK: %[[MEM:.+]] = call noalias nonnull i8* @_Znwm(i64 %[[SIZE]]) // CHECK: br label %[[InitBB]] // CHECK: [[InitBB]]: @@ -156,7 +156,7 @@ struct std::experimental::coroutine_traits { extern "C" void f2(promise_delete_tag) { // CHECK: %[[ID:.+]] = call token @llvm.coro.id(i32 16 // CHECK: %[[SIZE:.+]] = call i64 @llvm.coro.size.i64() - // CHECK: call i8* @_Znwm(i64 %[[SIZE]]) + // CHECK: call noalias nonnull i8* @_Znwm(i64 %[[SIZE]]) // CHECK: %[[FRAME:.+]] = call i8* @llvm.coro.begin( // CHECK: %[[MEM:.+]] = call i8* @llvm.coro.free(token %[[ID]], i8* %[[FRAME]]) @@ -202,7 +202,7 @@ struct std::experimental::coroutine_traits { extern "C" void f3(promise_sized_delete_tag) { // CHECK: %[[ID:.+]] = call token @llvm.coro.id(i32 16 // CHECK: %[[SIZE:.+]] = call i64 @llvm.coro.size.i64() - // CHECK: call i8* @_Znwm(i64 %[[SIZE]]) + // CHECK: call noalias nonnull i8* @_Znwm(i64 %[[SIZE]]) // CHECK: %[[FRAME:.+]] = call i8* @llvm.coro.begin( // CHECK: %[[MEM:.+]] = call i8* @llvm.coro.free(token %[[ID]], i8* %[[FRAME]]) @@ -230,7 +230,7 @@ extern "C" int f4(promise_on_alloc_failure_tag) { // CHECK: %[[Gro:.+]] = alloca i32 // CHECK: %[[ID:.+]] = call token @llvm.coro.id(i32 16 // CHECK: %[[SIZE:.+]] = call i64 @llvm.coro.size.i64() - // CHECK: %[[MEM:.+]] = call i8* @_ZnwmRKSt9nothrow_t(i64 %[[SIZE]], %"struct.std::nothrow_t"* dereferenceable(1) @_ZStL7nothrow) + // CHECK: %[[MEM:.+]] = call noalias i8* @_ZnwmRKSt9nothrow_t(i64 %[[SIZE]], %"struct.std::nothrow_t"* dereferenceable(1) @_ZStL7nothrow) // CHECK: %[[OK:.+]] = icmp ne i8* %[[MEM]], null // CHECK: br i1 %[[OK]], label %[[OKBB:.+]], label %[[ERRBB:.+]] diff --git a/clang/test/CodeGenCoroutines/coro-cleanup.cpp b/clang/test/CodeGenCoroutines/coro-cleanup.cpp index ba12469..16af75b 100644 --- a/clang/test/CodeGenCoroutines/coro-cleanup.cpp +++ b/clang/test/CodeGenCoroutines/coro-cleanup.cpp @@ -39,7 +39,7 @@ void may_throw(); // CHECK-LABEL: define void @_Z1fv( void f() { - // CHECK: call i8* @_Znwm(i64 + // CHECK: call noalias nonnull i8* @_Znwm(i64 // If promise constructor throws, check that we free the memory. diff --git a/clang/test/CodeGenCoroutines/coro-gro-nrvo.cpp b/clang/test/CodeGenCoroutines/coro-gro-nrvo.cpp index f4a7186..8a0b234 100644 --- a/clang/test/CodeGenCoroutines/coro-gro-nrvo.cpp +++ b/clang/test/CodeGenCoroutines/coro-gro-nrvo.cpp @@ -36,7 +36,7 @@ struct coro { // Verify that the NRVO is applied to the Gro object. // CHECK-LABEL: define void @_Z1fi(%struct.coro* noalias sret %agg.result, i32 %0) coro f(int) { -// CHECK: %call = call i8* @_Znwm( +// CHECK: %call = call noalias nonnull i8* @_Znwm( // CHECK-NEXT: br label %[[CoroInit:.*]] // CHECK: {{.*}}[[CoroInit]]: @@ -68,7 +68,7 @@ struct coro_two { // CHECK-LABEL: define void @_Z1hi(%struct.coro_two* noalias sret %agg.result, i32 %0) coro_two h(int) { -// CHECK: %call = call i8* @_ZnwmRKSt9nothrow_t +// CHECK: %call = call noalias i8* @_ZnwmRKSt9nothrow_t // CHECK-NEXT: %[[CheckNull:.*]] = icmp ne i8* %call, null // CHECK-NEXT: br i1 %[[CheckNull]], label %[[InitOnSuccess:.*]], label %[[InitOnFailure:.*]] diff --git a/clang/test/CodeGenCoroutines/coro-gro.cpp b/clang/test/CodeGenCoroutines/coro-gro.cpp index 95bf206..b2b9c11 100644 --- a/clang/test/CodeGenCoroutines/coro-gro.cpp +++ b/clang/test/CodeGenCoroutines/coro-gro.cpp @@ -49,7 +49,7 @@ int f() { // CHECK: %[[GroActive:.+]] = alloca i1 // CHECK: %[[Size:.+]] = call i64 @llvm.coro.size.i64() - // CHECK: call i8* @_Znwm(i64 %[[Size]]) + // CHECK: call noalias nonnull i8* @_Znwm(i64 %[[Size]]) // CHECK: store i1 false, i1* %[[GroActive]] // CHECK: call void @_ZNSt12experimental16coroutine_traitsIJiEE12promise_typeC1Ev( // CHECK: call void @_ZNSt12experimental16coroutine_traitsIJiEE12promise_type17get_return_objectEv( diff --git a/clang/test/CodeGenCoroutines/coro-return.cpp b/clang/test/CodeGenCoroutines/coro-return.cpp index 7577725..17356f9 100644 --- a/clang/test/CodeGenCoroutines/coro-return.cpp +++ b/clang/test/CodeGenCoroutines/coro-return.cpp @@ -33,7 +33,7 @@ template <> struct std::experimental::coroutine_traits { // CHECK-LABEL: f0( extern "C" void f0() { // CHECK: %__promise = alloca %"struct.std::experimental::coroutine_traits::promise_type" - // CHECK: %call = call i8* @_Znwm( + // CHECK: %call = call noalias nonnull i8* @_Znwm( // CHECK: call void @_ZNSt12experimental16coroutine_traitsIJvEE12promise_type11return_voidEv(%"struct.std::experimental::coroutine_traits::promise_type"* %__promise) // CHECK: call void @_ZdlPv co_return; @@ -52,7 +52,7 @@ struct std::experimental::coroutine_traits { // CHECK-LABEL: f1( extern "C" int f1() { // CHECK: %__promise = alloca %"struct.std::experimental::coroutine_traits::promise_type" - // CHECK: %call = call i8* @_Znwm( + // CHECK: %call = call noalias nonnull i8* @_Znwm( // CHECK: call void @_ZNSt12experimental16coroutine_traitsIJiEE12promise_type12return_valueEi(%"struct.std::experimental::coroutine_traits::promise_type"* %__promise, i32 42) // CHECK: call void @_ZdlPv co_return 42; diff --git a/clang/test/CodeGenObjCXX/arc-new-delete.mm b/clang/test/CodeGenObjCXX/arc-new-delete.mm index 0f66056b..ae3a863 100644 --- a/clang/test/CodeGenObjCXX/arc-new-delete.mm +++ b/clang/test/CodeGenObjCXX/arc-new-delete.mm @@ -12,32 +12,32 @@ void test_new(id invalue) { // OPT-NEXT: [[T0:%.*]] = call i8* @llvm.objc.retain(i8* [[INVALUE:%.*]]) // OPT-NEXT: store i8* [[T0]], i8** [[INVALUEADDR]] - // CHECK: call i8* @_Znwm + // CHECK: [[CALL:%.*]] = call noalias nonnull i8* @_Znwm // CHECK-NEXT: {{bitcast i8\*.*to i8\*\*}} // CHECK-NEXT: store i8* null, i8** new strong_id; - // CHECK: call i8* @_Znwm + // CHECK: [[CALL:%.*]] = call noalias nonnull i8* @_Znwm // CHECK-NEXT: {{bitcast i8\*.*to i8\*\*}} // UNOPT-NEXT: store i8* null, i8** // OPT-NEXT: call i8* @llvm.objc.initWeak(i8** {{.*}}, i8* null) new weak_id; - // CHECK: call i8* @_Znwm + // CHECK: [[CALL:%.*]] = call noalias nonnull i8* @_Znwm // CHECK-NEXT: {{bitcast i8\*.*to i8\*\*}} // CHECK-NEXT: store i8* null, i8** new __strong id; - // CHECK: call i8* @_Znwm + // CHECK: [[CALL:%.*]] = call noalias nonnull i8* @_Znwm // CHECK-NEXT: {{bitcast i8\*.*to i8\*\*}} // UNOPT-NEXT: store i8* null, i8** // OPT-NEXT: call i8* @llvm.objc.initWeak(i8** {{.*}}, i8* null) new __weak id; - // CHECK: call i8* @_Znwm + // CHECK: [[CALL:%.*]] = call noalias nonnull i8* @_Znwm // CHECK: call i8* @llvm.objc.retain // CHECK: store i8* new __strong id(invalue); - // CHECK: call i8* @_Znwm + // CHECK: [[CALL:%.*]] = call noalias nonnull i8* @_Znwm // CHECK: call i8* @llvm.objc.initWeak new __weak id(invalue); @@ -48,12 +48,12 @@ void test_new(id invalue) { // CHECK-LABEL: define void @_Z14test_array_new void test_array_new() { - // CHECK: call i8* @_Znam + // CHECK: call noalias nonnull i8* @_Znam // CHECK: store i64 17, i64* // CHECK: call void @llvm.memset.p0i8.i64 new strong_id[17]; - // CHECK: call i8* @_Znam + // CHECK: call noalias nonnull i8* @_Znam // CHECK: store i64 17, i64* // CHECK: call void @llvm.memset.p0i8.i64 new weak_id[17]; diff --git a/clang/test/CodeGenObjCXX/copy.mm b/clang/test/CodeGenObjCXX/copy.mm index 7783137..19a32eb 100644 --- a/clang/test/CodeGenObjCXX/copy.mm +++ b/clang/test/CodeGenObjCXX/copy.mm @@ -11,7 +11,7 @@ namespace test0 { // CHECK: alloca // CHECK-NEXT: getelementptr // CHECK-NEXT: store - // CHECK-NEXT: call i8* @_Znwm( + // CHECK-NEXT: [[CALL:%.*]] = call noalias nonnull i8* @_Znwm( // CHECK-NEXT: bitcast // CHECK-NEXT: bitcast // CHECK-NEXT: bitcast diff --git a/clang/test/SemaCXX/builtin-operator-new-delete.cpp b/clang/test/SemaCXX/builtin-operator-new-delete.cpp index 40d4732..6fcff92 100644 --- a/clang/test/SemaCXX/builtin-operator-new-delete.cpp +++ b/clang/test/SemaCXX/builtin-operator-new-delete.cpp @@ -75,7 +75,7 @@ void test_typo_in_args() { void test_arg_types() { __builtin_operator_new(NP); // expected-error {{no matching function for call to 'operator new'}} - __builtin_operator_new(NP, std::align_val_t(0)); // expected-error {{no matching function for call to 'operator new'}}} + __builtin_operator_new(NP, std::align_val_t(0)); // expected-error {{no matching function for call to 'operator new'}} } void test_return_type() { int w = __builtin_operator_new(42); // expected-error {{cannot initialize a variable of type 'int' with an rvalue of type 'void *'}} diff --git a/clang/test/SemaCXX/new-delete.cpp b/clang/test/SemaCXX/new-delete.cpp index 4db1206..64d32f2 100644 --- a/clang/test/SemaCXX/new-delete.cpp +++ b/clang/test/SemaCXX/new-delete.cpp @@ -27,7 +27,7 @@ inline void operator delete(void *); // expected-warning {{replacement function __attribute__((used)) inline void *operator new(size_t) { // no warning, due to __attribute__((used)) - return 0; + return 0; // expected-warning {{null returned from function that requires a non-null return value}} } // PR5823 @@ -53,9 +53,9 @@ void good_news() pi = ::new int; U *pu = new (ps) U; V *pv = new (ps) V; - + pi = new (S(1.0f, 2)) int; - + (void)new int[true]; // PR7147 @@ -329,7 +329,7 @@ namespace Test1 { void f() { (void)new int[10](1, 2); // expected-error {{array 'new' cannot have initialization arguments}} - + typedef int T[10]; (void)new T(1, 2); // expected-error {{array 'new' cannot have initialization arguments}} } @@ -363,7 +363,7 @@ class S2 { void operator delete(void* p); // expected-note {{declared private here}} }; -void test(S1* s1, S2* s2) { +void test(S1* s1, S2* s2) { delete s1; delete s2; // expected-error {{is a private member}} (void)new S1(); @@ -397,7 +397,7 @@ namespace rdar8018245 { // namespace Instantiate { - template struct X { + template struct X { operator T*(); }; -- 2.7.4